v0.4.0-gitea.1 polled /workspaces/:id/activity but never sent
/registry/heartbeat. The platform's healthsweep
(workspace-server/internal/registry/healthsweep.go) flipped any
runtime='external' workspace whose last_heartbeat_at was older than
90s back to status='awaiting_agent', so the canvas presence badge
stuck on awaiting_agent within 90s of plugin start even while A2A
traffic flowed fine over the long-poll loop.
Fix: per-workspace heartbeat ticker (default 30s, three ticks inside
the 90s stale window) POSTs the minimal HeartbeatPayload shape
(workspace_id only) — same path the Python runtime in
workspace/heartbeat.py uses when it has nothing else to report.
heartbeat.ts pure module + Bun.serve fixture test pin the wire
shape (POST + bearer + Origin + workspace_id body) so a future
refactor that drops any of those silently re-breaks the badge.
Bump 0.4.0-gitea.1 → 0.4.0-gitea.2 and document
MOLECULE_HEARTBEAT_INTERVAL_MS in README.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the bits needed for `claude plugin marketplace add
https://git.moleculesai.app/molecule-ai/molecule-mcp-claude-channel.git`
to actually work, and rewrites the README install section to use the
canonical Claude Code marketplace flow (replacing the suspended-GitHub
install command).
Changes:
- New `.claude-plugin/marketplace.json` describing the single-plugin
marketplace `molecule-channel` with one plugin entry `molecule`.
Required for `claude plugin marketplace add` to recognize this repo.
- Bump `.claude-plugin/plugin.json` version `0.1.0` → `0.4.0-gitea.1`.
- Bump `package.json` version `0.3.0` → `0.4.0-gitea.1`. (Both versions
were already drifted; this reconciles them.)
- README install section rewritten:
- Old: `claude --channels plugin:molecule@Molecule-AI/molecule-mcp-claude-channel`
(suspended-GitHub URL, no longer resolves)
- New: `claude plugin marketplace add https://git.moleculesai.app/...`
+ `claude plugin install molecule@molecule-channel` (canonical
marketplace flow per Claude Code docs)
- README "Contributing" issues link migrated github.com → Gitea.
- Migration note for users on the old install path: GitHub
Molecule-AI org permanently gone 2026-05-06; new path is direct
replacement, behavior unchanged.
Version `0.4.0-gitea.1` admits the lineage gap with the
never-recovered-from-GitHub `v0.4.x` work; preserves user expectation
of a 0.4.x release. Annotated tag to follow this PR (re-tag is cheap if
Hongming prefers a different version).
Refs: molecule-ai/internal#37, molecule-ai/internal#38
Bridges Molecule A2A traffic into a Claude Code session via MCP. Inbound
A2A messages from watched workspaces surface as conversation turns
(notifications/claude/channel); replies route back through the existing
POST /workspaces/:id/a2a endpoint via the reply_to_workspace MCP tool.
Architecture:
- Polling-based inbound (uses /activity?since_secs= shipped in molecule-core
PR #2300). Works through every NAT/firewall, no tunnel required —
optimized for laptop-launched Claude Code sessions vs the existing
push-based external-agent flow that needs ngrok.
- Per-workspace bearer auth (MOLECULE_WORKSPACE_TOKENS, comma-separated to
match MOLECULE_WORKSPACE_IDS). Same token covers /activity (read) and
/a2a (write).
- Singleton lock at ~/.claude/channels/molecule/bot.pid prevents two
channel servers racing the dedup state.
- Dedup by activity.id; 30s overlap window over a 5s poll interval
protects against missed ticks (laptop sleep, transient network blips).
v0.1 ships:
- .claude-plugin/plugin.json, .mcp.json, package.json, LICENSE (Apache-2.0)
- server.ts: MCP server with notification emission + reply_to_workspace tool
- README: install + .env config + architecture notes + v0.2 roadmap
v0.1 explicit non-goals (tracked in README):
- No push-mode inbound (requires tunnel; deferred to v0.2)
- No pairing flow (manual .env tokens; canvas pairing in v0.2)
- No file-attachment download (URLs surface in meta; host fetches on-demand)
- No outbound channel-init (only replies; start_workspace_chat in v0.2)
Mirrors the architecture of @claude-plugins-official/telegram v0.0.6
(MCP notification contract: notifications/claude/channel with
{content, meta}) so the host's existing channel-handling logic works
without custom adapters.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>