@nick848/fet 1.0.9 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +40 -8
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1989,6 +1989,7 @@ async function proxyCommand(ctx, command, args) {
|
|
|
1989
1989
|
await assertVerified(ctx);
|
|
1990
1990
|
}
|
|
1991
1991
|
const mapped = await mapOpenSpecCommand(ctx, command, openSpecArgs);
|
|
1992
|
+
await assertOpenSpecCommandSupported(ctx, mapped.command, command);
|
|
1992
1993
|
const mappedChangeId = extractChangeId(mapped.args);
|
|
1993
1994
|
const targetChangeId = command === "archive" ? mapped.args[0] ?? ctx.changeId ?? mappedChangeId : ctx.changeId ?? mappedChangeId;
|
|
1994
1995
|
runState.graphContext = await buildWorkflowGraphContext(ctx, {
|
|
@@ -2055,6 +2056,23 @@ async function proxyCommand(ctx, command, args) {
|
|
|
2055
2056
|
data: graphContext ? { graphContext } : void 0
|
|
2056
2057
|
});
|
|
2057
2058
|
}
|
|
2059
|
+
async function assertOpenSpecCommandSupported(ctx, openSpecCommand, fetCommand) {
|
|
2060
|
+
const capabilities = await ctx.openSpec.getCapabilities();
|
|
2061
|
+
if (capabilities.commands.includes(openSpecCommand)) {
|
|
2062
|
+
return;
|
|
2063
|
+
}
|
|
2064
|
+
throw new FetError({
|
|
2065
|
+
code: "OPENSPEC_UNSUPPORTED_VERSION" /* OpenSpecUnsupportedVersion */,
|
|
2066
|
+
message: `OpenSpec CLI ${capabilities.version} does not expose command "${openSpecCommand}" required by "fet ${fetCommand}". FET will not substitute another workflow command automatically.`,
|
|
2067
|
+
details: {
|
|
2068
|
+
openSpecVersion: capabilities.version,
|
|
2069
|
+
requiredCommand: openSpecCommand,
|
|
2070
|
+
availableCommands: capabilities.commands,
|
|
2071
|
+
supported: capabilities.supported
|
|
2072
|
+
},
|
|
2073
|
+
suggestedCommand: "Upgrade OpenSpec to a version that supports this command, then rerun FET. Try: npm install -g @fission-ai/openspec@latest && fet doctor. If your OpenSpec version intentionally removed this command, pause and choose a compatible FET workflow instead of running ff automatically."
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2058
2076
|
async function createChangelogEntry(projectRoot, changeId) {
|
|
2059
2077
|
return {
|
|
2060
2078
|
updateTime: formatLocalTimestamp(/* @__PURE__ */ new Date()),
|
|
@@ -2811,15 +2829,15 @@ After the command completes, report the GitNexus state, generated handoff files,
|
|
|
2811
2829
|
`;
|
|
2812
2830
|
}
|
|
2813
2831
|
function renderSlashPrompt(command, language) {
|
|
2832
|
+
if (command === "ff" || command === "propose") {
|
|
2833
|
+
return renderFastForwardSlashPrompt(command, language);
|
|
2834
|
+
}
|
|
2814
2835
|
if (language !== "en") {
|
|
2815
2836
|
return renderSlashPromptZh(command);
|
|
2816
2837
|
}
|
|
2817
2838
|
if (command === "continue") {
|
|
2818
2839
|
return renderContinueSlashPrompt(language);
|
|
2819
2840
|
}
|
|
2820
|
-
if (command === "ff" || command === "propose") {
|
|
2821
|
-
return renderFastForwardSlashPrompt(command, language);
|
|
2822
|
-
}
|
|
2823
2841
|
if (command === "explore") {
|
|
2824
2842
|
return renderExploreSlashPrompt(language);
|
|
2825
2843
|
}
|
|
@@ -3419,11 +3437,11 @@ Guardrails:
|
|
|
3419
3437
|
);
|
|
3420
3438
|
}
|
|
3421
3439
|
function renderFastForwardSlashPrompt(command, language) {
|
|
3422
|
-
const title = command === "propose" ? "Propose a new FET/OpenSpec change" : "Fast-forward FET/OpenSpec artifact creation";
|
|
3440
|
+
const title = language === "en" ? command === "propose" ? "Propose a new FET/OpenSpec change" : "Fast-forward FET/OpenSpec artifact creation" : command === "propose" ? "\u521B\u5EFA\u5E76\u8865\u9F50 FET/OpenSpec \u63D0\u6848\u4EA7\u7269" : "\u5FEB\u901F\u751F\u6210 FET/OpenSpec \u6240\u9700\u4EA7\u7269";
|
|
3423
3441
|
const commandLine = command === "propose" ? "fet propose <change-id-or-description>" : "fet ff --change <change-id>";
|
|
3424
3442
|
return renderManagedSlashPrompt(
|
|
3425
3443
|
`fet ${command} [...args]`,
|
|
3426
|
-
command === "propose" ? "Create a change and generate required OpenSpec artifacts" : "Generate required OpenSpec artifacts for a change",
|
|
3444
|
+
language === "en" ? command === "propose" ? "Create a change and generate required OpenSpec artifacts" : "Generate required OpenSpec artifacts for a change" : command === "propose" ? "\u521B\u5EFA\u5E76\u8865\u9F50 FET/OpenSpec \u63D0\u6848\u4EA7\u7269" : "\u5FEB\u901F\u751F\u6210 FET/OpenSpec \u6240\u9700\u4EA7\u7269",
|
|
3427
3445
|
`${title}.
|
|
3428
3446
|
|
|
3429
3447
|
Input after the slash command may be a change id or a description of what the user wants to build. For ff, it may be omitted when the active OpenSpec change is unambiguous.
|
|
@@ -3438,6 +3456,7 @@ Steps:
|
|
|
3438
3456
|
\`\`\`
|
|
3439
3457
|
4. Follow the native output. If it asks for clarification, ask the user rather than inventing details.
|
|
3440
3458
|
5. If the native output includes artifact paths or templates to write, create only those files and preserve OpenSpec structure.
|
|
3459
|
+
6. If FET reports that the OpenSpec CLI does not expose the requested command, stop immediately. Do not run \`fet ff\`, \`openspec ff\`, \`openspec change\`, or any alternative workflow command unless the user explicitly chooses that fallback after seeing the error.
|
|
3441
3460
|
|
|
3442
3461
|
Artifact rules:
|
|
3443
3462
|
- Follow the instruction field from OpenSpec/FET for each artifact.
|
|
@@ -3449,7 +3468,11 @@ Output:
|
|
|
3449
3468
|
- Change id and location.
|
|
3450
3469
|
- Artifacts created.
|
|
3451
3470
|
- Current status.
|
|
3452
|
-
- Next recommended command, usually /prompts:fet-apply <change-id
|
|
3471
|
+
- Next recommended command, usually /prompts:fet-apply <change-id>.
|
|
3472
|
+
|
|
3473
|
+
Guardrails:
|
|
3474
|
+
- Do not substitute one FET/OpenSpec workflow command for another after a command-not-found or unsupported-version error.
|
|
3475
|
+
- If OpenSpec appears outdated or incompatible, report the detected version and suggest \`npm install -g @fission-ai/openspec@latest\` or \`fet doctor\`, then wait for the user's decision.`,
|
|
3453
3476
|
void 0,
|
|
3454
3477
|
language
|
|
3455
3478
|
);
|
|
@@ -3855,7 +3878,7 @@ async function findExecutable() {
|
|
|
3855
3878
|
const command = process.platform === "win32" ? "where.exe" : "which";
|
|
3856
3879
|
try {
|
|
3857
3880
|
const { stdout } = await exec(command, ["openspec"]);
|
|
3858
|
-
const first = stdout.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
|
|
3881
|
+
const first = stdout.split(/\r?\n/).map((line) => line.trim()).sort((left, right) => executablePreference(left) - executablePreference(right)).find(Boolean);
|
|
3859
3882
|
if (first) {
|
|
3860
3883
|
return first;
|
|
3861
3884
|
}
|
|
@@ -3872,6 +3895,12 @@ async function findExecutable() {
|
|
|
3872
3895
|
});
|
|
3873
3896
|
}
|
|
3874
3897
|
}
|
|
3898
|
+
function executablePreference(path) {
|
|
3899
|
+
if (process.platform === "win32" && path.toLowerCase().endsWith(".cmd")) {
|
|
3900
|
+
return 0;
|
|
3901
|
+
}
|
|
3902
|
+
return 1;
|
|
3903
|
+
}
|
|
3875
3904
|
async function readVersion(executablePath) {
|
|
3876
3905
|
const command = executablePath === "npx openspec" ? "npx" : executablePath;
|
|
3877
3906
|
const args = executablePath === "npx openspec" ? ["openspec", "--version"] : ["--version"];
|
|
@@ -3986,7 +4015,10 @@ function parseCommands(help) {
|
|
|
3986
4015
|
"bulk-archive",
|
|
3987
4016
|
"onboard"
|
|
3988
4017
|
];
|
|
3989
|
-
return known.filter((command) =>
|
|
4018
|
+
return known.filter((command) => new RegExp(`\\b${escapeRegExp(command)}\\b`).test(help));
|
|
4019
|
+
}
|
|
4020
|
+
function escapeRegExp(value) {
|
|
4021
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3990
4022
|
}
|
|
3991
4023
|
|
|
3992
4024
|
// src/scanner/package.ts
|