lee-spec-kit 0.6.24 → 0.6.25
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/index.js
CHANGED
|
@@ -163,6 +163,9 @@ var ko = {
|
|
|
163
163
|
"context.suggestionHeader": "\uCD94\uCC9C \uB2E4\uC74C \uC120\uD0DD\uC9C0",
|
|
164
164
|
"context.suggestionCommandHint": "\uB77C\uBCA8 \uCC38\uACE0 \uBA85\uB839: {command}",
|
|
165
165
|
"context.suggestionFinalPrompt": "\uD604\uC7AC \uCD94\uCC9C \uB77C\uBCA8: {labels}. \uC751\uB2F5\uC740 \uB77C\uBCA8 \uD1A0\uD070 \uD3EC\uD568 \uD615\uC2DD\uC73C\uB85C \uD574\uC8FC\uC138\uC694. (\uC608: {example}, `A \uC9C4\uD589\uD574`)",
|
|
166
|
+
"context.autoRunUnavailable": "\uD604\uC7AC \uCEE8\uD14D\uC2A4\uD2B8\uC5D0\uC11C\uB294 \uC790\uB3D9 \uC2E4\uD589\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
167
|
+
"context.autoRunSummary": "config \uAE30\uC900\uC73C\uB85C \uC2B9\uC778 \uD544\uC694 \uCE74\uD14C\uACE0\uB9AC \uC804\uAE4C\uC9C0 \uC5F0\uC18D \uC2E4\uD589\uD558\uC138\uC694: {categories}",
|
|
168
|
+
"context.autoRunCommandHint": "\uC790\uB3D9 \uC2E4\uD589 \uBA85\uB839(config \uAC8C\uC774\uD2B8): {command}",
|
|
166
169
|
"context.commandDetail.branchCreateWithWorktree": "({scope}) worktree {worktree}\uB97C \uC0AC\uC6A9\uD574 \uBE0C\uB79C\uCE58 {branch}\uB97C \uC0DD\uC131\uD558\uAC70\uB098 \uC7AC\uC0AC\uC6A9\uD558\uC138\uC694",
|
|
167
170
|
"context.commandDetail.branchCreateWithBranch": "({scope}) \uBE0C\uB79C\uCE58 {branch}\uC6A9 worktree\uB97C \uC0DD\uC131\uD558\uAC70\uB098 \uC7AC\uC0AC\uC6A9\uD558\uC138\uC694",
|
|
168
171
|
"context.commandDetail.branchCreateGeneric": "({scope}) feature \uBE0C\uB79C\uCE58\uC6A9 worktree\uB97C \uC0DD\uC131\uD558\uAC70\uB098 \uC7AC\uC0AC\uC6A9\uD558\uC138\uC694",
|
|
@@ -492,8 +495,8 @@ var ko = {
|
|
|
492
495
|
worktreeCleanupCommand: 'cd "{projectGitCwd}" && git worktree remove "{worktreePath}" && git worktree prune && CURRENT_BRANCH=$(git branch --show-current) && DEFAULT_BRANCH=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | cut -d/ -f2-) && TARGET_BRANCH="${DEFAULT_BRANCH:-$CURRENT_BRANCH}" && if [ -n "$TARGET_BRANCH" ]; then git checkout "$TARGET_BRANCH" >/dev/null 2>&1 || true; fi && if git rev-parse --abbrev-ref --symbolic-full-name "@{u}" >/dev/null 2>&1 && [ -z "$(git status --porcelain)" ]; then git pull --ff-only || true; fi',
|
|
493
496
|
tasksAllDoneButNoChecklist: '\uC644\uB8CC \uC870\uAC74 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8\uB97C \uC791\uC131\uD558\uC138\uC694. tasks.md\uC758 "\uC644\uB8CC \uC870\uAC74" \uC139\uC158\uC5D0 \uAC80\uC99D \uD56D\uBAA9\uC744 \uCD94\uAC00\uD558\uACE0, \uC0AC\uC6A9\uC790\uC640 \uD655\uC778 \uD6C4 \uCDA9\uC871 \uD56D\uBAA9\uC744 [x]\uB85C \uCCB4\uD06C\uD558\uC138\uC694. \uCD5C\uC885 \uC2B9\uC778(OK)\uB3C4 \uBC18\uC601\uD558\uC138\uC694.',
|
|
494
497
|
tasksAllDoneButChecklist: "\uC644\uB8CC \uC870\uAC74 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8\uC758 \uB0A8\uC740 \uD56D\uBAA9\uC744 \uC9C4\uD589\uD558\uC138\uC694. \uD604\uC7AC \uC9C4\uD589: ({checked}/{total}) \uC0AC\uC6A9\uC790\uC640 \uD655\uC778 \uD6C4 \uCDA9\uC871 \uD56D\uBAA9\uC744 [x]\uB85C \uCCB4\uD06C\uD558\uACE0 \uCD5C\uC885 \uC2B9\uC778(OK)\uC744 \uBC18\uC601\uD558\uC138\uC694.",
|
|
495
|
-
finishDoingTask: '\uD604\uC7AC DOING/REVIEW \uD0DC\uC2A4\uD06C\uB97C \uC218\uD589\uD558\uC138\uC694: "{title}" ({done}/{total}) \uC644\uB8CC \uC2DC \uACB0\uACFC/\uAC80\uC99D\uC744 \uACF5\uC720\uD558\uACE0
|
|
496
|
-
startNextTodoTask: '\uB2E4\uC74C TODO \uD0DC\uC2A4\uD06C\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4: "{title}" ({done}/{total}) \
|
|
498
|
+
finishDoingTask: '\uD604\uC7AC DOING/REVIEW \uD0DC\uC2A4\uD06C\uB97C \uC218\uD589\uD558\uC138\uC694: "{title}" ({done}/{total}) \uC644\uB8CC \uC2DC \uACB0\uACFC/\uAC80\uC99D\uC744 \uACF5\uC720\uD558\uACE0 DONE \uCC98\uB9AC',
|
|
499
|
+
startNextTodoTask: '\uB2E4\uC74C TODO \uD0DC\uC2A4\uD06C\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4: "{title}" ({done}/{total}) \uC791\uC5C5\uC744 \uC2DC\uC791\uD558\uBA74 DOING \uCC98\uB9AC',
|
|
497
500
|
checkTaskStatuses: "\uD0DC\uC2A4\uD06C \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uC138\uC694. ({done}/{total})",
|
|
498
501
|
taskCommitGateStrictBlock: "\uB2E4\uC74C TODO \uD0DC\uC2A4\uD06C\uB85C \uB118\uC5B4\uAC00\uAE30 \uC804\uC5D0 `1 \uD0DC\uC2A4\uD06C = 1 \uCEE4\uBC0B` \uADDC\uCE59\uC744 \uCDA9\uC871\uD574\uC57C \uD569\uB2C8\uB2E4. \uC810\uAC80 \uACB0\uACFC: {reason}. \uD0DC\uC2A4\uD06C \uCEE4\uBC0B \uB2E8\uC704\uB97C \uC815\uB9AC\uD55C \uB4A4 \uB2E4\uC2DC \uC9C4\uD589\uD558\uC138\uC694.",
|
|
499
502
|
taskCommitGateWarnProceed: "\u26A0\uFE0F \uD0DC\uC2A4\uD06C \uCEE4\uBC0B \uB2E8\uC704 \uC810\uAC80 \uACBD\uACE0: {reason}. \uD604\uC7AC\uB294 \uC9C4\uD589 \uAC00\uB2A5\uD558\uC9C0\uB9CC `1 \uD0DC\uC2A4\uD06C = 1 \uCEE4\uBC0B`\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
|
|
@@ -650,6 +653,9 @@ var en = {
|
|
|
650
653
|
"context.suggestionHeader": "Suggested Next Options",
|
|
651
654
|
"context.suggestionCommandHint": "Reference command: {command}",
|
|
652
655
|
"context.suggestionFinalPrompt": "Recommended labels now: {labels}. Please reply with a format that includes a label token. (e.g. {example}, `A proceed`)",
|
|
656
|
+
"context.autoRunUnavailable": "Auto-run is not available in the current context.",
|
|
657
|
+
"context.autoRunSummary": "Run continuously by config until approval-required categories appear: {categories}",
|
|
658
|
+
"context.autoRunCommandHint": "Auto-run command (config-based gate): {command}",
|
|
653
659
|
"context.commandDetail.branchCreateWithWorktree": "({scope}) create or reuse worktree {worktree} for branch {branch}",
|
|
654
660
|
"context.commandDetail.branchCreateWithBranch": "({scope}) create or reuse worktree for branch {branch}",
|
|
655
661
|
"context.commandDetail.branchCreateGeneric": "({scope}) create or reuse feature branch worktree",
|
|
@@ -979,8 +985,8 @@ var en = {
|
|
|
979
985
|
worktreeCleanupCommand: 'cd "{projectGitCwd}" && git worktree remove "{worktreePath}" && git worktree prune && CURRENT_BRANCH=$(git branch --show-current) && DEFAULT_BRANCH=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | cut -d/ -f2-) && TARGET_BRANCH="${DEFAULT_BRANCH:-$CURRENT_BRANCH}" && if [ -n "$TARGET_BRANCH" ]; then git checkout "$TARGET_BRANCH" >/dev/null 2>&1 || true; fi && if git rev-parse --abbrev-ref --symbolic-full-name "@{u}" >/dev/null 2>&1 && [ -z "$(git status --porcelain)" ]; then git pull --ff-only || true; fi',
|
|
980
986
|
tasksAllDoneButNoChecklist: 'Create the completion checklist. Add verification items to the tasks.md "Completion Criteria" section, then mark satisfied items as [x] after user confirmation. Record final approval (OK) as well.',
|
|
981
987
|
tasksAllDoneButChecklist: "Proceed with remaining completion checklist items. Current progress: ({checked}/{total}) Mark items as [x] only after user confirmation and real verification. Record final approval (OK) as well.",
|
|
982
|
-
finishDoingTask: 'Continue working on the current DOING/REVIEW task: "{title}" ({done}/{total}) After it is complete, share outcome/verification and
|
|
983
|
-
startNextTodoTask: 'Start the next TODO task: "{title}" ({done}/{total})
|
|
988
|
+
finishDoingTask: 'Continue working on the current DOING/REVIEW task: "{title}" ({done}/{total}) After it is complete, share outcome/verification and mark it DONE',
|
|
989
|
+
startNextTodoTask: 'Start the next TODO task: "{title}" ({done}/{total}) Mark it DOING when you begin work',
|
|
984
990
|
checkTaskStatuses: "Check task statuses. ({done}/{total})",
|
|
985
991
|
taskCommitGateStrictBlock: "Before moving to the next TODO task, you must satisfy the `1 task = 1 commit` rule. Check result: {reason}. Re-align task commit boundaries, then continue.",
|
|
986
992
|
taskCommitGateWarnProceed: "\u26A0\uFE0F Task commit boundary warning: {reason}. You may continue, but `1 task = 1 commit` is recommended.",
|
|
@@ -7116,6 +7122,72 @@ function buildSuggestionFinalPrompt(lang, suggestionOptions) {
|
|
|
7116
7122
|
example
|
|
7117
7123
|
});
|
|
7118
7124
|
}
|
|
7125
|
+
function normalizeCategoryToken(value) {
|
|
7126
|
+
if (typeof value !== "string") return null;
|
|
7127
|
+
const normalized = value.trim().toLowerCase();
|
|
7128
|
+
if (!normalized) return null;
|
|
7129
|
+
return normalized;
|
|
7130
|
+
}
|
|
7131
|
+
function resolveAutoRunCategories(approval) {
|
|
7132
|
+
const known = new Set(ACTION_CATEGORIES);
|
|
7133
|
+
const unique2 = /* @__PURE__ */ new Set();
|
|
7134
|
+
const unknown = /* @__PURE__ */ new Set();
|
|
7135
|
+
for (const raw of approval?.requireCheckCategories ?? approval?.requireOkCategories ?? []) {
|
|
7136
|
+
const normalized = normalizeCategoryToken(raw);
|
|
7137
|
+
if (!normalized) continue;
|
|
7138
|
+
if (known.has(normalized)) {
|
|
7139
|
+
unique2.add(normalized);
|
|
7140
|
+
} else {
|
|
7141
|
+
unknown.add(normalized);
|
|
7142
|
+
}
|
|
7143
|
+
}
|
|
7144
|
+
return {
|
|
7145
|
+
untilCategories: Array.from(unique2),
|
|
7146
|
+
unknownCategories: Array.from(unknown)
|
|
7147
|
+
};
|
|
7148
|
+
}
|
|
7149
|
+
function buildAutoRunCommand(state, featureName, selectedComponent, untilCategories) {
|
|
7150
|
+
if (untilCategories.length === 0) return "";
|
|
7151
|
+
const featureRef = resolveFeatureRefForApproval(state, featureName);
|
|
7152
|
+
const componentArg = selectedComponent ? ` --component ${selectedComponent}` : "";
|
|
7153
|
+
return `npx lee-spec-kit flow ${featureRef}${componentArg} --auto-until-category ${untilCategories.join(",")}`;
|
|
7154
|
+
}
|
|
7155
|
+
function resolveAutoRunPlan(lang, state, featureName, selectedComponent, approval, approvalRequired) {
|
|
7156
|
+
const base = (reasonCode, untilCategories2 = [], unknownCategories2 = []) => ({
|
|
7157
|
+
available: false,
|
|
7158
|
+
reasonCode,
|
|
7159
|
+
summary: tr(lang, "cli", "context.autoRunUnavailable"),
|
|
7160
|
+
command: "",
|
|
7161
|
+
untilCategories: untilCategories2,
|
|
7162
|
+
unknownCategories: unknownCategories2
|
|
7163
|
+
});
|
|
7164
|
+
if (state.status !== "single_matched") return base("NOT_SINGLE_MATCHED");
|
|
7165
|
+
if (state.actionOptions.length === 0) return base("NO_ACTION_OPTIONS");
|
|
7166
|
+
if (approvalRequired) return base("APPROVAL_REQUIRED");
|
|
7167
|
+
const mode = approval?.mode ?? "builtin";
|
|
7168
|
+
if (mode !== "category") return base("APPROVAL_MODE_NOT_CATEGORY");
|
|
7169
|
+
const defaultPolicy = approval?.default ?? "keep";
|
|
7170
|
+
if (defaultPolicy !== "skip") return base("DEFAULT_NOT_SKIP");
|
|
7171
|
+
const { untilCategories, unknownCategories } = resolveAutoRunCategories(approval);
|
|
7172
|
+
if (untilCategories.length === 0) {
|
|
7173
|
+
return base("NO_REQUIRE_CHECK_CATEGORIES", [], unknownCategories);
|
|
7174
|
+
}
|
|
7175
|
+
return {
|
|
7176
|
+
available: true,
|
|
7177
|
+
reasonCode: "AVAILABLE",
|
|
7178
|
+
summary: tr(lang, "cli", "context.autoRunSummary", {
|
|
7179
|
+
categories: untilCategories.join(", ")
|
|
7180
|
+
}),
|
|
7181
|
+
command: buildAutoRunCommand(
|
|
7182
|
+
state,
|
|
7183
|
+
featureName,
|
|
7184
|
+
selectedComponent,
|
|
7185
|
+
untilCategories
|
|
7186
|
+
),
|
|
7187
|
+
untilCategories,
|
|
7188
|
+
unknownCategories
|
|
7189
|
+
};
|
|
7190
|
+
}
|
|
7119
7191
|
function toSuggestionLabel(index) {
|
|
7120
7192
|
let n = index + 1;
|
|
7121
7193
|
let label = "";
|
|
@@ -7520,6 +7592,26 @@ async function runContext(featureName, options) {
|
|
|
7520
7592
|
selectedComponent
|
|
7521
7593
|
);
|
|
7522
7594
|
const suggestionFinalPrompt = buildSuggestionFinalPrompt(lang, suggestionOptions);
|
|
7595
|
+
const checkRequiredLabels = state.actionOptions.filter((option) => !!option.action.requiresUserCheck).map((option) => option.label);
|
|
7596
|
+
const checkRequiredCategories = [
|
|
7597
|
+
...new Set(
|
|
7598
|
+
state.actionOptions.filter((option) => !!option.action.requiresUserCheck).map((option) => option.action.category || "uncategorized")
|
|
7599
|
+
)
|
|
7600
|
+
];
|
|
7601
|
+
const approvalRequired = checkRequiredLabels.length > 0;
|
|
7602
|
+
const finalApprovalPrompt = approvalRequired ? buildFinalApprovalPrompt(lang, state.actionOptions) : "";
|
|
7603
|
+
const approvalUserFacingLines = approvalRequired ? [
|
|
7604
|
+
...state.actionOptions.map((o) => o.approvalPrompt),
|
|
7605
|
+
finalApprovalPrompt
|
|
7606
|
+
].filter((line) => line.length > 0) : [];
|
|
7607
|
+
const autoRunPlan = resolveAutoRunPlan(
|
|
7608
|
+
lang,
|
|
7609
|
+
state,
|
|
7610
|
+
featureName,
|
|
7611
|
+
selectedComponent,
|
|
7612
|
+
config.approval,
|
|
7613
|
+
approvalRequired
|
|
7614
|
+
);
|
|
7523
7615
|
if (options.approve || options.execute) {
|
|
7524
7616
|
await runApprovedOption(
|
|
7525
7617
|
state,
|
|
@@ -7534,18 +7626,6 @@ async function runContext(featureName, options) {
|
|
|
7534
7626
|
const jsonMode = !!options.json || !!options.jsonCompact;
|
|
7535
7627
|
if (jsonMode) {
|
|
7536
7628
|
const primaryAction = state.actionOptions[0] ?? null;
|
|
7537
|
-
const checkRequiredLabels = state.actionOptions.filter((option) => !!option.action.requiresUserCheck).map((option) => option.label);
|
|
7538
|
-
const checkRequiredCategories = [
|
|
7539
|
-
...new Set(
|
|
7540
|
-
state.actionOptions.filter((option) => !!option.action.requiresUserCheck).map((option) => option.action.category || "uncategorized")
|
|
7541
|
-
)
|
|
7542
|
-
];
|
|
7543
|
-
const approvalRequired = checkRequiredLabels.length > 0;
|
|
7544
|
-
const finalApprovalPrompt = approvalRequired ? buildFinalApprovalPrompt(lang, state.actionOptions) : "";
|
|
7545
|
-
const approvalUserFacingLines = approvalRequired ? [
|
|
7546
|
-
...state.actionOptions.map((o) => o.approvalPrompt),
|
|
7547
|
-
finalApprovalPrompt
|
|
7548
|
-
].filter((line) => line.length > 0) : [];
|
|
7549
7629
|
const approveCommand = buildApprovalCommand(
|
|
7550
7630
|
state,
|
|
7551
7631
|
featureName,
|
|
@@ -7607,6 +7687,14 @@ async function runContext(featureName, options) {
|
|
|
7607
7687
|
contextVersion: state.contextVersion,
|
|
7608
7688
|
config: config.approval ?? { mode: "builtin" }
|
|
7609
7689
|
},
|
|
7690
|
+
autoRun: {
|
|
7691
|
+
available: autoRunPlan.available,
|
|
7692
|
+
reasonCode: autoRunPlan.reasonCode,
|
|
7693
|
+
summary: autoRunPlan.summary,
|
|
7694
|
+
command: autoRunPlan.command,
|
|
7695
|
+
untilCategories: autoRunPlan.untilCategories,
|
|
7696
|
+
unknownCategories: autoRunPlan.unknownCategories
|
|
7697
|
+
},
|
|
7610
7698
|
approvalRequest: {
|
|
7611
7699
|
required: approvalRequired,
|
|
7612
7700
|
finalPrompt: finalApprovalPrompt,
|
|
@@ -7686,6 +7774,15 @@ async function runContext(featureName, options) {
|
|
|
7686
7774
|
contextVersion: state.contextVersion,
|
|
7687
7775
|
config: config.approval ?? { mode: "builtin" }
|
|
7688
7776
|
},
|
|
7777
|
+
autoRun: {
|
|
7778
|
+
available: autoRunPlan.available,
|
|
7779
|
+
reasonCode: autoRunPlan.reasonCode,
|
|
7780
|
+
summary: autoRunPlan.summary,
|
|
7781
|
+
command: autoRunPlan.command,
|
|
7782
|
+
untilCategories: autoRunPlan.untilCategories,
|
|
7783
|
+
unknownCategories: autoRunPlan.unknownCategories,
|
|
7784
|
+
guidance: "Use auto-run only when `autoRun.available=true`. Stop and request approval when `approvalRequest.required=true` or when auto mode reaches configured gate categories."
|
|
7785
|
+
},
|
|
7689
7786
|
approvalRequest: {
|
|
7690
7787
|
guidance: "User-facing output must include only approval prompts (`A: ...`) and `finalPrompt`. Do not expose `requiredDocs`, `checkPolicy`, or raw `cmd` unless explicitly requested. For approved command actions, prefer one-shot `flow --approve <LABEL> --execute`.",
|
|
7691
7788
|
required: approvalRequired,
|
|
@@ -7899,7 +7996,7 @@ async function runContext(featureName, options) {
|
|
|
7899
7996
|
const f = state.targetFeatures[0];
|
|
7900
7997
|
const stepName = stepsMap[f.currentStep] || "Unknown";
|
|
7901
7998
|
const checkTag = (requiresUserCheck) => requiresUserCheck ? chalk6.yellow(tr(lang, "cli", "context.checkRequired")) : "";
|
|
7902
|
-
const hasCheckAction =
|
|
7999
|
+
const hasCheckAction = approvalRequired;
|
|
7903
8000
|
console.log(
|
|
7904
8001
|
`\u{1F539} Feature: ${chalk6.bold(f.folderName)} ${config.projectType === "multi" ? chalk6.cyan(`(${f.type})`) : ""}`
|
|
7905
8002
|
);
|
|
@@ -7971,8 +8068,17 @@ async function runContext(featureName, options) {
|
|
|
7971
8068
|
);
|
|
7972
8069
|
}
|
|
7973
8070
|
}
|
|
8071
|
+
if (autoRunPlan.available) {
|
|
8072
|
+
console.log(chalk6.gray(` \u21B3 ${autoRunPlan.summary}`));
|
|
8073
|
+
console.log(
|
|
8074
|
+
chalk6.gray(
|
|
8075
|
+
` \u21B3 ${tr(lang, "cli", "context.autoRunCommandHint", {
|
|
8076
|
+
command: autoRunPlan.command
|
|
8077
|
+
})}`
|
|
8078
|
+
)
|
|
8079
|
+
);
|
|
8080
|
+
}
|
|
7974
8081
|
if (actionOptions.length > 0 && hasCheckAction) {
|
|
7975
|
-
const finalApprovalPrompt = buildFinalApprovalPrompt(lang, actionOptions);
|
|
7976
8082
|
const approveCommand = buildApprovalCommand(
|
|
7977
8083
|
state,
|
|
7978
8084
|
featureName,
|