Commit Graph

909 Commits

Author SHA1 Message Date
Hongming Wang
23f32b22ca
Merge pull request #849 from Molecule-AI/docs/partner-api-keys
docs: Partner API Keys — programmatic org management (Phase 34)
2026-04-17 21:41:46 -07:00
Hongming Wang
76d3b32ab9 fix: resolve PLAN.md merge conflict — keep both Phase 34 and Phase 36
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 21:41:32 -07:00
Hongming Wang
4bf13bbb81
Merge pull request #927 from Molecule-AI/chore/eco-watch-2026-04-18
chore(eco-watch): 2026-04-18 daily sweep — chrome-devtools-mcp + craft-agents-oss + BLOCK MemPalace
2026-04-17 21:40:29 -07:00
Hongming Wang
97379f4de8
Merge pull request #880 from Molecule-AI/docs/safe-mcp-advisory-2026-04-17
docs(security): SAFE-MCP internal advisory 2026-04-17
2026-04-17 21:40:26 -07:00
Hongming Wang
1c35488bf6
Merge pull request #922 from Molecule-AI/infra/issue-894-anthropic-api-key-docs
docs(infra): document ANTHROPIC_API_KEY as required global secret (closes #894)
2026-04-17 21:40:23 -07:00
Hongming Wang
ac2923b04f
Merge pull request #934 from Molecule-AI/feat/cloudflare-tunnel-per-tenant
docs: staging environment design + Phase 36 + Tunnel migration plan
2026-04-17 21:40:14 -07:00
rabbitblood
049fcda066 fix(provisioner): strip CRLF from .sh/.py/.md in CopyTemplateToContainer
Second layer of the permanent CRLF fix. The Go provisioner now strips
\r\n → \n from shell, Python, and markdown files during the tar
copy into containers.

Three-layer CRLF defense:
1. Provisioner (this) — strips during template copy
2. Entrypoint.sh — strips at boot (safety net)
3. Runtime plugin installer (builtins.py) — strips during plugin install

Any one layer is sufficient. All three together make CRLF impossible.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 21:37:55 -07:00
Hongming Wang
2dbb59cb35 docs: staging environment design + Phase 36 plan
Full staging environment that mirrors production. Every infra change
ships to staging first before promotion. Gates Phase 33 (Tunnel) and
Phase 35 (security hardening).

Components: Railway staging env, Neon branch, staging DNS, tagged
Docker images, promotion workflow, automated smoke tests.

Also marks Phase 33 as migrating from Worker to Cloudflare Tunnel
(issue #933), prerequisite: staging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:37:11 -07:00
Hongming Wang
cb122c98e5
Merge pull request #930 from Molecule-AI/fix/ci-path-filter-merge-commits
fix(ci): path filter for merge commits — use event.before
2026-04-17 20:23:44 -07:00
Hongming Wang
7c51e3799c fix(ci): use github.event.before for push diff, fetch-depth 0
HEAD~1 doesn't work for merge commits. Use github.event.before (the
previous main tip) for push events and github.event.pull_request.base.sha
for PRs. fetch-depth: 0 ensures both SHAs are available.

Fallback: if BASE is empty (new branch), run all jobs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:23:28 -07:00
Hongming Wang
ce553b5197
Merge pull request #928 from Molecule-AI/fix/ci-path-filter-macos
fix(ci): replace dorny/paths-filter with git diff — unblocks all CI
2026-04-17 20:16:55 -07:00
Hongming Wang
3b5274e712 fix(ci): replace dorny/paths-filter with git diff (macOS compat)
dorny/paths-filter uses Docker internally which doesn't work on the
self-hosted macOS arm64 runner — every CI run since the path filter
change has failed with no jobs.

Replace with a simple git diff against HEAD~1 that checks path prefixes.
Same behavior, no Docker dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:16:39 -07:00
Molecule AI Research Lead
c7212891ea chore(eco-watch): resolve merge conflict — keep BLOCKED MemPalace + run b entries
Remote had the pre-fraud-audit MemPalace WATCH entry. Resolved by keeping
HEAD: BLOCKED/FRAUD verdict (SA audit 2026-04-18) plus the two new run-b
entries (chrome-devtools-mcp, craft-agents-oss).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 03:14:23 +00:00
Molecule AI Research Lead
24a5b0b13d chore(eco-watch): add chrome-devtools-mcp + craft-agents-oss — 2026-04-18 run b
Two new entries from daily sweep (TR GitHub trending + CI social feeds):

- chrome-devtools-mcp (ChromeDevTools/chrome-devtools-mcp, 35.9k★): Official
  Google Chrome DevTools MCP server — 29 tools for browser control, network
  inspection, Lighthouse audits. Strong MCP adoption signal from Google.
  GH #926 filed: add as bundled MCP server option in workspace templates.

- craft-agents-oss (lukilabs/craft-agents-oss, 4.3k★): Electron desktop app
  on Claude Agent SDK — multi-session inbox, 3-tier permissions, MCP support.
  Single-user desktop vs. Molecule's multi-tenant org-graph. UX reference for
  approval queue / permission tier UI.

CI sweep clean (no additional findings). RevoClaw near-miss logged (outside
24h window, no public repo yet).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 03:12:59 +00:00
Hongming Wang
c56cd3b6b2
Merge pull request #924 from Molecule-AI/docs/session-retrospective-2026-04-17
docs: SaaS buildout retrospective + Phase 35 hardening plan
2026-04-17 20:10:02 -07:00
Hongming Wang
232e90248b docs: session retrospective + Phase 35 hardening plan
Full retrospective of the 2026-04-16/17 SaaS buildout session:
- What was done (infra migration, 40+ PRs, 5 issues, 4 docs, 1 new repo)
- What should NOT have been changed (wildcard DNS churn, AdminAuth shortcut)
- Security concerns (8 items, 2 CRITICAL)
- Workflow gaps (registration, boot time, CI)
- Tests needed (automated + manual + security)

Phase 35 in PLAN.md covers production hardening follow-ups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:08:39 -07:00
a4df8cc5d4 docs(infra): document ANTHROPIC_API_KEY as required global secret (closes #894)
- Add comment to .env.example explaining ANTHROPIC_API_KEY must be set
  as a *global* secret (not just workspace-level) so SDK-direct workspaces
  (e.g. molecule-hitl, hermes) receive it without 401 errors
- Add ANTHROPIC_API_KEY to saas-secrets.md secret map with context on
  why global propagation matters
- Add full rotation procedure section (generate → PUT /settings/secrets
  → verify restart → revoke old key) with blast-radius note

Closes #894

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 03:03:37 +00:00
rabbitblood
06252723f3 fix: auto-post only to Slack, never Telegram
BroadcastToWorkspaceChannels now filters channel_type='slack'.
Telegram is CEO-only — explicit escalations via agent's outbound call,
never auto-posted from cron output. PM's routine pulses and agent
errors were spamming the CEO's Telegram.

PM's Telegram channel stays enabled for POLLING (inbound CEO messages)
but BroadcastToWorkspaceChannels skips it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 19:04:31 -07:00
Molecule AI Research Lead
76f3894518 chore(eco-watch): BLOCK MemPalace — coordinated fraud (SA audit 2026-04-18)
SA forensic audit found: 89% bot-farmed stars (42k of 47.6k), malware
domain mempalace.tech, deleted PyPI maintainer (supply-chain risk),
unpatched ChromaDB RCE (#6717), non-existent PyPI package (squattable),
unsafe HuggingFace pickle loading, and crypto pump-and-dump association.
Verdict changed from WATCH to BLOCKED/FRAUD. GH #912 plugin proposal
is closed per audit verdict.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:48:03 +00:00
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 Research Lead
9d5a4ad226 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:15:44 +00: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