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.
Files changed (74) hide show
  1. package/README.md +15 -6
  2. package/dist/__tests__/fixtures/review-gate.d.ts +59 -0
  3. package/dist/__tests__/fixtures/review-gate.d.ts.map +1 -0
  4. package/dist/__tests__/fixtures/review-gate.js +150 -0
  5. package/dist/__tests__/fixtures/review-gate.js.map +1 -0
  6. package/dist-web/assets/{arc-3h4SrJcP.js → arc-DXuQKY5O.js} +1 -1
  7. package/dist-web/assets/{architectureDiagram-3BPJPVTR-CHXVDgZv.js → architectureDiagram-3BPJPVTR-DaQd1Ie5.js} +1 -1
  8. package/dist-web/assets/{blockDiagram-GPEHLZMM-ByT2aIDh.js → blockDiagram-GPEHLZMM-BTAxxxkx.js} +1 -1
  9. package/dist-web/assets/{c4Diagram-AAUBKEIU-BpSMEH5T.js → c4Diagram-AAUBKEIU-DHuDwl7F.js} +1 -1
  10. package/dist-web/assets/channel-CKed0YrQ.js +1 -0
  11. package/dist-web/assets/{chunk-2J33WTMH-B00rt2rz.js → chunk-2J33WTMH-BD4uHGPG.js} +1 -1
  12. package/dist-web/assets/{chunk-4BX2VUAB-CUD0iXK7.js → chunk-4BX2VUAB-BqVSB0Q4.js} +1 -1
  13. package/dist-web/assets/{chunk-55IACEB6-KUROX5a_.js → chunk-55IACEB6-F-aB1oSz.js} +1 -1
  14. package/dist-web/assets/{chunk-727SXJPM-DdA9k_le.js → chunk-727SXJPM-iIr2R3ax.js} +1 -1
  15. package/dist-web/assets/{chunk-AQP2D5EJ-B4lS13Tr.js → chunk-AQP2D5EJ-UpIWfDiq.js} +1 -1
  16. package/dist-web/assets/{chunk-FMBD7UC4-C6DHs6Wv.js → chunk-FMBD7UC4-DeG5uTRD.js} +1 -1
  17. package/dist-web/assets/{chunk-ND2GUHAM-Nia1N7VP.js → chunk-ND2GUHAM-Tkl5amOh.js} +1 -1
  18. package/dist-web/assets/{chunk-QZHKN3VN-BKYt-ImO.js → chunk-QZHKN3VN-B3Af5I7v.js} +1 -1
  19. package/dist-web/assets/classDiagram-4FO5ZUOK-CD2fBLcy.js +1 -0
  20. package/dist-web/assets/classDiagram-v2-Q7XG4LA2-CD2fBLcy.js +1 -0
  21. package/dist-web/assets/{cose-bilkent-S5V4N54A-uxuOqDzC.js → cose-bilkent-S5V4N54A-uuts3r-t.js} +1 -1
  22. package/dist-web/assets/{dagre-BM42HDAG-CUr1pLbj.js → dagre-BM42HDAG-CHrjnY3X.js} +1 -1
  23. package/dist-web/assets/{diagram-2AECGRRQ-BCeBLzM-.js → diagram-2AECGRRQ-BjEnf2q8.js} +1 -1
  24. package/dist-web/assets/{diagram-5GNKFQAL-DuM6xmJY.js → diagram-5GNKFQAL-BzvzvRAO.js} +1 -1
  25. package/dist-web/assets/{diagram-KO2AKTUF-Cf1eoQYh.js → diagram-KO2AKTUF-DNx6lZaA.js} +1 -1
  26. package/dist-web/assets/{diagram-LMA3HP47-Buo60yAm.js → diagram-LMA3HP47-BQUKKiM4.js} +1 -1
  27. package/dist-web/assets/{diagram-OG6HWLK6-D54wh40p.js → diagram-OG6HWLK6-MgImJXDh.js} +1 -1
  28. package/dist-web/assets/{erDiagram-TEJ5UH35-59J8tJG_.js → erDiagram-TEJ5UH35-D79fXG1m.js} +1 -1
  29. package/dist-web/assets/{flowDiagram-I6XJVG4X-DfDuK7uP.js → flowDiagram-I6XJVG4X-DQDtqM9F.js} +1 -1
  30. package/dist-web/assets/{ganttDiagram-6RSMTGT7-CbA5p8Mi.js → ganttDiagram-6RSMTGT7-rbAdz41p.js} +1 -1
  31. package/dist-web/assets/{gitGraphDiagram-PVQCEYII-1WxXLmxX.js → gitGraphDiagram-PVQCEYII-C-ppoVQN.js} +1 -1
  32. package/dist-web/assets/{index-Cao1t6Aj.js → index-BpEA2dcR.js} +1 -1
  33. package/dist-web/assets/{index-DHgmc9MH.js → index-COfqZ5qw.js} +4 -4
  34. package/dist-web/assets/{index-CyyNP5mv.js → index-D8Y-LZu5.js} +1 -1
  35. package/dist-web/assets/{infoDiagram-5YYISTIA-C5SUQ2SF.js → infoDiagram-5YYISTIA-DVx4rmpa.js} +1 -1
  36. package/dist-web/assets/{ishikawaDiagram-YF4QCWOH-dU3aWKbh.js → ishikawaDiagram-YF4QCWOH-Bwo2Fe41.js} +1 -1
  37. package/dist-web/assets/{journeyDiagram-JHISSGLW-CMDkGbgV.js → journeyDiagram-JHISSGLW-Cpk1cbVU.js} +1 -1
  38. package/dist-web/assets/{kanban-definition-UN3LZRKU-mD1rJCc5.js → kanban-definition-UN3LZRKU-DT5hIyrL.js} +1 -1
  39. package/dist-web/assets/{linear-CUGnyMnk.js → linear-BHILOJgo.js} +1 -1
  40. package/dist-web/assets/{mermaid.core-Cpmiqmbf.js → mermaid.core-BYlMWjDD.js} +4 -4
  41. package/dist-web/assets/{mindmap-definition-RKZ34NQL-CDfl1B-m.js → mindmap-definition-RKZ34NQL-CjhPuIMr.js} +1 -1
  42. package/dist-web/assets/{pieDiagram-4H26LBE5-Cuo3mXQK.js → pieDiagram-4H26LBE5-BzD5r6aw.js} +1 -1
  43. package/dist-web/assets/{quadrantDiagram-W4KKPZXB-DnFnsvpl.js → quadrantDiagram-W4KKPZXB-ieE6W8Lz.js} +1 -1
  44. package/dist-web/assets/{requirementDiagram-4Y6WPE33-DCIMxgro.js → requirementDiagram-4Y6WPE33-B6Z6Nlwn.js} +1 -1
  45. package/dist-web/assets/{sankeyDiagram-5OEKKPKP-DfxERVIc.js → sankeyDiagram-5OEKKPKP-BAz2Fhdr.js} +1 -1
  46. package/dist-web/assets/{sequenceDiagram-3UESZ5HK-vKVzidDz.js → sequenceDiagram-3UESZ5HK-Dce-js6I.js} +1 -1
  47. package/dist-web/assets/{stateDiagram-AJRCARHV-OMYutbra.js → stateDiagram-AJRCARHV-DGx4tUMu.js} +1 -1
  48. package/dist-web/assets/stateDiagram-v2-BHNVJYJU-kMJLTVIN.js +1 -0
  49. package/dist-web/assets/{timeline-definition-PNZ67QCA-Ca2z9OPS.js → timeline-definition-PNZ67QCA-B8KWHkBS.js} +1 -1
  50. package/dist-web/assets/{vennDiagram-CIIHVFJN-DBrJv-N8.js → vennDiagram-CIIHVFJN-ByWUGcRD.js} +1 -1
  51. package/dist-web/assets/{wardley-L42UT6IY-C80ot0sX.js → wardley-L42UT6IY-C1B0dt0L.js} +1 -1
  52. package/dist-web/assets/{wardleyDiagram-YWT4CUSO-CzvhVwCG.js → wardleyDiagram-YWT4CUSO-BrCqwemc.js} +1 -1
  53. package/dist-web/assets/{xychartDiagram-2RQKCTM6-DFrhJySN.js → xychartDiagram-2RQKCTM6-Br_yjZmA.js} +1 -1
  54. package/dist-web/index.html +1 -1
  55. package/package.json +1 -1
  56. package/templates/harness/skills/st-code-review/SKILL.md +309 -0
  57. package/templates/harness/skills/st-code-review/scripts/code-review.cjs +1539 -0
  58. package/templates/harness/skills/st-code-review/scripts/find-strikethroo-root.cjs +116 -0
  59. package/templates/harness/skills/st-code-review/scripts/validate-plan-blueprint.cjs +429 -0
  60. package/templates/harness/skills/st-execute-blueprint/SKILL.md +49 -2
  61. package/templates/harness/skills/st-execute-blueprint/scripts/capture-base-commit.cjs +325 -0
  62. package/templates/harness/skills/st-execute-blueprint/scripts/create-feature-branch.cjs +9 -7
  63. package/templates/harness/skills/st-execute-blueprint/scripts/dispatch-task-execution.cjs +46 -26
  64. package/templates/harness/skills/st-execute-task/scripts/dispatch-task-execution.cjs +46 -26
  65. package/templates/harness/skills/st-full-workflow/SKILL.md +49 -2
  66. package/templates/harness/skills/st-full-workflow/scripts/capture-base-commit.cjs +325 -0
  67. package/templates/harness/skills/st-full-workflow/scripts/create-feature-branch.cjs +9 -7
  68. package/templates/harness/skills/st-full-workflow/scripts/dispatch-task-execution.cjs +46 -26
  69. package/templates/strikethroo/config/hooks/CODE_REVIEW.md +60 -0
  70. package/templates/strikethroo/config/schemas/self-review-v2.xsd +437 -0
  71. package/dist-web/assets/channel-DVGz7-Ij.js +0 -1
  72. package/dist-web/assets/classDiagram-4FO5ZUOK-BuW_hD8R.js +0 -1
  73. package/dist-web/assets/classDiagram-v2-Q7XG4LA2-BuW_hD8R.js +0 -1
  74. package/dist-web/assets/stateDiagram-v2-BHNVJYJU-2bqmqQl-.js +0 -1
@@ -3654,8 +3654,9 @@ var command = (executable, argv, request) => ({
3654
3654
  executable,
3655
3655
  argv,
3656
3656
  cwd: request.workspace,
3657
- stdin: taskPrompt(request)
3657
+ stdin: request.prompt
3658
3658
  });
3659
+ var modelArgv = (model) => model === void 0 ? [] : ["--model", model];
3659
3660
  var EXTERNAL_HARNESS_ADAPTERS = {
3660
3661
  claude: {
3661
3662
  executable: "claude",
@@ -3663,8 +3664,7 @@ var EXTERNAL_HARNESS_ADAPTERS = {
3663
3664
  "claude",
3664
3665
  [
3665
3666
  "-p",
3666
- "--model",
3667
- request.model,
3667
+ ...modelArgv(request.model),
3668
3668
  ...request.reasoningEffort === void 0 ? [] : ["--effort", request.reasoningEffort]
3669
3669
  ],
3670
3670
  request
@@ -3677,8 +3677,7 @@ var EXTERNAL_HARNESS_ADAPTERS = {
3677
3677
  "codex",
3678
3678
  [
3679
3679
  "exec",
3680
- "--model",
3681
- request.model,
3680
+ ...modelArgv(request.model),
3682
3681
  ...request.reasoningEffort === void 0 ? [] : ["--config", `model_reasoning_effort=${request.reasoningEffort}`],
3683
3682
  "-"
3684
3683
  ],
@@ -3688,17 +3687,19 @@ var EXTERNAL_HARNESS_ADAPTERS = {
3688
3687
  },
3689
3688
  cursor: {
3690
3689
  executable: "cursor-agent",
3691
- buildCommand: (request) => command("cursor-agent", ["--print", "--model", request.model], request),
3690
+ buildCommand: (request) => command("cursor-agent", ["--print", ...modelArgv(request.model)], request),
3692
3691
  authenticationArgv: () => ["status"]
3693
3692
  },
3694
3693
  gemini: {
3695
3694
  executable: "gemini",
3696
- buildCommand: (request) => command("gemini", ["--prompt", "", "--model", request.model], request),
3695
+ // The empty positional prompt is the existing contract — content travels on
3696
+ // stdin. It stays even when the model pair is dropped.
3697
+ buildCommand: (request) => command("gemini", ["--prompt", "", ...modelArgv(request.model)], request),
3697
3698
  authenticationArgv: () => ["auth", "status"]
3698
3699
  },
3699
3700
  copilot: {
3700
3701
  executable: "copilot",
3701
- buildCommand: (request) => command("copilot", ["-p", "", "--model", request.model], request),
3702
+ buildCommand: (request) => command("copilot", ["-p", "", ...modelArgv(request.model)], request),
3702
3703
  authenticationArgv: () => ["auth", "status"]
3703
3704
  },
3704
3705
  opencode: {
@@ -3707,8 +3708,7 @@ var EXTERNAL_HARNESS_ADAPTERS = {
3707
3708
  "opencode",
3708
3709
  [
3709
3710
  "run",
3710
- "--model",
3711
- request.model,
3711
+ ...modelArgv(request.model),
3712
3712
  ...request.reasoningEffort === void 0 ? [] : ["--variant", request.reasoningEffort],
3713
3713
  "-"
3714
3714
  ],
@@ -3722,6 +3722,12 @@ var harnessKeys = [...SUPPORTED_HARNESSES].sort();
3722
3722
  if (adapterKeys.join("\0") !== harnessKeys.join("\0")) {
3723
3723
  throw new Error("External harness adapter registry does not cover SUPPORTED_HARNESSES exactly.");
3724
3724
  }
3725
+ var taskCommandRequest = (request) => ({
3726
+ model: request.model,
3727
+ reasoningEffort: request.reasoningEffort,
3728
+ workspace: request.workspace,
3729
+ prompt: taskPrompt(request)
3730
+ });
3725
3731
  var executableOnPath = (executable) => (process.env.PATH ?? "").split(path2.delimiter).some((directory) => {
3726
3732
  if (!directory) return false;
3727
3733
  const candidate = path2.join(directory, executable);
@@ -3782,23 +3788,17 @@ var dependencies = {
3782
3788
  launch: (commandSpec) => runProcess(commandSpec.executable, commandSpec.argv, commandSpec.cwd, commandSpec.stdin, true)
3783
3789
  };
3784
3790
  var errorMessage = (error) => error instanceof Error ? error.message : String(error);
3785
- var dispatchExternalTask = async (request, overrides = {}) => {
3786
- const adapter = EXTERNAL_HARNESS_ADAPTERS[request.harness];
3791
+ var prepareLaunch = async (harness, input, active, guard) => {
3792
+ const adapter = EXTERNAL_HARNESS_ADAPTERS[harness];
3787
3793
  if (!adapter) {
3788
3794
  return {
3789
3795
  kind: "fallback",
3790
3796
  reason: "adapter-unavailable",
3791
- detail: `No adapter is registered for ${request.harness}.`
3792
- };
3793
- }
3794
- const active = { ...dependencies, ...overrides };
3795
- if (request.reasoningEffort !== void 0 && (request.harness === "cursor" || request.harness === "gemini" || request.harness === "copilot")) {
3796
- return {
3797
- kind: "fallback",
3798
- reason: "unsupported-reasoning-effort",
3799
- detail: `${request.harness} does not support a generic reasoning_effort override.`
3797
+ detail: `No adapter is registered for ${harness}.`
3800
3798
  };
3801
3799
  }
3800
+ const blocked = guard?.();
3801
+ if (blocked) return blocked;
3802
3802
  if (!active.executableExists(adapter.executable)) {
3803
3803
  return {
3804
3804
  kind: "fallback",
@@ -3806,7 +3806,7 @@ var dispatchExternalTask = async (request, overrides = {}) => {
3806
3806
  detail: `${adapter.executable} is unavailable.`
3807
3807
  };
3808
3808
  }
3809
- const commandSpec = adapter.buildCommand(request);
3809
+ const commandSpec = adapter.buildCommand(input);
3810
3810
  const authentication = await active.authenticate(commandSpec, adapter);
3811
3811
  if (!authentication.ok) {
3812
3812
  return {
@@ -3815,16 +3815,35 @@ var dispatchExternalTask = async (request, overrides = {}) => {
3815
3815
  detail: authentication.detail ?? `${adapter.executable} authentication check failed.`
3816
3816
  };
3817
3817
  }
3818
+ return { kind: "ready", command: commandSpec };
3819
+ };
3820
+ var launchPrepared = async (prepared, active, label) => {
3821
+ if (prepared.kind === "fallback") return prepared;
3818
3822
  try {
3819
- const launched = await active.launch(commandSpec);
3823
+ const launched = await active.launch(prepared.command);
3820
3824
  return launched.exitCode === 0 ? { kind: "launched-success", exitCode: 0 } : { kind: "launched-failure", exitCode: launched.exitCode };
3821
3825
  } catch (error) {
3822
3826
  return {
3823
3827
  kind: "infrastructure-failure",
3824
- detail: `External task process failed: ${errorMessage(error)}`
3828
+ detail: `External ${label} process failed: ${errorMessage(error)}`
3825
3829
  };
3826
3830
  }
3827
3831
  };
3832
+ var unsupportedReasoningEffort = (request) => request.reasoningEffort !== void 0 && (request.harness === "cursor" || request.harness === "gemini" || request.harness === "copilot") ? {
3833
+ kind: "fallback",
3834
+ reason: "unsupported-reasoning-effort",
3835
+ detail: `${request.harness} does not support a generic reasoning_effort override.`
3836
+ } : void 0;
3837
+ var dispatchExternalTask = async (request, overrides = {}) => {
3838
+ const active = { ...dependencies, ...overrides };
3839
+ const prepared = await prepareLaunch(
3840
+ request.harness,
3841
+ taskCommandRequest(request),
3842
+ active,
3843
+ () => unsupportedReasoningEffort(request)
3844
+ );
3845
+ return launchPrepared(prepared, active, "task");
3846
+ };
3828
3847
 
3829
3848
  // src/skill-scripts/shared/harness-availability.ts
3830
3849
  var fs2 = __toESM(require("fs"));
@@ -6509,7 +6528,7 @@ var main = async () => {
6509
6528
  );
6510
6529
  }
6511
6530
  const handoff = decodeHandoff(handoffArg);
6512
- const result = await dispatchExternalTask({
6531
+ const routed = {
6513
6532
  harness: handoff.harness,
6514
6533
  model: handoff.model,
6515
6534
  ...handoff.reasoningEffort === void 0 ? {} : { reasoningEffort: handoff.reasoningEffort },
@@ -6518,7 +6537,8 @@ var main = async () => {
6518
6537
  taskId: validTaskId,
6519
6538
  taskFile: taskPath,
6520
6539
  taskMarkdown
6521
- });
6540
+ };
6541
+ const result = await dispatchExternalTask(routed);
6522
6542
  emit(
6523
6543
  result,
6524
6544
  result.kind === "infrastructure-failure" ? 2 : result.kind === "launched-failure" ? 1 : 0
@@ -0,0 +1,60 @@
1
+ # CODE_REVIEW Hook
2
+
3
+ ## Automated Code Review Gate
4
+
5
+ This hook governs an unattended review loop that runs at the end of blueprint execution, after mechanical gates (lint, tests, Self Validation) report success. A reviewer on a discovered external harness critiques the plan's cumulative diff and emits findings; findings at or above the severity and confidence floors trigger automatic remediation, followed by a full re-run of the mechanical gates and re-verification.
6
+
7
+ The gate terminates on exhausted round budget or when no findings above threshold remain.
8
+
9
+ ## Mandate: Conformance and Defects Only
10
+
11
+ The reviewer checks the diff against the **plan's stated requirements** and for **demonstrable defects**. It does **not** raise general code-quality opinions, style notes, design critiques, or taste judgments — the linter owns style. Every finding must cite concrete evidence and trace to:
12
+
13
+ - An explicit requirement stated in the plan, **or**
14
+ - A demonstrable defect in the code as written
15
+
16
+ Anything else is out of scope and must not be included in findings.
17
+
18
+ ## Finding Categories In Scope
19
+
20
+ - **Requirement conformance** — the code does not implement what the plan explicitly asked for
21
+ - **Demonstrable defects** — the code fails at runtime, produces wrong behaviour, violates a contract it declares, has a security hole, causes data loss, or breaks something else in the plan
22
+
23
+ ## Severity Floor: `major`
24
+
25
+ Findings below `major` are recorded in the review output but never auto-applied. The severity levels, ordered from most to least consequential:
26
+
27
+ - `critical` — causes data loss, security hole, crash, or corruption on a path real usage reaches
28
+ - `major` — produces wrong behaviour or breaks a documented contract; nothing destroyed
29
+ - `minor` — real but bounded (mishandled edge case, missing test, maintenance hazard); behaviour correct today
30
+ - `info` — no defect (style, naming, question for author, recorded context)
31
+
32
+ If a finding omits the severity attribute, it falls below the floor and is never auto-applied.
33
+
34
+ ## Confidence Floor: `high`
35
+
36
+ Findings below `high` are recorded but never auto-applied. The confidence levels, ordered from most to least sure:
37
+
38
+ - `high` — evidence is in the code that was read; failure can be traced from the diff alone, no assumptions needed
39
+ - `medium` — likely real, but rests on one assumption not verified (how a caller behaves, what a dependency guarantees, what a requirement was)
40
+ - `low` — speculative (failure scenario imagined, not traced; constraint invented; intent could not be inferred)
41
+
42
+ If a finding omits the confidence attribute, it falls below the floor and is never auto-applied.
43
+
44
+ This attribute has no schema default on purpose. Findings that omit confidence are treated as falling below any floor. An automated consumer relies on confidence being lowered honestly; LLM reviewers systematically overstate certainty.
45
+
46
+ ## Round Budget: 3
47
+
48
+ The gate runs up to three detect-and-fix cycles:
49
+
50
+ 1. Reviewer critiques the cumulative diff → findings
51
+ 2. If findings above floor exist: implement fixes, re-run mechanical gates, verify
52
+ 3. Reviewer re-checks → repeat until no new findings above floor or budget exhausted
53
+
54
+ This value expressed here is advisory prose only. **Termination is enforced in code and cannot be bypassed by editing this file.** If the round budget is exhausted, the gate halts exactly as any mechanical gate failure does: the plan stays in `plans/`, findings are recorded, and the failure is documented.
55
+
56
+ ## Disable the Gate
57
+
58
+ **Emptying this file, or deleting it, disables the review gate cleanly.** The gate skips with no error and records the skip in the execution summary. This is the documented sentinel for "do not review this plan"; there is no undefined behaviour and no error.
59
+
60
+ Users who already have a code review step in their workflow disable this feature by editing or emptying the hook, matching the pattern of `PRE_TASK_EXECUTION` which ships an overridable default discipline.
@@ -0,0 +1,437 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xs:schema
3
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
4
+ xmlns:sr="urn:self-review:v2"
5
+ targetNamespace="urn:self-review:v2"
6
+ elementFormDefault="qualified"
7
+ >
8
+
9
+ <!--
10
+ self-review XML Schema v2
11
+ =========================
12
+ Defines the output format for the self-review application.
13
+ This schema is designed to be both machine-validated and
14
+ fed to an LLM so it can understand the structure of review feedback.
15
+
16
+ Key concepts:
17
+ - A <review> contains one <file> per file in the diff.
18
+ - A <file> contains zero or more <comment> elements.
19
+ - A <comment> with no line attributes is a file-level comment.
20
+ - A <comment> with old-line-start/old-line-end refers to lines
21
+ in the pre-change version of the file (typically deleted lines).
22
+ - A <comment> with new-line-start/new-line-end refers to lines
23
+ in the post-change version of the file (added or context lines).
24
+ - Exactly one pair (old-line-* or new-line-*) should be present
25
+ for line-level comments. This constraint cannot be expressed in
26
+ XSD 1.0 and is enforced by the application.
27
+
28
+ Changes from v1:
29
+ - <comment> gained two optional attributes, severity and confidence,
30
+ so an automated consumer can threshold on findings instead of
31
+ applying all of them or none of them. See CommentType.
32
+ -->
33
+
34
+ <!-- ===== Root element ===== -->
35
+
36
+ <xs:element name="review" type="sr:ReviewType">
37
+ <xs:annotation>
38
+ <xs:documentation>
39
+ Root element of a self-review output file. Contains one file element
40
+ per file in the git diff, including files with no comments.
41
+ </xs:documentation>
42
+ </xs:annotation>
43
+ </xs:element>
44
+
45
+ <!-- ===== Complex types ===== -->
46
+
47
+ <xs:complexType name="ReviewType">
48
+ <xs:sequence>
49
+ <xs:element name="file" type="sr:FileType" minOccurs="0" maxOccurs="unbounded" />
50
+ </xs:sequence>
51
+ <xs:attribute name="timestamp" type="xs:dateTime" use="required">
52
+ <xs:annotation>
53
+ <xs:documentation>
54
+ ISO 8601 timestamp of when the review was completed (window closed).
55
+ </xs:documentation>
56
+ </xs:annotation>
57
+ </xs:attribute>
58
+ <xs:attribute name="git-diff-args" type="xs:string" use="optional">
59
+ <xs:annotation>
60
+ <xs:documentation>
61
+ The git diff arguments that were passed to self-review on the CLI.
62
+ Example: "--staged", "main..feature-branch", "HEAD~3".
63
+ Present only when reviewing a git diff.
64
+ </xs:documentation>
65
+ </xs:annotation>
66
+ </xs:attribute>
67
+ <xs:attribute name="repository" type="xs:string" use="optional">
68
+ <xs:annotation>
69
+ <xs:documentation>
70
+ Absolute path to the repository root where self-review was invoked.
71
+ Present only when reviewing a git diff.
72
+ </xs:documentation>
73
+ </xs:annotation>
74
+ </xs:attribute>
75
+ <xs:attribute name="source-path" type="xs:string" use="optional">
76
+ <xs:annotation>
77
+ <xs:documentation>
78
+ Absolute path to the directory being reviewed.
79
+ Present only when reviewing a directory (non-git mode).
80
+ </xs:documentation>
81
+ </xs:annotation>
82
+ </xs:attribute>
83
+ </xs:complexType>
84
+
85
+ <xs:complexType name="FileType">
86
+ <xs:annotation>
87
+ <xs:documentation>
88
+ Represents a single file in the diff. Files with no comments
89
+ appear as empty elements. The path is relative to the repository root.
90
+ </xs:documentation>
91
+ </xs:annotation>
92
+ <xs:sequence>
93
+ <xs:element name="comment" type="sr:CommentType" minOccurs="0" maxOccurs="unbounded" />
94
+ </xs:sequence>
95
+ <xs:attribute name="path" type="xs:string" use="required">
96
+ <xs:annotation>
97
+ <xs:documentation>
98
+ File path relative to the repository root. For renamed files,
99
+ this is the new path.
100
+ </xs:documentation>
101
+ </xs:annotation>
102
+ </xs:attribute>
103
+ <xs:attribute name="change-type" type="sr:ChangeTypeEnum" use="required">
104
+ <xs:annotation>
105
+ <xs:documentation>
106
+ The type of change: added, modified, deleted, or renamed.
107
+ </xs:documentation>
108
+ </xs:annotation>
109
+ </xs:attribute>
110
+ <xs:attribute name="viewed" type="xs:boolean" use="required">
111
+ <xs:annotation>
112
+ <xs:documentation>
113
+ Whether the reviewer marked this file as reviewed.
114
+ true = the reviewer looked at this file.
115
+ false = the reviewer did not mark this file as viewed.
116
+ This helps an AI agent distinguish "reviewed with no comments"
117
+ from "not yet reviewed."
118
+ </xs:documentation>
119
+ </xs:annotation>
120
+ </xs:attribute>
121
+ </xs:complexType>
122
+
123
+ <xs:complexType name="CommentType">
124
+ <xs:annotation>
125
+ <xs:documentation>
126
+ A review comment. Three forms:
127
+
128
+ 1. File-level comment: no line attributes present.
129
+ Applies to the file as a whole.
130
+
131
+ 2. Comment on new/added/context lines: new-line-start and
132
+ new-line-end are present. These reference line numbers in the
133
+ post-change version of the file.
134
+
135
+ 3. Comment on old/deleted lines: old-line-start and old-line-end
136
+ are present. These reference line numbers in the pre-change
137
+ version of the file.
138
+
139
+ For single-line comments, start and end are equal.
140
+ Exactly one pair (old or new) should be present for line-level
141
+ comments. Both pairs absent = file-level comment.
142
+
143
+ The category child says what kind of finding this is. The severity
144
+ and confidence attributes say how much weight to put on it: severity
145
+ is how consequential the finding is if it is real, confidence is how
146
+ sure the author is that it is real. They are independent, and an
147
+ automated consumer is expected to threshold on both.
148
+ </xs:documentation>
149
+ </xs:annotation>
150
+ <xs:sequence>
151
+ <xs:element name="body" type="xs:string">
152
+ <xs:annotation>
153
+ <xs:documentation>
154
+ The comment text. May contain markdown formatting.
155
+ </xs:documentation>
156
+ </xs:annotation>
157
+ </xs:element>
158
+ <xs:element name="category" type="xs:string">
159
+ <xs:annotation>
160
+ <xs:documentation>
161
+ Required category tag for this comment (e.g., "bug", "style",
162
+ "nit", "question", "security"). Categories are defined in the
163
+ project-level .self-review.yaml configuration. Every comment
164
+ must have a category to help AI agents prioritize and triage
165
+ feedback.
166
+ </xs:documentation>
167
+ </xs:annotation>
168
+ </xs:element>
169
+ <xs:element name="suggestion" type="sr:SuggestionType" minOccurs="0">
170
+ <xs:annotation>
171
+ <xs:documentation>
172
+ Optional code replacement proposal. When present, the AI agent
173
+ should replace the original-code with the proposed-code at the
174
+ referenced line range.
175
+ </xs:documentation>
176
+ </xs:annotation>
177
+ </xs:element>
178
+ <xs:element name="attachment" type="sr:AttachmentType" minOccurs="0" maxOccurs="unbounded">
179
+ <xs:annotation>
180
+ <xs:documentation>
181
+ Optional image attachment. The path attribute references an image file
182
+ stored in the .self-review-assets/ directory alongside the XML output.
183
+ </xs:documentation>
184
+ </xs:annotation>
185
+ </xs:element>
186
+ </xs:sequence>
187
+ <xs:attribute name="old-line-start" type="xs:positiveInteger" use="optional">
188
+ <xs:annotation>
189
+ <xs:documentation>
190
+ Start line number in the pre-change (old) version of the file.
191
+ Use for comments on deleted lines.
192
+ </xs:documentation>
193
+ </xs:annotation>
194
+ </xs:attribute>
195
+ <xs:attribute name="old-line-end" type="xs:positiveInteger" use="optional">
196
+ <xs:annotation>
197
+ <xs:documentation>
198
+ End line number (inclusive) in the pre-change (old) version.
199
+ Must be >= old-line-start when both are present.
200
+ </xs:documentation>
201
+ </xs:annotation>
202
+ </xs:attribute>
203
+ <xs:attribute name="new-line-start" type="xs:positiveInteger" use="optional">
204
+ <xs:annotation>
205
+ <xs:documentation>
206
+ Start line number in the post-change (new) version of the file.
207
+ Use for comments on added or context (unchanged) lines.
208
+ </xs:documentation>
209
+ </xs:annotation>
210
+ </xs:attribute>
211
+ <xs:attribute name="new-line-end" type="xs:positiveInteger" use="optional">
212
+ <xs:annotation>
213
+ <xs:documentation>
214
+ End line number (inclusive) in the post-change (new) version.
215
+ Must be >= new-line-start when both are present.
216
+ </xs:documentation>
217
+ </xs:annotation>
218
+ </xs:attribute>
219
+ <xs:attribute name="author" type="xs:string" use="optional">
220
+ <xs:annotation>
221
+ <xs:documentation>
222
+ The author of this comment. When present, indicates the comment
223
+ was generated by a bot or LLM (e.g., "Claude Sonnet 4.6").
224
+ When absent, the comment is assumed to be authored by the human
225
+ reviewer.
226
+ </xs:documentation>
227
+ </xs:annotation>
228
+ </xs:attribute>
229
+ <xs:attribute name="severity" type="sr:SeverityEnum" use="optional">
230
+ <xs:annotation>
231
+ <xs:documentation>
232
+ How consequential this finding is if it turns out to be real.
233
+ Judge the impact of the problem, not how confident you are that
234
+ the problem exists, and not how much work the fix is.
235
+
236
+ This attribute has no schema default on purpose. When it is
237
+ absent, a consumer must treat the comment as falling below any
238
+ severity floor it applies, i.e. absent never satisfies a
239
+ threshold. Comments written by a human in the self-review UI
240
+ normally carry no severity.
241
+ </xs:documentation>
242
+ </xs:annotation>
243
+ </xs:attribute>
244
+ <xs:attribute name="confidence" type="sr:ConfidenceEnum" use="optional">
245
+ <xs:annotation>
246
+ <xs:documentation>
247
+ How sure the author is that this finding is real, i.e. that it
248
+ describes an actual defect in the code as written rather than a
249
+ hypothetical one.
250
+
251
+ Confidence is about the evidence, not about how strongly the
252
+ comment is worded. A finding whose argument depends on a
253
+ constraint that is not visible in the diff, on a caller that was
254
+ not read, or on a failure scenario that was imagined rather than
255
+ traced, is low confidence however plausible its prose sounds.
256
+ LLM reviewers systematically overstate certainty here; a
257
+ consumer thresholding on this attribute is relying on it being
258
+ lowered honestly.
259
+
260
+ This attribute has no schema default on purpose. When it is
261
+ absent, a consumer must treat the comment as falling below any
262
+ confidence floor it applies, i.e. absent never satisfies a
263
+ threshold.
264
+ </xs:documentation>
265
+ </xs:annotation>
266
+ </xs:attribute>
267
+ </xs:complexType>
268
+
269
+ <xs:complexType name="SuggestionType">
270
+ <xs:annotation>
271
+ <xs:documentation>
272
+ A code replacement proposal. The original-code is the literal text
273
+ currently at the referenced lines. The proposed-code is what the
274
+ reviewer suggests it should be replaced with. The AI agent can apply
275
+ this by performing a text substitution.
276
+ </xs:documentation>
277
+ </xs:annotation>
278
+ <xs:sequence>
279
+ <xs:element name="original-code" type="xs:string">
280
+ <xs:annotation>
281
+ <xs:documentation>
282
+ The existing code at the referenced line range, copied verbatim
283
+ from the diff. Used by the AI agent to locate the replacement
284
+ target via text matching.
285
+ </xs:documentation>
286
+ </xs:annotation>
287
+ </xs:element>
288
+ <xs:element name="proposed-code" type="xs:string">
289
+ <xs:annotation>
290
+ <xs:documentation>
291
+ The replacement code proposed by the reviewer. The AI agent
292
+ should substitute original-code with this text.
293
+ </xs:documentation>
294
+ </xs:annotation>
295
+ </xs:element>
296
+ </xs:sequence>
297
+ </xs:complexType>
298
+
299
+ <xs:complexType name="AttachmentType">
300
+ <xs:annotation>
301
+ <xs:documentation>
302
+ Reference to an image file attached to a review comment. The file is stored
303
+ alongside the XML output in the .self-review-assets/ directory.
304
+ </xs:documentation>
305
+ </xs:annotation>
306
+ <xs:attribute name="path" type="xs:string" use="required">
307
+ <xs:annotation>
308
+ <xs:documentation>Relative path from the XML file to the image file.</xs:documentation>
309
+ </xs:annotation>
310
+ </xs:attribute>
311
+ <xs:attribute name="media-type" type="xs:string" use="required">
312
+ <xs:annotation>
313
+ <xs:documentation>MIME type of the image (e.g., image/png, image/jpeg).</xs:documentation>
314
+ </xs:annotation>
315
+ </xs:attribute>
316
+ </xs:complexType>
317
+
318
+ <!-- ===== Simple types ===== -->
319
+
320
+ <xs:simpleType name="ChangeTypeEnum">
321
+ <xs:annotation>
322
+ <xs:documentation>
323
+ The type of change a file underwent in the diff.
324
+ </xs:documentation>
325
+ </xs:annotation>
326
+ <xs:restriction base="xs:string">
327
+ <xs:enumeration value="added">
328
+ <xs:annotation>
329
+ <xs:documentation>New file that did not exist before.</xs:documentation>
330
+ </xs:annotation>
331
+ </xs:enumeration>
332
+ <xs:enumeration value="modified">
333
+ <xs:annotation>
334
+ <xs:documentation>Existing file with content changes.</xs:documentation>
335
+ </xs:annotation>
336
+ </xs:enumeration>
337
+ <xs:enumeration value="deleted">
338
+ <xs:annotation>
339
+ <xs:documentation>File was removed.</xs:documentation>
340
+ </xs:annotation>
341
+ </xs:enumeration>
342
+ <xs:enumeration value="renamed">
343
+ <xs:annotation>
344
+ <xs:documentation>File was moved or renamed, with or without content changes.</xs:documentation>
345
+ </xs:annotation>
346
+ </xs:enumeration>
347
+ </xs:restriction>
348
+ </xs:simpleType>
349
+
350
+ <xs:simpleType name="SeverityEnum">
351
+ <xs:annotation>
352
+ <xs:documentation>
353
+ How consequential a finding is if it is real. Ordered from most to
354
+ least consequential: critical, major, minor, info.
355
+ </xs:documentation>
356
+ </xs:annotation>
357
+ <xs:restriction base="xs:string">
358
+ <xs:enumeration value="critical">
359
+ <xs:annotation>
360
+ <xs:documentation>
361
+ Causes data loss, a security hole, or a crash or corruption on a
362
+ path that real usage reaches. Shipping this is not acceptable.
363
+ </xs:documentation>
364
+ </xs:annotation>
365
+ </xs:enumeration>
366
+ <xs:enumeration value="major">
367
+ <xs:annotation>
368
+ <xs:documentation>
369
+ Produces wrong behaviour, or breaks a documented contract, on a
370
+ path that real usage reaches. The code does not do what it is
371
+ supposed to do, but nothing is destroyed and there is no security
372
+ impact.
373
+ </xs:documentation>
374
+ </xs:annotation>
375
+ </xs:enumeration>
376
+ <xs:enumeration value="minor">
377
+ <xs:annotation>
378
+ <xs:documentation>
379
+ Real but bounded: a mishandled edge case that is unlikely to be
380
+ hit, a missing test, a leak of something cheap, or a maintenance
381
+ hazard that will cost time later. Behaviour is correct today.
382
+ </xs:documentation>
383
+ </xs:annotation>
384
+ </xs:enumeration>
385
+ <xs:enumeration value="info">
386
+ <xs:annotation>
387
+ <xs:documentation>
388
+ No defect. Style, naming, phrasing, a question for the author, or
389
+ a note recorded for context. Nothing is wrong if this is never
390
+ acted on.
391
+ </xs:documentation>
392
+ </xs:annotation>
393
+ </xs:enumeration>
394
+ </xs:restriction>
395
+ </xs:simpleType>
396
+
397
+ <xs:simpleType name="ConfidenceEnum">
398
+ <xs:annotation>
399
+ <xs:documentation>
400
+ How sure the author is that a finding is real. Ordered from most to
401
+ least sure: high, medium, low.
402
+ </xs:documentation>
403
+ </xs:annotation>
404
+ <xs:restriction base="xs:string">
405
+ <xs:enumeration value="high">
406
+ <xs:annotation>
407
+ <xs:documentation>
408
+ The evidence is in the code that was read. The failure can be
409
+ traced from the diff itself, and no assumption about unseen code,
410
+ unseen callers, or unstated requirements is needed to reach it.
411
+ </xs:documentation>
412
+ </xs:annotation>
413
+ </xs:enumeration>
414
+ <xs:enumeration value="medium">
415
+ <xs:annotation>
416
+ <xs:documentation>
417
+ Likely real, but it rests on one assumption that was not verified,
418
+ such as how a caller behaves, what a dependency guarantees, or
419
+ what the intended requirement was. Stating that assumption in the
420
+ body is expected at this level.
421
+ </xs:documentation>
422
+ </xs:annotation>
423
+ </xs:enumeration>
424
+ <xs:enumeration value="low">
425
+ <xs:annotation>
426
+ <xs:documentation>
427
+ Speculative. The failure scenario was imagined rather than traced,
428
+ or the finding depends on a constraint the author invented, or the
429
+ author could not tell intent from the code. Worth a human's eyes,
430
+ not worth acting on unattended.
431
+ </xs:documentation>
432
+ </xs:annotation>
433
+ </xs:enumeration>
434
+ </xs:restriction>
435
+ </xs:simpleType>
436
+
437
+ </xs:schema>
@@ -1 +0,0 @@
1
- import{U as a,C as n}from"./mermaid.core-Cpmiqmbf.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-DdA9k_le.js";import{b as i}from"./mermaid.core-Cpmiqmbf.js";import"./chunk-FMBD7UC4-C6DHs6Wv.js";import"./chunk-ND2GUHAM-Nia1N7VP.js";import"./chunk-55IACEB6-KUROX5a_.js";import"./chunk-2J33WTMH-B00rt2rz.js";import"./index-DHgmc9MH.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-DdA9k_le.js";import{b as i}from"./mermaid.core-Cpmiqmbf.js";import"./chunk-FMBD7UC4-C6DHs6Wv.js";import"./chunk-ND2GUHAM-Nia1N7VP.js";import"./chunk-55IACEB6-KUROX5a_.js";import"./chunk-2J33WTMH-B00rt2rz.js";import"./index-DHgmc9MH.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};