lee-spec-kit 0.6.28 → 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 +135 -26
- 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/execute-task.md +1 -0
- 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/execute-task.md +1 -0
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",
|
|
@@ -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,7 +529,7 @@ 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 \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`)\
|
|
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)",
|
|
@@ -588,7 +588,7 @@ var ko = {
|
|
|
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. (`Pre-PR Review Log`/`PR \uC804 \uB9AC\uBDF0 \uB85C\uADF8`\
|
|
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
|
}
|
|
@@ -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,7 +1040,7 @@ 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/invalid. Point to a real file and include a `Pre-PR Review Log` section with non-placeholder `Summary` and `
|
|
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)",
|
|
@@ -1099,7 +1099,7 @@ var en = {
|
|
|
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. (Point to an existing file and include `Pre-PR Review Log` with non-placeholder `Summary` and `
|
|
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
|
}
|
|
@@ -4699,17 +4699,62 @@ function hasReviewLogQuality(content, headerRegex, summaryKeys, decisionKeys) {
|
|
|
4699
4699
|
}
|
|
4700
4700
|
return false;
|
|
4701
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
|
+
}
|
|
4702
4752
|
var PRE_PR_REVIEW_LOG_HEADER = /^##\s+(?:Pre-PR Review Log|PR 전 리뷰 로그)\b.*$/gim;
|
|
4703
4753
|
var PR_REVIEW_LOG_HEADER = /^##\s+(?:PR Review Log|PR 리뷰 로그)\b.*$/gim;
|
|
4704
4754
|
async function hasPrePrReviewLogEvidence(candidatePath) {
|
|
4705
4755
|
try {
|
|
4706
4756
|
const content = await fs17.readFile(candidatePath, "utf-8");
|
|
4707
|
-
return
|
|
4708
|
-
content,
|
|
4709
|
-
PRE_PR_REVIEW_LOG_HEADER,
|
|
4710
|
-
["Summary", "\uC694\uC57D", "Note", "\uB178\uD2B8"],
|
|
4711
|
-
["Decision", "\uACB0\uC815"]
|
|
4712
|
-
);
|
|
4757
|
+
return hasPrePrReviewLogQuality(content);
|
|
4713
4758
|
} catch {
|
|
4714
4759
|
return false;
|
|
4715
4760
|
}
|
|
@@ -6862,7 +6907,7 @@ function getApprovalSessionId() {
|
|
|
6862
6907
|
if (explicit) return explicit;
|
|
6863
6908
|
const terminalSession = (process.env.TERM_SESSION_ID || process.env.WT_SESSION || process.env.TMUX_PANE || "").trim();
|
|
6864
6909
|
if (terminalSession) return terminalSession;
|
|
6865
|
-
return
|
|
6910
|
+
return "";
|
|
6866
6911
|
}
|
|
6867
6912
|
function getApprovalTicketPaths(config) {
|
|
6868
6913
|
return {
|
|
@@ -7004,7 +7049,7 @@ async function consumeApprovalTicket(config, token, expected) {
|
|
|
7004
7049
|
"Approval ticket expired. Run `context` again and re-approve."
|
|
7005
7050
|
);
|
|
7006
7051
|
}
|
|
7007
|
-
if (record.sessionId !== sessionId) {
|
|
7052
|
+
if (record.sessionId && record.sessionId !== sessionId) {
|
|
7008
7053
|
throw createCliError(
|
|
7009
7054
|
"INVALID_APPROVAL",
|
|
7010
7055
|
"Approval ticket session mismatch. Re-run `context` in the current session and approve again."
|
|
@@ -7198,17 +7243,17 @@ var LONG_RUNNING_DELEGATION_CATEGORIES = [
|
|
|
7198
7243
|
"review_fix_commit",
|
|
7199
7244
|
"pre_pr_review"
|
|
7200
7245
|
];
|
|
7201
|
-
function shouldDelegateCurrentAction(actionOptions
|
|
7246
|
+
function shouldDelegateCurrentAction(actionOptions) {
|
|
7202
7247
|
const primaryCategory = actionOptions[0]?.action?.category || null;
|
|
7203
7248
|
const longRunningSet = new Set(LONG_RUNNING_DELEGATION_CATEGORIES);
|
|
7204
|
-
const shouldDelegate =
|
|
7249
|
+
const shouldDelegate = !!primaryCategory && longRunningSet.has(primaryCategory);
|
|
7205
7250
|
return {
|
|
7206
7251
|
shouldDelegate,
|
|
7207
7252
|
category: primaryCategory
|
|
7208
7253
|
};
|
|
7209
7254
|
}
|
|
7210
7255
|
function buildAgentOrchestrationPolicy(actionOptions, autoRunAvailable) {
|
|
7211
|
-
const delegation = shouldDelegateCurrentAction(actionOptions
|
|
7256
|
+
const delegation = shouldDelegateCurrentAction(actionOptions);
|
|
7212
7257
|
return {
|
|
7213
7258
|
mode: "main_orchestrates_subagent_execution",
|
|
7214
7259
|
delegationPolicy: "prefer_main_delegate_long_running_fallback_main",
|
|
@@ -7217,6 +7262,7 @@ function buildAgentOrchestrationPolicy(actionOptions, autoRunAvailable) {
|
|
|
7217
7262
|
fallbackToMainAgentWhenSubAgentUnavailable: true,
|
|
7218
7263
|
longRunningCategories: [...LONG_RUNNING_DELEGATION_CATEGORIES],
|
|
7219
7264
|
currentActionShouldDelegate: delegation.shouldDelegate,
|
|
7265
|
+
autoRunShouldDelegate: autoRunAvailable,
|
|
7220
7266
|
currentActionCategory: delegation.category,
|
|
7221
7267
|
mainAgentResponsibilities: [
|
|
7222
7268
|
"Keep user conversation state and approval boundaries",
|
|
@@ -8224,10 +8270,7 @@ async function runContext(featureName, options) {
|
|
|
8224
8270
|
}
|
|
8225
8271
|
const actionOptions = state.actionOptions;
|
|
8226
8272
|
const hasCommandOption = actionOptions.some((option) => option.action.type === "command");
|
|
8227
|
-
const longRunningDelegation = shouldDelegateCurrentAction(
|
|
8228
|
-
actionOptions,
|
|
8229
|
-
autoRunPlan.available
|
|
8230
|
-
);
|
|
8273
|
+
const longRunningDelegation = shouldDelegateCurrentAction(actionOptions);
|
|
8231
8274
|
console.log(chalk6.green(chalk6.bold("\u{1F449} Next Options (Atomic):")));
|
|
8232
8275
|
let hasDocsCommand = false;
|
|
8233
8276
|
actionOptions.forEach((option) => {
|
|
@@ -11485,6 +11528,54 @@ ${mermaidSection}
|
|
|
11485
11528
|
- **Spec**: \`${bodyPaths.specPath}\`
|
|
11486
11529
|
- **Tasks**: \`${bodyPaths.tasksPath}\`${closes}`;
|
|
11487
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
|
+
}
|
|
11488
11579
|
function getRequiredIssueSections(lang) {
|
|
11489
11580
|
return getGithubDraftRequiredSections("issue", lang);
|
|
11490
11581
|
}
|
|
@@ -11938,8 +12029,8 @@ function githubCommand(program2) {
|
|
|
11938
12029
|
kindLabel: tg(config.lang, "kindPr"),
|
|
11939
12030
|
lang: config.lang
|
|
11940
12031
|
});
|
|
11941
|
-
|
|
11942
|
-
|
|
12032
|
+
let body = preparedBody.body;
|
|
12033
|
+
let bodyFile = preparedBody.bodyFile;
|
|
11943
12034
|
const title = options.title?.trim() || (preparedBody.source === "workflow-ready" ? preparedBody.draftMetadata?.title : void 0) || defaultTitle;
|
|
11944
12035
|
const labels = parseLabels(
|
|
11945
12036
|
optionLabels || (preparedBody.source === "workflow-ready" ? preparedBody.draftMetadata?.labels : void 0),
|
|
@@ -11954,6 +12045,18 @@ function githubCommand(program2) {
|
|
|
11954
12045
|
let syncChanged = false;
|
|
11955
12046
|
const pushDocsSync = shouldPushDocsSync(config);
|
|
11956
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
|
+
}
|
|
11957
12060
|
const projectGitCwd = resolveGithubProjectCwd(config, feature);
|
|
11958
12061
|
ensureNoTodoPlaceholders(body, tg(config.lang, "kindPr"), config.lang);
|
|
11959
12062
|
ensurePrArtifacts(body, artifactPolicy, config.lang);
|
|
@@ -12983,6 +13086,12 @@ function buildReportContent(input) {
|
|
|
12983
13086
|
- **Skills**: ${skills}
|
|
12984
13087
|
- **Decision**: ${input.decision}
|
|
12985
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
|
|
12986
13095
|
- **Evidence**:
|
|
12987
13096
|
- TODO: review comments/paths/tests verified during pre-PR review
|
|
12988
13097
|
- **Trace**: pre-pr-review command executed and synced with tasks.md
|