forked from molecule-ai/molecule-core
fix(workspace-server): emit Gitea/PyPI URLs for external user instructions (RFC #229 P2-5)
The Molecule-AI GitHub org was suspended 2026-05-06; canonical SCM is now git.moleculesai.app. external_connection.go was still emitting github.com URLs in operator-facing copy-paste blocks, breaking external-agent onboarding silently. Per-site decisions (8 emit sites in 1 file): - L124 (channel template doc comment): swap source-of-truth comment to Gitea host. - L137 /plugin marketplace add Molecule-AI/...: swap to explicit Gitea HTTPS URL form. End-to-end-verified path per internal#37 § 1.A. - L138 /plugin install molecule@molecule-mcp-claude-channel: marketplace name is molecule-channel (per remote .claude-plugin/marketplace.json), not the repo name. Fix to molecule@molecule-channel. - L157 --channels plugin:molecule@molecule-mcp-claude-channel: same marketplace-name fix. - L179 user-facing GitHub URL: swap to Gitea. - L261 pip install git+https://github.com/Molecule-AI/molecule-sdk-python: not on PyPI; swap to git+https://git.moleculesai.app/molecule-ai/... - L310 hermes-channel doc comment: swap source-of-truth comment. - L339 pip install git+https://github.com/Molecule-AI/hermes-channel-molecule: not on PyPI; swap to Gitea. - L369 issue-tracker URL: swap to Gitea. Verification: - molecule-ai-workspace-runtime, codex-channel-molecule are on PyPI (200); no swap needed for those pip lines (they were already package-name form). - molecule-mcp-claude-channel, molecule-sdk-python, hermes-channel-molecule are NOT on PyPI; swapped to git+https://git.moleculesai.app/molecule-ai/ form. All three repos are public on Gitea (default branch main) and serve git-upload-pack unauthenticated (verified curl 200 against /info/refs?service=git-upload-pack). - Third-party github URLs (gin import, openai/codex, NousResearch/ hermes-agent upstream issue trackers, npm @openai/codex) intentionally preserved. Adds TestExternalTemplates_NoBrokenMoleculeAIGitHubURLs regression guard to prevent the same broken URLs from re-emerging on future template edits. go vet / go build / existing TestExternal* — all clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5ecec3f253
commit
a355b6f0ad
@ -121,7 +121,7 @@ curl -fsS -X POST "{{PLATFORM_URL}}/registry/register" \
|
||||
// operators whose external agent IS a Claude Code session (laptop or
|
||||
// remote dev VM); routes the workspace's A2A traffic into the running
|
||||
// Claude Code session as conversation turns via MCP. The plugin source
|
||||
// lives at github.com/Molecule-AI/molecule-mcp-claude-channel — polling
|
||||
// lives at git.moleculesai.app/molecule-ai/molecule-mcp-claude-channel — polling
|
||||
// based, no tunnel required (uses /workspaces/:id/activity?since_secs=,
|
||||
// platform-side support shipped in #2300).
|
||||
const externalChannelTemplate = `# Claude Code channel — bridges this workspace's A2A traffic into your
|
||||
@ -134,8 +134,8 @@ const externalChannelTemplate = `# Claude Code channel — bridges this workspac
|
||||
# The plugin is NOT on Anthropic's default allowlist, so a one-time
|
||||
# marketplace-add is needed before install:
|
||||
#
|
||||
# /plugin marketplace add Molecule-AI/molecule-mcp-claude-channel
|
||||
# /plugin install molecule@molecule-mcp-claude-channel
|
||||
# /plugin marketplace add https://git.moleculesai.app/molecule-ai/molecule-mcp-claude-channel.git
|
||||
# /plugin install molecule@molecule-channel
|
||||
#
|
||||
# Then either run /reload-plugins or restart Claude Code so the
|
||||
# plugin is registered.
|
||||
@ -154,7 +154,7 @@ chmod 600 ~/.claude/channels/molecule/.env
|
||||
# flag to opt in — without it, you'll see "not on the approved channels
|
||||
# allowlist" on startup.
|
||||
claude --dangerously-load-development-channels \
|
||||
--channels plugin:molecule@molecule-mcp-claude-channel
|
||||
--channels plugin:molecule@molecule-channel
|
||||
|
||||
# You should see on stderr:
|
||||
# molecule channel: connected — watching 1 workspace(s) at {{PLATFORM_URL}}
|
||||
@ -176,7 +176,7 @@ claude --dangerously-load-development-channels \
|
||||
# add the plugin to allowedChannelPlugins in claude.ai admin settings.
|
||||
#
|
||||
# Multi-workspace: comma-separate IDs and tokens (same order). See
|
||||
# https://github.com/Molecule-AI/molecule-mcp-claude-channel for
|
||||
# https://git.moleculesai.app/molecule-ai/molecule-mcp-claude-channel for
|
||||
# pairing flow, push-mode upgrade, and v0.2 roadmap.
|
||||
|
||||
# Need help?
|
||||
@ -258,7 +258,7 @@ claude mcp add molecule -s user -- env \
|
||||
// externalPythonTemplate uses molecule-sdk-python's RemoteAgentClient +
|
||||
// A2AServer (PR #13 in that repo). Until the SDK cuts a v0.y release
|
||||
// to PyPI the snippet pins git+main.
|
||||
const externalPythonTemplate = `# pip install 'git+https://github.com/Molecule-AI/molecule-sdk-python.git@main'
|
||||
const externalPythonTemplate = `# pip install 'git+https://git.moleculesai.app/molecule-ai/molecule-sdk-python.git@main'
|
||||
|
||||
import asyncio
|
||||
from molecule_agent import RemoteAgentClient, A2AServer
|
||||
@ -307,7 +307,7 @@ if __name__ == "__main__":
|
||||
// A2A traffic into the running hermes gateway as platform messages
|
||||
// via the molecule-channel plugin.
|
||||
//
|
||||
// The plugin (Molecule-AI/hermes-channel-molecule) is a hermes
|
||||
// The plugin (molecule-ai/hermes-channel-molecule on Gitea) is a hermes
|
||||
// platform adapter that:
|
||||
// 1. Spawns ``python -m molecule_runtime.a2a_mcp_server`` as a
|
||||
// stdio MCP subprocess (separate from any hermes-side MCP
|
||||
@ -336,7 +336,7 @@ const externalHermesChannelTemplate = `# Hermes channel — bridges this workspa
|
||||
#
|
||||
# 1. Install the runtime + plugin:
|
||||
pip install molecule-ai-workspace-runtime
|
||||
pip install 'git+https://github.com/Molecule-AI/hermes-channel-molecule.git'
|
||||
pip install 'git+https://git.moleculesai.app/molecule-ai/hermes-channel-molecule.git'
|
||||
|
||||
# 2. Export the workspace credentials:
|
||||
export MOLECULE_WORKSPACE_ID={{WORKSPACE_ID}}
|
||||
@ -366,7 +366,7 @@ hermes gateway --replace
|
||||
# by the plugin's molecule_runtime MCP subprocess).
|
||||
#
|
||||
# Source + issue tracker:
|
||||
# https://github.com/Molecule-AI/hermes-channel-molecule
|
||||
# https://git.moleculesai.app/molecule-ai/hermes-channel-molecule
|
||||
|
||||
# Need help?
|
||||
# Documentation: https://doc.moleculesai.app/docs/guides/external-agent-registration
|
||||
|
||||
@ -75,3 +75,46 @@ func TestExternalMcpTemplates_UseMoleculeMcpWrapper(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestExternalTemplates_NoBrokenMoleculeAIGitHubURLs pins the invariant
|
||||
// that operator-facing snippets never embed github.com URLs pointing at
|
||||
// Molecule-AI repos.
|
||||
//
|
||||
// Why: the Molecule-AI GitHub org was suspended 2026-05-06 and the
|
||||
// canonical SCM is now git.moleculesai.app. Any `pip install
|
||||
// git+https://github.com/Molecule-AI/...` or marketplace-add Molecule-AI/
|
||||
// URL emitted to an external operator hits a 404 / org-suspended page,
|
||||
// breaking onboarding silently. RFC #229 P2-5.
|
||||
//
|
||||
// Third-party github URLs (gin, openai/codex, NousResearch/hermes-agent
|
||||
// upstream issue trackers, npm @openai/codex) remain valid — only
|
||||
// Molecule-AI/ paths are broken.
|
||||
func TestExternalTemplates_NoBrokenMoleculeAIGitHubURLs(t *testing.T) {
|
||||
templates := map[string]string{
|
||||
"externalCurlTemplate": externalCurlTemplate,
|
||||
"externalChannelTemplate": externalChannelTemplate,
|
||||
"externalUniversalMcpTemplate": externalUniversalMcpTemplate,
|
||||
"externalPythonTemplate": externalPythonTemplate,
|
||||
"externalHermesChannelTemplate": externalHermesChannelTemplate,
|
||||
"externalCodexTemplate": externalCodexTemplate,
|
||||
"externalOpenClawTemplate": externalOpenClawTemplate,
|
||||
}
|
||||
// Substrings that imply the snippet is pointing an operator at the
|
||||
// suspended Molecule-AI GitHub org.
|
||||
bannedSubstrings := []string{
|
||||
"github.com/Molecule-AI/",
|
||||
"github.com/molecule-ai/",
|
||||
// Bare `Molecule-AI/<repo>` form used by `/plugin marketplace add`
|
||||
// resolves through GitHub by default — explicit Gitea URL is
|
||||
// required post-suspension.
|
||||
"marketplace add Molecule-AI/",
|
||||
"marketplace add molecule-ai/",
|
||||
}
|
||||
for name, body := range templates {
|
||||
for _, banned := range bannedSubstrings {
|
||||
if strings.Contains(body, banned) {
|
||||
t.Errorf("%s contains %q — Molecule-AI GitHub org is suspended; use git.moleculesai.app/molecule-ai/<repo> instead (RFC #229 P2-5)", name, banned)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user