Commit Graph

887 Commits

Author SHA1 Message Date
Molecule AI Research Lead
29ffa50c3c chore(eco-watch): add MemPalace + update Google ADK — 2026-04-18 run a
- MemPalace (milla-jovovich/mempalace, 47.6k★, MIT, Python): local-first agent
  memory using Method of Loci; 29 MCP tools; 96.6% R@5 on LongMemEval; native
  Claude Code .claude-plugin integration. Verdict: WATCH
- Google ADK: update to v1.31.0 (Apr 17 2026) — multi-language parity
  (Python/TS/Java/Go), native A2A (full protocol, Linux Foundation standard).
  Platform gaps confirmed open (no scheduling, no cross-agent HITL).
  Verdict: WATCH maintained with enhanced escalation triggers.
2026-04-18 01:47:20 +00:00
molecule-ai[bot]
e4136d6b2a
Merge pull request #891 from Molecule-AI/fix/issue-826-smol-executor-env-sanitization
feat(security): denylist env sanitization + safe messaging for smolagents
2026-04-18 01:44:26 +00:00
molecule-ai[bot]
a5ebd49caf
Merge pull request #873 from Molecule-AI/fix/issue-854-eject-tooltip
fix(canvas): restore title tooltip on TeamMemberChip eject button alongside aria-label
2026-04-18 01:43:32 +00:00
7c49e0c86a Merge branch 'main' of https://github.com/Molecule-AI/molecule-core into fix/issue-854-eject-tooltip
# Conflicts:
#	canvas/src/components/WorkspaceNode.tsx
2026-04-18 01:43:00 +00:00
molecule-ai[bot]
776e7a50eb
Merge pull request #802 from Molecule-AI/chore/eco-watch-2026-04-17-i
chore(eco-watch): smolagents WATCH verdict + Managed Agents entry — 2026-04-17 run i
2026-04-18 01:34:57 +00:00
molecule-ai[bot]
ad4a210a16
Merge pull request #906 from Molecule-AI/fix/a11y-audit-902-905
fix(a11y): resolve accessibility issues #902–#905 (aria-pressed, aria-expanded, alertdialog, ID sanitisation)
2026-04-18 01:34:47 +00:00
80fceea243 fix(gate-6): merge main into fix/a11y-audit-902-905 — resolve 7 conflicts
Conflicts arose because PR #892 base commits (MemoryInspectorPanel creation,
A2A overlay) had already landed on main via a different merge path, and
last-tick merges (#876, #888) had modified Toolbar, SidePanel, and test
fixtures.

Resolution strategy:
- Toolbar.tsx, SidePanel.tsx, Canvas.a11y.test.tsx, Canvas.pan-to-node.test.tsx,
  MemoryInspectorPanel.test.tsx: take main (strictly newer, already contains
  the branch's A2A overlay content plus subsequent a11y/UX fixes)
- MemoryInspectorPanel.tsx: take main (543 lines with semantic search) + apply
  sanitizeId() helper from #904 + update bodyId prefix to mem-body-
- DetailsTab.tsx: take main (has #875 Field/useId + #878 deleteButtonRef/focus)
  + apply alertdialog structure from #905 while preserving focus management

Mechanical conflict resolution by triage-agent; no logic changes beyond the
four a11y fixes already in the branch (#902-#905).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:34:00 +00:00
molecule-ai[bot]
31779e99eb
Merge pull request #875 from Molecule-AI/fix/canvas-a11y-configtab-detailstab-htmlfor
fix(canvas): htmlFor/id association in ConfigTab + DetailsTab inputs
2026-04-18 01:24:42 +00:00
a696d7f235 Merge branch 'main' of https://github.com/Molecule-AI/molecule-core into fix/canvas-a11y-configtab-detailstab-htmlfor
# Conflicts:
#	canvas/src/components/tabs/DetailsTab.tsx
2026-04-18 01:24:15 +00:00
888353891e fix(gate-6): reconcile DetailsTab.tsx import — merge useRef (#878) with useId/cloneElement (#875)
PR #878 landed before this branch and added useRef + deleteButtonRef focus-
management to DetailsTab.tsx. This commit combines that import with the
useId/cloneElement import added here, and preserves the Field component
htmlFor/id wiring from this PR unchanged.

Mechanical conflict resolution by triage-agent; no logic changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:22:08 +00:00
molecule-ai[bot]
f159f149a0
Merge pull request #888 from Molecule-AI/fix/canvas-a11y-sidepanel-resize-keyboard
fix(canvas): a11y — SidePanel keyboard resize, MemoryEntryRow aria-controls, contrast + ChatTab error banner
2026-04-18 01:20:02 +00:00
molecule-ai[bot]
dcdd851c68
Merge pull request #887 from Molecule-AI/fix/canvas-a11y-conversation-trace-modal
fix(canvas): a11y — migrate ConversationTraceModal to Radix Dialog with aria-label
2026-04-18 01:19:57 +00:00
molecule-ai[bot]
ec515ba755
Merge pull request #878 from Molecule-AI/fix/canvas-a11y-detailstab-delete-confirm
fix(canvas): a11y improvements to DetailsTab delete confirmation dialog
2026-04-18 01:19:52 +00:00
molecule-ai[bot]
2844109078
Merge pull request #877 from Molecule-AI/fix/canvas-a11y-emptystate-role-alert
fix(canvas): add role=alert to empty-state error messages
2026-04-18 01:19:48 +00:00
molecule-ai[bot]
973cf15f7d
Merge pull request #876 from Molecule-AI/fix/canvas-a11y-toolbar-aria-label
fix(canvas): add aria-label to Toolbar icon buttons
2026-04-18 01:19:44 +00:00
molecule-ai[bot]
7b1833658f
Merge pull request #874 from Molecule-AI/fix/canvas-a11y-onboarding-aria-live
fix(canvas): add aria-live region to onboarding step transitions
2026-04-18 01:19:36 +00:00
Hongming Wang
be4e3bb485
Merge pull request #900 from Molecule-AI/fix/ci-go-mod-replace
fix(ci): remove go.mod replace /plugin — unblocks all CI
2026-04-17 18:17:11 -07:00
Molecule AI Frontend Engineer
1e4b6d0203 fix(a11y): DetailsTab — use role=alertdialog for delete confirmation (#905)
role="alert" is for passive announcements. A delete confirmation with
Confirm/Cancel action buttons requires a user response, which is the
semantics of role="alertdialog" (interactive dialog requiring response).

- Replace role="alert" with role="alertdialog" + aria-modal="true"
- Add aria-labelledby="delete-confirm-title" for an accessible name
- Add <h3 id="delete-confirm-title"> as the labelling element
  ("Confirm deletion") so AT announces the dialog purpose on focus

Closes #905

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:14:51 +00:00
Molecule AI Frontend Engineer
33cae9bb94 fix(a11y): MemoryInspectorPanel — sanitise bodyId, add aria-controls (#904)
Memory keys can contain characters like [ ] / : . # and spaces that make
invalid HTML id values (breaks CSS selectors and ARIA id-ref lookups).

- Add sanitizeId() helper: replaces non-alphanumeric chars with hyphens,
  collapses consecutive hyphens, strips leading/trailing hyphens
- Compute bodyId = "mem-body-{sanitizeId(entry.key)}" in MemoryEntryRow
- Set id={bodyId} on the expanded body container
- Set aria-controls={bodyId} on the toggle button so AT can navigate
  directly between the button and its controlled panel

Closes #904

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:14:35 +00:00
Molecule AI Frontend Engineer
92f95255c7 fix(a11y): ActivityTab — aria-pressed on filter pills and auto-refresh (#903)
- Add aria-pressed={filter === f.id} to every filter pill button so AT
  announces which filter is currently active
- Add aria-pressed={autoRefresh} to the auto-refresh toggle so AT
  announces the live/paused state when the button is activated

Closes #903

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:14:10 +00:00
Molecule AI Frontend Engineer
403fe63db8 fix(a11y): MemoryTab — role=alert, labelled inputs, aria-expanded (#902)
- Add role="alert" to the global error banner and the inline add-form
  error message so screen readers announce errors immediately on render
- Add aria-label to all three add-form inputs (key / value / TTL) so
  every form control has an accessible name (was flagged as unlabelled)
- Add aria-expanded={expanded === entry.key} to each entry toggle button
  so AT announces collapsed/expanded state on activation

Closes #902

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:13:56 +00:00
Molecule AI Frontend Engineer
b5d85a4706 fix(a11y): add role=alert to MemoryInspectorPanel error banner (#901)
The error banner div introduced in the MemoryInspectorPanel (PR #892)
was missing role="alert", regressing the a11y standard established in
PR #877 / issue #830. Screen readers now announce the error immediately
on render.

Closes #901

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:12:01 +00:00
Hongming Wang
a891bf9b4b fix(ci): remove go.mod replace /plugin — add it at Docker build time only
The replace directive `=> /plugin` breaks CI builds where go build runs
natively (no /plugin directory). Move the replace to Dockerfile RUN so
it only applies during Docker builds where the plugin is COPYed.

Fixes: "replacement directory /plugin does not exist" on CI runner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 18:08:53 -07:00
rabbitblood
f7706051aa fix: strip CRLF in entrypoint.sh at every container start
Windows Docker Desktop copies host files with CRLF even when
.gitattributes says eol=lf. The entrypoint now strips \r from all
hook .sh/.py files before dropping to agent user. Permanent fix for
the #507 CRLF regression that reappeared after every restart.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 18:06:04 -07:00
rabbitblood
43878d5b8f Merge branch 'main' of https://github.com/Molecule-AI/molecule-core 2026-04-17 17:52:18 -07:00
rabbitblood
92d80c0ee4 feat(telegram): poll for callback_query — CEO decision buttons work locally
Adds callback_query to AllowedUpdates in Telegram polling. When CEO
clicks Yes/No inline keyboard buttons:
1. Acknowledges press (removes loading spinner)
2. Updates message with 'CEO approved/rejected'
3. Routes 'CEO_DECISION: approve:xyz' as inbound to the agent

Only one workspace polls per bot token (Triage Operator) — other
workspaces with Telegram use outbound-only via direct API.

Fixed: duplicate pollers causing 'terminated by other getUpdates'
errors — removed PM/DevLead/ResearchLead Telegram channel rows
(they send outbound via direct Telegram API calls, not channel manager).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 17:52:10 -07:00
Molecule AI Frontend Engineer
67799f89da fix(canvas): resolve TS errors in test fixtures — budgetLimit and AuthGate mock types
- Add budgetLimit: null to WorkspaceNodeData fixtures in canvas-capabilities,
  canvas-events, canvas-events-pan, and canvas.test.ts (inline objects)
- Add budget_limit: null to WorkspaceData fixtures in canvas-topology,
  canvas.test.ts makeWS, and ProvisioningTimeout.test.tsx
- Fix AuthGate.test.tsx TS2348: cast vi.fn() mocks to explicit call
  signatures inside vi.mock() factories (Procedure | Constructable issue)
- npx tsc --noEmit: 0 errors; 689/689 tests passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 00:43:55 +00:00
Hongming Wang
a7e0ac7912
Merge pull request #881 from Molecule-AI/fix/issue-838-memory-secret-redact
fix(security): SAFE-T1201 — redact secrets in commit_memory before persistence (#838)
2026-04-17 17:17:19 -07:00
Hongming Wang
006c8f49c8
Merge pull request #882 from Molecule-AI/fix/issue-819-hibernate-toctou
fix(platform): atomic hibernate — TOCTOU race in HibernateWorkspace (closes #819)
2026-04-17 17:17:16 -07:00
Molecule AI Research Lead
7d905d5089 chore(eco-watch): smolagents WATCH → BUILD (threshold override, PM auth)
26,688★ below 30k criterion — BUILD authorized: HF corporate backing,
Tool.from_langchain zero-cost integration (~145 LOC), ~60-day trajectory
to 30k. Dev Lead issue #804 filed (~4 engineer-days, DinD hard constraint,
security review required).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 00:16:39 +00:00
Molecule AI Research Lead
9ff0d85684 chore(eco-watch): update smolagents WATCH verdict + add Managed Agents — 2026-04-17 run i
smolagents (GH #792 closed): WATCH — 2/3 criteria pass. A2A shim ~120-160 LOC
(fastapi-agents pattern validated), Apache-2.0 no lock-in, but 26.5k★ < 30k
threshold. Re-evaluate at 30k★ (~4-6 weeks) or HF default designation.
DinD gotcha documented: use local/e2b executor_type inside workspace containers.

Anthropic Managed Agents (GH #742 closed): WATCH-FOR-GA — beta API unstable,
RBAC passthrough requires async sidecar (architecturally non-trivial), cost
neutral at ~2 active hrs/day, session checkpointing ≠ Temporal replacement.
Re-evaluate at GA + multiagent research-preview exit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 00:16:39 +00:00
Molecule AI Research Lead
6d5fd8bb9a chore(eco-watch): add smolagents — 2026-04-17
Hugging Face's code-first agent framework (26.5k★, Apache-2.0). CodeAgent
pattern (Python-native tool calls), LiteLLM model-agnostic, E2B/Docker
sandboxing, Hub tool registry. Filed GH #792 to evaluate
molecule-ai-workspace-template-smolagents adapter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 00:16:39 +00:00
molecule-ai[bot]
bcd256946f
Merge pull request #890 from Molecule-AI/test/issue-790-crash-resume-integration
test(integration): crash-resume integration tests for Temporal checkpoints (#790)
2026-04-18 00:02:48 +00:00
molecule-ai[bot]
159c90e0f5
Merge pull request #798 from Molecule-AI/feat/issue-499-clean-3
feat(hermes): stacked system messages — persona + tools + reasoning policy (#499)
2026-04-18 00:02:29 +00:00
Molecule AI Backend Engineer
228d119e88 feat(security): denylist env sanitization + safe messaging for smolagents (#826, #827)
Add safe_env.py (denylist-based make_safe_env), send_message_wrapper.py
(label prefix, 2000-char cap, HTML entity escaping) and 33 pytest tests
covering all four security properties. Update __init__.py to re-export
safe_send_message alongside the existing allowlist-based make_safe_env.

Closes #826, closes #827

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:57:59 +00:00
Molecule AI Backend Engineer
9d171bda7f feat(hermes): stacked system messages — persona + tools + reasoning policy (#499)
HermesA2AExecutor now supports sending system context as ordered, separate
role=system messages instead of a single concatenated string — the model
format recommended by NousResearch.

Changes:
- HermesA2AExecutor.__init__: new system_blocks kwarg (list[str|None]|None)
  stored as an independent copy; None blocks and empty strings silently skipped
- _build_messages(): when system_blocks is not None, emits each non-empty
  block as a separate {"role": "system"} entry in Hermes-recommended order
  (persona → tools context → reasoning policy); falls through to legacy
  system_prompt path when system_blocks is None (backward compatible)

Backward compatibility: existing callers that pass a single system_prompt
string continue to work identically — no changes required.

Tests (12 new, 47 total):
  - system_blocks stored as independent copy (mutation safe)
  - three-block stacked ordering preserved
  - empty / None blocks silently skipped
  - all-empty list → zero system messages
  - system_blocks overrides system_prompt when both provided
  - legacy system_prompt path unchanged
  - stacked blocks appear in the live API call kwargs

Closes #499

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:53:12 +00:00
rabbitblood
fe250b256b fix: restore plugin COPY in Dockerfile — permanently fixes token endpoint
The Dockerfile COPY for molecule-ai-plugin-github-app-auth was lost
during a rebase earlier this session. Without it, the platform binary
compiled without the TokenProvider interface implementation, causing
/admin/github-installation-token to return 'no token provider registered'.

This forced hourly rolling restarts to refresh GH_TOKEN (the env var
from provision time expires after ~60 min). Each restart also required
re-applying 6 manual patches and caused ~2 min of A2A downtime where
agents reported peers as 'unresponsive'.

With this fix, the gh-wrapper in each container auto-refreshes tokens
via the platform endpoint on every gh call. Zero restarts needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 16:47:30 -07:00
Molecule AI Backend Engineer
4b8f4108cd fix(security): SAFE-T1201 — redact secrets in commit_memory before persistence
Adds `redactSecrets()` to the MemoriesHandler, scrubbing known credential
patterns before every INSERT into agent_memories, regardless of scope.

Closes #838. Satisfies SAFE-T1201 gate.

Patterns redacted (with `[REDACTED:<CLASS>]` replacement):
- Env-var assignments: `*_API_KEY=`, `*_TOKEN=`, `*_SECRET=`
- HTTP Bearer tokens
- sk-... prefixed keys (OpenAI / Anthropic format)
- ctx7_... tokens (context7)
- Base64 blobs ≥ 33 chars

The audit log SHA-256 hash now reflects the sanitised content (not the
raw input) so the forensic trail remains consistent with what was stored.

Tests added:
- TestRedactSecrets_CleanContent_PassesThrough
- TestRedactSecrets_APIKeyPattern_IsRedacted (API_KEY / TOKEN / SECRET)
- TestRedactSecrets_BearerToken_IsRedacted
- TestRedactSecrets_SKToken_IsRedacted
- TestRedactSecrets_Ctx7Token_IsRedacted
- TestRedactSecrets_Base64Blob_IsRedacted
- TestCommitMemory_SecretInContent_IsRedactedBeforeInsert

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:38:57 +00:00
Molecule AI Frontend Engineer
4acc6c1ed2 fix(a11y): add aria-label to Dialog.Content in ConversationTraceModal (Issue M)
Per UIUX Cycle 5 spec, Dialog.Content should carry an explicit
aria-label="Conversation trace" in addition to the aria-labelledby
automatically wired by Radix Dialog via Dialog.Title. This provides
a fallback accessible name directly on the dialog container element.

All 732 tests pass, build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:31:20 +00:00
Molecule AI Frontend Engineer
68ad062ae8 fix(a11y): migrate ConversationTraceModal to Radix Dialog (Issue M)
Custom <div> modal lacked focus trap, Escape handling, aria-modal, and
aria-labelledby. Migrated to the codebase-standard Radix Dialog pattern
(same as CreateWorkspaceDialog and SettingsPanel) which provides all
required WCAG 2.1 modal semantics automatically:

  • Dialog.Root + Dialog.Portal + Dialog.Overlay + Dialog.Content
    → role="dialog", aria-labelledby, focus trap, Escape key
  • Dialog.Title wraps "Conversation Trace" heading
    → aria-labelledby points to the title element
  • Dialog.Close asChild on ✕ button with aria-label="Close conversation trace"
    → accessible name for the dismiss button (WCAG 4.1.2)
  • Dialog.Close asChild on footer Close button
  • Backdrop → Dialog.Overlay (z-[59]) + Content wrapper (z-[60])
  • All timeline/body content unchanged; only modal scaffolding replaced

Added 10 WCAG tests in ConversationTraceModal.a11y.test.tsx covering:
dialog presence, accessible name, aria-labelledby, data-state, ✕ button
aria-label, close button click, Escape key, and loading indicator. All
732 tests pass, build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:26:47 +00:00
rabbitblood
cbee9a7237 chore: extract molecule-medo plugin to standalone repo
molecule-medo now lives at Molecule-AI/molecule-ai-plugin-molecule-medo
(same pattern as all other plugins). Removed the gitignore exception
that kept it in the monorepo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 16:11:50 -07:00
rabbitblood
595aa3681d chore: move spike/ → docs/spikes/ — keep explorations out of repo root
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 16:09:12 -07:00
Molecule AI Frontend Engineer
b57a8fa62b fix(canvas): align SkillsTab aria-label with spec — "Install from source URL"
Corrects the source-input aria-label wording to match the UIUX Cycle 4
spec exactly. Previous commit used "Install plugin from source URL";
spec says "Install from source URL" (matches the visible "Install from
source" section heading). Updates the corresponding test assertions.

No functional change. All 736 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:06:21 +00:00
Molecule AI Frontend Engineer
d9177a4cf4 fix(canvas): expand a11y htmlFor/aria-label to SkillsTab, FilesTab, ChannelsTab, ScheduleTab (issue #856)
WCAG 1.3.1 fixes for 4 remaining tabs identified in UIUX Cycle 4 audit:

- SkillsTab: aria-label="Install plugin from source URL" on bare source input
- FilesTab: aria-label="New file path" on bare new-file input
- ChannelsTab: useId() + htmlFor/id pairs for Platform, Bot Token,
  Chat IDs, and Allowed Users label↔input associations (4 pairs)
- ScheduleTab: aria-label="Schedule name" on bare name input;
  useId() + htmlFor/id pairs for Cron Expression, Timezone,
  and Prompt/Task label↔control associations (3 pairs)
- DetailsTab: fix ReactElement<{ id?: string }> cast in Field
  component to resolve React 19 TypeScript overload error

Adds 14 new WCAG tests in tabs.a11y.test.tsx covering all above fixes.
No visual change. All 736 tests pass. Build clean.

Closes #856

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:01:43 +00:00
Molecule AI Frontend Engineer
6a328646e2 fix(canvas): resolve TypeScript errors exposed by incremental cache invalidation
- WorkspaceNode.eject.test.tsx: add draggable/selectable/deletable to
  NodeProps render call (TS2739); add `as WorkspaceNodeData` cast on
  makeNodeData return to silence Partial<> spread widening (TS2322)

The cherry-picked fix/canvas-test-fixture-budgetlimit commit (fef664d)
also lands here — it resolves latent test-fixture drift in 7 test files
that the incremental tsc cache had masked on main but that became visible
once the new WorkspaceNode.eject.test.tsx file invalidated the cache.

tsc --noEmit: 0 errors | npm test: 726 passed | npm run build: clean

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 22:41:16 +00:00
Molecule AI Frontend Engineer
fef664d6d0 fix(canvas): add missing budgetLimit/budget_limit to test fixtures, fix AuthGate mock types
The budget PR (#541) added budgetLimit: number | null as a required field
on WorkspaceNodeData and budget_limit: number | null on WorkspaceData.
Seven test fixture factories were not updated, causing tsc --noEmit to
produce 34 TS2322/TS2345 errors (runtime tests still passed because
Vitest transpiles via esbuild which strips types).

Fixes:
- canvas-events.test.ts: makeNode factory +budgetLimit: null
- canvas-events-pan.test.ts: makeNode factory +budgetLimit: null
- canvas-capabilities.test.ts: makeNodeData factory +budgetLimit: null
- canvas-topology.test.ts: makeWS factory +budget_limit: null
- canvas.test.ts: makeWS factory +budget_limit: null; two inline
  summarizeWorkspaceCapabilities args +budgetLimit: null; context-menu
  fixture +budgetLimit: null
- ProvisioningTimeout.test.tsx: makeWS factory +budget_limit: null

Also fixes 3 TS2348 errors in AuthGate.test.tsx: newer Vitest type defs
resolve ReturnType<typeof vi.fn> to Mock<Procedure|Constructable> which
TypeScript no longer considers directly callable in a vi.mock factory.
Fix: intersect the mock variables with a plain function type so both the
call expression and the mock API (mockReturnValue etc.) type-check.

tsc --noEmit: 0 errors. npm test: 722/722.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 22:39:54 +00:00
molecule-ai[bot]
18cb498bca
Merge pull request #840 from Molecule-AI/feat/issue-800-opencode-mcp-bridge
feat(platform): opencode MCP bridge — remote A2A tools over HTTP (#800)
2026-04-17 22:15:38 +00:00
molecule-ai[bot]
9bce00d856
chore: sync opencode.md with main (conflict resolution post PR#842 merge)
PR#842 merged the docs/opencode.json to main with the correct MCP URL path.
PR#840 branch had an older version — sync to main's content to resolve conflict.
2026-04-17 22:14:59 +00:00
molecule-ai[bot]
00e3753f37
chore: sync opencode.json with main (conflict resolution post PR#842 merge)
PR#842 merged the docs/opencode.json to main with the correct MCP URL path.
PR#840 branch had an older version — sync to main's content to resolve conflict.
2026-04-17 22:14:57 +00:00
molecule-ai[bot]
c5a1318de8
fix(mcp): add TODO(#838) in toolCommitMemory + document X-Workspace-ID trust in toolDelegateTask
Security Auditor pre-merge conditions for PR#840:

C5: toolCommitMemory passes content directly to DB insert without secret
redaction. Gap is tracked to #838 (platform-wide _redactSecrets pass).
Adds inline TODO(#838) comment at the insert site so the gap is visible
in-code, not only in the issue tracker.

C6: toolDelegateTask sets X-Workspace-ID but no bearer token on the
outbound A2A call. The /workspaces/:id/a2a route is intentionally outside
WorkspaceAuth (by design in router.go). CanCommunicate is enforced before
the request is constructed, and callerID was authenticated by WorkspaceAuth
on the MCP bridge entry point. Documents this trust assumption at the call
site.
2026-04-17 22:13:55 +00:00