Files
jiantw83andClaude Opus 5 17178f0c4d feat(佈署): 以 npm 裝出 tea-sdlc 指令並產生各平台轉接檔
單一入口 bin/tea-sdlc.js 認四個子指令。第一個位置參數是子指令,其餘 argv 原樣
交出去——既有的 flag 解析拒絕位置參數,所以子指令必須在那之前就被取走。

轉接檔裡沒有路徑,只有一句 tea-sdlc prompt --name <指令名>。正本在哪由 PATH 上
的 tea-sdlc 自己回推:fnm 把 Node 版號寫進全域安裝路徑,寫死路徑的話升一次
Node,七個平台的轉接檔會同時指向不存在的檔案,而且不會有任何錯誤訊息。

prompt 是全專案唯一輸出非 JSON 的路徑,理由只有一個:它的輸出要餵給模型讀。
失敗仍走 envelope——成功是內容,失敗才需要結構。

status 的 ok 不兼差表達環境好壞,健康與否放在 data.healthy:呼叫端要分得出
「status 掛了」與「status 成功查到你環境有問題」。

install 只寫進偵測得到的平台;缺 git/tea 只警告不中止,因為那兩個完全不影響
轉接檔產生,硬擋等於逼使用者為了裝 plugin 先去裝 tea。uninstall 只刪帶產生標記
的檔案,使用者自己寫的同名檔案一律留著並在輸出裡交代。裝哪些指令以 prompts/ 裡
實際存在的正本為準,不是寫死的六個名字——裝出指向不存在正本的轉接檔,使用者只會
看到 PROMPT_NOT_FOUND。

流程正本的 description 前綴在抄進轉接檔之前就檢查:有三個平台關不掉自動觸發,
全靠那句話把 description 窄到不會被誤判,不能等使用者發現誤觸才知道漏了。

議題 #26 #27 #28 #29 #17

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 06:59:37 +00:00

55 lines
2.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* prompt 子指令:把一份流程正本原樣交出去。
*
* 轉接檔裡沒有路徑,只有一句「執行 tea-sdlc prompt --name sdlc-plan」。正本在哪,
* 由 PATH 上的 tea-sdlc 自己從檔案位置回推——Node 升級、換版本管理器、改 npm prefix
* 都不會讓轉接檔指向不存在的檔案。
*
* 用法(由 bin/tea-sdlc.js 轉入):
* tea-sdlc prompt --name sdlc-plan [--adapter-version 0.0.1]
*/
import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import {
RawText,
ScriptError,
checkPluginLayout,
packageVersion,
parseFlags,
promptsDir,
} from './lib.js';
/** 指令名的合法樣子。擋的是路徑跳脫,順便把打錯的名字擋在讀檔之前。 */
const NAME = /^[a-z][a-z0-9-]*$/;
/**
* @param {string[]} argv bin 取走子指令之後剩下的參數
* @returns {import('./lib.js').RawText} 正本原文;版本不符時前面多一行警告
*/
export function runPrompt(argv) {
const flags = parseFlags(argv, { required: ['name'], optional: ['adapter-version'] });
checkPluginLayout();
const name = String(flags.name);
if (!NAME.test(name)) {
throw new ScriptError('BAD_PROMPT_NAME', `--name 只接受小寫英數與連字號,收到的是 ${name}`);
}
const path = join(promptsDir(), `${name}.md`);
if (!existsSync(path)) {
throw new ScriptError('PROMPT_NOT_FOUND', `沒有名為 ${name} 的流程正本(找不到 ${path})`);
}
const text = readFileSync(path, 'utf8');
const adapter = flags['adapter-version'];
const current = packageVersion();
if (adapter === undefined || adapter === current) return new RawText(text);
// 正本仍然照給。轉接檔過時只是清單可能不齊,不是流程不能跑;
// 警告放在最前面,是因為那是模型每次叫用必定會讀到的位置,不依賴使用者記得去查 status。
return new RawText(
`> ⚠️ 這份轉接檔是 tea-sdlc ${adapter} 產生的,目前安裝的是 ${current};` +
`請重跑 \`tea-sdlc install\` 更新轉接檔。\n\n${text}`,
);
}