import test from 'node:test'; import assert from 'node:assert/strict'; import { existsSync, mkdirSync, rmSync } from 'node:fs'; import { join } from 'node:path'; import { fakePrompt, makeFakePlugin } from './helpers/fake-plugin.js'; import { tmpRoot } from './helpers/run-script.js'; const PROMPTS = { 'sdlc-analyze': fakePrompt('sdlc-analyze'), 'sdlc-plan': fakePrompt('sdlc-plan'), }; function homeWith(t, platform) { mkdirSync(tmpRoot, { recursive: true }); const home = join(tmpRoot, `runtime-home-${platform}`); rmSync(home, { recursive: true, force: true }); mkdirSync(join(home, 'work'), { recursive: true }); const roots = { 'oh-my-pi': ['.omp'], claude: ['.claude'], codex: ['.codex'], kiro: ['.kiro'], }; mkdirSync(join(home, ...roots[platform]), { recursive: true }); t.after(() => rmSync(home, { recursive: true, force: true })); return home; } const runInHome = (plugin, home) => (args) => plugin.run(args, { env: { HOME: home }, cwd: join(home, 'work') }); test('sdlc-version 回報版本、實際 tea-sdlc executable 與六個流程', async (t) => { const plugin = makeFakePlugin(t, { prompts: PROMPTS }); const { json } = await plugin.run(['sdlc-version']); assert.equal(json.ok, true); assert.equal(json.data.name, 'tea-sdlc'); assert.equal(json.data.version, '0.0.2'); assert.equal(json.data.executable, join(plugin.shim, 'tea-sdlc')); assert.deepEqual(json.data.commands, ['sdlc-analyze', 'sdlc-plan']); }); test('OMP 使用 ~/.omp/agent/commands 作為 runtime registry,六個 command 全部找到才 pass', async (t) => { const plugin = makeFakePlugin(t, { prompts: PROMPTS }); const home = homeWith(t, 'oh-my-pi'); const run = runInHome(plugin, home); const installed = await run(['install']); assert.equal(installed.code, 0); assert.ok(existsSync(join(home, '.omp', 'agent', 'commands', 'sdlc-analyze.md'))); assert.equal(installed.json.data.verify.platforms[0].runtime.status, 'pass'); assert.deepEqual(installed.json.data.verify.platforms[0].runtime.commands, ['sdlc-analyze', 'sdlc-plan']); }); test('runtime registry 缺少 command 時 verify exit 1 並列出 missing', async (t) => { const plugin = makeFakePlugin(t, { prompts: PROMPTS }); const home = homeWith(t, 'claude'); const run = runInHome(plugin, home); await run(['install']); rmSync(join(home, '.claude', 'commands', 'sdlc-plan.md')); const result = await run(['verify', '--platform', 'claude']); assert.equal(result.code, 1); assert.equal(result.json.error.code, 'RUNTIME_VERIFY_FAILED'); assert.deepEqual(result.json.data.platforms[0].runtime.missing, ['sdlc-plan']); assert.equal(result.json.data.platforms[0].runtime.status, 'fail'); }); test('沒有安全 registry probe 的平台回報 not-supported 而不阻止 install', async (t) => { const plugin = makeFakePlugin(t, { prompts: PROMPTS }); const home = homeWith(t, 'kiro'); const result = await runInHome(plugin, home)(['install']); assert.equal(result.code, 0); assert.equal(result.json.data.verify.platforms[0].runtime.status, 'not-supported'); assert.deepEqual(result.json.data.verify.platforms[0].runtime.failures, []); });