strikethroo 3.14.2 → 3.15.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 +15 -6
- package/dist/__tests__/fixtures/review-gate.d.ts +59 -0
- package/dist/__tests__/fixtures/review-gate.d.ts.map +1 -0
- package/dist/__tests__/fixtures/review-gate.js +150 -0
- package/dist/__tests__/fixtures/review-gate.js.map +1 -0
- package/dist-web/assets/{arc-3h4SrJcP.js → arc-DXuQKY5O.js} +1 -1
- package/dist-web/assets/{architectureDiagram-3BPJPVTR-CHXVDgZv.js → architectureDiagram-3BPJPVTR-DaQd1Ie5.js} +1 -1
- package/dist-web/assets/{blockDiagram-GPEHLZMM-ByT2aIDh.js → blockDiagram-GPEHLZMM-BTAxxxkx.js} +1 -1
- package/dist-web/assets/{c4Diagram-AAUBKEIU-BpSMEH5T.js → c4Diagram-AAUBKEIU-DHuDwl7F.js} +1 -1
- package/dist-web/assets/channel-CKed0YrQ.js +1 -0
- package/dist-web/assets/{chunk-2J33WTMH-B00rt2rz.js → chunk-2J33WTMH-BD4uHGPG.js} +1 -1
- package/dist-web/assets/{chunk-4BX2VUAB-CUD0iXK7.js → chunk-4BX2VUAB-BqVSB0Q4.js} +1 -1
- package/dist-web/assets/{chunk-55IACEB6-KUROX5a_.js → chunk-55IACEB6-F-aB1oSz.js} +1 -1
- package/dist-web/assets/{chunk-727SXJPM-DdA9k_le.js → chunk-727SXJPM-iIr2R3ax.js} +1 -1
- package/dist-web/assets/{chunk-AQP2D5EJ-B4lS13Tr.js → chunk-AQP2D5EJ-UpIWfDiq.js} +1 -1
- package/dist-web/assets/{chunk-FMBD7UC4-C6DHs6Wv.js → chunk-FMBD7UC4-DeG5uTRD.js} +1 -1
- package/dist-web/assets/{chunk-ND2GUHAM-Nia1N7VP.js → chunk-ND2GUHAM-Tkl5amOh.js} +1 -1
- package/dist-web/assets/{chunk-QZHKN3VN-BKYt-ImO.js → chunk-QZHKN3VN-B3Af5I7v.js} +1 -1
- package/dist-web/assets/classDiagram-4FO5ZUOK-CD2fBLcy.js +1 -0
- package/dist-web/assets/classDiagram-v2-Q7XG4LA2-CD2fBLcy.js +1 -0
- package/dist-web/assets/{cose-bilkent-S5V4N54A-uxuOqDzC.js → cose-bilkent-S5V4N54A-uuts3r-t.js} +1 -1
- package/dist-web/assets/{dagre-BM42HDAG-CUr1pLbj.js → dagre-BM42HDAG-CHrjnY3X.js} +1 -1
- package/dist-web/assets/{diagram-2AECGRRQ-BCeBLzM-.js → diagram-2AECGRRQ-BjEnf2q8.js} +1 -1
- package/dist-web/assets/{diagram-5GNKFQAL-DuM6xmJY.js → diagram-5GNKFQAL-BzvzvRAO.js} +1 -1
- package/dist-web/assets/{diagram-KO2AKTUF-Cf1eoQYh.js → diagram-KO2AKTUF-DNx6lZaA.js} +1 -1
- package/dist-web/assets/{diagram-LMA3HP47-Buo60yAm.js → diagram-LMA3HP47-BQUKKiM4.js} +1 -1
- package/dist-web/assets/{diagram-OG6HWLK6-D54wh40p.js → diagram-OG6HWLK6-MgImJXDh.js} +1 -1
- package/dist-web/assets/{erDiagram-TEJ5UH35-59J8tJG_.js → erDiagram-TEJ5UH35-D79fXG1m.js} +1 -1
- package/dist-web/assets/{flowDiagram-I6XJVG4X-DfDuK7uP.js → flowDiagram-I6XJVG4X-DQDtqM9F.js} +1 -1
- package/dist-web/assets/{ganttDiagram-6RSMTGT7-CbA5p8Mi.js → ganttDiagram-6RSMTGT7-rbAdz41p.js} +1 -1
- package/dist-web/assets/{gitGraphDiagram-PVQCEYII-1WxXLmxX.js → gitGraphDiagram-PVQCEYII-C-ppoVQN.js} +1 -1
- package/dist-web/assets/{index-Cao1t6Aj.js → index-BpEA2dcR.js} +1 -1
- package/dist-web/assets/{index-DHgmc9MH.js → index-COfqZ5qw.js} +4 -4
- package/dist-web/assets/{index-CyyNP5mv.js → index-D8Y-LZu5.js} +1 -1
- package/dist-web/assets/{infoDiagram-5YYISTIA-C5SUQ2SF.js → infoDiagram-5YYISTIA-DVx4rmpa.js} +1 -1
- package/dist-web/assets/{ishikawaDiagram-YF4QCWOH-dU3aWKbh.js → ishikawaDiagram-YF4QCWOH-Bwo2Fe41.js} +1 -1
- package/dist-web/assets/{journeyDiagram-JHISSGLW-CMDkGbgV.js → journeyDiagram-JHISSGLW-Cpk1cbVU.js} +1 -1
- package/dist-web/assets/{kanban-definition-UN3LZRKU-mD1rJCc5.js → kanban-definition-UN3LZRKU-DT5hIyrL.js} +1 -1
- package/dist-web/assets/{linear-CUGnyMnk.js → linear-BHILOJgo.js} +1 -1
- package/dist-web/assets/{mermaid.core-Cpmiqmbf.js → mermaid.core-BYlMWjDD.js} +4 -4
- package/dist-web/assets/{mindmap-definition-RKZ34NQL-CDfl1B-m.js → mindmap-definition-RKZ34NQL-CjhPuIMr.js} +1 -1
- package/dist-web/assets/{pieDiagram-4H26LBE5-Cuo3mXQK.js → pieDiagram-4H26LBE5-BzD5r6aw.js} +1 -1
- package/dist-web/assets/{quadrantDiagram-W4KKPZXB-DnFnsvpl.js → quadrantDiagram-W4KKPZXB-ieE6W8Lz.js} +1 -1
- package/dist-web/assets/{requirementDiagram-4Y6WPE33-DCIMxgro.js → requirementDiagram-4Y6WPE33-B6Z6Nlwn.js} +1 -1
- package/dist-web/assets/{sankeyDiagram-5OEKKPKP-DfxERVIc.js → sankeyDiagram-5OEKKPKP-BAz2Fhdr.js} +1 -1
- package/dist-web/assets/{sequenceDiagram-3UESZ5HK-vKVzidDz.js → sequenceDiagram-3UESZ5HK-Dce-js6I.js} +1 -1
- package/dist-web/assets/{stateDiagram-AJRCARHV-OMYutbra.js → stateDiagram-AJRCARHV-DGx4tUMu.js} +1 -1
- package/dist-web/assets/stateDiagram-v2-BHNVJYJU-kMJLTVIN.js +1 -0
- package/dist-web/assets/{timeline-definition-PNZ67QCA-Ca2z9OPS.js → timeline-definition-PNZ67QCA-B8KWHkBS.js} +1 -1
- package/dist-web/assets/{vennDiagram-CIIHVFJN-DBrJv-N8.js → vennDiagram-CIIHVFJN-ByWUGcRD.js} +1 -1
- package/dist-web/assets/{wardley-L42UT6IY-C80ot0sX.js → wardley-L42UT6IY-C1B0dt0L.js} +1 -1
- package/dist-web/assets/{wardleyDiagram-YWT4CUSO-CzvhVwCG.js → wardleyDiagram-YWT4CUSO-BrCqwemc.js} +1 -1
- package/dist-web/assets/{xychartDiagram-2RQKCTM6-DFrhJySN.js → xychartDiagram-2RQKCTM6-Br_yjZmA.js} +1 -1
- package/dist-web/index.html +1 -1
- package/package.json +1 -1
- package/templates/harness/skills/st-code-review/SKILL.md +309 -0
- package/templates/harness/skills/st-code-review/scripts/code-review.cjs +1539 -0
- package/templates/harness/skills/st-code-review/scripts/find-strikethroo-root.cjs +116 -0
- package/templates/harness/skills/st-code-review/scripts/validate-plan-blueprint.cjs +429 -0
- package/templates/harness/skills/st-execute-blueprint/SKILL.md +49 -2
- package/templates/harness/skills/st-execute-blueprint/scripts/capture-base-commit.cjs +325 -0
- package/templates/harness/skills/st-execute-blueprint/scripts/create-feature-branch.cjs +9 -7
- package/templates/harness/skills/st-execute-blueprint/scripts/dispatch-task-execution.cjs +46 -26
- package/templates/harness/skills/st-execute-task/scripts/dispatch-task-execution.cjs +46 -26
- package/templates/harness/skills/st-full-workflow/SKILL.md +49 -2
- package/templates/harness/skills/st-full-workflow/scripts/capture-base-commit.cjs +325 -0
- package/templates/harness/skills/st-full-workflow/scripts/create-feature-branch.cjs +9 -7
- package/templates/harness/skills/st-full-workflow/scripts/dispatch-task-execution.cjs +46 -26
- package/templates/strikethroo/config/hooks/CODE_REVIEW.md +60 -0
- package/templates/strikethroo/config/schemas/self-review-v2.xsd +437 -0
- package/dist-web/assets/channel-DVGz7-Ij.js +0 -1
- package/dist-web/assets/classDiagram-4FO5ZUOK-BuW_hD8R.js +0 -1
- package/dist-web/assets/classDiagram-v2-Q7XG4LA2-BuW_hD8R.js +0 -1
- package/dist-web/assets/stateDiagram-v2-BHNVJYJU-2bqmqQl-.js +0 -1
package/README.md
CHANGED
|
@@ -109,20 +109,21 @@ flowchart LR
|
|
|
109
109
|
C -->|Approve| D[Tasks]
|
|
110
110
|
D --> E{Verify}
|
|
111
111
|
E --> G[Execute]
|
|
112
|
-
G --> H
|
|
113
|
-
H -->|
|
|
114
|
-
H -->|
|
|
112
|
+
G --> H["Code Review<br/>(optional)"]
|
|
113
|
+
H -->|Fix| G
|
|
114
|
+
H -->|Pass| J[Done]
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
Four steps, three delivered as Agent Skills that load when you describe what you need:
|
|
118
118
|
|
|
119
119
|
| Step | Skill | Output |
|
|
120
120
|
|-------------|---------------------------------|---------------------------------------------------|
|
|
121
121
|
| **Plan** | `/st-create-plan <your prompt>` | `.ai/strikethroo/plans/64--auth/plan-64--auth.md` |
|
|
122
122
|
| **Tasks** | `/st-generate-tasks 64` | `.ai/strikethroo/plans/64--auth/tasks/*.md` |
|
|
123
123
|
| **Execute** | `/st-execute-blueprint 64` | Working code, one commit per phase |
|
|
124
|
+
| **Review** | Automatic (optional) | Findings validated against schema; bounded fixes |
|
|
124
125
|
|
|
125
|
-
Human review gates between steps catch scope creep before any code is written. Each step runs with clean context -- the planning agent sees only the work order, the task agent sees only the approved plan, and each execution sub-agent receives only its specific task.
|
|
126
|
+
Human review gates between steps catch scope creep before any code is written. Each step runs with clean context -- the planning agent sees only the work order, the task agent sees only the approved plan, and each execution sub-agent receives only its specific task. After execution, an optional automated review gate runs on a discovered second harness, critiques the cumulative diff, and drives bounded remediation if findings exceed configured thresholds.
|
|
126
127
|
|
|
127
128
|
See the [Workflow Guide](https://strikethroo.canpicasoft.com/workflow.html) for the full step-by-step with advanced patterns. Once a plan exists, visualize its plans, tasks, and dependency graph in [Visualizations](https://strikethroo.canpicasoft.com/visualizations.html).
|
|
128
129
|
|
|
@@ -139,10 +140,18 @@ This will open a web page that will help you navigate your plans and their tasks
|
|
|
139
140
|
|-------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|
|
|
140
141
|
| [](docs/assets/plans-board.png) | [](docs/assets/plan-detail-graph.png) | [](docs/assets/archive-all.png) |
|
|
141
142
|
|
|
143
|
+
## Optional Code Review Gate
|
|
144
|
+
|
|
145
|
+
After blueprint execution, an optional automated code review gate runs when a second harness is discovered. The reviewer critiques the cumulative diff against the plan's requirements, emits findings validated against a schema, and hands high-confidence findings to the implementer for remediation. Any applied fix forces a full re-run of tests and validation before re-verification.
|
|
146
|
+
|
|
147
|
+
**To disable:** Edit `.ai/strikethroo/config/hooks/CODE_REVIEW.md` to empty or delete it. The gate skips cleanly with a note in the execution summary.
|
|
148
|
+
|
|
149
|
+
**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.
|
|
150
|
+
|
|
142
151
|
## Documentation
|
|
143
152
|
|
|
144
153
|
- [Workflow Guide](https://strikethroo.canpicasoft.com/workflow.html) -- Step-by-step workflow with visual guides
|
|
145
|
-
- [Customization Guide](https://strikethroo.canpicasoft.com/customization.html) -- Hooks, templates, and
|
|
154
|
+
- [Customization Guide](https://strikethroo.canpicasoft.com/customization.html) -- Hooks, templates, project context, and code review configuration
|
|
146
155
|
- [Reference](https://strikethroo.canpicasoft.com/reference.html) -- Glossary and CLI reference
|
|
147
156
|
- [FAQ](https://strikethroo.canpicasoft.com/faq.html) -- Answers to common questions
|
|
148
157
|
- [Visualizations](https://strikethroo.canpicasoft.com/visualizations.html) -- See plans, tasks, and the dependency graph
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared fixture factories for the review-gate test suites
|
|
3
|
+
* (`harness-discovery.test.ts`, `capture-base-commit.integration.test.ts`,
|
|
4
|
+
* `code-review.integration.test.ts`, `review-findings.integration.test.ts`).
|
|
5
|
+
*
|
|
6
|
+
* Two factories: a minimal v4 workspace whose hook/XSD/base-commit presence is
|
|
7
|
+
* independently switchable (so each fail-safe skip reason is one toggle away),
|
|
8
|
+
* and a `<review>` XML builder so partition/validation tests describe findings
|
|
9
|
+
* as data instead of hand-written XML.
|
|
10
|
+
*/
|
|
11
|
+
export declare const REAL_HOOK_CONTENT: string;
|
|
12
|
+
export declare const REAL_XSD_PATH: string;
|
|
13
|
+
/** A syntactically valid placeholder sha — never a real commit, just 40 hex chars. */
|
|
14
|
+
export declare const FAKE_SHA: string;
|
|
15
|
+
export interface ReviewGateWorkspaceOptions {
|
|
16
|
+
/** `'default'` copies the real shipped hook; `'absent'` skips the file; a string is literal content. */
|
|
17
|
+
hook?: 'default' | 'absent' | string;
|
|
18
|
+
/** `'default'` copies the real vendored XSD; `'absent'` skips the file. */
|
|
19
|
+
xsd?: 'default' | 'absent';
|
|
20
|
+
/** A 40-hex sha to record, or `'absent'` to skip writing base-commit.json. */
|
|
21
|
+
baseCommit?: string | 'absent';
|
|
22
|
+
planId?: number;
|
|
23
|
+
planSlug?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ReviewGateWorkspace {
|
|
26
|
+
/** The temporary project root — the directory a real `git init` would run in. */
|
|
27
|
+
root: string;
|
|
28
|
+
strikethrooRoot: string;
|
|
29
|
+
planDir: string;
|
|
30
|
+
planFile: string;
|
|
31
|
+
hookFile: string;
|
|
32
|
+
xsdFile: string;
|
|
33
|
+
baseCommitFile: string;
|
|
34
|
+
cleanup: () => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Builds `<root>/.ai/strikethroo/...` with a v4 `.init-metadata.json`, one plan
|
|
38
|
+
* directory with a valid frontmatter, and switchable hook/XSD/base-commit
|
|
39
|
+
* presence — every input the review gate's fail-safe skip ladder depends on.
|
|
40
|
+
*/
|
|
41
|
+
export declare const makeReviewGateWorkspace: (options?: ReviewGateWorkspaceOptions) => ReviewGateWorkspace;
|
|
42
|
+
export interface FindingSpec {
|
|
43
|
+
file: string;
|
|
44
|
+
severity?: string;
|
|
45
|
+
confidence?: string;
|
|
46
|
+
hasSuggestion?: boolean;
|
|
47
|
+
category?: string;
|
|
48
|
+
body?: string;
|
|
49
|
+
/** Verbatim XML to splice in place of the generated <body>/<category>/<suggestion> — for malformed-content cases (CDATA, escaped markup). */
|
|
50
|
+
rawInner?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Renders a schema-shaped `<review>` document from finding descriptions, one
|
|
54
|
+
* `<file>` per distinct `file` value (in first-seen order). Kept intentionally
|
|
55
|
+
* simple string concatenation — the documents under test are small and the
|
|
56
|
+
* point is to describe findings as data, not to build a general XML writer.
|
|
57
|
+
*/
|
|
58
|
+
export declare const buildReviewXml: (findings: readonly FindingSpec[], timestamp?: string) => string;
|
|
59
|
+
//# sourceMappingURL=review-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-gate.d.ts","sourceRoot":"","sources":["../../../src/__tests__/fixtures/review-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAyBH,eAAO,MAAM,iBAAiB,QAA4C,CAAC;AAC3E,eAAO,MAAM,aAAa,QAAkB,CAAC;AAE7C,sFAAsF;AACtF,eAAO,MAAM,QAAQ,QAAiB,CAAC;AAEvC,MAAM,WAAW,0BAA0B;IACzC,wGAAwG;IACxG,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,2EAA2E;IAC3E,GAAG,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAClC,UAAS,0BAA+B,KACvC,mBA4DF,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6IAA6I;IAC7I,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GACzB,UAAU,SAAS,WAAW,EAAE,EAChC,kBAAkC,KACjC,MAuCF,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared fixture factories for the review-gate test suites
|
|
4
|
+
* (`harness-discovery.test.ts`, `capture-base-commit.integration.test.ts`,
|
|
5
|
+
* `code-review.integration.test.ts`, `review-findings.integration.test.ts`).
|
|
6
|
+
*
|
|
7
|
+
* Two factories: a minimal v4 workspace whose hook/XSD/base-commit presence is
|
|
8
|
+
* independently switchable (so each fail-safe skip reason is one toggle away),
|
|
9
|
+
* and a `<review>` XML builder so partition/validation tests describe findings
|
|
10
|
+
* as data instead of hand-written XML.
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.buildReviewXml = exports.makeReviewGateWorkspace = exports.FAKE_SHA = exports.REAL_XSD_PATH = exports.REAL_HOOK_CONTENT = void 0;
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const os = __importStar(require("os"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const metadata_1 = require("../../metadata");
|
|
51
|
+
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..');
|
|
52
|
+
const REAL_XSD_SOURCE = path.join(REPO_ROOT, 'templates', 'strikethroo', 'config', 'schemas', 'self-review-v2.xsd');
|
|
53
|
+
const REAL_HOOK_SOURCE = path.join(REPO_ROOT, 'templates', 'strikethroo', 'config', 'hooks', 'CODE_REVIEW.md');
|
|
54
|
+
exports.REAL_HOOK_CONTENT = fs.readFileSync(REAL_HOOK_SOURCE, 'utf8');
|
|
55
|
+
exports.REAL_XSD_PATH = REAL_XSD_SOURCE;
|
|
56
|
+
/** A syntactically valid placeholder sha — never a real commit, just 40 hex chars. */
|
|
57
|
+
exports.FAKE_SHA = 'a'.repeat(40);
|
|
58
|
+
/**
|
|
59
|
+
* Builds `<root>/.ai/strikethroo/...` with a v4 `.init-metadata.json`, one plan
|
|
60
|
+
* directory with a valid frontmatter, and switchable hook/XSD/base-commit
|
|
61
|
+
* presence — every input the review gate's fail-safe skip ladder depends on.
|
|
62
|
+
*/
|
|
63
|
+
const makeReviewGateWorkspace = (options = {}) => {
|
|
64
|
+
const planId = options.planId ?? 1;
|
|
65
|
+
const planSlug = options.planSlug ?? 'demo';
|
|
66
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'strikethroo-review-gate-'));
|
|
67
|
+
const strikethrooRoot = path.join(root, '.ai', 'strikethroo');
|
|
68
|
+
const planDir = path.join(strikethrooRoot, 'plans', `${planId}--${planSlug}`);
|
|
69
|
+
fs.mkdirSync(planDir, { recursive: true });
|
|
70
|
+
fs.mkdirSync(path.join(strikethrooRoot, 'config', 'hooks'), { recursive: true });
|
|
71
|
+
fs.mkdirSync(path.join(strikethrooRoot, 'config', 'schemas'), { recursive: true });
|
|
72
|
+
fs.writeFileSync(path.join(strikethrooRoot, '.init-metadata.json'), JSON.stringify({
|
|
73
|
+
version: 'test',
|
|
74
|
+
workspaceSchemaVersion: metadata_1.CURRENT_WORKSPACE_SCHEMA_VERSION,
|
|
75
|
+
timestamp: new Date().toISOString(),
|
|
76
|
+
files: {},
|
|
77
|
+
}));
|
|
78
|
+
const planFile = path.join(planDir, `plan-${planId}--${planSlug}.md`);
|
|
79
|
+
fs.writeFileSync(planFile, `---\nid: ${planId}\nsummary: "fixture"\ncreated: 2026-01-01\n---\nbody\n`);
|
|
80
|
+
const hookFile = path.join(strikethrooRoot, 'config', 'hooks', 'CODE_REVIEW.md');
|
|
81
|
+
const hook = options.hook ?? 'default';
|
|
82
|
+
if (hook !== 'absent') {
|
|
83
|
+
fs.writeFileSync(hookFile, hook === 'default' ? exports.REAL_HOOK_CONTENT : hook);
|
|
84
|
+
}
|
|
85
|
+
const xsdFile = path.join(strikethrooRoot, 'config', 'schemas', 'self-review-v2.xsd');
|
|
86
|
+
if ((options.xsd ?? 'default') !== 'absent') {
|
|
87
|
+
fs.copyFileSync(REAL_XSD_SOURCE, xsdFile);
|
|
88
|
+
}
|
|
89
|
+
const baseCommitFile = path.join(planDir, 'review', 'base-commit.json');
|
|
90
|
+
if (options.baseCommit !== undefined && options.baseCommit !== 'absent') {
|
|
91
|
+
fs.mkdirSync(path.dirname(baseCommitFile), { recursive: true });
|
|
92
|
+
fs.writeFileSync(baseCommitFile, `${JSON.stringify({
|
|
93
|
+
version: 1,
|
|
94
|
+
baseCommit: options.baseCommit,
|
|
95
|
+
capturedAt: new Date().toISOString(),
|
|
96
|
+
})}\n`);
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
root,
|
|
100
|
+
strikethrooRoot,
|
|
101
|
+
planDir,
|
|
102
|
+
planFile,
|
|
103
|
+
hookFile,
|
|
104
|
+
xsdFile,
|
|
105
|
+
baseCommitFile,
|
|
106
|
+
cleanup: () => fs.rmSync(root, { recursive: true, force: true }),
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
exports.makeReviewGateWorkspace = makeReviewGateWorkspace;
|
|
110
|
+
/**
|
|
111
|
+
* Renders a schema-shaped `<review>` document from finding descriptions, one
|
|
112
|
+
* `<file>` per distinct `file` value (in first-seen order). Kept intentionally
|
|
113
|
+
* simple string concatenation — the documents under test are small and the
|
|
114
|
+
* point is to describe findings as data, not to build a general XML writer.
|
|
115
|
+
*/
|
|
116
|
+
const buildReviewXml = (findings, timestamp = '2026-01-01T00:00:00Z') => {
|
|
117
|
+
const order = [];
|
|
118
|
+
const byFile = new Map();
|
|
119
|
+
for (const finding of findings) {
|
|
120
|
+
if (!byFile.has(finding.file)) {
|
|
121
|
+
byFile.set(finding.file, []);
|
|
122
|
+
order.push(finding.file);
|
|
123
|
+
}
|
|
124
|
+
byFile.get(finding.file).push(finding);
|
|
125
|
+
}
|
|
126
|
+
const filesXml = order
|
|
127
|
+
.map(file => {
|
|
128
|
+
const comments = byFile
|
|
129
|
+
.get(file)
|
|
130
|
+
.map(finding => {
|
|
131
|
+
const attrs = (finding.severity ? ` severity="${finding.severity}"` : '') +
|
|
132
|
+
(finding.confidence ? ` confidence="${finding.confidence}"` : '');
|
|
133
|
+
if (finding.rawInner !== undefined) {
|
|
134
|
+
return `<comment${attrs}>${finding.rawInner}</comment>`;
|
|
135
|
+
}
|
|
136
|
+
const suggestion = finding.hasSuggestion
|
|
137
|
+
? '<suggestion><original-code>old</original-code><proposed-code>new</proposed-code></suggestion>'
|
|
138
|
+
: '';
|
|
139
|
+
return (`<comment${attrs}><body>${finding.body ?? 'A finding.'}</body>` +
|
|
140
|
+
`<category>${finding.category ?? 'bug'}</category>${suggestion}</comment>`);
|
|
141
|
+
})
|
|
142
|
+
.join('');
|
|
143
|
+
return `<file path="${file}" change-type="modified" viewed="true">${comments}</file>`;
|
|
144
|
+
})
|
|
145
|
+
.join('');
|
|
146
|
+
return ('<?xml version="1.0" encoding="UTF-8"?>\n' +
|
|
147
|
+
`<review xmlns="urn:self-review:v2" timestamp="${timestamp}">${filesXml}</review>\n`);
|
|
148
|
+
};
|
|
149
|
+
exports.buildReviewXml = buildReviewXml;
|
|
150
|
+
//# sourceMappingURL=review-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-gate.js","sourceRoot":"","sources":["../../../src/__tests__/fixtures/review-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{bk as ln,aN as an,H as k,b7 as w,F as N,ag as un,V as g,bc as tn,b8 as C,aH as _,c as rn,m as o,aF as on,j as sn,d as fn}from"./mermaid.core-
|
|
1
|
+
import{bk as ln,aN as an,H as k,b7 as w,F as N,ag as un,V as g,bc as tn,b8 as C,aH as _,c as rn,m as o,aF as on,j as sn,d as fn}from"./mermaid.core-BYlMWjDD.js";function cn(l){return l.innerRadius}function gn(l){return l.outerRadius}function yn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,j,F,v,A,O,a){var q=j-l,i=F-h,n=O-v,d=a-A,u=d*q-n*i;if(!(u*u<g))return u=(n*(h-A)-d*(l-v))/u,[l+u*q,h+u*i]}function Q(l,h,j,F,v,A,O){var a=l-j,q=h-F,i=(O?A:-A)/C(a*a+q*q),n=i*q,d=-i*a,u=l+n,s=h+d,f=j+n,c=F+d,S=(u+f)/2,t=(s+c)/2,m=f-u,y=c-s,R=m*m+y*y,T=v-A,P=u*c-f*s,D=(y<0?-1:1)*C(on(0,T*T*R-P*P)),E=(P*y-m*D)/R,I=(-P*m-y*D)/R,b=(P*y+m*D)/R,p=(-P*m+y*D)/R,x=E-S,e=I-t,r=b-S,V=p-t;return x*x+e*e>r*r+V*V&&(E=b,I=p),{cx:E,cy:I,x01:-n,y01:-d,x11:E*(v/T-1),y11:I*(v/T-1)}}function hn(){var l=cn,h=gn,j=N(0),F=null,v=yn,A=dn,O=mn,a=null,q=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,S=rn(c-f),t=c>f;if(a||(a=n=q()),s<u&&(d=s,s=u,u=d),!(s>g))a.moveTo(0,0);else if(S>tn-g)a.moveTo(s*k(f),s*w(f)),a.arc(0,0,s,f,c,!t),u>g&&(a.moveTo(u*k(c),u*w(c)),a.arc(0,0,u,c,f,t));else{var m=f,y=c,R=f,T=c,P=S,D=S,E=O.apply(this,arguments)/2,I=E>g&&(F?+F.apply(this,arguments):C(u*u+s*s)),b=_(rn(s-u)/2,+j.apply(this,arguments)),p=b,x=b,e,r;if(I>g){var V=sn(I/u*w(E)),G=sn(I/s*w(E));(P-=V*2)>g?(V*=t?1:-1,R+=V,T-=V):(P=0,R=T=(f+c)/2),(D-=G*2)>g?(G*=t?1:-1,m+=G,y-=G):(D=0,m=y=(f+c)/2)}var z=s*k(m),B=s*w(m),J=u*k(T),K=u*w(T);if(b>g){var L=s*k(y),M=s*w(y),U=u*k(R),W=u*w(R),H;if(S<an)if(H=pn(z,B,U,W,L,M,J,K)){var X=z-H[0],Y=B-H[1],Z=L-H[0],$=M-H[1],nn=1/w(fn((X*Z+Y*$)/(C(X*X+Y*Y)*C(Z*Z+$*$)))/2),en=C(H[0]*H[0]+H[1]*H[1]);p=_(b,(u-en)/(nn-1)),x=_(b,(s-en)/(nn+1))}else p=x=0}D>g?x>g?(e=Q(U,W,z,B,s,x,t),r=Q(L,M,J,K,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<b?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(z,B),a.arc(0,0,s,m,y,!t)):a.moveTo(z,B),!(u>g)||!(P>g)?a.lineTo(J,K):p>g?(e=Q(J,K,L,M,u,-p,t),r=Q(z,B,U,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<b?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[k(d)*n,w(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:N(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:N(+n),i):h},i.cornerRadius=function(n){return arguments.length?(j=typeof n=="function"?n:N(+n),i):j},i.padRadius=function(n){return arguments.length?(F=n==null?null:typeof n=="function"?n:N(+n),i):F},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:N(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:N(+n),i):A},i.padAngle=function(n){return arguments.length?(O=typeof n=="function"?n:N(+n),i):O},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|