lee-spec-kit 0.6.27 → 0.6.29
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 +260 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/en/common/agents/agents.md +1 -0
- package/templates/en/common/agents/skills/create-issue.md +1 -1
- package/templates/en/common/agents/skills/create-pr.md +4 -2
- package/templates/en/common/agents/skills/execute-task.md +1 -0
- package/templates/en/common/features/feature-base/tasks.md +1 -1
- package/templates/ko/common/agents/agents.md +1 -0
- package/templates/ko/common/agents/skills/create-issue.md +1 -1
- package/templates/ko/common/agents/skills/create-pr.md +4 -2
- package/templates/ko/common/agents/skills/execute-task.md +1 -0
- package/templates/ko/common/features/feature-base/tasks.md +1 -1
package/dist/index.js
CHANGED
|
@@ -186,7 +186,7 @@ var ko = {
|
|
|
186
186
|
"context.actionDetail.tasksWriteImprove": "tasks.md\uB97C \uBCF4\uC644\uD558\uACE0 \uBB38\uC11C \uC0C1\uD0DC\uB97C \uC815\uB82C\uD558\uC138\uC694",
|
|
187
187
|
"context.actionDetail.tasksApprove": "tasks.md\uB97C \uC2B9\uC778\uD569\uB2C8\uB2E4",
|
|
188
188
|
"context.actionDetail.issueCreate": "\uC774\uC288\uB97C \uC0DD\uC131\uD558\uACE0 tasks.md\uC758 \uC774\uC288 \uC815\uBCF4\uB97C \uB9DE\uCD94\uC138\uC694",
|
|
189
|
-
"context.actionDetail.issueCreateAndWrite": "\uC774\uC288 \uCD08\uC548\uC744 \uBCF4\uC644\uD558\uACE0 \uC2B9\uC778(OK) \uD6C4 \uC774\uC288\uB97C \uC0DD\uC131\uD574 \uBC88\uD638\uB97C \uB3D9\uAE30\uD654\uD558\uC138\uC694",
|
|
189
|
+
"context.actionDetail.issueCreateAndWrite": "\uC774\uC288 \uCD08\uC548\uC744 \uBCF4\uC644\uD558\uACE0 \uB77C\uBCA8 \uC2B9\uC778(`A` \uB610\uB294 `A OK`) \uD6C4 \uC774\uC288\uB97C \uC0DD\uC131\uD574 \uBC88\uD638\uB97C \uB3D9\uAE30\uD654\uD558\uC138\uC694",
|
|
190
190
|
"context.actionDetail.issueCreatePrepareFromDoc": "issue.md \uCD08\uC548\uC744 \uBCF4\uC644\uD558\uACE0 \uC0C1\uD0DC\uB97C Ready\uB85C \uC124\uC815\uD558\uC138\uC694",
|
|
191
191
|
"context.actionDetail.issueCreateFromDoc": "Ready \uC0C1\uD0DC issue.md\uB85C \uC774\uC288\uB97C \uC0DD\uC131\uD558\uACE0 \uBC88\uD638\uB97C \uB3D9\uAE30\uD654\uD558\uC138\uC694",
|
|
192
192
|
"context.actionDetail.taskExecute": "\uD604\uC7AC \uD0DC\uC2A4\uD06C\uB97C \uC9C4\uD589\uD558\uC138\uC694",
|
|
@@ -201,7 +201,7 @@ var ko = {
|
|
|
201
201
|
"context.actionDetail.prStatusUpdateSyncApproved": "\uC6D0\uACA9 \uBA38\uC9C0 \uC0C1\uD0DC\uB97C \uBC18\uC601\uD574 PR \uC0C1\uD0DC\uB97C Approved\uB85C \uB3D9\uAE30\uD654\uD558\uC138\uC694",
|
|
202
202
|
"context.actionDetail.codeReview": "\uCF54\uB4DC \uB9AC\uBDF0 \uC9C0\uC801\uC0AC\uD56D\uC744 \uBC18\uC601\uD558\uACE0 PR \uB9AC\uBDF0 \uC815\uBCF4\uB97C \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694",
|
|
203
203
|
"context.actionDetail.codeReviewNeedEvidenceField": "tasks.md\uC5D0 PR \uB9AC\uBDF0 Evidence \uD544\uB4DC\uB97C \uCD94\uAC00\uD558\uC138\uC694",
|
|
204
|
-
"context.actionDetail.codeReviewNeedEvidence": "PR \uB9AC\uBDF0
|
|
204
|
+
"context.actionDetail.codeReviewNeedEvidence": "`summary: ...` \uD615\uC2DD \uB610\uB294 decisions.md\uC758 PR \uB9AC\uBDF0 \uB85C\uADF8 \uACBD\uB85C\uB85C PR \uB9AC\uBDF0 Evidence\uB97C \uAE30\uB85D\uD558\uC138\uC694",
|
|
205
205
|
"context.actionDetail.codeReviewNeedDecisionField": "tasks.md\uC5D0 PR \uB9AC\uBDF0 Decision \uD544\uB4DC\uB97C \uCD94\uAC00\uD558\uC138\uC694",
|
|
206
206
|
"context.actionDetail.codeReviewNeedDecision": "PR \uB9AC\uBDF0 Decision\uC744 \uAE30\uB85D\uD558\uC138\uC694",
|
|
207
207
|
"context.actionDetail.codeReviewResolve": "\uB9AC\uBDF0 \uCF54\uBA58\uD2B8\uB97C \uBC18\uC601\uD558\uACE0 PR \uB9AC\uBDF0 \uBB38\uC11C\uB97C \uCD5C\uC2E0\uD654\uD558\uC138\uC694",
|
|
@@ -504,8 +504,8 @@ var ko = {
|
|
|
504
504
|
tasksImprove: "tasks.md\uB97C \uBCF4\uC644\uD558\uACE0 \uBB38\uC11C \uC0C1\uD0DC\uB97C Review\uB85C \uBCC0\uACBD\uD558\uC138\uC694.",
|
|
505
505
|
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)",
|
|
506
506
|
docsCommitPlanning: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs(planning): {folderName} \uAE30\uD68D \uBB38\uC11C"',
|
|
507
|
-
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, \
|
|
508
|
-
issuePrepareFromDoc: "`issue.md`\uB97C \uAE30\uC900\uC73C\uB85C \uC774\uC288 \uC81C\uBAA9/\uBCF8\uBB38/\uB77C\uBCA8 \uCD08\uC548\uC744 \uBCF4\uC644\uD558\uACE0 \
|
|
507
|
+
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, \uB77C\uBCA8 \uC2B9\uC778(`A` \uB610\uB294 `A OK`) \uD6C4 \uC774\uC288\uB97C \uC0DD\uC131\uD558\uC138\uC694. \uC774\uD6C4 tasks.md\uC758 \uC774\uC288 \uBC88\uD638\uB97C \uCC44\uC6B0\uACE0 \uBB38\uC11C \uCEE4\uBC0B\uC744 \uC900\uBE44\uD558\uC138\uC694.",
|
|
508
|
+
issuePrepareFromDoc: "`issue.md`\uB97C \uAE30\uC900\uC73C\uB85C \uC774\uC288 \uC81C\uBAA9/\uBCF8\uBB38/\uB77C\uBCA8 \uCD08\uC548\uC744 \uBCF4\uC644\uD558\uACE0 \uB77C\uBCA8 \uC2B9\uC778(`A` \uB610\uB294 `A OK`)\uC744 \uBC1B\uC544 \uC0C1\uD0DC\uB97C `Ready`\uB85C \uBCC0\uACBD\uD558\uC138\uC694.",
|
|
509
509
|
issueCreateFromDoc: "`issue.md` \uC0C1\uD0DC\uAC00 `Ready`\uC774\uBA74 GitHub Issue\uB97C \uC0DD\uC131\uD558\uACE0, \uC0DD\uC131\uB41C \uC774\uC288 \uBC88\uD638\uB97C `tasks.md`\uC5D0 \uBC18\uC601\uD558\uC138\uC694.",
|
|
510
510
|
docsCommitIssueUpdate: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs(#{issueNumber}): {folderName} \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8"',
|
|
511
511
|
docsCommitUpdate: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs: {folderName} \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8"',
|
|
@@ -529,11 +529,11 @@ var ko = {
|
|
|
529
529
|
taskCommitGateReasonMismatchLastDone: "\uCD5C\uADFC \uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uCEE4\uBC0B\uC774 \uC9C1\uC804 \uC644\uB8CC \uD0DC\uC2A4\uD06C\uC640 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4",
|
|
530
530
|
prLegacyAsk: "tasks.md\uC5D0 PR/PR \uC0C1\uD0DC \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uD15C\uD50C\uB9BF\uC744 \uCD5C\uC2E0 \uD3EC\uB9F7\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8\uD560\uAE4C\uC694? (\uD655\uC778 \uD544\uC694)",
|
|
531
531
|
prePrReviewFieldMissing: "tasks.md\uC5D0 `PR \uC804 \uB9AC\uBDF0` \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. `- **PR \uC804 \uB9AC\uBDF0**: Pending | Done` \uD56D\uBAA9\uC744 \uCD94\uAC00\uD558\uACE0 \uB2E4\uC2DC context\uB97C \uC2E4\uD589\uD558\uC138\uC694. (\uD655\uC778 \uD544\uC694)",
|
|
532
|
-
prePrReviewEvidenceMissing: "tasks.md\uC758 `PR \uC804 \uB9AC\uBDF0 Evidence`\uAC00 \uBE44\uC5B4\uC788\uAC70\uB098
|
|
532
|
+
prePrReviewEvidenceMissing: "tasks.md\uC758 `PR \uC804 \uB9AC\uBDF0 Evidence`\uAC00 \uBE44\uC5B4\uC788\uAC70\uB098 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC2E4\uC81C \uD30C\uC77C \uACBD\uB85C\uC640 `Pre-PR Review Log`(\uB610\uB294 `PR \uC804 \uB9AC\uBDF0 \uB85C\uADF8`)\uC5D0 placeholder\uAC00 \uC544\uB2CC `Summary`/`Decision`/`Findings`(\uB610\uB294 \uBA85\uC2DC\uC801 `0 findings`)/`Residual Risks`/`Tests Run`\uC744 \uAE30\uB85D\uD558\uC138\uC694. (\uD655\uC778 \uD544\uC694)",
|
|
533
533
|
prePrReviewDecisionMissing: "tasks.md\uC758 `PR \uC804 \uB9AC\uBDF0 Decision`\uC774 \uBE44\uC5B4\uC788\uAC70\uB098 \uACB0\uC815 \uD615\uC2DD\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. `\uACB0\uC815: ...`(\uB610\uB294 `decision: ...`) \uD615\uC2DD\uC73C\uB85C \uAE30\uB85D\uD558\uC138\uC694. (\uD655\uC778 \uD544\uC694)",
|
|
534
534
|
prePrReviewRun: "PR \uC0DD\uC131 \uC804 \uC0AC\uC804 \uCF54\uB4DC\uB9AC\uBDF0\uB97C \uC9C4\uD589\uD558\uC138\uC694. \uAE30\uBCF8 \uBCA0\uC774\uC2A4\uB77C\uC778\uC740 `{fallback}`\uC774\uBA70, `create-pr` \uBB38\uC11C\uC758 `Pre-PR \uAE30\uBCF8 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8` \uC139\uC158\uC744 \uD56D\uC0C1 \uC218\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)\uB85C \uCD94\uAC00 \uC2EC\uD654 \uAC80\uD1A0\uB97C \uC9C4\uD589\uD558\uC138\uC694. \uC644\uB8CC \uD6C4 `PR \uC804 \uB9AC\uBDF0`\uB97C Done\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694.",
|
|
535
535
|
prReviewEvidenceFieldMissing: "tasks.md\uC5D0 `PR \uB9AC\uBDF0 Evidence` \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. `- **PR \uB9AC\uBDF0 Evidence**: -` \uD56D\uBAA9\uC744 \uCD94\uAC00\uD558\uACE0 \uB2E4\uC2DC \uC9C4\uD589\uD558\uC138\uC694. (\uD655\uC778 \uD544\uC694)",
|
|
536
|
-
prReviewEvidenceMissing: "tasks.md\uC758 `PR \uB9AC\uBDF0 Evidence`\uAC00 \uBE44\uC5B4\uC788\uAC70\uB098
|
|
536
|
+
prReviewEvidenceMissing: "tasks.md\uC758 `PR \uB9AC\uBDF0 Evidence`\uAC00 \uBE44\uC5B4\uC788\uAC70\uB098 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. `\uC694\uC57D: ...`(\uB610\uB294 `summary: ...`) \uD615\uC2DD\uC73C\uB85C \uAE30\uB85D\uD558\uAC70\uB098 `PR Review Log`(\uB610\uB294 `PR \uB9AC\uBDF0 \uB85C\uADF8`)\uC758 `Summary`/`Decision`\uC774 \uC788\uB294 \uD30C\uC77C \uACBD\uB85C\uB97C \uC9C0\uC815\uD558\uC138\uC694. (\uD655\uC778 \uD544\uC694)",
|
|
537
537
|
prReviewDecisionFieldMissing: "tasks.md\uC5D0 `PR \uB9AC\uBDF0 Decision` \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. `- **PR \uB9AC\uBDF0 Decision**: -` \uD56D\uBAA9\uC744 \uCD94\uAC00\uD558\uACE0 \uB2E4\uC2DC \uC9C4\uD589\uD558\uC138\uC694. (\uD655\uC778 \uD544\uC694)",
|
|
538
538
|
prReviewDecisionMissing: "tasks.md\uC758 `PR \uB9AC\uBDF0 Decision`\uC774 \uBE44\uC5B4\uC788\uAC70\uB098 \uACB0\uC815 \uD615\uC2DD\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. `\uACB0\uC815: ...`(\uB610\uB294 `decision: ...`) \uD615\uC2DD\uC73C\uB85C \uAE30\uB85D\uD558\uC138\uC694. (\uD655\uC778 \uD544\uC694)",
|
|
539
539
|
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.",
|
|
@@ -581,14 +581,14 @@ var ko = {
|
|
|
581
581
|
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.)",
|
|
582
582
|
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.)",
|
|
583
583
|
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.)",
|
|
584
|
-
workflowPrReviewEvidenceMissing: "\uB9AC\uBDF0 \uB2E8\uACC4\uC5D0\uC11C `PR \uB9AC\uBDF0 Evidence`\uAC00 \uBE44\uC5B4\uC788\uAC70\uB098
|
|
584
|
+
workflowPrReviewEvidenceMissing: "\uB9AC\uBDF0 \uB2E8\uACC4\uC5D0\uC11C `PR \uB9AC\uBDF0 Evidence`\uAC00 \uBE44\uC5B4\uC788\uAC70\uB098 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. (`\uC694\uC57D: ...`/`summary: ...` \uB610\uB294 `PR Review Log`\uC758 `Summary`/`Decision`\uC774 \uC788\uB294 \uACBD\uB85C\uB97C \uAE30\uB85D)",
|
|
585
585
|
workflowPrReviewDecisionMissing: "\uB9AC\uBDF0 \uB2E8\uACC4\uC5D0\uC11C `PR \uB9AC\uBDF0 Decision`\uC774 \uBE44\uC5B4\uC788\uAC70\uB098 \uACB0\uC815 \uD615\uC2DD\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. (`\uACB0\uC815: ...` \uB610\uB294 `decision: ...` \uD615\uC2DD\uC73C\uB85C \uAE30\uB85D)",
|
|
586
586
|
workflowPrRemoteChangesRequested: "\uC6D0\uACA9 PR\uC5D0\uC11C \uBCC0\uACBD \uC694\uCCAD \uB610\uB294 \uCD94\uAC00 \uB9AC\uBDF0\uAC00 \uAC10\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uCF54\uBA58\uD2B8 \uBC18\uC601 \uD6C4 push\uD558\uACE0 \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694.",
|
|
587
587
|
workflowPrRemoteChecksFailing: "\uC6D0\uACA9 PR \uCCB4\uD06C \uC2E4\uD328\uAC00 {count}\uAC74 \uAC10\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC2E4\uD328 \uC6D0\uC778\uC744 \uD574\uACB0 \uD6C4 \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694.",
|
|
588
588
|
workflowPrRemoteChecksPending: "\uC6D0\uACA9 PR \uCCB4\uD06C \uB300\uAE30\uAC00 {count}\uAC74 \uAC10\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uCCB4\uD06C \uC644\uB8CC \uD6C4 \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694.",
|
|
589
589
|
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.)",
|
|
590
590
|
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.)",
|
|
591
|
-
workflowPrePrEvidenceMissing: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC `PR \uC804 \uB9AC\uBDF0 Evidence`\uAC00 \uBE44\uC5B4\uC788\uAC70\uB098 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. (
|
|
591
|
+
workflowPrePrEvidenceMissing: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC `PR \uC804 \uB9AC\uBDF0 Evidence`\uAC00 \uBE44\uC5B4\uC788\uAC70\uB098 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. (`Pre-PR Review Log`/`PR \uC804 \uB9AC\uBDF0 \uB85C\uADF8`\uC5D0 placeholder\uAC00 \uC544\uB2CC `Summary`/`Decision`/`Findings`(\uB610\uB294 \uBA85\uC2DC\uC801 `0 findings`)/`Residual Risks`/`Tests Run`\uC774 \uC788\uB294 \uC2E4\uC81C \uACBD\uB85C\uB97C \uAE30\uB85D\uD558\uC138\uC694.)",
|
|
592
592
|
workflowPrePrDecisionMissing: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC `PR \uC804 \uB9AC\uBDF0 Decision`\uC774 \uBE44\uC5B4\uC788\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. (`decision: approve|changes_requested|blocked ...` \uD615\uC2DD)",
|
|
593
593
|
workflowPrePrDecisionNotApproved: "\uC644\uB8CC \uC0C1\uD0DC\uC774\uC9C0\uB9CC `PR \uC804 \uB9AC\uBDF0 Decision`\uC774 `{outcome}`\uC785\uB2C8\uB2E4. \uB9AC\uBDF0 \uB9AC\uC2A4\uD06C\uB97C \uD574\uC18C\uD55C \uB4A4 pre-pr-review\uB97C \uC7AC\uC2E4\uD589\uD574 `approve`\uB85C \uB9DE\uCD94\uC138\uC694."
|
|
594
594
|
}
|
|
@@ -712,7 +712,7 @@ var en = {
|
|
|
712
712
|
"context.actionDetail.prStatusUpdateSyncApproved": "PR merged remotely; sync PR Status to Approved",
|
|
713
713
|
"context.actionDetail.codeReview": "Address review feedback and update PR review fields",
|
|
714
714
|
"context.actionDetail.codeReviewNeedEvidenceField": "Add PR Review Evidence field in tasks.md",
|
|
715
|
-
"context.actionDetail.codeReviewNeedEvidence": "Record PR Review Evidence summary",
|
|
715
|
+
"context.actionDetail.codeReviewNeedEvidence": "Record PR Review Evidence (`summary: ...`) or PR Review Log path in decisions.md",
|
|
716
716
|
"context.actionDetail.codeReviewNeedDecisionField": "Add PR Review Decision field in tasks.md",
|
|
717
717
|
"context.actionDetail.codeReviewNeedDecision": "Record PR Review Decision",
|
|
718
718
|
"context.actionDetail.codeReviewResolve": "Address review feedback and keep PR review docs updated",
|
|
@@ -1015,8 +1015,8 @@ var en = {
|
|
|
1015
1015
|
tasksImprove: "Improve tasks.md and change Doc Status to Review.",
|
|
1016
1016
|
tasksApproval: "Share tasks.md with the user and get progress approval (`A` or `A OK` format). (Then set Doc Status to Approved)",
|
|
1017
1017
|
docsCommitPlanning: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs(planning): {folderName} planning docs"',
|
|
1018
|
-
issueCreateAndWrite: "Generate the issue body template, refine goals/completion criteria, get
|
|
1019
|
-
issuePrepareFromDoc: "Use `issue.md` to refine issue title/body/labels draft, get
|
|
1018
|
+
issueCreateAndWrite: "Generate the issue body template, refine goals/completion criteria, get label approval (`A` or `A OK`), create the issue, then update issue number in tasks.md and prepare a docs commit.",
|
|
1019
|
+
issuePrepareFromDoc: "Use `issue.md` to refine issue title/body/labels draft, get label approval (`A` or `A OK`), then set status to `Ready`.",
|
|
1020
1020
|
issueCreateFromDoc: "When `issue.md` status is `Ready`, create the GitHub Issue and sync the created issue number into `tasks.md`.",
|
|
1021
1021
|
docsCommitIssueUpdate: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs(#{issueNumber}): {folderName} docs update"',
|
|
1022
1022
|
docsCommitUpdate: 'cd "{docsGitCwd}" && git add "{featurePath}" && git commit -m "docs: {folderName} docs update"',
|
|
@@ -1040,11 +1040,11 @@ var en = {
|
|
|
1040
1040
|
taskCommitGateReasonMismatchLastDone: "The latest project code commit does not match the last completed task",
|
|
1041
1041
|
prLegacyAsk: "tasks.md is missing PR/PR Status fields. Update to the latest template format? (CHECK required)",
|
|
1042
1042
|
prePrReviewFieldMissing: "tasks.md is missing the `Pre-PR Review` field. Add `- **Pre-PR Review**: Pending | Done` and run context again. (CHECK required)",
|
|
1043
|
-
prePrReviewEvidenceMissing: "tasks.md `Pre-PR Evidence` is empty
|
|
1043
|
+
prePrReviewEvidenceMissing: "tasks.md `Pre-PR Evidence` is empty/invalid. Point to a real file and include a `Pre-PR Review Log` section with non-placeholder `Summary`, `Decision`, `Findings` (or explicit `0 findings`), `Residual Risks`, and `Tests Run`. (CHECK required)",
|
|
1044
1044
|
prePrReviewDecisionMissing: "tasks.md `Pre-PR Decision` is empty/placeholder or missing decision format. Record it as `decision: ...` (or `\uACB0\uC815: ...`). (CHECK required)",
|
|
1045
1045
|
prePrReviewRun: "Run a pre-PR code review before creating the PR. Always execute the `{fallback}` baseline by following the `Pre-PR Baseline Checklist` section in the `create-pr` doc. Then use preferred skills ({skills}) for deeper review (if a better installed skill fits this change, propose it first). After completing it, set `Pre-PR Review` to Done in tasks.md.",
|
|
1046
1046
|
prReviewEvidenceFieldMissing: "tasks.md is missing the `PR Review Evidence` field. Add `- **PR Review Evidence**: -` and continue. (CHECK required)",
|
|
1047
|
-
prReviewEvidenceMissing: "tasks.md `PR Review Evidence` is empty/
|
|
1047
|
+
prReviewEvidenceMissing: "tasks.md `PR Review Evidence` is empty/invalid. Use `summary: ...` (or `\uC694\uC57D: ...`), or point to a file containing `PR Review Log` with non-placeholder `Summary` and `Decision`. (CHECK required)",
|
|
1048
1048
|
prReviewDecisionFieldMissing: "tasks.md is missing the `PR Review Decision` field. Add `- **PR Review Decision**: -` and continue. (CHECK required)",
|
|
1049
1049
|
prReviewDecisionMissing: "tasks.md `PR Review Decision` is empty/placeholder or missing decision format. Record it as `decision: ...` (or `\uACB0\uC815: ...`). (CHECK required)",
|
|
1050
1050
|
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.",
|
|
@@ -1092,14 +1092,14 @@ var en = {
|
|
|
1092
1092
|
workflowPrLinkMissing: "Implementation is done but PR link is missing. (Fill the PR field in tasks.md.)",
|
|
1093
1093
|
workflowPrStatusMissing: "Implementation is done but PR Status is missing. (Set PR Status to Review during PR creation/review stages.)",
|
|
1094
1094
|
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.)",
|
|
1095
|
-
workflowPrReviewEvidenceMissing: "In review stage, `PR Review Evidence` is empty/
|
|
1095
|
+
workflowPrReviewEvidenceMissing: "In review stage, `PR Review Evidence` is empty/invalid. (Use `summary: ...`/`\uC694\uC57D: ...`, or point to a `PR Review Log` section with `Summary` and `Decision`.)",
|
|
1096
1096
|
workflowPrReviewDecisionMissing: "In review stage, `PR Review Decision` is empty/placeholder or missing decision format. (Use `decision: ...` or `\uACB0\uC815: ...`.)",
|
|
1097
1097
|
workflowPrRemoteChangesRequested: "Remote PR shows changes requested or additional review required. Address comments, push, then re-check.",
|
|
1098
1098
|
workflowPrRemoteChecksFailing: "Remote PR has {count} failing check(s). Fix failures, then re-check.",
|
|
1099
1099
|
workflowPrRemoteChecksPending: "Remote PR has {count} pending check(s). Wait for checks to complete, then re-check.",
|
|
1100
1100
|
workflowPrePrReviewMissing: "Implementation is done but `Pre-PR Review` is missing. (Add `- **Pre-PR Review**: Pending | Done` in tasks.md.)",
|
|
1101
1101
|
workflowPrePrReviewNotDone: "Implementation is done but `Pre-PR Review` is not Done. (Run pre-PR review, then update it to Done.)",
|
|
1102
|
-
workflowPrePrEvidenceMissing: "Implementation is done but `Pre-PR Evidence` is empty/invalid. (
|
|
1102
|
+
workflowPrePrEvidenceMissing: "Implementation is done but `Pre-PR Evidence` is empty/invalid. (Point to an existing file and include `Pre-PR Review Log` with non-placeholder `Summary`, `Decision`, `Findings` (or explicit `0 findings`), `Residual Risks`, and `Tests Run`.)",
|
|
1103
1103
|
workflowPrePrDecisionMissing: "Implementation is done but `Pre-PR Decision` is empty/invalid. (Use `decision: approve|changes_requested|blocked ...`.)",
|
|
1104
1104
|
workflowPrePrDecisionNotApproved: "Implementation is done but `Pre-PR Decision` is `{outcome}`. Resolve review risks and re-run pre-PR review until decision becomes `approve`."
|
|
1105
1105
|
}
|
|
@@ -4636,13 +4636,147 @@ function resolveEvidencePathValue(value) {
|
|
|
4636
4636
|
if (mdLink && mdLink[1]) return mdLink[1].trim();
|
|
4637
4637
|
return trimmed.split(/\s+/)[0] || "";
|
|
4638
4638
|
}
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
if (
|
|
4639
|
+
function splitReviewLogSections(content, headerRegex) {
|
|
4640
|
+
const normalizedHeaderRegex = new RegExp(headerRegex.source, headerRegex.flags);
|
|
4641
|
+
const matches = [...content.matchAll(normalizedHeaderRegex)];
|
|
4642
|
+
if (matches.length === 0) return [];
|
|
4643
|
+
const sections = [];
|
|
4644
|
+
for (let i = 0; i < matches.length; i += 1) {
|
|
4645
|
+
const start = matches[i].index ?? 0;
|
|
4646
|
+
const end = i + 1 < matches.length ? matches[i + 1].index ?? content.length : content.length;
|
|
4647
|
+
sections.push(content.slice(start, end));
|
|
4648
|
+
}
|
|
4649
|
+
return sections;
|
|
4650
|
+
}
|
|
4651
|
+
function collectStructuredReviewEntries(section, keys) {
|
|
4652
|
+
const lines = section.split("\n");
|
|
4653
|
+
const escaped = keys.map((key) => escapeRegExp(key));
|
|
4654
|
+
const fieldRegex = new RegExp(
|
|
4655
|
+
`^\\s*-\\s*\\*\\*(?:${escaped.join("|")})\\*\\*\\s*:\\s*(.*)$`,
|
|
4656
|
+
"i"
|
|
4657
|
+
);
|
|
4658
|
+
const entries = [];
|
|
4659
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
4660
|
+
const match = lines[i].match(fieldRegex);
|
|
4661
|
+
if (!match) continue;
|
|
4662
|
+
const inlineValue = (match[1] || "").trim();
|
|
4663
|
+
if (inlineValue) entries.push(inlineValue);
|
|
4664
|
+
let cursor = i + 1;
|
|
4665
|
+
while (cursor < lines.length) {
|
|
4666
|
+
const line = lines[cursor];
|
|
4667
|
+
if (/^\s*-\s*\*\*.+\*\*\s*:/.test(line)) break;
|
|
4668
|
+
if (/^\s*##\s+/.test(line)) break;
|
|
4669
|
+
const nestedBullet = line.match(/^\s{2,}-\s+(.+)\s*$/);
|
|
4670
|
+
if (nestedBullet && nestedBullet[1]) {
|
|
4671
|
+
entries.push(nestedBullet[1].trim());
|
|
4672
|
+
}
|
|
4673
|
+
cursor += 1;
|
|
4674
|
+
}
|
|
4675
|
+
break;
|
|
4676
|
+
}
|
|
4677
|
+
return entries.filter((entry) => entry.length > 0);
|
|
4678
|
+
}
|
|
4679
|
+
function isReviewDraftPlaceholder(value) {
|
|
4680
|
+
const trimmed = value.trim();
|
|
4681
|
+
if (!trimmed) return true;
|
|
4682
|
+
return /^(?:-|#)?\s*(?:tbd|todo|pending|fill(?:\s+in)?|template|example|미정|작성|기입|n\/a|na)\b/i.test(
|
|
4683
|
+
trimmed
|
|
4684
|
+
);
|
|
4685
|
+
}
|
|
4686
|
+
function hasValidReviewLogEntries(entries) {
|
|
4687
|
+
return entries.map((entry) => entry.trim()).some(
|
|
4688
|
+
(entry) => entry.length > 0 && !isReviewDraftPlaceholder(entry) && !isPlaceholderReviewEvidence(entry)
|
|
4689
|
+
);
|
|
4690
|
+
}
|
|
4691
|
+
function hasReviewLogQuality(content, headerRegex, summaryKeys, decisionKeys) {
|
|
4692
|
+
const sections = splitReviewLogSections(content, headerRegex);
|
|
4693
|
+
for (const section of sections) {
|
|
4694
|
+
const summaryEntries = collectStructuredReviewEntries(section, summaryKeys);
|
|
4695
|
+
if (!hasValidReviewLogEntries(summaryEntries)) continue;
|
|
4696
|
+
const decisionEntries = collectStructuredReviewEntries(section, decisionKeys);
|
|
4697
|
+
if (!hasValidReviewLogEntries(decisionEntries)) continue;
|
|
4698
|
+
return true;
|
|
4699
|
+
}
|
|
4700
|
+
return false;
|
|
4701
|
+
}
|
|
4702
|
+
function isExplicitZeroFindingsEntry(value) {
|
|
4703
|
+
const trimmed = value.trim().toLowerCase();
|
|
4704
|
+
if (!trimmed) return false;
|
|
4705
|
+
return /^0+\s*findings?\b/.test(trimmed) || /^no\s+findings?\b/.test(trimmed) || /^findings?\s*[::]\s*0+\b/.test(trimmed) || /^지적\s*사항?\s*[::]?\s*0+\b/.test(trimmed) || /^지적\s*없음\b/.test(trimmed);
|
|
4706
|
+
}
|
|
4707
|
+
function hasPrePrReviewLogQuality(content) {
|
|
4708
|
+
const sections = splitReviewLogSections(content, PRE_PR_REVIEW_LOG_HEADER);
|
|
4709
|
+
for (const section of sections) {
|
|
4710
|
+
const summaryEntries = collectStructuredReviewEntries(section, [
|
|
4711
|
+
"Summary",
|
|
4712
|
+
"\uC694\uC57D",
|
|
4713
|
+
"Note",
|
|
4714
|
+
"\uB178\uD2B8"
|
|
4715
|
+
]);
|
|
4716
|
+
if (!hasValidReviewLogEntries(summaryEntries)) continue;
|
|
4717
|
+
const decisionEntries = collectStructuredReviewEntries(section, [
|
|
4718
|
+
"Decision",
|
|
4719
|
+
"\uACB0\uC815"
|
|
4720
|
+
]);
|
|
4721
|
+
if (!hasValidReviewLogEntries(decisionEntries)) continue;
|
|
4722
|
+
const findingsEntries = collectStructuredReviewEntries(section, [
|
|
4723
|
+
"Findings",
|
|
4724
|
+
"\uC9C0\uC801\uC0AC\uD56D",
|
|
4725
|
+
"\uC9C0\uC801 \uC0AC\uD56D"
|
|
4726
|
+
]);
|
|
4727
|
+
const hasActionableFindings = findingsEntries.map((entry) => entry.trim()).some(
|
|
4728
|
+
(entry) => entry.length > 0 && !isReviewDraftPlaceholder(entry) && !isPlaceholderReviewEvidence(entry) && /\S+:\d+/.test(entry)
|
|
4729
|
+
);
|
|
4730
|
+
const hasExplicitZeroFindings = findingsEntries.some(
|
|
4731
|
+
(entry) => isExplicitZeroFindingsEntry(entry)
|
|
4732
|
+
);
|
|
4733
|
+
if (!hasActionableFindings && !hasExplicitZeroFindings) continue;
|
|
4734
|
+
const residualRiskEntries = collectStructuredReviewEntries(section, [
|
|
4735
|
+
"Residual Risks",
|
|
4736
|
+
"Residual Risk",
|
|
4737
|
+
"\uC794\uC5EC \uB9AC\uC2A4\uD06C",
|
|
4738
|
+
"\uC794\uC5EC \uC704\uD5D8"
|
|
4739
|
+
]);
|
|
4740
|
+
if (!hasValidReviewLogEntries(residualRiskEntries)) continue;
|
|
4741
|
+
const testsRunEntries = collectStructuredReviewEntries(section, [
|
|
4742
|
+
"Tests Run",
|
|
4743
|
+
"Test Run",
|
|
4744
|
+
"\uC2E4\uD589 \uD14C\uC2A4\uD2B8",
|
|
4745
|
+
"\uD14C\uC2A4\uD2B8 \uC2E4\uD589"
|
|
4746
|
+
]);
|
|
4747
|
+
if (!hasValidReviewLogEntries(testsRunEntries)) continue;
|
|
4748
|
+
return true;
|
|
4749
|
+
}
|
|
4750
|
+
return false;
|
|
4751
|
+
}
|
|
4752
|
+
var PRE_PR_REVIEW_LOG_HEADER = /^##\s+(?:Pre-PR Review Log|PR 전 리뷰 로그)\b.*$/gim;
|
|
4753
|
+
var PR_REVIEW_LOG_HEADER = /^##\s+(?:PR Review Log|PR 리뷰 로그)\b.*$/gim;
|
|
4754
|
+
async function hasPrePrReviewLogEvidence(candidatePath) {
|
|
4755
|
+
try {
|
|
4756
|
+
const content = await fs17.readFile(candidatePath, "utf-8");
|
|
4757
|
+
return hasPrePrReviewLogQuality(content);
|
|
4758
|
+
} catch {
|
|
4759
|
+
return false;
|
|
4760
|
+
}
|
|
4761
|
+
}
|
|
4762
|
+
async function hasPrReviewLogEvidence(candidatePath) {
|
|
4763
|
+
try {
|
|
4764
|
+
const content = await fs17.readFile(candidatePath, "utf-8");
|
|
4765
|
+
return hasReviewLogQuality(
|
|
4766
|
+
content,
|
|
4767
|
+
PR_REVIEW_LOG_HEADER,
|
|
4768
|
+
["Summary", "\uC694\uC57D", "Note", "\uB178\uD2B8"],
|
|
4769
|
+
["Decision", "\uACB0\uC815"]
|
|
4770
|
+
);
|
|
4771
|
+
} catch {
|
|
4772
|
+
return false;
|
|
4773
|
+
}
|
|
4774
|
+
}
|
|
4775
|
+
function resolveLocalEvidencePathCandidates(rawValue, context) {
|
|
4776
|
+
if (!rawValue) return [];
|
|
4643
4777
|
const evidencePath = resolveEvidencePathValue(rawValue);
|
|
4644
|
-
if (!evidencePath) return
|
|
4645
|
-
if (/^https?:\/\//i.test(evidencePath)) return
|
|
4778
|
+
if (!evidencePath) return [];
|
|
4779
|
+
if (/^https?:\/\//i.test(evidencePath)) return [];
|
|
4646
4780
|
const candidates = /* @__PURE__ */ new Set();
|
|
4647
4781
|
if (path23.isAbsolute(evidencePath)) {
|
|
4648
4782
|
candidates.add(path23.resolve(evidencePath));
|
|
@@ -4651,10 +4785,31 @@ async function isPrePrEvidenceProvided(rawValue, policy, context) {
|
|
|
4651
4785
|
candidates.add(path23.resolve(context.docsDir, evidencePath));
|
|
4652
4786
|
candidates.add(path23.resolve(path23.dirname(context.docsDir), evidencePath));
|
|
4653
4787
|
}
|
|
4788
|
+
return [...candidates];
|
|
4789
|
+
}
|
|
4790
|
+
async function resolveExistingEvidencePath(rawValue, context) {
|
|
4791
|
+
const candidates = resolveLocalEvidencePathCandidates(rawValue, context);
|
|
4654
4792
|
for (const candidate of candidates) {
|
|
4655
|
-
if (await fs17.pathExists(candidate)) return
|
|
4793
|
+
if (await fs17.pathExists(candidate)) return candidate;
|
|
4656
4794
|
}
|
|
4657
|
-
return
|
|
4795
|
+
return void 0;
|
|
4796
|
+
}
|
|
4797
|
+
async function isPrePrEvidenceProvided(rawValue, policy, context) {
|
|
4798
|
+
if (isPlaceholderReviewEvidence(rawValue)) return false;
|
|
4799
|
+
const existingEvidencePath = await resolveExistingEvidencePath(rawValue, context);
|
|
4800
|
+
if (policy.evidenceMode !== "path_required") {
|
|
4801
|
+
if (!existingEvidencePath) return true;
|
|
4802
|
+
return hasPrePrReviewLogEvidence(existingEvidencePath);
|
|
4803
|
+
}
|
|
4804
|
+
if (!existingEvidencePath) return false;
|
|
4805
|
+
return hasPrePrReviewLogEvidence(existingEvidencePath);
|
|
4806
|
+
}
|
|
4807
|
+
async function isPrReviewEvidenceProvided(rawValue, context) {
|
|
4808
|
+
if (isPlaceholderReviewEvidence(rawValue)) return false;
|
|
4809
|
+
if (hasStructuredReviewSummary(rawValue)) return true;
|
|
4810
|
+
const existingEvidencePath = await resolveExistingEvidencePath(rawValue, context);
|
|
4811
|
+
if (!existingEvidencePath) return false;
|
|
4812
|
+
return hasPrReviewLogEvidence(existingEvidencePath);
|
|
4658
4813
|
}
|
|
4659
4814
|
function parseIssueNumber(value) {
|
|
4660
4815
|
if (!value) return void 0;
|
|
@@ -5119,7 +5274,10 @@ async function parseFeature(featurePath, type, context, options) {
|
|
|
5119
5274
|
"PR Review Evidence"
|
|
5120
5275
|
]);
|
|
5121
5276
|
prReviewEvidence = prReviewEvidenceValue?.trim();
|
|
5122
|
-
prReviewEvidenceProvided =
|
|
5277
|
+
prReviewEvidenceProvided = await isPrReviewEvidenceProvided(
|
|
5278
|
+
prReviewEvidenceValue,
|
|
5279
|
+
{ featurePath, docsDir: context.docsDir }
|
|
5280
|
+
);
|
|
5123
5281
|
const prReviewDecisionValue = extractFirstSpecValue(content, [
|
|
5124
5282
|
"PR \uB9AC\uBDF0 Decision",
|
|
5125
5283
|
"PR Review Decision"
|
|
@@ -6749,7 +6907,7 @@ function getApprovalSessionId() {
|
|
|
6749
6907
|
if (explicit) return explicit;
|
|
6750
6908
|
const terminalSession = (process.env.TERM_SESSION_ID || process.env.WT_SESSION || process.env.TMUX_PANE || "").trim();
|
|
6751
6909
|
if (terminalSession) return terminalSession;
|
|
6752
|
-
return
|
|
6910
|
+
return "";
|
|
6753
6911
|
}
|
|
6754
6912
|
function getApprovalTicketPaths(config) {
|
|
6755
6913
|
return {
|
|
@@ -6891,7 +7049,7 @@ async function consumeApprovalTicket(config, token, expected) {
|
|
|
6891
7049
|
"Approval ticket expired. Run `context` again and re-approve."
|
|
6892
7050
|
);
|
|
6893
7051
|
}
|
|
6894
|
-
if (record.sessionId !== sessionId) {
|
|
7052
|
+
if (record.sessionId && record.sessionId !== sessionId) {
|
|
6895
7053
|
throw createCliError(
|
|
6896
7054
|
"INVALID_APPROVAL",
|
|
6897
7055
|
"Approval ticket session mismatch. Re-run `context` in the current session and approve again."
|
|
@@ -7085,17 +7243,17 @@ var LONG_RUNNING_DELEGATION_CATEGORIES = [
|
|
|
7085
7243
|
"review_fix_commit",
|
|
7086
7244
|
"pre_pr_review"
|
|
7087
7245
|
];
|
|
7088
|
-
function shouldDelegateCurrentAction(actionOptions
|
|
7246
|
+
function shouldDelegateCurrentAction(actionOptions) {
|
|
7089
7247
|
const primaryCategory = actionOptions[0]?.action?.category || null;
|
|
7090
7248
|
const longRunningSet = new Set(LONG_RUNNING_DELEGATION_CATEGORIES);
|
|
7091
|
-
const shouldDelegate =
|
|
7249
|
+
const shouldDelegate = !!primaryCategory && longRunningSet.has(primaryCategory);
|
|
7092
7250
|
return {
|
|
7093
7251
|
shouldDelegate,
|
|
7094
7252
|
category: primaryCategory
|
|
7095
7253
|
};
|
|
7096
7254
|
}
|
|
7097
7255
|
function buildAgentOrchestrationPolicy(actionOptions, autoRunAvailable) {
|
|
7098
|
-
const delegation = shouldDelegateCurrentAction(actionOptions
|
|
7256
|
+
const delegation = shouldDelegateCurrentAction(actionOptions);
|
|
7099
7257
|
return {
|
|
7100
7258
|
mode: "main_orchestrates_subagent_execution",
|
|
7101
7259
|
delegationPolicy: "prefer_main_delegate_long_running_fallback_main",
|
|
@@ -7104,6 +7262,7 @@ function buildAgentOrchestrationPolicy(actionOptions, autoRunAvailable) {
|
|
|
7104
7262
|
fallbackToMainAgentWhenSubAgentUnavailable: true,
|
|
7105
7263
|
longRunningCategories: [...LONG_RUNNING_DELEGATION_CATEGORIES],
|
|
7106
7264
|
currentActionShouldDelegate: delegation.shouldDelegate,
|
|
7265
|
+
autoRunShouldDelegate: autoRunAvailable,
|
|
7107
7266
|
currentActionCategory: delegation.category,
|
|
7108
7267
|
mainAgentResponsibilities: [
|
|
7109
7268
|
"Keep user conversation state and approval boundaries",
|
|
@@ -8111,10 +8270,7 @@ async function runContext(featureName, options) {
|
|
|
8111
8270
|
}
|
|
8112
8271
|
const actionOptions = state.actionOptions;
|
|
8113
8272
|
const hasCommandOption = actionOptions.some((option) => option.action.type === "command");
|
|
8114
|
-
const longRunningDelegation = shouldDelegateCurrentAction(
|
|
8115
|
-
actionOptions,
|
|
8116
|
-
autoRunPlan.available
|
|
8117
|
-
);
|
|
8273
|
+
const longRunningDelegation = shouldDelegateCurrentAction(actionOptions);
|
|
8118
8274
|
console.log(chalk6.green(chalk6.bold("\u{1F449} Next Options (Atomic):")));
|
|
8119
8275
|
let hasDocsCommand = false;
|
|
8120
8276
|
actionOptions.forEach((option) => {
|
|
@@ -11372,6 +11528,54 @@ ${mermaidSection}
|
|
|
11372
11528
|
- **Spec**: \`${bodyPaths.specPath}\`
|
|
11373
11529
|
- **Tasks**: \`${bodyPaths.tasksPath}\`${closes}`;
|
|
11374
11530
|
}
|
|
11531
|
+
function stripMarkdownCodeContexts(body) {
|
|
11532
|
+
const lines = body.split("\n");
|
|
11533
|
+
const out = [];
|
|
11534
|
+
let inFence = false;
|
|
11535
|
+
let fenceChar = "";
|
|
11536
|
+
let fenceLength = 0;
|
|
11537
|
+
for (const line of lines) {
|
|
11538
|
+
const fenceStartMatch = line.match(/^\s*(`{3,}|~{3,})/);
|
|
11539
|
+
if (fenceStartMatch) {
|
|
11540
|
+
const marker = fenceStartMatch[1];
|
|
11541
|
+
const markerChar = marker[0];
|
|
11542
|
+
const markerLength = marker.length;
|
|
11543
|
+
if (!inFence) {
|
|
11544
|
+
inFence = true;
|
|
11545
|
+
fenceChar = markerChar;
|
|
11546
|
+
fenceLength = markerLength;
|
|
11547
|
+
continue;
|
|
11548
|
+
}
|
|
11549
|
+
if (markerChar === fenceChar && markerLength >= fenceLength) {
|
|
11550
|
+
inFence = false;
|
|
11551
|
+
fenceChar = "";
|
|
11552
|
+
fenceLength = 0;
|
|
11553
|
+
}
|
|
11554
|
+
continue;
|
|
11555
|
+
}
|
|
11556
|
+
if (inFence) continue;
|
|
11557
|
+
out.push(line.replace(/`[^`\n]*`/g, ""));
|
|
11558
|
+
}
|
|
11559
|
+
return out.join("\n");
|
|
11560
|
+
}
|
|
11561
|
+
function hasIssueClosingKeyword(body, issueNumber) {
|
|
11562
|
+
if (!issueNumber) return false;
|
|
11563
|
+
const cleaned = stripMarkdownCodeContexts(body);
|
|
11564
|
+
const issue = escapeRegExp3(issueNumber);
|
|
11565
|
+
const closeKeywordRegex = new RegExp(
|
|
11566
|
+
`\\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\b\\s*(?:[a-zA-Z0-9_.-]+\\/)?#\\s*${issue}\\b`,
|
|
11567
|
+
"i"
|
|
11568
|
+
);
|
|
11569
|
+
return closeKeywordRegex.test(cleaned);
|
|
11570
|
+
}
|
|
11571
|
+
function ensureIssueClosingLine(body, issueNumber) {
|
|
11572
|
+
if (!issueNumber) return body;
|
|
11573
|
+
if (hasIssueClosingKeyword(body, issueNumber)) return body;
|
|
11574
|
+
const trimmed = body.trimEnd();
|
|
11575
|
+
const separator = trimmed.length > 0 ? "\n\n" : "";
|
|
11576
|
+
return `${trimmed}${separator}Closes #${issueNumber}
|
|
11577
|
+
`;
|
|
11578
|
+
}
|
|
11375
11579
|
function getRequiredIssueSections(lang) {
|
|
11376
11580
|
return getGithubDraftRequiredSections("issue", lang);
|
|
11377
11581
|
}
|
|
@@ -11825,8 +12029,8 @@ function githubCommand(program2) {
|
|
|
11825
12029
|
kindLabel: tg(config.lang, "kindPr"),
|
|
11826
12030
|
lang: config.lang
|
|
11827
12031
|
});
|
|
11828
|
-
|
|
11829
|
-
|
|
12032
|
+
let body = preparedBody.body;
|
|
12033
|
+
let bodyFile = preparedBody.bodyFile;
|
|
11830
12034
|
const title = options.title?.trim() || (preparedBody.source === "workflow-ready" ? preparedBody.draftMetadata?.title : void 0) || defaultTitle;
|
|
11831
12035
|
const labels = parseLabels(
|
|
11832
12036
|
optionLabels || (preparedBody.source === "workflow-ready" ? preparedBody.draftMetadata?.labels : void 0),
|
|
@@ -11841,6 +12045,18 @@ function githubCommand(program2) {
|
|
|
11841
12045
|
let syncChanged = false;
|
|
11842
12046
|
const pushDocsSync = shouldPushDocsSync(config);
|
|
11843
12047
|
if (options.create) {
|
|
12048
|
+
const normalizedBody = ensureIssueClosingLine(body, feature.issueNumber);
|
|
12049
|
+
if (normalizedBody !== body) {
|
|
12050
|
+
body = normalizedBody;
|
|
12051
|
+
const fallbackBodyFile = defaultBodyFile;
|
|
12052
|
+
if (preparedBody.source === "generated") {
|
|
12053
|
+
await fs17.writeFile(bodyFile, body, "utf-8");
|
|
12054
|
+
} else {
|
|
12055
|
+
await fs17.ensureDir(path23.dirname(fallbackBodyFile));
|
|
12056
|
+
await fs17.writeFile(fallbackBodyFile, body, "utf-8");
|
|
12057
|
+
bodyFile = fallbackBodyFile;
|
|
12058
|
+
}
|
|
12059
|
+
}
|
|
11844
12060
|
const projectGitCwd = resolveGithubProjectCwd(config, feature);
|
|
11845
12061
|
ensureNoTodoPlaceholders(body, tg(config.lang, "kindPr"), config.lang);
|
|
11846
12062
|
ensurePrArtifacts(body, artifactPolicy, config.lang);
|
|
@@ -12869,7 +13085,15 @@ function buildReportContent(input) {
|
|
|
12869
13085
|
- **Baseline**: ${input.fallback}
|
|
12870
13086
|
- **Skills**: ${skills}
|
|
12871
13087
|
- **Decision**: ${input.decision}
|
|
12872
|
-
- **
|
|
13088
|
+
- **Summary**: ${input.note}
|
|
13089
|
+
- **Findings**:
|
|
13090
|
+
- TODO: <file:line | severity: low|medium|high | fix: required|optional | note: ...> OR 0 findings
|
|
13091
|
+
- **Residual Risks**:
|
|
13092
|
+
- TODO: residual risk assessment after review
|
|
13093
|
+
- **Tests Run**:
|
|
13094
|
+
- TODO: commands/results verified during pre-PR review
|
|
13095
|
+
- **Evidence**:
|
|
13096
|
+
- TODO: review comments/paths/tests verified during pre-PR review
|
|
12873
13097
|
- **Trace**: pre-pr-review command executed and synced with tasks.md
|
|
12874
13098
|
`;
|
|
12875
13099
|
}
|