Commit Graph

4 Commits

Author SHA1 Message Date
00799b45c6 fix: v0.4.0-gitea.3 — claude/channel capability + notify echo filter + README accuracy
All checks were successful
Test / bun test (pull_request) Successful in 23s
Reno-Stars (airenostars) verified install end-to-end against v0.4.0-gitea.2
ONLY after applying a local patch. This ships the same patch upstream so
fresh self-hosters get a working install out-of-the-box, no per-host
workaround required.

P0 (CRITICAL) — declare experimental.claude/channel capability
The Server constructor previously declared `{ capabilities: { tools: {} } }`.
Without `experimental['claude/channel']` (and the companion
`claude/channel/permission` flag), Claude Code's MCP host treats the
server as tool-only and silently drops every `notifications/claude/channel`
event we emit. Symptom: poll loop runs cleanly, cursor advances, stderr
says "delivered", message never reaches the conversation. Mirrors the
shape used by the official telegram channel plugin's MCP server.

P1 — filter outbound `method=notify` rows in pollWorkspace
The activity feed under `?type=a2a_receive` ALSO returns the agent's own
outbound /notify calls (recorded with method='notify' and source_id=null
on the same workspace_id). emitNotification would classify them as
canvas_user inbound and the reply would echo back as a fake user turn one
poll later — the model would see its own answer as a new user prompt and
try to "respond" to it. Filtered at the per-row layer via a new pure
helper `shouldEmitActivity` so the cursor still advances past the
skipped rows.

P2 — README accuracy
- Drop the `claude --channels plugin:…` one-liner instruction (silently
  no-ops on Claude Code 2.1.129; only the marketplace flow works).
- Document `allowedChannelPlugins` schema: it's an array of OBJECTS
  `{ plugin, marketplace }`, not strings — the host's Zod validator
  silently ignores string entries, which is the most common cause of
  "plugin installed but no notifications" reports.
- Document `allowedChannelPlugins` LOCATION: only takes effect from the
  managed-settings file (/Library/Application Support/ClaudeCode/
  managed-settings.json on macOS, /etc/claude-code/managed-settings.json
  on Linux), NOT from `~/.claude/settings.json`. Most self-hosters try
  user settings first.

Tests
Added channel-capabilities-and-filter.test.ts (9 cases) that pin both
regressions via two small exported surfaces (`SERVER_CAPABILITIES`,
`shouldEmitActivity`). Verified the new tests fail when each fix is
reverted: removing the experimental block makes 2 tests fail; removing
the notify-method filter makes 2 tests fail. 27 pass / 0 fail (was 18).

Version bump (all four manifests + the Server() literal):
0.4.0-gitea.2 → 0.4.0-gitea.3.

Closes Reno-Stars feedback P0+P1+P2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 11:01:33 -07:00
b3b79a5efc fix(presence): POST /registry/heartbeat ticker so canvas badge stays online (closes #6, closes molecule-core#24)
All checks were successful
Test / bun test (pull_request) Successful in 20s
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>
2026-05-07 08:28:24 -07:00
documentation-specialist
a6a61b78d0 fix(marketplace): switch source from '.' to url-form (#37 Phase 4 verify)
Some checks failed
Test / bun test (pull_request) Failing after 17s
Phase 4 E2E install verify of #37 (clean Docker container,
node:20-bookworm, Claude Code 2.1.132 latest stable):

Step 1: claude plugin marketplace add — SUCCEEDED (marketplace.json
recognized, validated, registered as 'molecule-channel').

Step 2: claude plugin install molecule@molecule-channel — FAILED with:
'This plugin uses a source type your Claude Code version does not
support. Update Claude Code and try again.'

Root cause: source: '.' (relative-path form) is not supported in
Claude Code 2.1.132. The url-form is supported and works
identically:

  source:
    source: url
    url: https://git.moleculesai.app/molecule-ai/molecule-mcp-claude-channel.git

Re-tested with the url-form: claude plugin install succeeded; plugin
appears in 'claude plugin list' as 'molecule@molecule-channel'
v0.4.0-gitea.1, status: enabled.

This is exactly the §1 weakest spot in molecule-mcp-claude-channel#1's
hostile self-review:
  '"source: "."" in marketplace.json is a guess at semantics. The
  Claude Code docs confirm source accepts a local path or git URL
  but don't give an example for "the plugin is at the marketplace
  root". "." is the conventional same-dir-as-marketplace.json
  semantic; if it's wrong, claude plugin install fails fast in
  Phase 4 with a clear error and the fix is one line.'

The fix IS one line. Phase 4 forecast was correct.

Refs: molecule-ai/internal#37 (Phase 4)
2026-05-07 02:22:18 -07:00
documentation-specialist
ebeb7d9f55 fix(install): make Gitea repo install-ready + canonical marketplace flow (#37)
Some checks failed
Test / bun test (pull_request) Failing after 20s
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
2026-05-06 23:14:42 -07:00