strikethroo 4.1.0 → 4.1.1
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 +2 -2
- package/dist/__tests__/fixtures/blueprint-trailing-summary.d.ts +14 -0
- package/dist/__tests__/fixtures/blueprint-trailing-summary.d.ts.map +1 -0
- package/dist/__tests__/fixtures/blueprint-trailing-summary.js +54 -0
- package/dist/__tests__/fixtures/blueprint-trailing-summary.js.map +1 -0
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/conflict-detector.d.ts +28 -12
- package/dist/conflict-detector.d.ts.map +1 -1
- package/dist/conflict-detector.js +45 -53
- package/dist/conflict-detector.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +97 -86
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +2 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +3 -2
- package/dist/metadata.js.map +1 -1
- package/dist/prompts.d.ts +6 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +47 -3
- package/dist/prompts.js.map +1 -1
- package/dist/serve/derivation.d.ts +17 -19
- package/dist/serve/derivation.d.ts.map +1 -1
- package/dist/serve/derivation.js +43 -82
- package/dist/serve/derivation.js.map +1 -1
- package/dist/serve/server.js +1 -1
- package/dist/serve/server.js.map +1 -1
- package/dist/serve/workspace-model.d.ts +11 -17
- package/dist/serve/workspace-model.d.ts.map +1 -1
- package/dist/serve/workspace-model.js +48 -49
- package/dist/serve/workspace-model.js.map +1 -1
- package/dist/skill-scripts/shared/blueprint-parse.d.ts +16 -0
- package/dist/skill-scripts/shared/blueprint-parse.d.ts.map +1 -0
- package/dist/skill-scripts/shared/blueprint-parse.js +66 -0
- package/dist/skill-scripts/shared/blueprint-parse.js.map +1 -0
- package/dist/skill-scripts/shared/root.d.ts +6 -0
- package/dist/skill-scripts/shared/root.d.ts.map +1 -1
- package/dist/skill-scripts/shared/root.js +10 -4
- package/dist/skill-scripts/shared/root.js.map +1 -1
- package/dist/validation/graph-checks.d.ts +6 -14
- package/dist/validation/graph-checks.d.ts.map +1 -1
- package/dist/validation/graph-checks.js +8 -15
- package/dist/validation/graph-checks.js.map +1 -1
- package/dist/validation/metadata-gate.d.ts +2 -6
- package/dist/validation/metadata-gate.d.ts.map +1 -1
- package/dist/validation/metadata-gate.js +17 -6
- package/dist/validation/metadata-gate.js.map +1 -1
- package/dist/validation/strict-pass.d.ts.map +1 -1
- package/dist/validation/strict-pass.js +50 -6
- package/dist/validation/strict-pass.js.map +1 -1
- package/dist-web/assets/{abnfDiagram-VCTEODGH-BCoAyQ8y.js → abnfDiagram-VCTEODGH-CY8QEBrj.js} +1 -1
- package/dist-web/assets/architecture-7GRP2DOG-drIky86B.js +1 -0
- package/dist-web/assets/{architectureDiagram-5GKGNRK7-BbYvyste.js → architectureDiagram-5GKGNRK7-YZUSf-Fx.js} +1 -1
- package/dist-web/assets/{blockDiagram-I7D4REHJ-CGYIKoI0.js → blockDiagram-I7D4REHJ-ByyeaYP7.js} +1 -1
- package/dist-web/assets/{c4Diagram-7LVT6UL2-Cpat9Q1R.js → c4Diagram-7LVT6UL2-YSA0IA7A.js} +1 -1
- package/dist-web/assets/channel-DEeX8XvW.js +1 -0
- package/dist-web/assets/{chunk-4HAMMTFA-D1PXshWJ.js → chunk-4HAMMTFA-8VzDhfwy.js} +1 -1
- package/dist-web/assets/{chunk-75Z2AOVW-C19f30iG.js → chunk-75Z2AOVW-D3fZto5-.js} +1 -1
- package/dist-web/assets/{chunk-DU6HZSFF-CV-KOPc1.js → chunk-DU6HZSFF-vtUmBAxv.js} +1 -1
- package/dist-web/assets/{chunk-F27PBJKO-DMfX40T1.js → chunk-F27PBJKO-BMcZVmbf.js} +1 -1
- package/dist-web/assets/{chunk-GMAD6QVW-Nd9kACgc.js → chunk-GMAD6QVW-C5gwfNkR.js} +1 -1
- package/dist-web/assets/{chunk-GVQU2GXP-3G8ojGFe.js → chunk-GVQU2GXP-CqFZMp6I.js} +1 -1
- package/dist-web/assets/{chunk-IMKFNOWR-CmhGyHNd.js → chunk-IMKFNOWR-CJDfPbiX.js} +1 -1
- package/dist-web/assets/{chunk-L3NEJ4N5-Dsa1ER8Q.js → chunk-L3NEJ4N5-CHeJ2XSW.js} +1 -1
- package/dist-web/assets/{chunk-OSK3NFVY-ObCj9P3B.js → chunk-OSK3NFVY-CXOClbf5.js} +1 -1
- package/dist-web/assets/{chunk-P2QGCYS3-CfNHqVGX.js → chunk-P2QGCYS3-C9Wc2Z2I.js} +1 -1
- package/dist-web/assets/{chunk-POPQ4Y6H-Cg5tk8by.js → chunk-POPQ4Y6H-CfiiGKfO.js} +1 -1
- package/dist-web/assets/{chunk-PWAF6VOD-e6XMS-JR.js → chunk-PWAF6VOD-CtZ4gx65.js} +1 -1
- package/dist-web/assets/{chunk-SHT3W25Y-B1M0HI76.js → chunk-SHT3W25Y-C50-QCrR.js} +1 -1
- package/dist-web/assets/{chunk-SVP7TREG-XLNHY4Z2.js → chunk-SVP7TREG-EIHQbPfX.js} +1 -1
- package/dist-web/assets/{chunk-TICWLB2K-Bpm0S7rI.js → chunk-TICWLB2K-DOB5NZ4R.js} +1 -1
- package/dist-web/assets/classDiagram-ZZMXUADV-H5H_txsg.js +1 -0
- package/dist-web/assets/classDiagram-v2-VYDZK3BY-H5H_txsg.js +1 -0
- package/dist-web/assets/{cynefin-OW5HDTMX-B5ohibc7.js → cynefin-OW5HDTMX-mR6pfDSH.js} +1 -1
- package/dist-web/assets/{cynefinDiagram-5FMLGOSQ-C1202n-x.js → cynefinDiagram-5FMLGOSQ-6-2oQdEg.js} +1 -1
- package/dist-web/assets/{dagre-GXQ25YYZ-CQlKKJXg.js → dagre-GXQ25YYZ-Cm1zvIWj.js} +1 -1
- package/dist-web/assets/{diagram-S7CK7UJ4-DRf7iTH9.js → diagram-S7CK7UJ4-D6mECnyP.js} +1 -1
- package/dist-web/assets/{diagram-UQ7AKVKN-CxSX3b2_.js → diagram-UQ7AKVKN-CzmXABVS.js} +1 -1
- package/dist-web/assets/{diagram-VSXAHHWV-D9vrB5je.js → diagram-VSXAHHWV-CpEauecU.js} +1 -1
- package/dist-web/assets/{diagram-VX7I27RA-DTOqcpBV.js → diagram-VX7I27RA-CXPYrCgX.js} +1 -1
- package/dist-web/assets/{diagram-Z3DM3KII-mlhRA4lR.js → diagram-Z3DM3KII-RcMIMVWZ.js} +1 -1
- package/dist-web/assets/{dist-DqTG_rhR.js → dist--eYrBgi0.js} +1 -1
- package/dist-web/assets/{ebnfDiagram-PWID7BFC-BhB_RJPM.js → ebnfDiagram-PWID7BFC-MZpZ_VnU.js} +1 -1
- package/dist-web/assets/{erDiagram-RLTQ6QDP-0wE1kPYz.js → erDiagram-RLTQ6QDP-BcZ7Ctxy.js} +1 -1
- package/dist-web/assets/{esm-COEoxUhE.js → esm-CQW0DO89.js} +1 -1
- package/dist-web/assets/eventmodeling-NTZA5JFV-BwLlQZcI.js +1 -0
- package/dist-web/assets/flowDiagram-HODETNUW-DGqUYaRC.js +1 -0
- package/dist-web/assets/{ganttDiagram-EL5Y4UJY-BsvlpHPt.js → ganttDiagram-EL5Y4UJY-CcJ72sCU.js} +1 -1
- package/dist-web/assets/{gitGraph-4MIJSDKK-Dm82FCqy.js → gitGraph-4MIJSDKK-BheSjO6S.js} +1 -1
- package/dist-web/assets/{gitGraphDiagram-WWUBYQGX-OPit_3vA.js → gitGraphDiagram-WWUBYQGX-Qv13SyYh.js} +1 -1
- package/dist-web/assets/index-D0npIBvI.css +2 -0
- package/dist-web/assets/index-DsQxKERJ.js +103 -0
- package/dist-web/assets/{info-A6RAGUB7-8sl1XQWq.js → info-A6RAGUB7-BemnwZ_B.js} +1 -1
- package/dist-web/assets/{infoDiagram-27XIBGKW-DIpdnB7L.js → infoDiagram-27XIBGKW-otpjj8PV.js} +1 -1
- package/dist-web/assets/{ishikawaDiagram-5VMMS53U-DpoLDWpF.js → ishikawaDiagram-5VMMS53U-BuZBZkYN.js} +1 -1
- package/dist-web/assets/{journeyDiagram-3NMN7TZE-BAEbJ33U.js → journeyDiagram-3NMN7TZE-D-uflaQS.js} +1 -1
- package/dist-web/assets/{kanban-definition-UXKFOSKX-CqzyUA0g.js → kanban-definition-UXKFOSKX-BI643rxH.js} +1 -1
- package/dist-web/assets/{line-CQRHrtV_.js → line-fay7lQM4.js} +1 -1
- package/dist-web/assets/{mermaid-parser.core-XlEvAPi2.js → mermaid-parser.core-CI9Bt8lf.js} +3 -3
- package/dist-web/assets/{mermaid.core-CvFTFi5O.js → mermaid.core-CpvTzp9Q.js} +4 -4
- package/dist-web/assets/{mindmap-definition-YA3MSWOX-Ch0vW4Mc.js → mindmap-definition-YA3MSWOX-Dw-DFKfU.js} +1 -1
- package/dist-web/assets/{packet-AYTQ26CC-lk-QU-qZ.js → packet-AYTQ26CC-CsBrScsn.js} +1 -1
- package/dist-web/assets/{pegDiagram-XKGWAZYB-Cgf4CYg-.js → pegDiagram-XKGWAZYB-BVal7Apj.js} +1 -1
- package/dist-web/assets/{pie-WAS4IAKB-dWyVjg9O.js → pie-WAS4IAKB-DZFMDceO.js} +1 -1
- package/dist-web/assets/{pieDiagram-E7YTZNPT-BDZxWO8n.js → pieDiagram-E7YTZNPT-B3QEKixf.js} +1 -1
- package/dist-web/assets/{quadrantDiagram-AXDQQJYC-DCu9cx1_.js → quadrantDiagram-AXDQQJYC-CRgAf_p-.js} +1 -1
- package/dist-web/assets/{radar-RG4KPBEZ-CphwvESj.js → radar-RG4KPBEZ-BkOoPAbJ.js} +1 -1
- package/dist-web/assets/{railroad-74A4TZTK-COTrvtXu.js → railroad-74A4TZTK-BgIna4sT.js} +1 -1
- package/dist-web/assets/railroad-abnf-HS5TGJTU-CVlFeN1b.js +1 -0
- package/dist-web/assets/railroad-ebnf-LZEXJU2U-DCEa0WVT.js +1 -0
- package/dist-web/assets/railroad-peg-WCYAUIDC-BHX1T-4x.js +1 -0
- package/dist-web/assets/{railroadDiagram-O6MQD6OU-S9ZI1Adi.js → railroadDiagram-O6MQD6OU-BZwRaQM3.js} +1 -1
- package/dist-web/assets/{requirementDiagram-BXWQKSXE-a_3FElqS.js → requirementDiagram-BXWQKSXE-BN3nmFpY.js} +1 -1
- package/dist-web/assets/{sankeyDiagram-P5KCCOFB-D-i6r8wy.js → sankeyDiagram-P5KCCOFB-DBhFOKcq.js} +1 -1
- package/dist-web/assets/{sequenceDiagram-WJ2MYXX4-D8hA2m0U.js → sequenceDiagram-WJ2MYXX4-CBc9y9xq.js} +1 -1
- package/dist-web/assets/{stateDiagram-D77RDMKH-C14W-8zT.js → stateDiagram-D77RDMKH-BDdsXTTr.js} +1 -1
- package/dist-web/assets/stateDiagram-v2-MP3YSRHH-C04o4SeT.js +1 -0
- package/dist-web/assets/{swimlanes-42K2YHIH-FMv8YLkC.js → swimlanes-42K2YHIH-1QXV5L5H.js} +1 -1
- package/dist-web/assets/swimlanesDiagram-VR7AAH4N-CQ46EU90.js +8 -0
- package/dist-web/assets/{timeline-definition-24CTP7MA-DmBN45fY.js → timeline-definition-24CTP7MA-D9CdAGEV.js} +1 -1
- package/dist-web/assets/{treeView-Q6P3EWNA-C5-PUnPN.js → treeView-Q6P3EWNA-CxKfpZsz.js} +1 -1
- package/dist-web/assets/{treemap-WGGIJYW6-C_veVYMi.js → treemap-WGGIJYW6-Bg5-PJ6G.js} +1 -1
- package/dist-web/assets/{vennDiagram-4TSXK5OY-CiWHjSVc.js → vennDiagram-4TSXK5OY-DIlZEQm_.js} +1 -1
- package/dist-web/assets/{wardley-WFR3VGLG-FOCO1NlU.js → wardley-WFR3VGLG-DCKFxH5V.js} +1 -1
- package/dist-web/assets/{wardleyDiagram-VM6X3IG4-Da3kkvxV.js → wardleyDiagram-VM6X3IG4-D8O8WtAP.js} +1 -1
- package/dist-web/assets/{xychartDiagram-S5SC5T6Z-DPxie1fH.js → xychartDiagram-S5SC5T6Z-Dz9bYgtE.js} +1 -1
- package/dist-web/index.html +2 -2
- package/package.json +7 -4
- package/templates/strikethroo/config/templates/TASK_TEMPLATE.md +1 -1
- package/dist-web/assets/architecture-7GRP2DOG-C2Oj1AcH.js +0 -1
- package/dist-web/assets/channel-Da0Eg5hZ.js +0 -1
- package/dist-web/assets/classDiagram-ZZMXUADV-CZI086hK.js +0 -1
- package/dist-web/assets/classDiagram-v2-VYDZK3BY-CZI086hK.js +0 -1
- package/dist-web/assets/eventmodeling-NTZA5JFV-DzkXb9nA.js +0 -1
- package/dist-web/assets/flowDiagram-HODETNUW-cgl8ipSt.js +0 -1
- package/dist-web/assets/index-6XzOqB6r.js +0 -103
- package/dist-web/assets/index-CgIHUWsX.css +0 -2
- package/dist-web/assets/railroad-abnf-HS5TGJTU-CYfpugMj.js +0 -1
- package/dist-web/assets/railroad-ebnf-LZEXJU2U--Ui_4jm6.js +0 -1
- package/dist-web/assets/railroad-peg-WCYAUIDC-DzcveMan.js +0 -1
- package/dist-web/assets/stateDiagram-v2-MP3YSRHH-Dhuhsub3.js +0 -1
- package/dist-web/assets/swimlanesDiagram-VR7AAH4N-O94a9jW3.js +0 -8
package/README.md
CHANGED
|
@@ -177,7 +177,7 @@ Then browse to the VM's IP address, for example `http://192.168.122.10:4317`; `s
|
|
|
177
177
|
npx strikethroo validate
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
Reads your workspace and reports internal inconsistencies -- missing or malformed plan and task frontmatter, dependencies pointing at tasks that do not exist, dependency cycles, blueprint phases and task files that disagree, duplicate ids. It only reads: nothing is written or fixed for you. Every finding is an error, so the command exits non-zero as soon as it reports one, which makes it usable as a CI step. Add `--json` for a machine-readable report on stdout, or `--workspace <path>` to point it at a workspace other than the one discovered from the current directory.
|
|
180
|
+
Reads your workspace and reports internal inconsistencies -- missing or malformed plan and task frontmatter, dependencies pointing at tasks that do not exist, dependency cycles, blueprint phases and task files that disagree, duplicate ids. It only reads: nothing is written or fixed for you. Every finding is an error, so the command exits non-zero as soon as it reports one, which makes it usable as a CI step. Add `--json` for a machine-readable report on stdout, or `--workspace <path>` to point it at a workspace other than the one discovered from the current directory. A workspace without `CODE_REVIEW.md`, `schemas/self-review-v2.xsd`, or `templates/UPDATE_NOTICE_TEMPLATE.md` is valid and produces no finding for them, while a missing required file is reported. `init` and `update` restore any shipped file you deleted.
|
|
181
181
|
|
|
182
182
|
| Plans board | Plan detail page | Archive |
|
|
183
183
|
|-------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|
|
|
@@ -187,7 +187,7 @@ Reads your workspace and reports internal inconsistencies -- missing or malforme
|
|
|
187
187
|
|
|
188
188
|
After blueprint execution, an optional automated code review gate runs once when a second harness is discovered. The reviewer critiques the cumulative diff against the plan's requirements and emits findings validated against a schema. The gate reports; it does not decide -- there are no severity or confidence floors, and nothing is applied automatically. You read the findings and choose what to act on.
|
|
189
189
|
|
|
190
|
-
**To disable:**
|
|
190
|
+
**To disable:** Empty `.ai/strikethroo/config/hooks/CODE_REVIEW.md`. The gate skips cleanly with a note in the execution summary. A deleted file is restored by the next `init` or `update`.
|
|
191
191
|
|
|
192
192
|
**Important:** A green review gate is not a correctness guarantee. The gate reduces exposure to the same class of error a human PR approval reduces, and leaves the same class of error behind. See [Customization](https://strikethroo.canpicasoft.com/customization.html) for limitations and configuration.
|
|
193
193
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One plan body shared by the viewer, validator, and readiness-bundle suites.
|
|
3
|
+
*
|
|
4
|
+
* The blueprint carries two phases plus the template's `### Post-phase Actions`
|
|
5
|
+
* and `### Execution Summary` subsections. `TRAILING_EXECUTION_SUMMARY` is the
|
|
6
|
+
* `## Execution Summary` section `st-execute-blueprint` appends after a run;
|
|
7
|
+
* its bullets name an existing task (01) and a nonexistent one (04). Every
|
|
8
|
+
* consumer must read the same phases with or without that trailing section.
|
|
9
|
+
*/
|
|
10
|
+
export declare const BLUEPRINT_SECTION = "\n## Execution Blueprint\n\n**Validation Gates:**\n- Reference: `/config/hooks/POST_PHASE.md`\n\n### Phase 1: Foundations\n**Parallel Tasks:**\n- Task 01: First\n- Task 02: Second\n\n### Phase 2: Follow-through\n**Parallel Tasks:**\n- Task 03: Third (depends on: 01, 02)\n\n### Post-phase Actions\n\nRun the validation gates after each phase.\n\n### Execution Summary\n- Total Phases: 2\n- Total Tasks: 3\n";
|
|
11
|
+
export declare const TRAILING_EXECUTION_SUMMARY = "\n## Execution Summary\n\n**Status**: Completed Successfully\n**Completed Date**: 2026-10-07\n\n### Results\n- Task 03: shipped the follow-through\n- Task 04: deferred to a later plan\n\n### Noteworthy Events\n- Task 01 needed a second attempt.\n\n### Necessary follow-ups\n- None.\n";
|
|
12
|
+
/** Phase membership the blueprint section alone declares. */
|
|
13
|
+
export declare const EXPECTED_PHASE_TASK_IDS: number[][];
|
|
14
|
+
//# sourceMappingURL=blueprint-trailing-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blueprint-trailing-summary.d.ts","sourceRoot":"","sources":["../../../src/__tests__/fixtures/blueprint-trailing-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,iBAAiB,2ZAsB7B,CAAC;AAEF,eAAO,MAAM,0BAA0B,gSAetC,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,uBAAuB,EAAE,MAAM,EAAE,EAAkB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* One plan body shared by the viewer, validator, and readiness-bundle suites.
|
|
4
|
+
*
|
|
5
|
+
* The blueprint carries two phases plus the template's `### Post-phase Actions`
|
|
6
|
+
* and `### Execution Summary` subsections. `TRAILING_EXECUTION_SUMMARY` is the
|
|
7
|
+
* `## Execution Summary` section `st-execute-blueprint` appends after a run;
|
|
8
|
+
* its bullets name an existing task (01) and a nonexistent one (04). Every
|
|
9
|
+
* consumer must read the same phases with or without that trailing section.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.EXPECTED_PHASE_TASK_IDS = exports.TRAILING_EXECUTION_SUMMARY = exports.BLUEPRINT_SECTION = void 0;
|
|
13
|
+
exports.BLUEPRINT_SECTION = `
|
|
14
|
+
## Execution Blueprint
|
|
15
|
+
|
|
16
|
+
**Validation Gates:**
|
|
17
|
+
- Reference: \`/config/hooks/POST_PHASE.md\`
|
|
18
|
+
|
|
19
|
+
### Phase 1: Foundations
|
|
20
|
+
**Parallel Tasks:**
|
|
21
|
+
- Task 01: First
|
|
22
|
+
- Task 02: Second
|
|
23
|
+
|
|
24
|
+
### Phase 2: Follow-through
|
|
25
|
+
**Parallel Tasks:**
|
|
26
|
+
- Task 03: Third (depends on: 01, 02)
|
|
27
|
+
|
|
28
|
+
### Post-phase Actions
|
|
29
|
+
|
|
30
|
+
Run the validation gates after each phase.
|
|
31
|
+
|
|
32
|
+
### Execution Summary
|
|
33
|
+
- Total Phases: 2
|
|
34
|
+
- Total Tasks: 3
|
|
35
|
+
`;
|
|
36
|
+
exports.TRAILING_EXECUTION_SUMMARY = `
|
|
37
|
+
## Execution Summary
|
|
38
|
+
|
|
39
|
+
**Status**: Completed Successfully
|
|
40
|
+
**Completed Date**: 2026-10-07
|
|
41
|
+
|
|
42
|
+
### Results
|
|
43
|
+
- Task 03: shipped the follow-through
|
|
44
|
+
- Task 04: deferred to a later plan
|
|
45
|
+
|
|
46
|
+
### Noteworthy Events
|
|
47
|
+
- Task 01 needed a second attempt.
|
|
48
|
+
|
|
49
|
+
### Necessary follow-ups
|
|
50
|
+
- None.
|
|
51
|
+
`;
|
|
52
|
+
/** Phase membership the blueprint section alone declares. */
|
|
53
|
+
exports.EXPECTED_PHASE_TASK_IDS = [[1, 2], [3]];
|
|
54
|
+
//# sourceMappingURL=blueprint-trailing-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blueprint-trailing-summary.js","sourceRoot":"","sources":["../../../src/__tests__/fixtures/blueprint-trailing-summary.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEU,QAAA,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBhC,CAAC;AAEW,QAAA,0BAA0B,GAAG;;;;;;;;;;;;;;;CAezC,CAAC;AAEF,6DAA6D;AAChD,QAAA,uBAAuB,GAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -19,8 +19,12 @@ const server_1 = require("./serve/server");
|
|
|
19
19
|
const export_profile_1 = require("./export-profile");
|
|
20
20
|
const workspace_1 = require("./validation/workspace");
|
|
21
21
|
const update_1 = require("./update");
|
|
22
|
+
const metadata_1 = require("./metadata");
|
|
22
23
|
const program = new commander_1.Command();
|
|
23
|
-
program
|
|
24
|
+
program
|
|
25
|
+
.name('strikethroo')
|
|
26
|
+
.version((0, metadata_1.getPackageVersion)())
|
|
27
|
+
.description('AI-powered task management CLI tool');
|
|
24
28
|
program
|
|
25
29
|
.command('init')
|
|
26
30
|
.description('Initialize a new Strikethroo project')
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AACA;;;;;GAKG;;;;;AAEH,yCAAoC;AACpC,kDAA0B;AAC1B,6BAA2B;AAC3B,mCAA+B;AAE/B,uCAAoE;AACpE,2CAA+D;AAC/D,qDAAiD;AACjD,sDAA2D;AAE3D,qCAAkC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,21 +4,37 @@
|
|
|
4
4
|
* This file handles detection of user-modified files during init command
|
|
5
5
|
* by comparing current file hashes against stored baseline hashes
|
|
6
6
|
*/
|
|
7
|
-
import { FileConflict
|
|
7
|
+
import { FileConflict } from './types';
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* List every file under `<rootDir>/config/`, relative to `rootDir`, sorted.
|
|
10
|
+
*
|
|
11
|
+
* Shared by conflict detection and the refresh pass in `src/index.ts` so both
|
|
12
|
+
* walk the same incoming paths in the same order.
|
|
13
|
+
*
|
|
14
|
+
* @param rootDir - Workspace or template root holding a `config/` tree
|
|
15
|
+
*/
|
|
16
|
+
export declare function getConfigFiles(rootDir: string): Promise<string[]>;
|
|
17
|
+
/**
|
|
18
|
+
* `FileConflict.originalHash` for a destination with no recorded baseline.
|
|
19
|
+
*
|
|
20
|
+
* The prompt keys its wording on it: such a file is reported as untracked,
|
|
21
|
+
* never as modified since a baseline Strikethroo does not have.
|
|
14
22
|
*/
|
|
15
|
-
export declare
|
|
23
|
+
export declare const NO_RECORDED_BASELINE = "";
|
|
16
24
|
/**
|
|
17
|
-
*
|
|
25
|
+
* Detect the incoming paths that need a decision before they are written.
|
|
26
|
+
*
|
|
27
|
+
* A destination is compared against its recorded baseline, not against the
|
|
28
|
+
* incoming file: the question is whether the user changed it. A destination
|
|
29
|
+
* with no recorded hash has nothing to compare against, so it conflicts
|
|
30
|
+
* whenever it differs from the incoming file and carries
|
|
31
|
+
* `NO_RECORDED_BASELINE`. A destination byte-identical to the incoming file is
|
|
32
|
+
* never a conflict, tracked or not; writing it would change nothing.
|
|
33
|
+
*
|
|
18
34
|
* @param destDir - Destination directory (.ai/strikethroo)
|
|
19
|
-
* @param
|
|
20
|
-
* @param
|
|
21
|
-
*
|
|
35
|
+
* @param templateDir - Source template directory from package
|
|
36
|
+
* @param baseline - Recorded hashes by relative path; `{}` when no metadata
|
|
37
|
+
* can be trusted, which makes every existing destination untracked
|
|
22
38
|
*/
|
|
23
|
-
export declare function
|
|
39
|
+
export declare function detectConflicts(destDir: string, templateDir: string, baseline: Record<string, string>): Promise<FileConflict[]>;
|
|
24
40
|
//# sourceMappingURL=conflict-detector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-detector.d.ts","sourceRoot":"","sources":["../src/conflict-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"conflict-detector.d.ts","sourceRoot":"","sources":["../src/conflict-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAwBvE;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,YAAY,EAAE,CAAC,CAyBzB"}
|
|
@@ -39,18 +39,22 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
39
39
|
};
|
|
40
40
|
})();
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.NO_RECORDED_BASELINE = void 0;
|
|
43
|
+
exports.getConfigFiles = getConfigFiles;
|
|
42
44
|
exports.detectConflicts = detectConflicts;
|
|
43
|
-
exports.isFileDeleted = isFileDeleted;
|
|
44
45
|
const fs = __importStar(require("fs-extra"));
|
|
45
46
|
const path = __importStar(require("path"));
|
|
46
47
|
const metadata_1 = require("./metadata");
|
|
47
48
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* List every file under `<rootDir>/config/`, relative to `rootDir`, sorted.
|
|
50
|
+
*
|
|
51
|
+
* Shared by conflict detection and the refresh pass in `src/index.ts` so both
|
|
52
|
+
* walk the same incoming paths in the same order.
|
|
53
|
+
*
|
|
54
|
+
* @param rootDir - Workspace or template root holding a `config/` tree
|
|
51
55
|
*/
|
|
52
|
-
async function getConfigFiles(
|
|
53
|
-
const configDir = path.join(
|
|
56
|
+
async function getConfigFiles(rootDir) {
|
|
57
|
+
const configDir = path.join(rootDir, 'config');
|
|
54
58
|
const files = [];
|
|
55
59
|
async function walkDir(dir, relativeTo) {
|
|
56
60
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
@@ -66,65 +70,53 @@ async function getConfigFiles(destDir) {
|
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
if (await fs.pathExists(configDir)) {
|
|
69
|
-
await walkDir(configDir,
|
|
73
|
+
await walkDir(configDir, rootDir);
|
|
70
74
|
}
|
|
71
|
-
return files;
|
|
75
|
+
return files.sort();
|
|
72
76
|
}
|
|
73
77
|
/**
|
|
74
|
-
*
|
|
78
|
+
* `FileConflict.originalHash` for a destination with no recorded baseline.
|
|
79
|
+
*
|
|
80
|
+
* The prompt keys its wording on it: such a file is reported as untracked,
|
|
81
|
+
* never as modified since a baseline Strikethroo does not have.
|
|
82
|
+
*/
|
|
83
|
+
exports.NO_RECORDED_BASELINE = '';
|
|
84
|
+
/**
|
|
85
|
+
* Detect the incoming paths that need a decision before they are written.
|
|
86
|
+
*
|
|
87
|
+
* A destination is compared against its recorded baseline, not against the
|
|
88
|
+
* incoming file: the question is whether the user changed it. A destination
|
|
89
|
+
* with no recorded hash has nothing to compare against, so it conflicts
|
|
90
|
+
* whenever it differs from the incoming file and carries
|
|
91
|
+
* `NO_RECORDED_BASELINE`. A destination byte-identical to the incoming file is
|
|
92
|
+
* never a conflict, tracked or not; writing it would change nothing.
|
|
93
|
+
*
|
|
75
94
|
* @param destDir - Destination directory (.ai/strikethroo)
|
|
76
95
|
* @param templateDir - Source template directory from package
|
|
77
|
-
* @param
|
|
78
|
-
*
|
|
96
|
+
* @param baseline - Recorded hashes by relative path; `{}` when no metadata
|
|
97
|
+
* can be trusted, which makes every existing destination untracked
|
|
79
98
|
*/
|
|
80
|
-
async function detectConflicts(destDir, templateDir,
|
|
99
|
+
async function detectConflicts(destDir, templateDir, baseline) {
|
|
81
100
|
const conflicts = [];
|
|
82
|
-
const
|
|
83
|
-
for (const relativePath of configFiles) {
|
|
101
|
+
for (const relativePath of await getConfigFiles(templateDir)) {
|
|
84
102
|
const userFilePath = path.join(destDir, relativePath);
|
|
85
103
|
const newFilePath = path.join(templateDir, relativePath);
|
|
86
|
-
|
|
87
|
-
const userFileExists = await fs.pathExists(userFilePath);
|
|
88
|
-
if (!userFileExists) {
|
|
89
|
-
// File doesn't exist in user's directory, no conflict (new file)
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
// Get original hash from metadata
|
|
93
|
-
const originalHash = metadata.files[relativePath];
|
|
94
|
-
if (!originalHash) {
|
|
95
|
-
// File wasn't tracked in metadata (new file in this version), no conflict
|
|
104
|
+
if (!(await fs.pathExists(userFilePath)))
|
|
96
105
|
continue;
|
|
97
|
-
}
|
|
98
|
-
// Calculate current hash of user's file
|
|
99
106
|
const currentHash = await (0, metadata_1.calculateFileHash)(userFilePath);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
113
|
-
}
|
|
107
|
+
if (currentHash === (await (0, metadata_1.calculateFileHash)(newFilePath)))
|
|
108
|
+
continue;
|
|
109
|
+
const originalHash = baseline[relativePath];
|
|
110
|
+
if (originalHash !== undefined && currentHash === originalHash)
|
|
111
|
+
continue;
|
|
112
|
+
conflicts.push({
|
|
113
|
+
relativePath,
|
|
114
|
+
userFileContent: await fs.readFile(userFilePath, 'utf-8'),
|
|
115
|
+
newFileContent: await fs.readFile(newFilePath, 'utf-8'),
|
|
116
|
+
originalHash: originalHash ?? exports.NO_RECORDED_BASELINE,
|
|
117
|
+
currentHash,
|
|
118
|
+
});
|
|
114
119
|
}
|
|
115
120
|
return conflicts;
|
|
116
121
|
}
|
|
117
|
-
/**
|
|
118
|
-
* Check if a file has been deleted by the user
|
|
119
|
-
* @param destDir - Destination directory (.ai/strikethroo)
|
|
120
|
-
* @param relativePath - Relative path from destDir
|
|
121
|
-
* @param metadata - Previously stored metadata
|
|
122
|
-
* @returns true if file existed in metadata but is now deleted
|
|
123
|
-
*/
|
|
124
|
-
function isFileDeleted(destDir, relativePath, metadata) {
|
|
125
|
-
const filePath = path.join(destDir, relativePath);
|
|
126
|
-
const existsInMetadata = relativePath in metadata.files;
|
|
127
|
-
const existsOnDisk = fs.pathExistsSync(filePath);
|
|
128
|
-
return existsInMetadata && !existsOnDisk;
|
|
129
|
-
}
|
|
130
122
|
//# sourceMappingURL=conflict-detector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-detector.js","sourceRoot":"","sources":["../src/conflict-detector.ts"],"names":[],"mappings":";AAAA;;;;;GAKG
|
|
1
|
+
{"version":3,"file":"conflict-detector.js","sourceRoot":"","sources":["../src/conflict-detector.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeH,wCAwBC;AAyBD,0CA6BC;AA3FD,6CAA+B;AAC/B,2CAA6B;AAE7B,yCAA+C;AAE/C;;;;;;;GAOG;AACI,KAAK,UAAU,cAAc,CAAC,OAAe;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,UAAkB;QACpD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAEzD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACtC,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACU,QAAA,oBAAoB,GAAG,EAAE,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACI,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,WAAmB,EACnB,QAAgC;IAEhC,MAAM,SAAS,GAAmB,EAAE,CAAC;IAErC,KAAK,MAAM,YAAY,IAAI,MAAM,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAEzD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YAAE,SAAS;QAEnD,MAAM,WAAW,GAAG,MAAM,IAAA,4BAAiB,EAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,WAAW,KAAK,CAAC,MAAM,IAAA,4BAAiB,EAAC,WAAW,CAAC,CAAC;YAAE,SAAS;QAErE,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,YAAY,KAAK,SAAS,IAAI,WAAW,KAAK,YAAY;YAAE,SAAS;QAEzE,SAAS,CAAC,IAAI,CAAC;YACb,YAAY;YACZ,eAAe,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;YACzD,cAAc,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;YACvD,YAAY,EAAE,YAAY,IAAI,4BAAoB;YAClD,WAAW;SACZ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,WAAW,EAAE,aAAa,EAA6C,MAAM,SAAS,CAAC;AA6FhG;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAwIvE;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,WAAW,EAAE,aAAa,EAA6C,MAAM,SAAS,CAAC;AA6FhG;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAwIvE;AA2RD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGtE;AAyBD,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACzF,YAAY,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -299,56 +299,113 @@ async function recordHarnessSelection(metadataPath, harnesses) {
|
|
|
299
299
|
/**
|
|
300
300
|
* Copy common template files to .ai/strikethroo directory with conflict detection
|
|
301
301
|
*
|
|
302
|
+
* Each incoming `config/` path gets its own outcome, so one conflict never stops
|
|
303
|
+
* another path from being installed, refreshed, or restored. Missing or
|
|
304
|
+
* unusable metadata is not a first install: every existing destination is then
|
|
305
|
+
* untracked, and each one that differs from its incoming file needs a decision
|
|
306
|
+
* before anything is written. An empty or byte-identical tree needs none, and
|
|
307
|
+
* `force` is the only route that skips the question. The tracked tree is
|
|
308
|
+
* written first and the metadata last; a failed copy throws before
|
|
309
|
+
* `saveMetadata` runs, leaving the previous metadata in place.
|
|
310
|
+
*
|
|
302
311
|
* @param sourceDir - Source template tree; defaults to the shipped
|
|
303
312
|
* `templates/strikethroo/` path, overridden by a profile staging tree
|
|
304
313
|
*/
|
|
305
314
|
async function copyCommonTemplates(baseDir, force, sourceDir = getTemplatePath('strikethroo')) {
|
|
306
315
|
const destDir = resolvePath(baseDir, '.ai/strikethroo');
|
|
307
316
|
const metadataPath = resolvePath(destDir, '.init-metadata.json');
|
|
308
|
-
// Check if source template directory exists
|
|
309
317
|
if (!(await exists(sourceDir))) {
|
|
310
318
|
throw new Error(`Template directory not found: ${sourceDir}`);
|
|
311
319
|
}
|
|
312
|
-
// Load existing metadata if present
|
|
313
320
|
const existingMetadata = await (0, metadata_1.loadMetadata)(metadataPath);
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
return;
|
|
321
|
+
const baseline = existingMetadata?.files ?? {};
|
|
322
|
+
let resolutions = new Map();
|
|
323
|
+
if (!force) {
|
|
324
|
+
const conflicts = await (0, conflict_detector_1.detectConflicts)(destDir, sourceDir, baseline);
|
|
325
|
+
if (conflicts.length > 0) {
|
|
326
|
+
if (!existingMetadata) {
|
|
327
|
+
console.log(chalk_1.default.yellow('\n⚠ .init-metadata.json is missing or unusable, so nothing under config/ has a trusted baseline.'));
|
|
328
|
+
}
|
|
329
|
+
console.log(chalk_1.default.yellow(`\n⚠ ${conflicts.length} file(s) differ from the incoming version and need a decision.\n`));
|
|
330
|
+
resolutions = await (0, prompts_1.promptForConflicts)(conflicts);
|
|
331
|
+
}
|
|
326
332
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
333
|
+
const outcomes = await refreshConfigTree(sourceDir, destDir, baseline, resolutions, force);
|
|
334
|
+
await copyUntrackedTemplateFiles(sourceDir, destDir);
|
|
335
|
+
await copyWorkspaceIgnoreFile(sourceDir, destDir);
|
|
336
|
+
await createMetadata(metadataPath, existingMetadata, recordBaselines(baseline, outcomes));
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Decide and apply one outcome per incoming `config/` path.
|
|
340
|
+
*/
|
|
341
|
+
async function refreshConfigTree(sourceDir, destDir, baseline, resolutions, force) {
|
|
342
|
+
const outcomes = [];
|
|
343
|
+
for (const relativePath of await (0, conflict_detector_1.getConfigFiles)(sourceDir)) {
|
|
344
|
+
const sourcePath = path.join(sourceDir, relativePath);
|
|
345
|
+
const destPath = path.join(destDir, relativePath);
|
|
346
|
+
const outcome = await decideRefreshOutcome(destPath, await (0, metadata_1.calculateFileHash)(sourcePath), baseline[relativePath], resolutions.get(relativePath), force);
|
|
347
|
+
if (outcome.kind !== 'kept' && outcome.kind !== 'unchanged') {
|
|
348
|
+
await fs.copy(sourcePath, destPath, { overwrite: true });
|
|
349
|
+
}
|
|
350
|
+
outcomes.push({ relativePath, ...outcome });
|
|
334
351
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
352
|
+
return outcomes;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Classify one destination against its incoming file and recorded baseline.
|
|
356
|
+
*
|
|
357
|
+
* A destination that diverged from its baseline, or that has no baseline, is
|
|
358
|
+
* replaced only by `force` or an explicit `overwrite` answer; with no answer it
|
|
359
|
+
* is kept, because only the prompt may authorize destroying a file this refresh
|
|
360
|
+
* did not write. A kept destination with no baseline records none.
|
|
361
|
+
*/
|
|
362
|
+
async function decideRefreshOutcome(destPath, incomingHash, recordedHash, resolution, force) {
|
|
363
|
+
if (!(await exists(destPath))) {
|
|
364
|
+
return { kind: 'installed', hash: incomingHash };
|
|
343
365
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
366
|
+
const currentHash = await (0, metadata_1.calculateFileHash)(destPath);
|
|
367
|
+
if (currentHash === incomingHash) {
|
|
368
|
+
return { kind: 'unchanged', hash: incomingHash };
|
|
369
|
+
}
|
|
370
|
+
if (recordedHash !== undefined && currentHash === recordedHash) {
|
|
371
|
+
return { kind: 'refreshed', hash: incomingHash };
|
|
372
|
+
}
|
|
373
|
+
if (force || resolution === 'overwrite' || resolution === 'overwrite-all') {
|
|
374
|
+
return { kind: 'overwritten', hash: incomingHash };
|
|
375
|
+
}
|
|
376
|
+
return { kind: 'kept', hash: recordedHash };
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Build the `files` map from the refresh outcomes.
|
|
380
|
+
*
|
|
381
|
+
* A recorded path the incoming tree no longer ships keeps its recorded hash:
|
|
382
|
+
* the refresh learned nothing new about it, and dropping one that is also gone
|
|
383
|
+
* from disk would erase the deletion `validate` reports. An outcome with no
|
|
384
|
+
* hash records nothing.
|
|
385
|
+
*/
|
|
386
|
+
function recordBaselines(baseline, outcomes) {
|
|
387
|
+
const files = { ...baseline };
|
|
388
|
+
for (const { relativePath, hash } of outcomes) {
|
|
389
|
+
if (hash !== undefined) {
|
|
390
|
+
files[relativePath] = hash;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return files;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Copy the template entries outside `config/`, such as `README.md`, verbatim.
|
|
397
|
+
*
|
|
398
|
+
* Only `config/` is hash-tracked, so these refresh on every run. The ignore
|
|
399
|
+
* template is excluded here because it lands under a different name.
|
|
400
|
+
*/
|
|
401
|
+
async function copyUntrackedTemplateFiles(sourceDir, destDir) {
|
|
402
|
+
await fs.copy(sourceDir, destDir, {
|
|
403
|
+
overwrite: true,
|
|
404
|
+
filter: src => {
|
|
405
|
+
const [first] = path.relative(sourceDir, src).split(path.sep);
|
|
406
|
+
return first !== 'config' && first !== WORKSPACE_IGNORE_TEMPLATE;
|
|
407
|
+
},
|
|
408
|
+
});
|
|
352
409
|
}
|
|
353
410
|
/**
|
|
354
411
|
* Copy the workspace ignore template to its final `.gitignore` name.
|
|
@@ -368,42 +425,10 @@ async function copyWorkspaceIgnoreFile(sourceDir, destDir) {
|
|
|
368
425
|
await fs.copy(source, path.join(destDir, WORKSPACE_IGNORE_FILE), { overwrite: true });
|
|
369
426
|
}
|
|
370
427
|
/**
|
|
371
|
-
*
|
|
428
|
+
* Write the metadata for a completed refresh, carrying provenance and the
|
|
429
|
+
* harness selection forward from the previous metadata.
|
|
372
430
|
*/
|
|
373
|
-
async function createMetadata(
|
|
374
|
-
const existingMetadata = await (0, metadata_1.loadMetadata)(metadataPath);
|
|
375
|
-
const files = {};
|
|
376
|
-
async function walkDir(dir, relativeTo) {
|
|
377
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
378
|
-
for (const entry of entries) {
|
|
379
|
-
const fullPath = path.join(dir, entry.name);
|
|
380
|
-
const relativePath = path.relative(relativeTo, fullPath);
|
|
381
|
-
// Skip README.md (always overwrite on init/re-init)
|
|
382
|
-
if (relativePath === 'README.md') {
|
|
383
|
-
continue;
|
|
384
|
-
}
|
|
385
|
-
// Skip metadata file itself
|
|
386
|
-
if (relativePath === '.init-metadata.json') {
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
if (entry.isDirectory()) {
|
|
390
|
-
await walkDir(fullPath, relativeTo);
|
|
391
|
-
}
|
|
392
|
-
else if (entry.isFile()) {
|
|
393
|
-
// Calculate hash of the destination file (what we just copied)
|
|
394
|
-
const destFilePath = path.join(destDir, relativePath);
|
|
395
|
-
if (await exists(destFilePath)) {
|
|
396
|
-
const hash = await (0, metadata_1.calculateFileHash)(destFilePath);
|
|
397
|
-
files[relativePath] = hash;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
const configDir = path.join(destDir, 'config');
|
|
403
|
-
if (await exists(configDir)) {
|
|
404
|
-
await walkDir(configDir, destDir);
|
|
405
|
-
}
|
|
406
|
-
// Create metadata object
|
|
431
|
+
async function createMetadata(metadataPath, existingMetadata, files) {
|
|
407
432
|
const metadata = {
|
|
408
433
|
version: (0, metadata_1.getPackageVersion)(),
|
|
409
434
|
workspaceSchemaVersion: metadata_1.CURRENT_WORKSPACE_SCHEMA_VERSION,
|
|
@@ -416,22 +441,8 @@ async function createMetadata(sourceDir, destDir, metadataPath) {
|
|
|
416
441
|
if (existingMetadata?.harnesses) {
|
|
417
442
|
metadata.harnesses = existingMetadata.harnesses;
|
|
418
443
|
}
|
|
419
|
-
// Save metadata
|
|
420
444
|
await (0, metadata_1.saveMetadata)(metadataPath, metadata);
|
|
421
445
|
}
|
|
422
|
-
/**
|
|
423
|
-
* Apply user resolutions to file conflicts
|
|
424
|
-
*/
|
|
425
|
-
async function applyResolutions(sourceDir, destDir, resolutions) {
|
|
426
|
-
for (const [relativePath, resolution] of resolutions) {
|
|
427
|
-
const sourcePath = path.join(sourceDir, relativePath);
|
|
428
|
-
const destPath = path.join(destDir, relativePath);
|
|
429
|
-
if (resolution === 'overwrite') {
|
|
430
|
-
await fs.copy(sourcePath, destPath, { overwrite: true });
|
|
431
|
-
}
|
|
432
|
-
// If 'keep', do nothing - keep user's file
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
446
|
/**
|
|
436
447
|
* Check if a directory already has Strikethroo initialized
|
|
437
448
|
*/
|