diff --git a/README.md b/README.md index bed10d55..8d50dc6b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ **Turn a codebase or system description into a polished, interactive system map — directly in chat.** -Archify is a Node.js rendering and validation system for Cursor, Claude Code, Codex CLI, OpenCode, and GitHub Copilot. Agents produce typed JSON IR; Archify deterministically compiles it into HTML/SVG. +Archify is a rendering and validation system for Cursor, Claude Code, Codex CLI, OpenCode, GitHub Copilot, and WorkBuddy. Agents produce typed JSON IR; Archify deterministically compiles it into HTML/SVG. - **Open it and present** — five diagram types, four presets, dark/light themes, built-in brand marks, and finite motion - **Review architecture changes before merge** — compare two validated snapshots as Before / Delta / After, with exact added, removed, changed, moved, and rerouted facts diff --git a/README_EN.md b/README_EN.md index bed10d55..8d50dc6b 100644 --- a/README_EN.md +++ b/README_EN.md @@ -12,7 +12,7 @@ **Turn a codebase or system description into a polished, interactive system map — directly in chat.** -Archify is a Node.js rendering and validation system for Cursor, Claude Code, Codex CLI, OpenCode, and GitHub Copilot. Agents produce typed JSON IR; Archify deterministically compiles it into HTML/SVG. +Archify is a rendering and validation system for Cursor, Claude Code, Codex CLI, OpenCode, GitHub Copilot, and WorkBuddy. Agents produce typed JSON IR; Archify deterministically compiles it into HTML/SVG. - **Open it and present** — five diagram types, four presets, dark/light themes, built-in brand marks, and finite motion - **Review architecture changes before merge** — compare two validated snapshots as Before / Delta / After, with exact added, removed, changed, moved, and rerouted facts diff --git a/README_ZH.md b/README_ZH.md index e07f3123..71f6bff5 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -8,7 +8,7 @@ **在对话里,把代码仓库或系统描述变成漂亮、可靠、可交互的系统地图。** -Archify 是一套基于 Node.js 的渲染与校验系统,并以 Agent Skill 的形式支持 Raven、Cursor、Claude Code、Codex CLI、OpenCode 和 GitHub Copilot。Agent 负责生成 Typed JSON IR,Archify 再校验并确定性编译为便携、独立的 HTML/SVG 成品。 +Archify 是一套基于 Node.js 的渲染与校验系统,并以 Agent Skill 的形式支持 Raven、Cursor、Claude Code、Codex CLI、OpenCode、GitHub Copilot 和 WorkBuddy。Agent 负责生成 Typed JSON IR,Archify 再校验并确定性编译为便携、独立的 HTML/SVG 成品。 - **打开就是成品** —— 五种技术图、四套视觉预设、深浅主题、内置品牌徽标,以及显式启用的有限动态 - **合并前先看清架构变化** —— 把两份已校验快照对比为 Before / Delta / After,准确区分新增、删除、语义变化、移动和重路由 diff --git a/archify/test/cursor-onboarding.test.mjs b/archify/test/cursor-onboarding.test.mjs index 78c6e5ac..30324b68 100644 --- a/archify/test/cursor-onboarding.test.mjs +++ b/archify/test/cursor-onboarding.test.mjs @@ -19,8 +19,8 @@ test('Cursor onboarding stays explicit, bilingual, and backed by the same Skill' const landing = fs.readFileSync(path.join(repoRoot, 'docs', 'index.html'), 'utf8'); assert.equal(english, englishMirror, 'English README mirrors must stay synchronized'); - assert.match(english, /Cursor, Claude Code, Codex CLI, OpenCode, and GitHub Copilot/); - assert.match(chinese, /Cursor、Claude Code、Codex CLI、OpenCode 和 GitHub Copilot/); + assert.match(english, /Cursor, Claude Code, Codex CLI, OpenCode, GitHub Copilot, and WorkBuddy/); + assert.match(chinese, /Cursor、Claude Code、Codex CLI、OpenCode、GitHub Copilot 和 WorkBuddy/); for (const surface of [english, chinese, landing]) assert.ok(surface.includes(cursorCommand)); for (const surface of [english, chinese, start, landing]) { assert.doesNotMatch(surface, /skills use[^\n<]*--agent cursor/); @@ -39,6 +39,86 @@ test('Cursor onboarding stays explicit, bilingual, and backed by the same Skill' assert.doesNotMatch(start, /vendor-specific (?:renderer|schema|skill)/i); }); +// The generated switcher's current membership. GitHub Copilot joined in #288, so this +// baseline tracks the five tabs the Start surface actually ships today. WorkBuddy is +// deliberately absent: it is a manual-copy instruction, not a generated switcher tab. +const switcherAgents = ['cursor', 'codex', 'claude-code', 'opencode', 'github-copilot']; + +test('WorkBuddy is documented on the Start surface but stays outside the agent switcher', () => { + const english = fs.readFileSync(path.join(repoRoot, 'README.md'), 'utf8'); + const chinese = fs.readFileSync(path.join(repoRoot, 'README_ZH.md'), 'utf8'); + const landing = fs.readFileSync(path.join(repoRoot, 'docs', 'index.html'), 'utf8'); + const template = fs.readFileSync(path.join(repoRoot, 'scripts', 'start-template.html'), 'utf8'); + const start = fs.readFileSync(path.join(repoRoot, 'docs', 'start.html'), 'utf8'); + + // The canonical template and the checked-in generated page must agree: both carry + // the bilingual WorkBuddy manual-install instruction and its exact destination. + for (const [surface, label] of [ + [template, 'scripts/start-template.html'], + [start, 'docs/start.html'], + ]) { + assert.match( + surface, + /data-en="WorkBuddy is supported by copying the skill into your WorkBuddy skills directory/, + `${label}: English WorkBuddy instruction must stay on the Start surface`, + ); + assert.match( + surface, + /data-zh="WorkBuddy 采用手动复制到技能目录的方式安装/, + `${label}: Chinese WorkBuddy instruction must stay on the Start surface`, + ); + + // Exact documented destination: once in the English copy, once in the Chinese + // copy, and once as the visible text a reader can select. + const destinations = surface.match(/~\/\.workbuddy\/skills\/archify/g) ?? []; + assert.equal( + destinations.length, + 3, + `${label}: ~/.workbuddy/skills/archify must appear in the English copy, the Chinese copy, and the visible text`, + ); + + // Switcher boundary: WorkBuddy is documented, never a generated tab. + assert.doesNotMatch( + surface, + /data-agent="workbuddy"/, + `${label}: WorkBuddy must not become an agent-switcher tab`, + ); + const tabs = [...surface.matchAll(/data-agent="([a-z-]+)">/g)].map((match) => match[1]); + assert.deepEqual( + tabs, + switcherAgents, + `${label}: the switcher must stay exactly the supported agents, with WorkBuddy excluded`, + ); + + const knownAgents = /var KNOWN_AGENTS = new Set\(\[([^\]]*)\]\)/.exec(surface); + assert.ok(knownAgents, `${label}: KNOWN_AGENTS must stay readable`); + const parsed = knownAgents[1] + .split(',') + .map((entry) => entry.trim().replace(/^'|'$/g, '')) + .filter(Boolean); + assert.deepEqual( + parsed, + switcherAgents, + `${label}: KNOWN_AGENTS must stay exactly the supported agents, with WorkBuddy excluded`, + ); + } + + // Listing a platform must not imply a generated switcher command exists for it. + for (const [surface, label] of [ + [english, 'README.md'], + [chinese, 'README_ZH.md'], + [template, 'scripts/start-template.html'], + [start, 'docs/start.html'], + [landing, 'docs/index.html'], + ]) { + assert.doesNotMatch( + surface, + /--agent workbuddy/, + `${label}: no generated agent-switcher command may be claimed for WorkBuddy`, + ); + } +}); + test('the zero-dependency archive works from the canonical Cursor-visible agent path', () => { const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'archify-cursor-package-')); const agentSkills = path.join(tmp, '.agents', 'skills'); diff --git a/archify/test/landing.test.mjs b/archify/test/landing.test.mjs index ba160ebf..af192d8b 100644 --- a/archify/test/landing.test.mjs +++ b/archify/test/landing.test.mjs @@ -29,7 +29,7 @@ const proofs = [ test('landing metadata describes the full technical-diagram product and trusted hero promise', () => { assert.match(landing, /Archify — Technical Diagrams from Plain English<\/title>/); assert.match(landing, /<meta property="og:title" content="Archify — Technical Diagrams from Plain English">/); - assert.match(landing, /An agent skill for Cursor, Claude Code, Codex CLI, OpenCode, and GitHub Copilot/); + assert.match(landing, /An agent skill for Cursor, Claude Code, Codex CLI, OpenCode, GitHub Copilot, and WorkBuddy/); assert.equal((landing.match(/npx -y skills add tt-a1i\/archify --skill archify --agent cursor --global --copy --yes/g) || []).length, 2); assert.match(landing, /From plain English<br>to architecture <em>you can trust\.<\/em>/); }); diff --git a/docs/index.html b/docs/index.html index 9e4b5aab..89bc5cf0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4,7 +4,7 @@ <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Archify — Technical Diagrams from Plain English - + diff --git a/docs/start.html b/docs/start.html index 0581eed3..902c4c3a 100644 --- a/docs/start.html +++ b/docs/start.html @@ -249,6 +249,7 @@

Keep the t
npx -y skills add tt-a1i/archify --skill archify --agent codex --copy --yes

Raven is supported through a manual ZIP installation, not a generated agent-switcher command. Extract archify.zip into ~/.raven/workspace/skills, which yields ~/.raven/workspace/skills/archify.

+

WorkBuddy is supported by copying the skill into your WorkBuddy skills directory, not a generated agent-switcher command. Copy the repository's archify/ folder (SKILL.md and assets) into ~/.workbuddy/skills/archify.

The Start link carries only your agent, language, diagram type, input mode, and a coarse source label. Journey events stay in this browser session and are never sent by Archify. No repository path, title, node, relationship, or source JSON is recorded.

diff --git a/scripts/start-template.html b/scripts/start-template.html index 61317007..6d0f3776 100644 --- a/scripts/start-template.html +++ b/scripts/start-template.html @@ -249,6 +249,7 @@

Keep the t
npx -y skills add tt-a1i/archify --skill archify --agent codex --copy --yes

Raven is supported through a manual ZIP installation, not a generated agent-switcher command. Extract archify.zip into ~/.raven/workspace/skills, which yields ~/.raven/workspace/skills/archify.

+

WorkBuddy is supported by copying the skill into your WorkBuddy skills directory, not a generated agent-switcher command. Copy the repository's archify/ folder (SKILL.md and assets) into ~/.workbuddy/skills/archify.

The Start link carries only your agent, language, diagram type, input mode, and a coarse source label. Journey events stay in this browser session and are never sent by Archify. No repository path, title, node, relationship, or source JSON is recorded.