lee-spec-kit 0.6.10 → 0.6.11
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/README.en.md +1 -1
- package/README.md +1 -1
- package/dist/index.js +150 -46
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -464,7 +464,7 @@ Running `init` creates `.lee-spec-kit.json` in your docs root (default: `docs/`)
|
|
|
464
464
|
- `workflow.componentPaths` (optional): explicit per-component paths for component-scoped checks (e.g. `"web": ["apps/web", "packages/web-ui"]`)
|
|
465
465
|
- backward compatibility: if omitted, runtime defaults to `repo`
|
|
466
466
|
- `workflow.taskCommitGate`:
|
|
467
|
-
- `strict`: block
|
|
467
|
+
- `strict`: block only when the latest `tasks.md` commit includes 2+ DONE transitions
|
|
468
468
|
- `warn`: show warning but allow progress
|
|
469
469
|
- `off`: disable the check
|
|
470
470
|
- backward compatibility: if omitted, runtime defaults to `warn`
|
package/README.md
CHANGED
|
@@ -510,7 +510,7 @@ npx lee-spec-kit update --force
|
|
|
510
510
|
- `workflow.componentPaths`(선택): component 판정 경로를 컴포넌트별로 명시 (예: `"web": ["apps/web", "packages/web-ui"]`)
|
|
511
511
|
- 하위 호환: 값이 없으면 기존 동작인 `repo`로 처리
|
|
512
512
|
- `workflow.taskCommitGate`:
|
|
513
|
-
- `strict`:
|
|
513
|
+
- `strict`: 최근 `tasks.md` 커밋에서 DONE 전환이 2개 이상이면 차단
|
|
514
514
|
- `warn`: 점검 실패 시 경고만 표시하고 진행 허용
|
|
515
515
|
- `off`: 점검 비활성화
|
|
516
516
|
- 하위 호환: 값이 없으면 `warn`으로 처리
|
package/dist/index.js
CHANGED
|
@@ -131,14 +131,14 @@ var I18N = {
|
|
|
131
131
|
"context.tipShowAll": "\uC804\uCCB4 \uBCF4\uAE30",
|
|
132
132
|
"context.tipShowDone": "\uC644\uB8CC\uB9CC \uBCF4\uAE30",
|
|
133
133
|
"context.checkRequired": "[\uD655\uC778 \uD544\uC694] ",
|
|
134
|
-
"context.checkPolicyHint": "\u2139\uFE0F \uC0AC\uC6A9\uC790 \uD655\uC778 \uC815\uCC45\uC740 \uC138\uC158 \uC2DC\uC791(\uB610\uB294 context \uC555\uCD95/\uB9AC\uC14B \uC9C1\uD6C4)\uC5D0
|
|
134
|
+
"context.checkPolicyHint": "\u2139\uFE0F \uC0AC\uC6A9\uC790 \uD655\uC778 \uC815\uCC45\uC740 \uC138\uC158 \uC2DC\uC791(\uB610\uB294 context \uC555\uCD95/\uB9AC\uC14B \uC9C1\uD6C4)\uC5D0 1\uD68C \uD655\uC778\uD558\uACE0, \uC774\uD6C4\uC5D0\uB294 \uC815\uCC45/\uC124\uC815 \uBCC0\uACBD \uB610\uB294 \uC0AC\uC6A9\uC790 \uC0C8\uB85C\uACE0\uCE68 \uC694\uCCAD \uC2DC\uC5D0\uB9CC \uC7AC\uD655\uC778\uD558\uC138\uC694. (git push/merge/merge commit \uD3EC\uD568) [\uD655\uC778 \uD544\uC694]\uAC00 \uC788\uC73C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C `<\uB77C\uBCA8>` \uB610\uB294 `<\uB77C\uBCA8> OK` (\uC608: `A`, `A OK`) \uC751\uB2F5\uC744 \uBC1B\uC740 \uB4A4 \uC9C4\uD589 (config: approval\uB85C \uC870\uC815 \uAC00\uB2A5)",
|
|
135
135
|
"context.actionOptionHint": "\uC2B9\uC778 \uC751\uB2F5 \uD615\uC2DD: \uB77C\uBCA8 \uD1A0\uD070 \uD3EC\uD568 (\uC608: `A`, `A OK`, `A \uC9C4\uD589\uD574`)",
|
|
136
136
|
"context.actionExplainHint": "\uC2B9\uC778 \uC694\uCCAD \uC804, \uAC01 \uB77C\uBCA8\uC774 \uBB34\uC5C7\uC744 \uC2E4\uD589/\uBCC0\uACBD\uD558\uB294\uC9C0 \uD55C \uC904 \uC694\uC57D\uACFC \uD568\uAED8 \uC124\uBA85\uD558\uC138\uC694.",
|
|
137
137
|
"context.finalLabelPrompt": "\uD604\uC7AC \uC120\uD0DD \uAC00\uB2A5\uD55C \uB77C\uBCA8: {labels}. \uB9C8\uC9C0\uB9C9 \uC751\uB2F5\uC740 `<\uB77C\uBCA8>` \uB610\uB294 `<\uB77C\uBCA8> OK` \uD615\uC2DD\uC73C\uB85C \uBC1B\uC73C\uC138\uC694. (\uC608: {example})",
|
|
138
138
|
"context.finalLabelCommandHint": "\uB77C\uBCA8\uC744 \uBC1B\uC73C\uBA74 \uC2B9\uC778 \uC120\uD0DD \uC2E4\uD589: {command}",
|
|
139
139
|
"context.finalTicketCommandHint": "\uBA85\uB839 \uC2E4\uD589\uC740 \uC2B9\uC778 \uACB0\uACFC\uC758 \uD2F0\uCF13\uC73C\uB85C \uC2E4\uD589: {command}",
|
|
140
|
-
"context.readBuiltinDocFirst": "\uC774\uBC88 \uC138\uC158\uC5D0 \uC544\uC9C1 \uC77D\uC9C0 \uC54A\uC558\uAC70\uB098 \uBCC0\uACBD \uAC00\uB2A5\uC131\uC774 \uC788\uC744 \uB54C\uB9CC \uB0B4\uC7A5 \uBB38\uC11C\uB97C \uD655\uC778\uD558\uC138\uC694
|
|
141
|
-
"context.tipDocsCommitRules": "\uCEE4\uBC0B \uBA54\uC2DC\uC9C0 \uADDC\uCE59\uC740
|
|
140
|
+
"context.readBuiltinDocFirst": "\uC774\uBC88 \uC138\uC158\uC5D0 \uC544\uC9C1 \uC77D\uC9C0 \uC54A\uC558\uAC70\uB098 \uBCC0\uACBD \uAC00\uB2A5\uC131\uC774 \uC788\uC744 \uB54C\uB9CC \uD544\uC694\uD55C \uB0B4\uC7A5 \uBB38\uC11C\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
141
|
+
"context.tipDocsCommitRules": "\uCEE4\uBC0B \uBA54\uC2DC\uC9C0 \uADDC\uCE59\uC740 git-workflow \uAC00\uC774\uB4DC\uB97C \uAE30\uC900\uC73C\uB85C \uD655\uC778\uD558\uC138\uC694.",
|
|
142
142
|
"context.list.docsCommitNeeded": "\uBB38\uC11C \uCEE4\uBC0B \uD544\uC694",
|
|
143
143
|
"context.list.projectCommitNeeded": "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uCEE4\uBC0B \uD544\uC694",
|
|
144
144
|
"context.list.issueNumberNeeded": "\uC774\uC288 \uBC88\uD638 \uAE30\uB85D \uD544\uC694",
|
|
@@ -147,7 +147,7 @@ var I18N = {
|
|
|
147
147
|
"context.list.addPrePrReviewField": "Pre-PR Review \uD544\uB4DC \uCD94\uAC00",
|
|
148
148
|
"context.list.completePrePrReview": "Pre-PR \uB9AC\uBDF0 \uC644\uB8CC \uCC98\uB9AC",
|
|
149
149
|
"context.list.setPrStatus": "PR \uC0C1\uD0DC \uC124\uC815",
|
|
150
|
-
"context.list.prStatusToApproved": "PR \uC0C1\uD0DC {status} \u2192 Approved",
|
|
150
|
+
"context.list.prStatusToApproved": "PR \uBA38\uC9C0 \uD544\uC694 (\uD604\uC7AC PR \uC0C1\uD0DC: {status} \u2192 Approved)",
|
|
151
151
|
"context.list.approveSpec": "spec \uC2B9\uC778 \uD544\uC694",
|
|
152
152
|
"context.list.approvePlan": "plan \uC2B9\uC778 \uD544\uC694",
|
|
153
153
|
"init.selectLangPrompt": "\uBB38\uC11C \uC5B8\uC5B4\uB97C \uC120\uD0DD\uD558\uC138\uC694:",
|
|
@@ -396,30 +396,30 @@ var I18N = {
|
|
|
396
396
|
featureDone: "Feature \uC644\uB8CC"
|
|
397
397
|
},
|
|
398
398
|
messages: {
|
|
399
|
-
specCreate: "\
|
|
399
|
+
specCreate: "spec.md\uB97C \uC791\uC131\uD558\uACE0 \uC0C1\uD0DC\uB97C Review\uB85C \uBCC0\uACBD\uD558\uC138\uC694. (agents \uAC00\uC774\uB4DC \uAE30\uC900)",
|
|
400
400
|
specImprove: "spec.md\uB97C \uBCF4\uC644\uD558\uACE0 \uC0C1\uD0DC\uB97C Review\uB85C \uBCC0\uACBD\uD558\uC138\uC694.",
|
|
401
401
|
specApproval: "spec.md \uB0B4\uC6A9\uC744 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uACF5\uC720\uD558\uACE0 \uC2B9\uC778(`A` \uB610\uB294 `A OK` \uD615\uC2DD)\uC744 \uBC1B\uC73C\uC138\uC694.",
|
|
402
|
-
planCreate: "\
|
|
402
|
+
planCreate: "plan.md\uB97C \uC791\uC131\uD558\uACE0 \uC0C1\uD0DC\uB97C Review\uB85C \uBCC0\uACBD\uD558\uC138\uC694. (agents \uAC00\uC774\uB4DC \uAE30\uC900)",
|
|
403
403
|
planImprove: "plan.md\uB97C \uBCF4\uC644\uD558\uACE0 \uC0C1\uD0DC\uB97C Review\uB85C \uBCC0\uACBD\uD558\uC138\uC694.",
|
|
404
404
|
planApproval: "plan.md \uB0B4\uC6A9\uC744 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uACF5\uC720\uD558\uACE0 \uC2B9\uC778(`A` \uB610\uB294 `A OK` \uD615\uC2DD)\uC744 \uBC1B\uC73C\uC138\uC694.",
|
|
405
|
-
tasksCreate: "\
|
|
405
|
+
tasksCreate: "tasks.md\uB97C \uC791\uC131\uD558\uACE0 \uBB38\uC11C \uC0C1\uD0DC\uB97C Review\uB85C \uBCC0\uACBD\uD558\uC138\uC694. (agents/execute-task \uAC00\uC774\uB4DC \uAE30\uC900)",
|
|
406
406
|
tasksNeedAtLeastOne: "tasks.md\uC5D0 \uCD5C\uC18C 1\uAC1C \uC774\uC0C1\uC758 \uD0DC\uC2A4\uD06C\uB97C \uC791\uC131\uD558\uC138\uC694.",
|
|
407
407
|
tasksImprove: "tasks.md\uB97C \uBCF4\uC644\uD558\uACE0 \uBB38\uC11C \uC0C1\uD0DC\uB97C Review\uB85C \uBCC0\uACBD\uD558\uC138\uC694.",
|
|
408
408
|
tasksApproval: "tasks.md \uB0B4\uC6A9\uC744 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uACF5\uC720\uD558\uACE0 \uC9C4\uD589 \uC2B9\uC778(`A` \uB610\uB294 `A OK` \uD615\uC2DD)\uC744 \uBC1B\uC73C\uC138\uC694. (\uC2B9\uC778 \uD6C4 \uBB38\uC11C \uC0C1\uD0DC\uB97C Approved\uB85C \uBCC0\uACBD)",
|
|
409
409
|
docsCommitPlanning: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs(planning): {folderName} \uAE30\uD68D \uBB38\uC11C"',
|
|
410
|
-
issueCreateAndWrite: "\uC774\
|
|
410
|
+
issueCreateAndWrite: "\uC774\uC288 \uBCF8\uBB38 \uD15C\uD50C\uB9BF\uC744 \uC0DD\uC131\uD574 \uBAA9\uD45C/\uC644\uB8CC \uAE30\uC900\uC744 \uAC80\uD1A0\xB7\uBCF4\uC644\uD558\uACE0, \uC0AC\uC6A9\uC790 \uC2B9\uC778(OK) \uD6C4 \uC774\uC288\uB97C \uC0DD\uC131\uD558\uC138\uC694. \uC774\uD6C4 spec.md/tasks.md\uC758 \uC774\uC288 \uBC88\uD638\uB97C \uCC44\uC6B0\uACE0 \uBB38\uC11C \uCEE4\uBC0B\uC744 \uC900\uBE44\uD558\uC138\uC694.",
|
|
411
411
|
docsCommitIssueUpdate: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs(#{issueNumber}): {folderName} \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8"',
|
|
412
412
|
docsCommitUpdate: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs: {folderName} \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8"',
|
|
413
413
|
projectCommitIssueUpdate: 'cd "{projectGitCwd}" && (git diff --cached --quiet && echo "\uC2A4\uD14C\uC774\uC9D5\uB41C \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC774\uBC88 \uD0DC\uC2A4\uD06C\uC5D0\uC11C \uC218\uC815\uD55C \uD30C\uC77C\uB9CC \uC120\uD0DD\uD574 git add [files] \uD6C4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694." && exit 1 || git commit -m "feat(#{issueNumber}): {commitTopic}")',
|
|
414
414
|
projectCommitUpdate: 'cd "{projectGitCwd}" && (git diff --cached --quiet && echo "\uC2A4\uD14C\uC774\uC9D5\uB41C \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC774\uBC88 \uD0DC\uC2A4\uD06C\uC5D0\uC11C \uC218\uC815\uD55C \uD30C\uC77C\uB9CC \uC120\uD0DD\uD574 git add [files] \uD6C4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694." && exit 1 || git commit -m "feat({folderName}): {commitTopic}")',
|
|
415
415
|
standaloneNeedsProjectRoot: "standalone \uBAA8\uB4DC\uC5D0\uC11C\uB294 projectRoot \uC124\uC815\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. (npx lee-spec-kit config --project-root ...)",
|
|
416
416
|
createBranch: 'cd "{projectGitCwd}" && git checkout -b feat/{issueNumber}-{slug}',
|
|
417
|
-
tasksAllDoneButNoChecklist: '\
|
|
418
|
-
tasksAllDoneButChecklist: "\
|
|
419
|
-
finishDoingTask: '\uD604\uC7AC DOING/REVIEW \
|
|
420
|
-
startNextTodoTask: '\uB2E4\uC74C TODO \uD0DC\uC2A4\uD06C\uB97C \uC2DC\uC791\
|
|
421
|
-
checkTaskStatuses: "\uD0DC\uC2A4\uD06C \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uC138\uC694. ({done}/{total})
|
|
422
|
-
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}.
|
|
417
|
+
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.',
|
|
418
|
+
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.",
|
|
419
|
+
finishDoingTask: '\uD604\uC7AC DOING/REVIEW \uD0DC\uC2A4\uD06C\uB97C \uC644\uB8CC\uD569\uB2C8\uB2E4: "{title}" ({done}/{total}) \uACB0\uACFC/\uAC80\uC99D \uACF5\uC720 + \uC2B9\uC778(`A` \uB610\uB294 `A OK` \uD615\uC2DD) \uD6C4 DONE \uCC98\uB9AC',
|
|
420
|
+
startNextTodoTask: '\uB2E4\uC74C TODO \uD0DC\uC2A4\uD06C\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4: "{title}" ({done}/{total}) \uC2B9\uC778(`A` \uB610\uB294 `A OK` \uD615\uC2DD) \uD6C4 DOING \uCC98\uB9AC',
|
|
421
|
+
checkTaskStatuses: "\uD0DC\uC2A4\uD06C \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uC138\uC694. ({done}/{total})",
|
|
422
|
+
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.",
|
|
423
423
|
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.",
|
|
424
424
|
taskCommitGateReasonNoTasksCommit: "\uCD5C\uADFC tasks.md \uCEE4\uBC0B\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4",
|
|
425
425
|
taskCommitGateReasonTasksFileUnavailable: "\uCD5C\uADFC \uCEE4\uBC0B\uC5D0\uC11C tasks.md \uC774\uB825\uC744 \uD310\uB3C5\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4",
|
|
@@ -430,10 +430,10 @@ var I18N = {
|
|
|
430
430
|
prePrReviewRun: "PR \uC0DD\uC131 \uC804 \uC0AC\uC804 \uCF54\uB4DC\uB9AC\uBDF0\uB97C \uC9C4\uD589\uD558\uC138\uC694. \uC6B0\uC120\uC21C\uC704 \uC2A4\uD0AC: {skills} (\uC124\uCE58\uB41C \uB354 \uC801\uD569\uD55C \uC2A4\uD0AC\uC774 \uC788\uB2E4\uBA74 \uBA3C\uC800 \uC81C\uC548 \uD6C4 \uC0AC\uC6A9). \uC2A4\uD0AC\uC744 \uC4F8 \uC218 \uC5C6\uC73C\uBA74 `{fallback}` \uC815\uCC45\uC73C\uB85C \uC9C4\uD589\uD558\uACE0 `PR \uC804 \uB9AC\uBDF0`\uB97C Done\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694. Findings \uC815\uCC45: {findingsPolicy}",
|
|
431
431
|
prePrReviewFindingsBlock: "\uC911\uC694 \uC774\uC288\uB294 \uC218\uC815/\uD569\uC758 \uD6C4\uC5D0\uB9CC PR \uC0DD\uC131",
|
|
432
432
|
prePrReviewFindingsWarn: "\uB9AC\uC2A4\uD06C\uB97C \uACF5\uC720\uD558\uBA74 PR \uC0DD\uC131 \uC9C4\uD589 \uAC00\uB2A5",
|
|
433
|
-
prCreate: "
|
|
434
|
-
prFillStatus: "tasks.md\uC758 PR \uC0C1\uD0DC\uB97C Review
|
|
435
|
-
prResolveReview: "\uB9AC\uBDF0 \uCF54\uBA58\uD2B8\uB97C \uD574\uACB0\uD558\
|
|
436
|
-
prRequestReview: "\uB9AC\uBDF0\uC5B4\uC5D0\uAC8C \uB9AC\uBDF0\uB97C \uC694\uCCAD\uD558\uACE0 PR \uC0C1\uD0DC\uB97C Review\uB85C \
|
|
433
|
+
prCreate: "PR \uBCF8\uBB38 \uD15C\uD50C\uB9BF\uC744 \uC0DD\uC131\uD574 \uBCC0\uACBD \uC0AC\uD56D/\uD14C\uC2A4\uD2B8 \uC139\uC158\uC744 \uAC80\uD1A0\xB7\uBCF4\uC644\uD558\uACE0, \uC0AC\uC6A9\uC790 \uC2B9\uC778(OK) \uD6C4 PR\uC744 \uC0DD\uC131\uD558\uC138\uC694. \uC774\uD6C4 tasks.md\uC5D0 PR \uB9C1\uD06C\uB97C \uAE30\uB85D\uD558\uC138\uC694.",
|
|
434
|
+
prFillStatus: "tasks.md\uC758 PR \uC0C1\uD0DC\uB97C Review\uB85C \uC124\uC815\uD558\uC138\uC694. (PR \uC0DD\uC131/\uB9AC\uBDF0 \uB2E8\uACC4\uC5D0\uC11C\uB294 Review\uB97C \uC720\uC9C0\uD569\uB2C8\uB2E4.)",
|
|
435
|
+
prResolveReview: "\uB9AC\uBDF0 \uCF54\uBA58\uD2B8\uB97C \uD574\uACB0\uD558\uB294 \uB3D9\uC548 PR \uC0C1\uD0DC\uB294 Review\uB85C \uC720\uC9C0\uD558\uC138\uC694. \uBA38\uC9C0 \uC900\uBE44\uAC00 \uB418\uBA74 \uC0AC\uC6A9\uC790 \uC2B9\uC778(OK) \uD6C4 `npx lee-spec-kit github pr {featureRef} --merge --confirm OK`\uB97C \uC2E4\uD589\uD558\uC138\uC694. (\uC131\uACF5 \uC2DC PR \uC0C1\uD0DC\uAC00 Approved\uB85C \uB3D9\uAE30\uD654\uB429\uB2C8\uB2E4.)",
|
|
436
|
+
prRequestReview: "\uB9AC\uBDF0\uC5B4\uC5D0\uAC8C \uB9AC\uBDF0\uB97C \uC694\uCCAD\uD558\uACE0 PR \uC0C1\uD0DC\uB97C Review\uB85C \uC124\uC815/\uC720\uC9C0\uD558\uC138\uC694.",
|
|
437
437
|
featureDone: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC694\uAD6C\uC0AC\uD56D\uACFC \uBAA8\uB4E0 \uD0DC\uC2A4\uD06C/\uC644\uB8CC \uC870\uAC74\uC774 \uCDA9\uC871\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC774 Feature\uB294 \uC644\uB8CC \uC0C1\uD0DC\uC785\uB2C8\uB2E4.",
|
|
438
438
|
fallbackRerunContext: "\uC0C1\uD0DC\uB97C \uD310\uBCC4\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uBB38\uC11C\uB97C \uD655\uC778\uD55C \uB4A4 \uB2E4\uC2DC context\uB97C \uC2E4\uD589\uD558\uC138\uC694."
|
|
439
439
|
},
|
|
@@ -441,7 +441,7 @@ var I18N = {
|
|
|
441
441
|
projectBranchUnavailable: "\uD504\uB85C\uC81D\uD2B8 \uBE0C\uB79C\uCE58\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. (standalone \uBAA8\uB4DC\uC5D0\uC11C\uB294 projectRoot\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.)",
|
|
442
442
|
docsGitUnavailable: "docs \uB808\uD3EC\uC758 git \uC0C1\uD0DC\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. (\uB808\uD3EC \uC704\uCE58 / git init \uD655\uC778)",
|
|
443
443
|
docsPathIgnored: "\uD604\uC7AC Feature \uBB38\uC11C \uACBD\uB85C\uAC00 git ignore \uB300\uC0C1\uC785\uB2C8\uB2E4: {path} (docs \uCEE4\uBC0B \uAC10\uC9C0\uAC00 \uC81C\uD55C\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.)",
|
|
444
|
-
docsUncommittedChanges: "\uBB38\uC11C \uBCC0\uACBD\uC0AC\uD56D\uC774 \uCEE4\uBC0B\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. (\uCD94\uAC00 \uBB38\uC11C \uCEE4\uBC0B \uD544\uC694) \uCEE4\uBC0B \uBA54\uC2DC\uC9C0 \uADDC\uCE59\uC740
|
|
444
|
+
docsUncommittedChanges: "\uBB38\uC11C \uBCC0\uACBD\uC0AC\uD56D\uC774 \uCEE4\uBC0B\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. (\uCD94\uAC00 \uBB38\uC11C \uCEE4\uBC0B \uD544\uC694) \uCEE4\uBC0B \uBA54\uC2DC\uC9C0 \uADDC\uCE59\uC740 git-workflow \uAC00\uC774\uB4DC\uB97C \uAE30\uC900\uC73C\uB85C \uD655\uC778\uD558\uC138\uC694.",
|
|
445
445
|
projectUncommittedChanges: "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uBCC0\uACBD\uC0AC\uD56D\uC774 \uCEE4\uBC0B\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. (\uCD94\uAC00 \uCF54\uB4DC \uCEE4\uBC0B \uD544\uC694)",
|
|
446
446
|
legacyTasksDocStatusField: "\uAD6C\uBC84\uC804 tasks.md \uD3EC\uB9F7\uC785\uB2C8\uB2E4. `\uBB38\uC11C \uC0C1\uD0DC` \uD544\uB4DC(Review/Approved)\uB97C \uCD94\uAC00\uD574 \uD0DC\uC2A4\uD06C \uC2B9\uC778 \uB2E8\uACC4\uB97C \uD65C\uC131\uD654\uD558\uC138\uC694.",
|
|
447
447
|
legacyTasksPrFields: "\uAD6C\uBC84\uC804 tasks.md \uD3EC\uB9F7\uC785\uB2C8\uB2E4. PR \uB2E8\uACC4 \uC804\uC5D0 `PR` \uBC0F `PR \uC0C1\uD0DC` \uD544\uB4DC\uB97C \uCD94\uAC00\uD558\uC138\uC694.",
|
|
@@ -451,8 +451,8 @@ var I18N = {
|
|
|
451
451
|
workflowIssueMissing: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC \uC774\uC288 \uBC88\uD638\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. (spec.md/tasks.md\uC758 \uC774\uC288 \uBC88\uD638\uB97C \uCC44\uC6B0\uC138\uC694.)",
|
|
452
452
|
workflowProjectUncommittedChanges: "\uC644\uB8CC \uC870\uAC74 \uC774\uC804\uC5D0 \uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uBCC0\uACBD\uC0AC\uD56D\uC744 \uCEE4\uBC0B\uD574\uC57C \uD569\uB2C8\uB2E4. (\uD504\uB85C\uC81D\uD2B8 \uC6CC\uD06C\uD2B8\uB9AC \uBBF8\uCEE4\uBC0B \uBCC0\uACBD \uC874\uC7AC)",
|
|
453
453
|
workflowPrLinkMissing: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC PR \uB9C1\uD06C\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. (tasks.md\uC758 PR \uD544\uB4DC\uB97C \uCC44\uC6B0\uC138\uC694.)",
|
|
454
|
-
workflowPrStatusMissing: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC PR \uC0C1\uD0DC\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. (
|
|
455
|
-
workflowPrStatusNotApproved: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC PR \uC0C1\uD0DC\uAC00 Approved\uAC00 \uC544\uB2D9\uB2C8\uB2E4. (
|
|
454
|
+
workflowPrStatusMissing: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC PR \uC0C1\uD0DC\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. (PR \uC0DD\uC131/\uB9AC\uBDF0 \uB2E8\uACC4\uC5D0\uC11C\uB294 PR \uC0C1\uD0DC\uB97C Review\uB85C \uC124\uC815\uD558\uC138\uC694.)",
|
|
455
|
+
workflowPrStatusNotApproved: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC PR \uC0C1\uD0DC\uAC00 Approved\uAC00 \uC544\uB2D9\uB2C8\uB2E4. (PR \uC0DD\uC131/\uB9AC\uBDF0 \uB2E8\uACC4\uB294 Review\uB97C \uC720\uC9C0\uD558\uACE0, merge \uC131\uACF5 \uC2DC\uC5D0\uB9CC Approved\uB85C \uB3D9\uAE30\uD654\uD558\uC138\uC694.)",
|
|
456
456
|
workflowPrePrReviewMissing: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC `PR \uC804 \uB9AC\uBDF0` \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. (tasks.md\uC5D0 `- **PR \uC804 \uB9AC\uBDF0**: Pending | Done`\uC744 \uCD94\uAC00\uD558\uC138\uC694.)",
|
|
457
457
|
workflowPrePrReviewNotDone: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC `PR \uC804 \uB9AC\uBDF0`\uAC00 Done\uC774 \uC544\uB2D9\uB2C8\uB2E4. (\uC0AC\uC804 \uCF54\uB4DC\uB9AC\uBDF0 \uD6C4 Done\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694.)"
|
|
458
458
|
}
|
|
@@ -527,14 +527,14 @@ var I18N = {
|
|
|
527
527
|
"context.tipShowAll": "Show all",
|
|
528
528
|
"context.tipShowDone": "Show done only",
|
|
529
529
|
"context.checkRequired": "[CHECK required] ",
|
|
530
|
-
"context.checkPolicyHint": "\u2139\uFE0F Check user-approval policy once at session start (or right after context compression/reset)
|
|
530
|
+
"context.checkPolicyHint": "\u2139\uFE0F Check user-approval policy once at session start (or right after context compression/reset); re-check only when policy/config changes or the user explicitly requests refresh. (includes git push/merge and merge commits). If you see [CHECK required], wait for `<label>` or `<label> OK` (e.g. `A`, `A OK`) before proceeding (config: approval can override)",
|
|
531
531
|
"context.actionOptionHint": "Approval reply format: include a label token (e.g. `A`, `A OK`, `A proceed`)",
|
|
532
532
|
"context.actionExplainHint": "Before requesting approval, explain what each label will run/change with a one-line summary.",
|
|
533
533
|
"context.finalLabelPrompt": "Available labels now: {labels}. End with a label request in `<label>` or `<label> OK` format. (e.g. {example})",
|
|
534
534
|
"context.finalLabelCommandHint": "When a label is provided, run approval selection: {command}",
|
|
535
535
|
"context.finalTicketCommandHint": "Execute commands using the ticket from approval result: {command}",
|
|
536
|
-
"context.readBuiltinDocFirst": "Read built-in docs only if not read in this session yet or likely changed
|
|
537
|
-
"context.tipDocsCommitRules": "Check commit message rules
|
|
536
|
+
"context.readBuiltinDocFirst": "Read required built-in docs only if not read in this session yet or likely changed.",
|
|
537
|
+
"context.tipDocsCommitRules": "Check commit message rules against the git-workflow guide.",
|
|
538
538
|
"context.list.docsCommitNeeded": "Commit docs changes",
|
|
539
539
|
"context.list.projectCommitNeeded": "Commit project code changes",
|
|
540
540
|
"context.list.issueNumberNeeded": "Fill issue number in docs",
|
|
@@ -543,7 +543,7 @@ var I18N = {
|
|
|
543
543
|
"context.list.addPrePrReviewField": "Add Pre-PR Review field",
|
|
544
544
|
"context.list.completePrePrReview": "Complete Pre-PR review",
|
|
545
545
|
"context.list.setPrStatus": "Set PR Status",
|
|
546
|
-
"context.list.prStatusToApproved": "PR Status {status} \u2192 Approved",
|
|
546
|
+
"context.list.prStatusToApproved": "PR merge required (PR Status: {status} \u2192 Approved)",
|
|
547
547
|
"context.list.approveSpec": "Approve spec",
|
|
548
548
|
"context.list.approvePlan": "Approve plan",
|
|
549
549
|
"init.selectLangPrompt": "Select docs language:",
|
|
@@ -792,30 +792,30 @@ var I18N = {
|
|
|
792
792
|
featureDone: "Feature done"
|
|
793
793
|
},
|
|
794
794
|
messages: {
|
|
795
|
-
specCreate: "
|
|
795
|
+
specCreate: "Write spec.md and change Status to Review. (Follow the agents guide baseline.)",
|
|
796
796
|
specImprove: "Improve spec.md and change Status to Review.",
|
|
797
797
|
specApproval: "Share spec.md with the user and get approval (`A` or `A OK` format).",
|
|
798
|
-
planCreate: "
|
|
798
|
+
planCreate: "Write plan.md and change Status to Review. (Follow the agents guide baseline.)",
|
|
799
799
|
planImprove: "Improve plan.md and change Status to Review.",
|
|
800
800
|
planApproval: "Share plan.md with the user and get approval (`A` or `A OK` format).",
|
|
801
|
-
tasksCreate: "
|
|
801
|
+
tasksCreate: "Write tasks.md and change Doc Status to Review. (Follow the agents/execute-task guide baseline.)",
|
|
802
802
|
tasksNeedAtLeastOne: "Write at least 1 task in tasks.md.",
|
|
803
803
|
tasksImprove: "Improve tasks.md and change Doc Status to Review.",
|
|
804
804
|
tasksApproval: "Share tasks.md with the user and get progress approval (`A` or `A OK` format). (Then set Doc Status to Approved)",
|
|
805
805
|
docsCommitPlanning: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs(planning): {folderName} planning docs"',
|
|
806
|
-
issueCreateAndWrite: "
|
|
806
|
+
issueCreateAndWrite: "Generate the issue body template, refine goals/completion criteria, get explicit user OK, create the issue, then update issue number in spec.md/tasks.md and prepare a docs commit.",
|
|
807
807
|
docsCommitIssueUpdate: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs(#{issueNumber}): {folderName} docs update"',
|
|
808
808
|
docsCommitUpdate: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs: {folderName} docs update"',
|
|
809
809
|
projectCommitIssueUpdate: 'cd "{projectGitCwd}" && (git diff --cached --quiet && echo "No staged files. Stage only files changed in this task with git add [files], then run again." && exit 1 || git commit -m "feat(#{issueNumber}): {commitTopic}")',
|
|
810
810
|
projectCommitUpdate: 'cd "{projectGitCwd}" && (git diff --cached --quiet && echo "No staged files. Stage only files changed in this task with git add [files], then run again." && exit 1 || git commit -m "feat({folderName}): {commitTopic}")',
|
|
811
811
|
standaloneNeedsProjectRoot: "Standalone mode requires projectRoot. (npx lee-spec-kit config --project-root ...)",
|
|
812
812
|
createBranch: 'cd "{projectGitCwd}" && git checkout -b feat/{issueNumber}-{slug}',
|
|
813
|
-
tasksAllDoneButNoChecklist: '
|
|
814
|
-
tasksAllDoneButChecklist: "
|
|
815
|
-
finishDoingTask: 'Finish the current DOING/REVIEW task: "{title}" ({done}/{total})
|
|
816
|
-
startNextTodoTask: 'Start the next TODO task: "{title}" ({done}/{total}) (
|
|
817
|
-
checkTaskStatuses: "Check task statuses. ({done}/{total})
|
|
818
|
-
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
|
|
813
|
+
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.',
|
|
814
|
+
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.",
|
|
815
|
+
finishDoingTask: 'Finish the current DOING/REVIEW task: "{title}" ({done}/{total}) Share outcome/verification + get OK before marking DONE',
|
|
816
|
+
startNextTodoTask: 'Start the next TODO task: "{title}" ({done}/{total}) Get approval (`A` or `A OK`) before marking DOING',
|
|
817
|
+
checkTaskStatuses: "Check task statuses. ({done}/{total})",
|
|
818
|
+
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.",
|
|
819
819
|
taskCommitGateWarnProceed: "\u26A0\uFE0F Task commit boundary warning: {reason}. You may continue, but `1 task = 1 commit` is recommended.",
|
|
820
820
|
taskCommitGateReasonNoTasksCommit: "No recent tasks.md commit was found",
|
|
821
821
|
taskCommitGateReasonTasksFileUnavailable: "Cannot read tasks.md history from the latest commit",
|
|
@@ -826,10 +826,10 @@ var I18N = {
|
|
|
826
826
|
prePrReviewRun: "Run a pre-PR code review before creating the PR. Preferred skills: {skills} (if a better installed skill fits this change, propose it first). If no skill can run, use `{fallback}` and set `Pre-PR Review` to Done in tasks.md. Findings policy: {findingsPolicy}",
|
|
827
827
|
prePrReviewFindingsBlock: "major findings must be fixed/aligned before PR creation",
|
|
828
828
|
prePrReviewFindingsWarn: "you may proceed after sharing the risks",
|
|
829
|
-
prCreate: "
|
|
830
|
-
prFillStatus: "Set PR Status in tasks.md to Review
|
|
831
|
-
prResolveReview: "
|
|
832
|
-
prRequestReview: "Request review and
|
|
829
|
+
prCreate: "Generate the PR body template, refine changes/tests sections, get explicit user OK, create the PR, then record the PR link in tasks.md.",
|
|
830
|
+
prFillStatus: "Set PR Status in tasks.md to Review. (Keep Review during PR creation/review stages.)",
|
|
831
|
+
prResolveReview: "Keep PR Status as Review while addressing comments. Once ready to merge, get explicit user OK and run `npx lee-spec-kit github pr {featureRef} --merge --confirm OK`. (On success, PR Status is synced to Approved.)",
|
|
832
|
+
prRequestReview: "Request review and set/keep PR Status as Review.",
|
|
833
833
|
featureDone: "Workflow requirements and all tasks/completion criteria are satisfied. This feature is done.",
|
|
834
834
|
fallbackRerunContext: "Cannot determine status. Check the docs and run context again."
|
|
835
835
|
},
|
|
@@ -837,7 +837,7 @@ var I18N = {
|
|
|
837
837
|
projectBranchUnavailable: "Cannot determine project branch. (In standalone mode, projectRoot is required.)",
|
|
838
838
|
docsGitUnavailable: "Cannot read git status for the docs repo. (Check repo location / git init.)",
|
|
839
839
|
docsPathIgnored: "Current feature docs path is ignored by git: {path} (docs commit detection may be limited).",
|
|
840
|
-
docsUncommittedChanges: "Docs changes are not committed. (Additional docs commit needed.) Check commit message rules
|
|
840
|
+
docsUncommittedChanges: "Docs changes are not committed. (Additional docs commit needed.) Check commit message rules against the git-workflow guide.",
|
|
841
841
|
projectUncommittedChanges: "Project code changes are not committed. (Additional code commit needed.)",
|
|
842
842
|
legacyTasksDocStatusField: "Legacy tasks.md format detected. Add a `Doc Status` field (Review/Approved) to enable tasks approval.",
|
|
843
843
|
legacyTasksPrFields: "Legacy tasks.md format detected. Add `PR` and `PR Status` fields before PR steps.",
|
|
@@ -847,8 +847,8 @@ var I18N = {
|
|
|
847
847
|
workflowIssueMissing: "Implementation is done but Issue Number is missing. (Fill Issue Number in spec.md/tasks.md.)",
|
|
848
848
|
workflowProjectUncommittedChanges: "Commit project code changes before completing workflow. (Project worktree has uncommitted changes.)",
|
|
849
849
|
workflowPrLinkMissing: "Implementation is done but PR link is missing. (Fill the PR field in tasks.md.)",
|
|
850
|
-
workflowPrStatusMissing: "Implementation is done but PR Status is missing. (Set PR Status to Review/
|
|
851
|
-
workflowPrStatusNotApproved: "Implementation is done but PR Status is not Approved. (
|
|
850
|
+
workflowPrStatusMissing: "Implementation is done but PR Status is missing. (Set PR Status to Review during PR creation/review stages.)",
|
|
851
|
+
workflowPrStatusNotApproved: "Implementation is done but PR Status is not Approved. (Keep PR Status as Review before merge and sync to Approved only after successful merge.)",
|
|
852
852
|
workflowPrePrReviewMissing: "Implementation is done but `Pre-PR Review` is missing. (Add `- **Pre-PR Review**: Pending | Done` in tasks.md.)",
|
|
853
853
|
workflowPrePrReviewNotDone: "Implementation is done but `Pre-PR Review` is not Done. (Run pre-PR review, then update it to Done.)"
|
|
854
854
|
}
|
|
@@ -2702,6 +2702,13 @@ function resolveProjectCommitTopic(feature) {
|
|
|
2702
2702
|
const topic = withoutTaskId || normalizeCommitTopicText(feature.folderName);
|
|
2703
2703
|
return toShellSafeCommitTopic(topic);
|
|
2704
2704
|
}
|
|
2705
|
+
function shouldBlockTaskCommitGate(policy, check) {
|
|
2706
|
+
if (policy !== "strict") return false;
|
|
2707
|
+
if (check.reason === "MULTIPLE_DONE_TRANSITIONS") {
|
|
2708
|
+
return (check.newDoneCount ?? 0) > 1;
|
|
2709
|
+
}
|
|
2710
|
+
return false;
|
|
2711
|
+
}
|
|
2705
2712
|
function normalizeGitRelativePath(value) {
|
|
2706
2713
|
return value.replace(/\\/g, "/").replace(/^\.\/+/, "").replace(/\/+$/, "");
|
|
2707
2714
|
}
|
|
@@ -3044,6 +3051,57 @@ function getStepDefinitions(lang, workflow) {
|
|
|
3044
3051
|
when: (f) => f.docs.tasksExists && f.tasks.total > 0 && (f.tasks.done < f.tasks.total || !isCompletionChecklistDone(f)) && isTasksDocApproved(f) && (!workflowPolicy.requireBranch || f.git.onExpectedBranch || f.tasks.done === f.tasks.total),
|
|
3045
3052
|
actions: (f) => {
|
|
3046
3053
|
if (f.tasks.total === f.tasks.done && !isCompletionChecklistDone(f)) {
|
|
3054
|
+
if (f.git.docsHasUncommittedChanges) {
|
|
3055
|
+
return [
|
|
3056
|
+
{
|
|
3057
|
+
type: "command",
|
|
3058
|
+
category: "docs_commit",
|
|
3059
|
+
requiresUserCheck: true,
|
|
3060
|
+
scope: "docs",
|
|
3061
|
+
cwd: f.git.docsGitCwd,
|
|
3062
|
+
cmd: f.issueNumber ? tr(lang, "messages", "docsCommitIssueUpdate", {
|
|
3063
|
+
docsGitCwd: f.git.docsGitCwd,
|
|
3064
|
+
featurePath: f.docs.featurePathFromDocs,
|
|
3065
|
+
issueNumber: f.issueNumber,
|
|
3066
|
+
folderName: f.folderName
|
|
3067
|
+
}) : tr(lang, "messages", "docsCommitUpdate", {
|
|
3068
|
+
docsGitCwd: f.git.docsGitCwd,
|
|
3069
|
+
featurePath: f.docs.featurePathFromDocs,
|
|
3070
|
+
folderName: f.folderName
|
|
3071
|
+
})
|
|
3072
|
+
}
|
|
3073
|
+
];
|
|
3074
|
+
}
|
|
3075
|
+
if (f.git.projectHasUncommittedChanges) {
|
|
3076
|
+
if (!f.git.projectGitCwd) {
|
|
3077
|
+
return [
|
|
3078
|
+
{
|
|
3079
|
+
type: "instruction",
|
|
3080
|
+
category: "task_execute",
|
|
3081
|
+
message: tr(lang, "messages", "standaloneNeedsProjectRoot")
|
|
3082
|
+
}
|
|
3083
|
+
];
|
|
3084
|
+
}
|
|
3085
|
+
return [
|
|
3086
|
+
{
|
|
3087
|
+
type: "command",
|
|
3088
|
+
category: "task_execute",
|
|
3089
|
+
requiresUserCheck: true,
|
|
3090
|
+
scope: "project",
|
|
3091
|
+
cwd: f.git.projectGitCwd,
|
|
3092
|
+
cmd: f.issueNumber ? tr(lang, "messages", "projectCommitIssueUpdate", {
|
|
3093
|
+
projectGitCwd: f.git.projectGitCwd,
|
|
3094
|
+
issueNumber: f.issueNumber,
|
|
3095
|
+
folderName: f.folderName,
|
|
3096
|
+
commitTopic: resolveProjectCommitTopic(f)
|
|
3097
|
+
}) : tr(lang, "messages", "projectCommitUpdate", {
|
|
3098
|
+
projectGitCwd: f.git.projectGitCwd,
|
|
3099
|
+
folderName: f.folderName,
|
|
3100
|
+
commitTopic: resolveProjectCommitTopic(f)
|
|
3101
|
+
})
|
|
3102
|
+
}
|
|
3103
|
+
];
|
|
3104
|
+
}
|
|
3047
3105
|
const actions = [
|
|
3048
3106
|
{
|
|
3049
3107
|
type: "instruction",
|
|
@@ -3135,7 +3193,7 @@ function getStepDefinitions(lang, workflow) {
|
|
|
3135
3193
|
const commitGate = checkTaskCommitGate(f);
|
|
3136
3194
|
if (!commitGate.pass) {
|
|
3137
3195
|
const reasonText = getTaskCommitGateReasonText(lang, commitGate);
|
|
3138
|
-
if (taskCommitGatePolicy
|
|
3196
|
+
if (shouldBlockTaskCommitGate(taskCommitGatePolicy, commitGate)) {
|
|
3139
3197
|
return [
|
|
3140
3198
|
{
|
|
3141
3199
|
type: "instruction",
|
|
@@ -3363,7 +3421,10 @@ ${tr(lang, "messages", "taskCommitGateWarnProceed", {
|
|
|
3363
3421
|
{
|
|
3364
3422
|
type: "instruction",
|
|
3365
3423
|
category: "code_review",
|
|
3366
|
-
|
|
3424
|
+
requiresUserCheck: true,
|
|
3425
|
+
message: tr(lang, "messages", "prResolveReview", {
|
|
3426
|
+
featureRef: f.id || f.folderName
|
|
3427
|
+
})
|
|
3367
3428
|
}
|
|
3368
3429
|
];
|
|
3369
3430
|
}
|
|
@@ -4982,7 +5043,22 @@ function getActionSummary(action) {
|
|
|
4982
5043
|
return action.message;
|
|
4983
5044
|
}
|
|
4984
5045
|
function formatActionSummary(action) {
|
|
5046
|
+
const extractCommitMessage = (command) => {
|
|
5047
|
+
const doubleQuoted = command.match(/git\s+commit\s+-m\s+"((?:\\"|[^"])*)"/);
|
|
5048
|
+
if (doubleQuoted) {
|
|
5049
|
+
return doubleQuoted[1].replace(/\\"/g, '"').trim();
|
|
5050
|
+
}
|
|
5051
|
+
const singleQuoted = command.match(/git\s+commit\s+-m\s+'((?:\\'|[^'])*)'/);
|
|
5052
|
+
if (singleQuoted) {
|
|
5053
|
+
return singleQuoted[1].replace(/\\'/g, "'").trim();
|
|
5054
|
+
}
|
|
5055
|
+
return null;
|
|
5056
|
+
};
|
|
4985
5057
|
if (action.type === "command") {
|
|
5058
|
+
const commitMessage = extractCommitMessage(action.cmd);
|
|
5059
|
+
if (commitMessage) {
|
|
5060
|
+
return `(${action.scope}) commit: ${commitMessage}`;
|
|
5061
|
+
}
|
|
4986
5062
|
return `(${action.scope}) ${action.cmd}`;
|
|
4987
5063
|
}
|
|
4988
5064
|
return action.message;
|
|
@@ -5779,15 +5855,19 @@ async function runContext(featureName, options) {
|
|
|
5779
5855
|
"actionOptions[].detail",
|
|
5780
5856
|
"actionOptions[].approvalPrompt"
|
|
5781
5857
|
],
|
|
5782
|
-
recommendation: "Before asking for approval,
|
|
5858
|
+
recommendation: "Before asking for approval, show only `actionOptions[].approvalPrompt` lines and `approvalRequest.finalPrompt` to the user. Keep `requiredDocs`, `checkPolicy`, and raw execution commands as internal guidance. For commit actions, include scope (`docs`/`project`) and commit message in the visible prompt. User replies should include the label token (e.g. `A`, `A OK`, `A proceed`, `A \uC9C4\uD589\uD574`). For command execution, require one-time `approvalTicket` only when the selected action has `requiresUserCheck=true`.",
|
|
5783
5859
|
oneApprovalPerAction: true,
|
|
5784
5860
|
requireFreshContext: true,
|
|
5785
5861
|
contextVersion: state.contextVersion,
|
|
5786
5862
|
config: config.approval ?? { mode: "builtin" }
|
|
5787
5863
|
},
|
|
5788
5864
|
approvalRequest: {
|
|
5789
|
-
guidance: "
|
|
5865
|
+
guidance: "User-facing output must include only approval prompts (`A: ...`) and `finalPrompt`. Do not expose `requiredDocs`, `checkPolicy`, or raw `cmd` unless explicitly requested.",
|
|
5790
5866
|
finalPrompt: finalApprovalPrompt,
|
|
5867
|
+
userFacingLines: [
|
|
5868
|
+
...state.actionOptions.map((o) => o.approvalPrompt),
|
|
5869
|
+
finalApprovalPrompt
|
|
5870
|
+
].filter((line) => line.length > 0),
|
|
5791
5871
|
labels: state.actionOptions.map((o) => o.label),
|
|
5792
5872
|
approveCommand,
|
|
5793
5873
|
executeCommand,
|
|
@@ -8720,6 +8800,30 @@ function githubCommand(program2) {
|
|
|
8720
8800
|
projectGitCwd,
|
|
8721
8801
|
tg(config.lang, "pullBaseAfterMergeFailed", { base: baseBranch })
|
|
8722
8802
|
);
|
|
8803
|
+
if (prUrl && options.syncTasks !== false) {
|
|
8804
|
+
const mergedSync = syncTasksPrMetadata(
|
|
8805
|
+
path18.join(config.docsDir, paths.tasksPath),
|
|
8806
|
+
prUrl,
|
|
8807
|
+
"Approved",
|
|
8808
|
+
config.lang
|
|
8809
|
+
);
|
|
8810
|
+
syncChanged = syncChanged || mergedSync.changed;
|
|
8811
|
+
if (mergedSync.changed) {
|
|
8812
|
+
const docsGitCwd = resolveGithubDocsCwd(config, feature);
|
|
8813
|
+
const message = feature.issueNumber ? tg(config.lang, "syncCommitWithIssue", {
|
|
8814
|
+
issue: feature.issueNumber,
|
|
8815
|
+
folder: feature.folderName
|
|
8816
|
+
}) : tg(config.lang, "syncCommitNoIssue", {
|
|
8817
|
+
folder: feature.folderName
|
|
8818
|
+
});
|
|
8819
|
+
commitAndPushPath(
|
|
8820
|
+
docsGitCwd,
|
|
8821
|
+
mergedSync.path,
|
|
8822
|
+
message,
|
|
8823
|
+
config.lang
|
|
8824
|
+
);
|
|
8825
|
+
}
|
|
8826
|
+
}
|
|
8723
8827
|
}
|
|
8724
8828
|
if (options.json) {
|
|
8725
8829
|
console.log(
|