單一入口 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>
69 lines
2.1 KiB
JavaScript
69 lines
2.1 KiB
JavaScript
/**
|
|
* status 子指令:一行 JSON 回答「我現在到底是什麼狀態」。
|
|
*
|
|
* 四件事:裝的是哪個版本、正本實際解析到哪個目錄(順帶揭露是不是 npm link 開發模式)、
|
|
* node / git / tea 在不在 PATH、Gitea 登入還有沒有效,外加各平台的轉接檔現況。
|
|
*
|
|
* 登入那層會打網路。status 存在的理由就是在出事前先知道,而 token 失效是實務上最常見
|
|
* 的故障;一次使用者主動發起的查詢很便宜,為它多開一個旗標只是把判斷推回給使用者。
|
|
*
|
|
* 用法(由 bin/tea-sdlc.js 轉入):
|
|
* tea-sdlc status
|
|
*/
|
|
import { sep } from 'node:path';
|
|
import {
|
|
giteaRequest,
|
|
onPath,
|
|
packageVersion,
|
|
parseFlags,
|
|
pluginRoot,
|
|
resolveLogin,
|
|
} from './lib.js';
|
|
import { platformReport } from './install.js';
|
|
|
|
/**
|
|
* @param {string[]} argv bin 取走子指令之後剩下的參數
|
|
* @returns {Promise<object>} 放進 data 的內容
|
|
*/
|
|
export async function runStatus(argv) {
|
|
parseFlags(argv, {});
|
|
|
|
const environment = {
|
|
node: onPath('node') !== null,
|
|
git: onPath('git') !== null,
|
|
tea: onPath('tea') !== null,
|
|
login: await loginWorks(),
|
|
};
|
|
|
|
return {
|
|
version: packageVersion(),
|
|
root: pluginRoot(),
|
|
linked: isLinked(),
|
|
// ok 說的是「這支指令跑成功了」,環境好不好是 data 的事,兩者不能混
|
|
healthy: Object.values(environment).every(Boolean),
|
|
environment,
|
|
platforms: platformReport(),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 登入還有沒有效。三種失敗(沒登入、token 過期、連不上)在這裡都只是 false——
|
|
* 這支指令的工作是回報,不是替使用者決定要不要停下來。
|
|
*/
|
|
async function loginWorks() {
|
|
try {
|
|
const response = await giteaRequest(resolveLogin(), 'GET', '/user');
|
|
return response.status >= 200 && response.status < 300;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 是不是 npm link 的開發模式。判準是「解析到的目錄在不在某個 node_modules 底下」:
|
|
* link 出來的套件實際住在 working tree,裝進去的則住在 node_modules。
|
|
*/
|
|
function isLinked() {
|
|
return !pluginRoot().split(sep).includes('node_modules');
|
|
}
|