strikethroo 3.7.0 → 3.9.0
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.md +12 -12
- package/dist/index.js +1 -1
- package/dist/metadata.d.ts +1 -1
- package/dist/metadata.js +1 -1
- package/dist/serve/derivation.d.ts +1 -0
- package/dist/serve/derivation.d.ts.map +1 -1
- package/dist/serve/derivation.js +1 -0
- package/dist/serve/derivation.js.map +1 -1
- package/dist/serve/markdown.d.ts +1 -12
- package/dist/serve/markdown.d.ts.map +1 -1
- package/dist/serve/markdown.js +9 -2
- package/dist/serve/markdown.js.map +1 -1
- package/dist/skill-scripts/shared/complexity-score.d.ts +14 -0
- package/dist/skill-scripts/shared/complexity-score.d.ts.map +1 -0
- package/dist/skill-scripts/shared/complexity-score.js +21 -0
- package/dist/skill-scripts/shared/complexity-score.js.map +1 -0
- package/dist/skill-scripts/shared/root.js +1 -1
- package/dist-web/assets/{arc-xFaTbwSI.js → arc-U8dalZIB.js} +1 -1
- package/dist-web/assets/{architectureDiagram-3BPJPVTR-Xz0i2dF0.js → architectureDiagram-3BPJPVTR-BII4UusQ.js} +1 -1
- package/dist-web/assets/{blockDiagram-GPEHLZMM-BdKR7Rki.js → blockDiagram-GPEHLZMM-DY4WZYhw.js} +1 -1
- package/dist-web/assets/{c4Diagram-AAUBKEIU-DAayjcH7.js → c4Diagram-AAUBKEIU-ByZWkPq5.js} +1 -1
- package/dist-web/assets/channel-hoQZJ4FP.js +1 -0
- package/dist-web/assets/{chunk-2J33WTMH-D4OfjzqG.js → chunk-2J33WTMH-BkTWBAb4.js} +1 -1
- package/dist-web/assets/{chunk-4BX2VUAB-Ds6twHLE.js → chunk-4BX2VUAB-CQkRWCB3.js} +1 -1
- package/dist-web/assets/{chunk-55IACEB6-CoVGj0A6.js → chunk-55IACEB6-C-6bW0I1.js} +1 -1
- package/dist-web/assets/{chunk-727SXJPM--kGZcEL_.js → chunk-727SXJPM-C4TUUt4s.js} +1 -1
- package/dist-web/assets/{chunk-AQP2D5EJ-dK8X6Knv.js → chunk-AQP2D5EJ-Dtp8JWF7.js} +1 -1
- package/dist-web/assets/{chunk-FMBD7UC4-CIkH8fwk.js → chunk-FMBD7UC4-BwHFSRRs.js} +1 -1
- package/dist-web/assets/{chunk-ND2GUHAM-BqrY0fV2.js → chunk-ND2GUHAM-Cig_3TB-.js} +1 -1
- package/dist-web/assets/{chunk-QZHKN3VN-Bx8TPE1r.js → chunk-QZHKN3VN-BGETuJY7.js} +1 -1
- package/dist-web/assets/classDiagram-4FO5ZUOK-B0lk8Y6z.js +1 -0
- package/dist-web/assets/classDiagram-v2-Q7XG4LA2-B0lk8Y6z.js +1 -0
- package/dist-web/assets/{cose-bilkent-S5V4N54A-PyZxi1yI.js → cose-bilkent-S5V4N54A-DuOybbaS.js} +1 -1
- package/dist-web/assets/{dagre-BM42HDAG-yXPAIOqC.js → dagre-BM42HDAG-VnC37qtr.js} +1 -1
- package/dist-web/assets/{diagram-2AECGRRQ-DDkzzAIo.js → diagram-2AECGRRQ-Ty7SQMgH.js} +1 -1
- package/dist-web/assets/{diagram-5GNKFQAL-BD_aXIRb.js → diagram-5GNKFQAL-BlKDu0VW.js} +1 -1
- package/dist-web/assets/{diagram-KO2AKTUF-rntOw_IG.js → diagram-KO2AKTUF-Bbg0OCZg.js} +1 -1
- package/dist-web/assets/{diagram-LMA3HP47-BAB3HQQs.js → diagram-LMA3HP47-kkVpRIsu.js} +1 -1
- package/dist-web/assets/{diagram-OG6HWLK6-CwTzozdw.js → diagram-OG6HWLK6-DOWYkZlS.js} +1 -1
- package/dist-web/assets/{erDiagram-TEJ5UH35-BW-Ha54s.js → erDiagram-TEJ5UH35-D8WlLdtK.js} +1 -1
- package/dist-web/assets/{flowDiagram-I6XJVG4X-AGkxH_mx.js → flowDiagram-I6XJVG4X-U7NYonjl.js} +1 -1
- package/dist-web/assets/{ganttDiagram-6RSMTGT7--ZS9LkZ2.js → ganttDiagram-6RSMTGT7-vw1uFVh5.js} +1 -1
- package/dist-web/assets/{gitGraphDiagram-PVQCEYII-D4KfIxPI.js → gitGraphDiagram-PVQCEYII-Coc0d6Bs.js} +1 -1
- package/dist-web/assets/{index-uk0kSvAs.js → index-4vwdK2qG.js} +4 -4
- package/dist-web/assets/{index-IHSMZO2U.js → index-D53fh0zY.js} +1 -1
- package/dist-web/assets/{index-BN30VZfQ.js → index-TwwNd18Z.js} +1 -1
- package/dist-web/assets/{infoDiagram-5YYISTIA-D_Z40zdo.js → infoDiagram-5YYISTIA-D1rd3cgn.js} +1 -1
- package/dist-web/assets/{ishikawaDiagram-YF4QCWOH-CGzxJ2vS.js → ishikawaDiagram-YF4QCWOH-C6QHofgd.js} +1 -1
- package/dist-web/assets/{journeyDiagram-JHISSGLW-DLtpX1Ni.js → journeyDiagram-JHISSGLW-CfCP3_lL.js} +1 -1
- package/dist-web/assets/{kanban-definition-UN3LZRKU-C4_O7GEC.js → kanban-definition-UN3LZRKU-eK9aAtUE.js} +1 -1
- package/dist-web/assets/{linear-BoMijEDN.js → linear-Xl4NTVLR.js} +1 -1
- package/dist-web/assets/{mermaid.core-B7AM5BmV.js → mermaid.core-Bpv3Fy5r.js} +4 -4
- package/dist-web/assets/{mindmap-definition-RKZ34NQL-b8o1AjHb.js → mindmap-definition-RKZ34NQL-C-UftEj-.js} +1 -1
- package/dist-web/assets/{pieDiagram-4H26LBE5-D7BGsvW4.js → pieDiagram-4H26LBE5--B3LdTQd.js} +1 -1
- package/dist-web/assets/{quadrantDiagram-W4KKPZXB-BOsVmBQ_.js → quadrantDiagram-W4KKPZXB-DTr-7cow.js} +1 -1
- package/dist-web/assets/{requirementDiagram-4Y6WPE33-BwuELhlD.js → requirementDiagram-4Y6WPE33-CMKPuFbL.js} +1 -1
- package/dist-web/assets/{sankeyDiagram-5OEKKPKP-DDoQnSJz.js → sankeyDiagram-5OEKKPKP-DnThFDZc.js} +1 -1
- package/dist-web/assets/{sequenceDiagram-3UESZ5HK-Dto9SgGd.js → sequenceDiagram-3UESZ5HK-WqT16YFF.js} +1 -1
- package/dist-web/assets/{stateDiagram-AJRCARHV-Dx0qn_5x.js → stateDiagram-AJRCARHV-5nr9Um5q.js} +1 -1
- package/dist-web/assets/stateDiagram-v2-BHNVJYJU-Doh4LSg5.js +1 -0
- package/dist-web/assets/{timeline-definition-PNZ67QCA-Dbhzc3Xh.js → timeline-definition-PNZ67QCA-CNOVn_B3.js} +1 -1
- package/dist-web/assets/{vennDiagram-CIIHVFJN-BEUtD6fT.js → vennDiagram-CIIHVFJN-D-h0Gph6.js} +1 -1
- package/dist-web/assets/{wardley-L42UT6IY-CqNfcWnP.js → wardley-L42UT6IY-C1fuBpoj.js} +1 -1
- package/dist-web/assets/{wardleyDiagram-YWT4CUSO-Co_bCOQZ.js → wardleyDiagram-YWT4CUSO-BauL5Z2B.js} +1 -1
- package/dist-web/assets/{xychartDiagram-2RQKCTM6-CguzZIIB.js → xychartDiagram-2RQKCTM6-Z9Z3wS3v.js} +1 -1
- package/dist-web/index.html +1 -1
- package/package.json +1 -1
- package/templates/harness/skills/st-create-plan/scripts/find-strikethroo-root.cjs +1 -1
- package/templates/harness/skills/st-create-plan/scripts/get-next-plan-id.cjs +1 -1
- package/templates/harness/skills/st-execute-blueprint/SKILL.md +1 -1
- package/templates/harness/skills/st-execute-blueprint/scripts/check-phase-readiness.cjs +1 -1
- package/templates/harness/skills/st-execute-blueprint/scripts/create-feature-branch.cjs +1 -1
- package/templates/harness/skills/st-execute-blueprint/scripts/find-strikethroo-root.cjs +1 -1
- package/templates/harness/skills/st-execute-blueprint/scripts/validate-plan-blueprint.cjs +93 -22
- package/templates/harness/skills/st-execute-task/scripts/check-task-dependencies.cjs +1 -1
- package/templates/harness/skills/st-execute-task/scripts/find-strikethroo-root.cjs +1 -1
- package/templates/harness/skills/st-execute-task/scripts/validate-plan-blueprint.cjs +93 -22
- package/templates/harness/skills/st-full-workflow/SKILL.md +56 -10
- package/templates/harness/skills/st-full-workflow/scripts/check-phase-readiness.cjs +1 -1
- package/templates/harness/skills/st-full-workflow/scripts/create-feature-branch.cjs +1 -1
- package/templates/harness/skills/st-full-workflow/scripts/find-strikethroo-root.cjs +1 -1
- package/templates/harness/skills/st-full-workflow/scripts/get-next-plan-id.cjs +1 -1
- package/templates/harness/skills/st-full-workflow/scripts/get-next-task-id.cjs +1 -1
- package/templates/harness/skills/st-full-workflow/scripts/validate-plan-blueprint.cjs +93 -22
- package/templates/harness/skills/st-generate-tasks/SKILL.md +56 -11
- package/templates/harness/skills/st-generate-tasks/scripts/find-strikethroo-root.cjs +1 -1
- package/templates/harness/skills/st-generate-tasks/scripts/get-next-task-id.cjs +1 -1
- package/templates/harness/skills/st-generate-tasks/scripts/validate-plan-blueprint.cjs +93 -22
- package/templates/harness/skills/st-refine-plan/scripts/find-strikethroo-root.cjs +1 -1
- package/templates/harness/skills/st-refine-plan/scripts/validate-plan-blueprint.cjs +93 -22
- package/templates/strikethroo/README.md +1 -1
- package/templates/strikethroo/config/hooks/POST_TASK_GENERATION_ALL.md +3 -13
- package/templates/strikethroo/config/templates/TASK_TEMPLATE.md +1 -0
- package/dist-web/assets/channel-Cmb5ngmL.js +0 -1
- package/dist-web/assets/classDiagram-4FO5ZUOK-Dh2pEfOy.js +0 -1
- package/dist-web/assets/classDiagram-v2-Q7XG4LA2-Dh2pEfOy.js +0 -1
- package/dist-web/assets/stateDiagram-v2-BHNVJYJU-qo6que2v.js +0 -1
|
@@ -160,7 +160,42 @@ A task B depends on A if B requires A's output or artifacts, modifies code
|
|
|
160
160
|
created by A, or tests functionality implemented by A. Validate that the
|
|
161
161
|
final dependency graph is acyclic.
|
|
162
162
|
|
|
163
|
-
### 8.
|
|
163
|
+
### 8. Complexity analysis
|
|
164
|
+
|
|
165
|
+
For every candidate task, assign a `complexity_score` (integer 1–10) before
|
|
166
|
+
writing any file. Base the score on these four dimensions:
|
|
167
|
+
|
|
168
|
+
| Score | Skill breadth | Acceptance-criteria clarity | Integration surface | Decomposition depth |
|
|
169
|
+
| --- | --- | --- | --- | --- |
|
|
170
|
+
| 1–3 | One well-known skill | Criteria are concrete and observable | None or a single file/module | No further split possible |
|
|
171
|
+
| 4–5 | One primary skill plus a familiar adjacent skill | Criteria are clear with few edge cases | One component or API boundary | Already atomic |
|
|
172
|
+
| 6–7 | Two distinct skills, or one skill with ambiguous requirements | Criteria need clarification or have multiple edge cases | Multiple components or contracts | Could still be split |
|
|
173
|
+
| 8–10 | Three or more skills, or cross-cutting design decisions | Criteria are vague, unknown, or depend on unresolved choices | Wide integration surface or external systems | Must be decomposed further |
|
|
174
|
+
|
|
175
|
+
**Pre-emission sanity rules** — apply these before any task is written:
|
|
176
|
+
|
|
177
|
+
- 3+ skills assigned → split the task into smaller tasks, each with 1–2 skills.
|
|
178
|
+
- Vague acceptance criteria → sharpen them until they include at least one
|
|
179
|
+
concrete, runnable verification step.
|
|
180
|
+
- Trivially small adjacent tasks → merge them into a single task.
|
|
181
|
+
- Score ≥ 8 → decompose further; do not emit as-is.
|
|
182
|
+
- Score 6–7 → either sharpen criteria or split; do not emit without an
|
|
183
|
+
explicit reason.
|
|
184
|
+
|
|
185
|
+
**Required frontmatter:**
|
|
186
|
+
|
|
187
|
+
- Every emitted task MUST include `complexity_score` (integer 1–10).
|
|
188
|
+
- Optionally include `complexity_notes` when the score needs justification,
|
|
189
|
+
such as "Ambiguous API contract" or "Decomposed from a higher-score parent".
|
|
190
|
+
|
|
191
|
+
**Loop-back rule:**
|
|
192
|
+
|
|
193
|
+
After applying split, sharpen, or merge, re-run dependency analysis and
|
|
194
|
+
re-score the adjusted tasks. Repeat this loop no more than three times. If
|
|
195
|
+
complexity is still unresolved after three passes, stop and surface the
|
|
196
|
+
blocker to the user.
|
|
197
|
+
|
|
198
|
+
### 9. Allocate task IDs
|
|
164
199
|
|
|
165
200
|
Run `scripts/get-next-task-id.cjs <plan-id>` to obtain the first available
|
|
166
201
|
task ID. Allocate subsequent IDs by incrementing in-process; do not invoke
|
|
@@ -170,7 +205,7 @@ field and the zero-padded form (`{padded-id}--{slug}`) for the filename.
|
|
|
170
205
|
The slug derives from a short task title: lowercase, alphanumeric and
|
|
171
206
|
hyphens only, collapsed, trimmed.
|
|
172
207
|
|
|
173
|
-
###
|
|
208
|
+
### 10. Emit the task files
|
|
174
209
|
|
|
175
210
|
Write each task to:
|
|
176
211
|
|
|
@@ -188,11 +223,15 @@ including required frontmatter fields:
|
|
|
188
223
|
- `created` (YYYY-MM-DD)
|
|
189
224
|
- `skills` (array of 1–2 kebab-case skills)
|
|
190
225
|
|
|
191
|
-
|
|
226
|
+
Required additional frontmatter:
|
|
227
|
+
|
|
228
|
+
- `complexity_score` (integer 1–10, required on every emitted task)
|
|
229
|
+
|
|
230
|
+
Optional frontmatter:
|
|
192
231
|
|
|
193
|
-
- `
|
|
194
|
-
|
|
195
|
-
|
|
232
|
+
- `complexity_notes` (string) — include when the score needs justification,
|
|
233
|
+
such as "Decomposed from a cross-cutting parent task" or "Ambiguous API
|
|
234
|
+
contract".
|
|
196
235
|
|
|
197
236
|
The body sections (Objective, Skills Required, Acceptance Criteria, Technical
|
|
198
237
|
Requirements, Input Dependencies, Output Artifacts, Implementation Notes)
|
|
@@ -200,7 +239,7 @@ must be filled with task-specific content. Place detailed implementation
|
|
|
200
239
|
guidance inside a `<details>` block under "Implementation Notes" — write it
|
|
201
240
|
so a non-thinking LLM could execute the task from that section alone.
|
|
202
241
|
|
|
203
|
-
###
|
|
242
|
+
### 11. Validation checklist
|
|
204
243
|
|
|
205
244
|
Before declaring task generation complete, verify:
|
|
206
245
|
|
|
@@ -218,21 +257,27 @@ Before declaring task generation complete, verify:
|
|
|
218
257
|
- Minimization applied (20–30% reduction target).
|
|
219
258
|
- Test tasks focus on business logic, not framework functionality.
|
|
220
259
|
- No gold-plating: only plan requirements are addressed.
|
|
260
|
+
- After writing the task files, run
|
|
261
|
+
`scripts/validate-plan-blueprint.cjs <plan-id> complexityScoresValid`. Stop
|
|
262
|
+
unless it prints `yes`; if it prints `no`, run
|
|
263
|
+
`scripts/validate-plan-blueprint.cjs <plan-id> invalidComplexityTasks` to see
|
|
264
|
+
which files are missing, non-integer, or out-of-range, fix them, and re-run.
|
|
265
|
+
Every generated task must carry an integer `complexity_score` from 1 to 10.
|
|
266
|
+
- Add `complexity_notes` only when a score needs explanation (typically atomic
|
|
267
|
+
tasks scoring greater than 4).
|
|
221
268
|
|
|
222
|
-
###
|
|
269
|
+
### 12. Run the POST_TASK_GENERATION_ALL hook
|
|
223
270
|
|
|
224
271
|
Read `<root>/config/hooks/POST_TASK_GENERATION_ALL.md` and follow its
|
|
225
272
|
instructions. This typically requires:
|
|
226
273
|
|
|
227
|
-
- Sanity-checking complexity (3+ technologies/skills → split; vague criteria
|
|
228
|
-
→ sharpen; trivially small → merge).
|
|
229
274
|
- Appending an Execution Blueprint section to the plan document, including a
|
|
230
275
|
Mermaid dependency diagram and explicit phase groupings (Phase 1 contains
|
|
231
276
|
zero-dependency tasks; each subsequent phase contains tasks whose
|
|
232
277
|
dependencies all live in earlier phases). Use
|
|
233
278
|
`<root>/config/templates/BLUEPRINT_TEMPLATE.md` for structure.
|
|
234
279
|
|
|
235
|
-
###
|
|
280
|
+
### 13. Emit the structured summary
|
|
236
281
|
|
|
237
282
|
Conclude with exactly this block as the final output:
|
|
238
283
|
|
|
@@ -37,7 +37,7 @@ module.exports = __toCommonJS(find_strikethroo_root_exports);
|
|
|
37
37
|
// src/skill-scripts/shared/root.ts
|
|
38
38
|
var fs = __toESM(require("fs"));
|
|
39
39
|
var path = __toESM(require("path"));
|
|
40
|
-
var EXPECTED_SCHEMA = true ?
|
|
40
|
+
var EXPECTED_SCHEMA = true ? 3 : 3;
|
|
41
41
|
var isValidStrikethrooRoot = (strikethrooPath) => {
|
|
42
42
|
try {
|
|
43
43
|
if (!fs.existsSync(strikethrooPath)) return false;
|
|
@@ -41,7 +41,7 @@ var path3 = __toESM(require("path"));
|
|
|
41
41
|
// src/skill-scripts/shared/root.ts
|
|
42
42
|
var fs = __toESM(require("fs"));
|
|
43
43
|
var path = __toESM(require("path"));
|
|
44
|
-
var EXPECTED_SCHEMA = true ?
|
|
44
|
+
var EXPECTED_SCHEMA = true ? 3 : 3;
|
|
45
45
|
var isValidStrikethrooRoot = (strikethrooPath) => {
|
|
46
46
|
try {
|
|
47
47
|
if (!fs.existsSync(strikethrooPath)) return false;
|
|
@@ -33,13 +33,11 @@ __export(validate_plan_blueprint_exports, {
|
|
|
33
33
|
main: () => main
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(validate_plan_blueprint_exports);
|
|
36
|
-
var fs4 = __toESM(require("fs"));
|
|
37
|
-
var path4 = __toESM(require("path"));
|
|
38
36
|
|
|
39
37
|
// src/skill-scripts/shared/root.ts
|
|
40
38
|
var fs = __toESM(require("fs"));
|
|
41
39
|
var path = __toESM(require("path"));
|
|
42
|
-
var EXPECTED_SCHEMA = true ?
|
|
40
|
+
var EXPECTED_SCHEMA = true ? 3 : 3;
|
|
43
41
|
var isValidStrikethrooRoot = (strikethrooPath) => {
|
|
44
42
|
try {
|
|
45
43
|
if (!fs.existsSync(strikethrooPath)) return false;
|
|
@@ -242,34 +240,104 @@ var resolvePlan = (input, startPath = process.cwd()) => {
|
|
|
242
240
|
return resolveByIdInAncestry(planId, startPath);
|
|
243
241
|
};
|
|
244
242
|
|
|
245
|
-
// src/skill-scripts/
|
|
246
|
-
var
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
243
|
+
// src/skill-scripts/shared/blueprint-detection.ts
|
|
244
|
+
var fs4 = __toESM(require("fs"));
|
|
245
|
+
var hasExecutionBlueprint = (planFile) => {
|
|
246
|
+
try {
|
|
247
|
+
const content = fs4.readFileSync(planFile, "utf8");
|
|
248
|
+
return /^## Execution Blueprint/m.test(content);
|
|
249
|
+
} catch (_err) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// src/skill-scripts/shared/task-count.ts
|
|
255
|
+
var fs5 = __toESM(require("fs"));
|
|
256
|
+
var path4 = __toESM(require("path"));
|
|
257
|
+
var countTaskFiles = (planDir) => {
|
|
255
258
|
const tasksDir = path4.join(planDir, "tasks");
|
|
256
|
-
if (!
|
|
259
|
+
if (!fs5.existsSync(tasksDir)) return 0;
|
|
257
260
|
try {
|
|
258
|
-
const stat =
|
|
261
|
+
const stat = fs5.lstatSync(tasksDir);
|
|
259
262
|
if (!stat.isDirectory()) return 0;
|
|
260
|
-
return
|
|
263
|
+
return fs5.readdirSync(tasksDir).filter((f) => f.endsWith(".md")).length;
|
|
261
264
|
} catch (_err) {
|
|
262
265
|
return 0;
|
|
263
266
|
}
|
|
264
267
|
};
|
|
265
|
-
|
|
268
|
+
|
|
269
|
+
// src/skill-scripts/shared/task-complexity.ts
|
|
270
|
+
var fs6 = __toESM(require("fs"));
|
|
271
|
+
var path5 = __toESM(require("path"));
|
|
272
|
+
|
|
273
|
+
// src/skill-scripts/shared/complexity-score.ts
|
|
274
|
+
var validateComplexityScore = (value) => {
|
|
275
|
+
const trimmed = value.trim();
|
|
276
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
277
|
+
return { valid: false, reason: "non-integer" };
|
|
278
|
+
}
|
|
279
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
280
|
+
if (parsed < 1 || parsed > 10) {
|
|
281
|
+
return { valid: false, reason: "out-of-range", value: parsed };
|
|
282
|
+
}
|
|
283
|
+
return { valid: true, value: parsed };
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// src/skill-scripts/shared/task-file.ts
|
|
287
|
+
var extractFrontmatter = (content) => {
|
|
288
|
+
const match = content.match(/^---\s*\r?\n([\s\S]*?)\r?\n---/);
|
|
289
|
+
return match && match[1] ? match[1] : null;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// src/skill-scripts/shared/task-complexity.ts
|
|
293
|
+
var validateTaskComplexityScores = (planDir) => {
|
|
294
|
+
const tasksDir = path5.join(planDir, "tasks");
|
|
295
|
+
if (!fs6.existsSync(tasksDir)) return [];
|
|
296
|
+
let files;
|
|
266
297
|
try {
|
|
267
|
-
|
|
268
|
-
|
|
298
|
+
if (!fs6.lstatSync(tasksDir).isDirectory()) return [];
|
|
299
|
+
files = fs6.readdirSync(tasksDir).filter((f) => f.endsWith(".md")).sort();
|
|
269
300
|
} catch (_err) {
|
|
270
|
-
return
|
|
301
|
+
return [];
|
|
271
302
|
}
|
|
303
|
+
const invalid = [];
|
|
304
|
+
for (const file of files) {
|
|
305
|
+
let content;
|
|
306
|
+
try {
|
|
307
|
+
content = fs6.readFileSync(path5.join(tasksDir, file), "utf8");
|
|
308
|
+
} catch (_err) {
|
|
309
|
+
invalid.push(`${file}: unreadable`);
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
const frontmatter = extractFrontmatter(content);
|
|
313
|
+
const match = frontmatter ? frontmatter.match(/^\s*complexity_score\s*:\s*(.*?)\s*(?:#.*)?$/im) : null;
|
|
314
|
+
if (!match || match[1] === void 0) {
|
|
315
|
+
invalid.push(`${file}: missing complexity_score`);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
const raw = match[1].trim();
|
|
319
|
+
const result = validateComplexityScore(raw);
|
|
320
|
+
if (result.valid) continue;
|
|
321
|
+
if (result.reason === "non-integer") {
|
|
322
|
+
invalid.push(`${file}: non-integer complexity_score "${raw}"`);
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
invalid.push(`${file}: complexity_score ${result.value} out of range 1-10`);
|
|
326
|
+
}
|
|
327
|
+
return invalid;
|
|
272
328
|
};
|
|
329
|
+
|
|
330
|
+
// src/skill-scripts/validate-plan-blueprint.ts
|
|
331
|
+
var VALID_FIELDS = [
|
|
332
|
+
"planFile",
|
|
333
|
+
"planDir",
|
|
334
|
+
"taskCount",
|
|
335
|
+
"blueprintExists",
|
|
336
|
+
"strikethrooRoot",
|
|
337
|
+
"planId",
|
|
338
|
+
"complexityScoresValid",
|
|
339
|
+
"invalidComplexityTasks"
|
|
340
|
+
];
|
|
273
341
|
var usage = () => {
|
|
274
342
|
const lines = [
|
|
275
343
|
"Plan ID or absolute path is required",
|
|
@@ -324,13 +392,16 @@ var main = () => {
|
|
|
324
392
|
}
|
|
325
393
|
process.exit(1);
|
|
326
394
|
}
|
|
395
|
+
const invalidComplexity = validateTaskComplexityScores(resolved.planDir);
|
|
327
396
|
const result = {
|
|
328
397
|
planFile: resolved.planFile,
|
|
329
398
|
planDir: resolved.planDir,
|
|
330
399
|
strikethrooRoot: resolved.strikethrooRoot,
|
|
331
400
|
planId: resolved.planId,
|
|
332
|
-
taskCount:
|
|
333
|
-
blueprintExists:
|
|
401
|
+
taskCount: countTaskFiles(resolved.planDir),
|
|
402
|
+
blueprintExists: hasExecutionBlueprint(resolved.planFile) ? "yes" : "no",
|
|
403
|
+
complexityScoresValid: invalidComplexity.length === 0 ? "yes" : "no",
|
|
404
|
+
invalidComplexityTasks: invalidComplexity.join("; ")
|
|
334
405
|
};
|
|
335
406
|
if (fieldName) {
|
|
336
407
|
if (!VALID_FIELDS.includes(fieldName)) {
|
|
@@ -37,7 +37,7 @@ module.exports = __toCommonJS(find_strikethroo_root_exports);
|
|
|
37
37
|
// src/skill-scripts/shared/root.ts
|
|
38
38
|
var fs = __toESM(require("fs"));
|
|
39
39
|
var path = __toESM(require("path"));
|
|
40
|
-
var EXPECTED_SCHEMA = true ?
|
|
40
|
+
var EXPECTED_SCHEMA = true ? 3 : 3;
|
|
41
41
|
var isValidStrikethrooRoot = (strikethrooPath) => {
|
|
42
42
|
try {
|
|
43
43
|
if (!fs.existsSync(strikethrooPath)) return false;
|
|
@@ -33,13 +33,11 @@ __export(validate_plan_blueprint_exports, {
|
|
|
33
33
|
main: () => main
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(validate_plan_blueprint_exports);
|
|
36
|
-
var fs4 = __toESM(require("fs"));
|
|
37
|
-
var path4 = __toESM(require("path"));
|
|
38
36
|
|
|
39
37
|
// src/skill-scripts/shared/root.ts
|
|
40
38
|
var fs = __toESM(require("fs"));
|
|
41
39
|
var path = __toESM(require("path"));
|
|
42
|
-
var EXPECTED_SCHEMA = true ?
|
|
40
|
+
var EXPECTED_SCHEMA = true ? 3 : 3;
|
|
43
41
|
var isValidStrikethrooRoot = (strikethrooPath) => {
|
|
44
42
|
try {
|
|
45
43
|
if (!fs.existsSync(strikethrooPath)) return false;
|
|
@@ -242,34 +240,104 @@ var resolvePlan = (input, startPath = process.cwd()) => {
|
|
|
242
240
|
return resolveByIdInAncestry(planId, startPath);
|
|
243
241
|
};
|
|
244
242
|
|
|
245
|
-
// src/skill-scripts/
|
|
246
|
-
var
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
243
|
+
// src/skill-scripts/shared/blueprint-detection.ts
|
|
244
|
+
var fs4 = __toESM(require("fs"));
|
|
245
|
+
var hasExecutionBlueprint = (planFile) => {
|
|
246
|
+
try {
|
|
247
|
+
const content = fs4.readFileSync(planFile, "utf8");
|
|
248
|
+
return /^## Execution Blueprint/m.test(content);
|
|
249
|
+
} catch (_err) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// src/skill-scripts/shared/task-count.ts
|
|
255
|
+
var fs5 = __toESM(require("fs"));
|
|
256
|
+
var path4 = __toESM(require("path"));
|
|
257
|
+
var countTaskFiles = (planDir) => {
|
|
255
258
|
const tasksDir = path4.join(planDir, "tasks");
|
|
256
|
-
if (!
|
|
259
|
+
if (!fs5.existsSync(tasksDir)) return 0;
|
|
257
260
|
try {
|
|
258
|
-
const stat =
|
|
261
|
+
const stat = fs5.lstatSync(tasksDir);
|
|
259
262
|
if (!stat.isDirectory()) return 0;
|
|
260
|
-
return
|
|
263
|
+
return fs5.readdirSync(tasksDir).filter((f) => f.endsWith(".md")).length;
|
|
261
264
|
} catch (_err) {
|
|
262
265
|
return 0;
|
|
263
266
|
}
|
|
264
267
|
};
|
|
265
|
-
|
|
268
|
+
|
|
269
|
+
// src/skill-scripts/shared/task-complexity.ts
|
|
270
|
+
var fs6 = __toESM(require("fs"));
|
|
271
|
+
var path5 = __toESM(require("path"));
|
|
272
|
+
|
|
273
|
+
// src/skill-scripts/shared/complexity-score.ts
|
|
274
|
+
var validateComplexityScore = (value) => {
|
|
275
|
+
const trimmed = value.trim();
|
|
276
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
277
|
+
return { valid: false, reason: "non-integer" };
|
|
278
|
+
}
|
|
279
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
280
|
+
if (parsed < 1 || parsed > 10) {
|
|
281
|
+
return { valid: false, reason: "out-of-range", value: parsed };
|
|
282
|
+
}
|
|
283
|
+
return { valid: true, value: parsed };
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// src/skill-scripts/shared/task-file.ts
|
|
287
|
+
var extractFrontmatter = (content) => {
|
|
288
|
+
const match = content.match(/^---\s*\r?\n([\s\S]*?)\r?\n---/);
|
|
289
|
+
return match && match[1] ? match[1] : null;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// src/skill-scripts/shared/task-complexity.ts
|
|
293
|
+
var validateTaskComplexityScores = (planDir) => {
|
|
294
|
+
const tasksDir = path5.join(planDir, "tasks");
|
|
295
|
+
if (!fs6.existsSync(tasksDir)) return [];
|
|
296
|
+
let files;
|
|
266
297
|
try {
|
|
267
|
-
|
|
268
|
-
|
|
298
|
+
if (!fs6.lstatSync(tasksDir).isDirectory()) return [];
|
|
299
|
+
files = fs6.readdirSync(tasksDir).filter((f) => f.endsWith(".md")).sort();
|
|
269
300
|
} catch (_err) {
|
|
270
|
-
return
|
|
301
|
+
return [];
|
|
271
302
|
}
|
|
303
|
+
const invalid = [];
|
|
304
|
+
for (const file of files) {
|
|
305
|
+
let content;
|
|
306
|
+
try {
|
|
307
|
+
content = fs6.readFileSync(path5.join(tasksDir, file), "utf8");
|
|
308
|
+
} catch (_err) {
|
|
309
|
+
invalid.push(`${file}: unreadable`);
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
const frontmatter = extractFrontmatter(content);
|
|
313
|
+
const match = frontmatter ? frontmatter.match(/^\s*complexity_score\s*:\s*(.*?)\s*(?:#.*)?$/im) : null;
|
|
314
|
+
if (!match || match[1] === void 0) {
|
|
315
|
+
invalid.push(`${file}: missing complexity_score`);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
const raw = match[1].trim();
|
|
319
|
+
const result = validateComplexityScore(raw);
|
|
320
|
+
if (result.valid) continue;
|
|
321
|
+
if (result.reason === "non-integer") {
|
|
322
|
+
invalid.push(`${file}: non-integer complexity_score "${raw}"`);
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
invalid.push(`${file}: complexity_score ${result.value} out of range 1-10`);
|
|
326
|
+
}
|
|
327
|
+
return invalid;
|
|
272
328
|
};
|
|
329
|
+
|
|
330
|
+
// src/skill-scripts/validate-plan-blueprint.ts
|
|
331
|
+
var VALID_FIELDS = [
|
|
332
|
+
"planFile",
|
|
333
|
+
"planDir",
|
|
334
|
+
"taskCount",
|
|
335
|
+
"blueprintExists",
|
|
336
|
+
"strikethrooRoot",
|
|
337
|
+
"planId",
|
|
338
|
+
"complexityScoresValid",
|
|
339
|
+
"invalidComplexityTasks"
|
|
340
|
+
];
|
|
273
341
|
var usage = () => {
|
|
274
342
|
const lines = [
|
|
275
343
|
"Plan ID or absolute path is required",
|
|
@@ -324,13 +392,16 @@ var main = () => {
|
|
|
324
392
|
}
|
|
325
393
|
process.exit(1);
|
|
326
394
|
}
|
|
395
|
+
const invalidComplexity = validateTaskComplexityScores(resolved.planDir);
|
|
327
396
|
const result = {
|
|
328
397
|
planFile: resolved.planFile,
|
|
329
398
|
planDir: resolved.planDir,
|
|
330
399
|
strikethrooRoot: resolved.strikethrooRoot,
|
|
331
400
|
planId: resolved.planId,
|
|
332
|
-
taskCount:
|
|
333
|
-
blueprintExists:
|
|
401
|
+
taskCount: countTaskFiles(resolved.planDir),
|
|
402
|
+
blueprintExists: hasExecutionBlueprint(resolved.planFile) ? "yes" : "no",
|
|
403
|
+
complexityScoresValid: invalidComplexity.length === 0 ? "yes" : "no",
|
|
404
|
+
invalidComplexityTasks: invalidComplexity.join("; ")
|
|
334
405
|
};
|
|
335
406
|
if (fieldName) {
|
|
336
407
|
if (!VALID_FIELDS.includes(fieldName)) {
|
|
@@ -4,4 +4,4 @@ This directory contains AI-assisted task management files for this project.
|
|
|
4
4
|
|
|
5
5
|
Managed by the [Strikethroo](https://www.github.com/e0ipso/strikethroo) project.
|
|
6
6
|
|
|
7
|
-
**Documentation**: https://
|
|
7
|
+
**Documentation**: https://strikethroo.canpicasoft.com
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
# POST_TASK_GENERATION_ALL Hook
|
|
2
2
|
|
|
3
|
-
After all tasks have been generated,
|
|
3
|
+
After all tasks have been generated, update the plan with the execution blueprint.
|
|
4
4
|
|
|
5
|
-
## 1.
|
|
5
|
+
## 1. Update Plan with Blueprint
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- **Too complex?** If a task spans 3+ technologies or requires 3+ skills, split it.
|
|
10
|
-
- **Too vague?** If acceptance criteria are unclear, sharpen them.
|
|
11
|
-
- **Too trivial?** If two tasks could be one without adding complexity, merge them.
|
|
12
|
-
|
|
13
|
-
Target: every task should be completable with 1-2 skills and have clear acceptance criteria.
|
|
14
|
-
|
|
15
|
-
## 2. Update Plan with Blueprint
|
|
16
|
-
|
|
17
|
-
After finalizing tasks, append to the plan document:
|
|
7
|
+
Append to the plan document:
|
|
18
8
|
|
|
19
9
|
### Dependency Diagram
|
|
20
10
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{U as a,C as n}from"./mermaid.core-B7AM5BmV.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM--kGZcEL_.js";import{b as i}from"./mermaid.core-B7AM5BmV.js";import"./chunk-FMBD7UC4-CIkH8fwk.js";import"./chunk-ND2GUHAM-BqrY0fV2.js";import"./chunk-55IACEB6-CoVGj0A6.js";import"./chunk-2J33WTMH-D4OfjzqG.js";import"./index-uk0kSvAs.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM--kGZcEL_.js";import{b as i}from"./mermaid.core-B7AM5BmV.js";import"./chunk-FMBD7UC4-CIkH8fwk.js";import"./chunk-ND2GUHAM-BqrY0fV2.js";import"./chunk-55IACEB6-CoVGj0A6.js";import"./chunk-2J33WTMH-D4OfjzqG.js";import"./index-uk0kSvAs.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as e,a as r,s as a,S as s}from"./chunk-AQP2D5EJ-dK8X6Knv.js";import{b as i}from"./mermaid.core-B7AM5BmV.js";import"./chunk-55IACEB6-CoVGj0A6.js";import"./chunk-2J33WTMH-D4OfjzqG.js";import"./index-uk0kSvAs.js";var u={parser:a,get db(){return new s(2)},renderer:r,styles:e,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{u as diagram};
|