@quickchatai/pi-quickreview 1.2.0 → 1.3.2

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 (231) hide show
  1. package/README.md +79 -27
  2. package/assets/config.example.toml +25 -7
  3. package/assets/prompts/onboarding.md +8 -7
  4. package/assets/schemas/review-result.v1.json +60 -0
  5. package/dist/extensions/quickreview.d.ts +17 -5
  6. package/dist/extensions/quickreview.d.ts.map +1 -1
  7. package/dist/extensions/quickreview.js +79 -26
  8. package/dist/extensions/quickreview.js.map +1 -1
  9. package/dist/src/engine/auth.d.ts +4 -0
  10. package/dist/src/engine/auth.d.ts.map +1 -1
  11. package/dist/src/engine/auth.js +11 -2
  12. package/dist/src/engine/auth.js.map +1 -1
  13. package/dist/src/engine/lens/activity.d.ts +45 -0
  14. package/dist/src/engine/lens/activity.d.ts.map +1 -0
  15. package/dist/src/engine/lens/activity.js +118 -0
  16. package/dist/src/engine/lens/activity.js.map +1 -0
  17. package/dist/src/engine/lens/runlens.d.ts +7 -0
  18. package/dist/src/engine/lens/runlens.d.ts.map +1 -1
  19. package/dist/src/engine/lens/runlens.js +30 -1
  20. package/dist/src/engine/lens/runlens.js.map +1 -1
  21. package/dist/src/engine/lens/tool.d.ts +7 -0
  22. package/dist/src/engine/lens/tool.d.ts.map +1 -1
  23. package/dist/src/engine/lens/tool.js +101 -18
  24. package/dist/src/engine/lens/tool.js.map +1 -1
  25. package/dist/src/engine/lens/wave.d.ts +6 -0
  26. package/dist/src/engine/lens/wave.d.ts.map +1 -1
  27. package/dist/src/engine/lens/wave.js +16 -0
  28. package/dist/src/engine/lens/wave.js.map +1 -1
  29. package/dist/src/homes.js +1 -1
  30. package/dist/src/homes.js.map +1 -1
  31. package/dist/src/live/events.d.ts +3 -0
  32. package/dist/src/live/events.d.ts.map +1 -1
  33. package/dist/src/live/events.js.map +1 -1
  34. package/dist/src/live/lensline.d.ts +20 -0
  35. package/dist/src/live/lensline.d.ts.map +1 -0
  36. package/dist/src/live/lensline.js +70 -0
  37. package/dist/src/live/lensline.js.map +1 -0
  38. package/dist/src/live/projection.d.ts +55 -0
  39. package/dist/src/live/projection.d.ts.map +1 -0
  40. package/dist/src/live/projection.js +465 -0
  41. package/dist/src/live/projection.js.map +1 -0
  42. package/dist/src/live/read.d.ts +24 -0
  43. package/dist/src/live/read.d.ts.map +1 -0
  44. package/dist/src/live/read.js +60 -0
  45. package/dist/src/live/read.js.map +1 -0
  46. package/dist/src/live/writer.d.ts +3 -0
  47. package/dist/src/live/writer.d.ts.map +1 -1
  48. package/dist/src/live/writer.js +6 -1
  49. package/dist/src/live/writer.js.map +1 -1
  50. package/dist/src/localreview.d.ts +18 -8
  51. package/dist/src/localreview.d.ts.map +1 -1
  52. package/dist/src/localreview.js +103 -43
  53. package/dist/src/localreview.js.map +1 -1
  54. package/dist/src/modelroute.d.ts +4 -0
  55. package/dist/src/modelroute.d.ts.map +1 -1
  56. package/dist/src/modelroute.js +21 -0
  57. package/dist/src/modelroute.js.map +1 -1
  58. package/dist/src/plugin/args.d.ts +38 -7
  59. package/dist/src/plugin/args.d.ts.map +1 -1
  60. package/dist/src/plugin/args.js +134 -37
  61. package/dist/src/plugin/args.js.map +1 -1
  62. package/dist/src/plugin/index.d.ts.map +1 -1
  63. package/dist/src/plugin/index.js +5 -1
  64. package/dist/src/plugin/index.js.map +1 -1
  65. package/dist/src/plugin/login.d.ts +8 -4
  66. package/dist/src/plugin/login.d.ts.map +1 -1
  67. package/dist/src/plugin/login.js +25 -32
  68. package/dist/src/plugin/login.js.map +1 -1
  69. package/dist/src/plugin/messages.d.ts +7 -0
  70. package/dist/src/plugin/messages.d.ts.map +1 -0
  71. package/dist/src/plugin/messages.js +13 -0
  72. package/dist/src/plugin/messages.js.map +1 -0
  73. package/dist/src/plugin/peers.d.ts +17 -0
  74. package/dist/src/plugin/peers.d.ts.map +1 -0
  75. package/dist/src/plugin/peers.js +55 -0
  76. package/dist/src/plugin/peers.js.map +1 -0
  77. package/dist/src/plugin/review.d.ts +52 -6
  78. package/dist/src/plugin/review.d.ts.map +1 -1
  79. package/dist/src/plugin/review.js +261 -95
  80. package/dist/src/plugin/review.js.map +1 -1
  81. package/dist/src/plugin/scan.d.ts +80 -44
  82. package/dist/src/plugin/scan.d.ts.map +1 -1
  83. package/dist/src/plugin/scan.js +450 -233
  84. package/dist/src/plugin/scan.js.map +1 -1
  85. package/dist/src/plugin/scancases.d.ts +33 -0
  86. package/dist/src/plugin/scancases.d.ts.map +1 -0
  87. package/dist/src/plugin/scancases.js +153 -0
  88. package/dist/src/plugin/scancases.js.map +1 -0
  89. package/dist/src/plugin/settings.d.ts +18 -0
  90. package/dist/src/plugin/settings.d.ts.map +1 -0
  91. package/dist/src/plugin/settings.js +47 -0
  92. package/dist/src/plugin/settings.js.map +1 -0
  93. package/dist/src/plugin/setup.d.ts +35 -12
  94. package/dist/src/plugin/setup.d.ts.map +1 -1
  95. package/dist/src/plugin/setup.js +258 -118
  96. package/dist/src/plugin/setup.js.map +1 -1
  97. package/dist/src/plugin/versiongate.d.ts +3 -0
  98. package/dist/src/plugin/versiongate.d.ts.map +1 -1
  99. package/dist/src/plugin/versiongate.js +9 -4
  100. package/dist/src/plugin/versiongate.js.map +1 -1
  101. package/dist/src/profileoverrides.d.ts +3 -0
  102. package/dist/src/profileoverrides.d.ts.map +1 -1
  103. package/dist/src/profileoverrides.js +9 -2
  104. package/dist/src/profileoverrides.js.map +1 -1
  105. package/dist/src/reviewapi.d.ts +22 -31
  106. package/dist/src/reviewapi.d.ts.map +1 -1
  107. package/dist/src/reviewapi.js +90 -66
  108. package/dist/src/reviewapi.js.map +1 -1
  109. package/dist/src/reviewdest.d.ts +1 -1
  110. package/dist/src/reviewdest.d.ts.map +1 -1
  111. package/dist/src/reviewdest.js +4 -3
  112. package/dist/src/reviewdest.js.map +1 -1
  113. package/dist/src/reviewtarget.d.ts +36 -0
  114. package/dist/src/reviewtarget.d.ts.map +1 -0
  115. package/dist/src/reviewtarget.js +6 -0
  116. package/dist/src/reviewtarget.js.map +1 -0
  117. package/dist/src/round-progress.d.ts +5 -0
  118. package/dist/src/round-progress.d.ts.map +1 -1
  119. package/dist/src/round-progress.js.map +1 -1
  120. package/dist/src/round-stage-deadlines.d.ts +26 -1
  121. package/dist/src/round-stage-deadlines.d.ts.map +1 -1
  122. package/dist/src/round-stage-deadlines.js +45 -2
  123. package/dist/src/round-stage-deadlines.js.map +1 -1
  124. package/dist/src/savedpost.d.ts +65 -0
  125. package/dist/src/savedpost.d.ts.map +1 -0
  126. package/dist/src/savedpost.js +131 -0
  127. package/dist/src/savedpost.js.map +1 -0
  128. package/dist/src/scan/caseread.d.ts +84 -0
  129. package/dist/src/scan/caseread.d.ts.map +1 -0
  130. package/dist/src/scan/caseread.js +263 -0
  131. package/dist/src/scan/caseread.js.map +1 -0
  132. package/dist/src/scan/channelfs.d.ts +6 -0
  133. package/dist/src/scan/channelfs.d.ts.map +1 -0
  134. package/dist/src/scan/channelfs.js +27 -0
  135. package/dist/src/scan/channelfs.js.map +1 -0
  136. package/dist/src/scan/cutrender.d.ts +13 -0
  137. package/dist/src/scan/cutrender.d.ts.map +1 -0
  138. package/dist/src/scan/cutrender.js +51 -0
  139. package/dist/src/scan/cutrender.js.map +1 -0
  140. package/dist/src/scan/facts.d.ts +72 -0
  141. package/dist/src/scan/facts.d.ts.map +1 -0
  142. package/dist/src/scan/facts.js +593 -0
  143. package/dist/src/scan/facts.js.map +1 -0
  144. package/dist/src/scan/findings.d.ts +320 -0
  145. package/dist/src/scan/findings.d.ts.map +1 -0
  146. package/dist/src/scan/findings.js +948 -0
  147. package/dist/src/scan/findings.js.map +1 -0
  148. package/dist/src/scan/ledger.d.ts +116 -0
  149. package/dist/src/scan/ledger.d.ts.map +1 -0
  150. package/dist/src/scan/ledger.js +207 -0
  151. package/dist/src/scan/ledger.js.map +1 -0
  152. package/dist/src/scan/presentation.d.ts +19 -0
  153. package/dist/src/scan/presentation.d.ts.map +1 -0
  154. package/dist/src/scan/presentation.js +9 -0
  155. package/dist/src/scan/presentation.js.map +1 -0
  156. package/dist/src/scan/scan.d.ts +354 -0
  157. package/dist/src/scan/scan.d.ts.map +1 -0
  158. package/dist/src/scan/scan.js +725 -0
  159. package/dist/src/scan/scan.js.map +1 -0
  160. package/dist/src/scan/scanagents.d.ts +23 -0
  161. package/dist/src/scan/scanagents.d.ts.map +1 -0
  162. package/dist/src/scan/scanagents.js +99 -0
  163. package/dist/src/scan/scanagents.js.map +1 -0
  164. package/dist/src/scan/scanassemble.d.ts +65 -0
  165. package/dist/src/scan/scanassemble.d.ts.map +1 -0
  166. package/dist/src/scan/scanassemble.js +93 -0
  167. package/dist/src/scan/scanassemble.js.map +1 -0
  168. package/dist/src/scan/scanfs.d.ts +26 -0
  169. package/dist/src/scan/scanfs.d.ts.map +1 -0
  170. package/dist/src/scan/scanfs.js +229 -0
  171. package/dist/src/scan/scanfs.js.map +1 -0
  172. package/dist/src/scan/scanlease.d.ts +50 -0
  173. package/dist/src/scan/scanlease.d.ts.map +1 -0
  174. package/dist/src/scan/scanlease.js +251 -0
  175. package/dist/src/scan/scanlease.js.map +1 -0
  176. package/dist/src/scan/scanleaves.d.ts +55 -0
  177. package/dist/src/scan/scanleaves.d.ts.map +1 -0
  178. package/dist/src/scan/scanleaves.js +258 -0
  179. package/dist/src/scan/scanleaves.js.map +1 -0
  180. package/dist/src/scan/scanports.d.ts +79 -0
  181. package/dist/src/scan/scanports.d.ts.map +1 -0
  182. package/dist/src/scan/scanports.js +8 -0
  183. package/dist/src/scan/scanports.js.map +1 -0
  184. package/dist/src/scan/scanrender.d.ts +128 -0
  185. package/dist/src/scan/scanrender.d.ts.map +1 -0
  186. package/dist/src/scan/scanrender.js +527 -0
  187. package/dist/src/scan/scanrender.js.map +1 -0
  188. package/dist/src/scan/scanreport.d.ts +126 -0
  189. package/dist/src/scan/scanreport.d.ts.map +1 -0
  190. package/dist/src/scan/scanreport.js +289 -0
  191. package/dist/src/scan/scanreport.js.map +1 -0
  192. package/dist/src/scan/scanrun.d.ts +472 -0
  193. package/dist/src/scan/scanrun.d.ts.map +1 -0
  194. package/dist/src/scan/scanrun.js +1733 -0
  195. package/dist/src/scan/scanrun.js.map +1 -0
  196. package/dist/src/scan/scantree.d.ts +21 -0
  197. package/dist/src/scan/scantree.d.ts.map +1 -0
  198. package/dist/src/scan/scantree.js +297 -0
  199. package/dist/src/scan/scantree.js.map +1 -0
  200. package/dist/src/scan/scanverbs.d.ts +208 -0
  201. package/dist/src/scan/scanverbs.d.ts.map +1 -0
  202. package/dist/src/scan/scanverbs.js +689 -0
  203. package/dist/src/scan/scanverbs.js.map +1 -0
  204. package/dist/src/scan/stage2.d.ts +221 -0
  205. package/dist/src/scan/stage2.d.ts.map +1 -0
  206. package/dist/src/scan/stage2.js +617 -0
  207. package/dist/src/scan/stage2.js.map +1 -0
  208. package/dist/src/scan/stage2request.d.ts +125 -0
  209. package/dist/src/scan/stage2request.d.ts.map +1 -0
  210. package/dist/src/scan/stage2request.js +259 -0
  211. package/dist/src/scan/stage2request.js.map +1 -0
  212. package/dist/src/scan/textsniff.d.ts +14 -0
  213. package/dist/src/scan/textsniff.d.ts.map +1 -0
  214. package/dist/src/scan/textsniff.js +88 -0
  215. package/dist/src/scan/textsniff.js.map +1 -0
  216. package/dist/src/scan/unitcut.d.ts +135 -0
  217. package/dist/src/scan/unitcut.d.ts.map +1 -0
  218. package/dist/src/scan/unitcut.js +437 -0
  219. package/dist/src/scan/unitcut.js.map +1 -0
  220. package/dist/src/scan/unitcutstore.d.ts +155 -0
  221. package/dist/src/scan/unitcutstore.d.ts.map +1 -0
  222. package/dist/src/scan/unitcutstore.js +381 -0
  223. package/dist/src/scan/unitcutstore.js.map +1 -0
  224. package/dist/src/setupchecklist.d.ts +240 -0
  225. package/dist/src/setupchecklist.d.ts.map +1 -0
  226. package/dist/src/setupchecklist.js +407 -0
  227. package/dist/src/setupchecklist.js.map +1 -0
  228. package/package.json +7 -3
  229. package/skills/qcr-review/SKILL.md +24 -0
  230. package/skills/qcr-scan/SKILL.md +23 -0
  231. package/skills/qcr-setup/SKILL.md +18 -0
@@ -0,0 +1,155 @@
1
+ import { type UnitCandidate } from "./facts.js";
2
+ import type { Refusal, RepoReader, StateFs } from "./scanports.js";
3
+ import { type CaseBudget, type CasePlan, type UnitCut } from "./unitcut.js";
4
+ export declare const UNIT_CUT_FILE = "setup/unit-cut.json";
5
+ export declare const UNIT_CUT_VERSION = 1;
6
+ export interface SavedCut extends UnitCut {
7
+ saved_at: string;
8
+ /** The commit the cut was checked against, when readable. */
9
+ head: string | null;
10
+ /** How many files the cut covered at save — a later listing that differs is
11
+ * how a stale cut shows itself. */
12
+ files: number;
13
+ }
14
+ export interface DraftCut extends UnitCut {
15
+ updated_at: string;
16
+ /** `candidates` = the deterministic guess taken as-is; `companion` = a
17
+ * proposal the companion wrote; `adjusted` = either, after operator edits. */
18
+ source: "candidates" | "companion" | "adjusted";
19
+ }
20
+ export interface UnitCutFile {
21
+ version: number;
22
+ saved: SavedCut | null;
23
+ previous: SavedCut | null;
24
+ draft: DraftCut | null;
25
+ }
26
+ export interface UnitSummary {
27
+ name: string;
28
+ kind: string;
29
+ roots: string[];
30
+ note: string;
31
+ files: number | null;
32
+ /** Files a pass would actually read (lockfiles, binaries, prose skipped). */
33
+ reviewable: number | null;
34
+ lines: number | null;
35
+ /** One per case; a unit that fits is one case under its own name. */
36
+ cases: Array<{
37
+ id: string;
38
+ files: number;
39
+ lines: number;
40
+ over_budget: boolean;
41
+ }> | null;
42
+ }
43
+ export interface CutView {
44
+ units: UnitSummary[];
45
+ ignored: string[];
46
+ ignored_files: number | null;
47
+ unassigned: string[] | null;
48
+ /** Structural refusals — should never appear on a stored cut; shown if a
49
+ * hand-edited file carries one. */
50
+ errors: string[];
51
+ /** What save would refuse for (a draft may carry these; a saved cut that
52
+ * shows one has gone stale against the repo). */
53
+ blocking_save: string[];
54
+ }
55
+ export interface CutStatus {
56
+ ok: boolean;
57
+ /** Why the file or the repo could not be read — the rest is then partial. */
58
+ problems: string[];
59
+ /** The cut file exists but could not be read: `saved`/`draft` are then
60
+ * unknown, not absent. */
61
+ cut_file_unreadable: boolean;
62
+ saved: (CutView & {
63
+ saved_at: string;
64
+ head: string | null;
65
+ files_at_save: number;
66
+ }) | null;
67
+ draft: (CutView & {
68
+ updated_at: string;
69
+ source: DraftCut["source"];
70
+ }) | null;
71
+ has_previous: boolean;
72
+ repo_files: number | null;
73
+ head: string | null;
74
+ }
75
+ /** The cut setup offers when none is saved: the candidates as units, the
76
+ * vendored roots ignored. */
77
+ export declare function candidateCut(candidates: readonly UnitCandidate[], files: readonly string[]): UnitCut;
78
+ /** What the store reads and writes through. */
79
+ export interface UnitCutPorts {
80
+ repo: RepoReader;
81
+ state: StateFs;
82
+ clock: () => Date;
83
+ }
84
+ export declare class UnitCutStore {
85
+ private readonly ports;
86
+ private readonly budget;
87
+ constructor(ports: UnitCutPorts,
88
+ /** How much one case of the unit view may read. */
89
+ caseBudget?: CaseBudget);
90
+ files(): string[] | null;
91
+ noRepo(): Refusal;
92
+ load(): {
93
+ file: UnitCutFile;
94
+ error: string | null;
95
+ };
96
+ private store;
97
+ /** Load for a write: an unreadable file refuses rather than being replaced. */
98
+ private loadForWrite;
99
+ /** A unit's case plans over its reviewable (not sweep-skipped) files. */
100
+ private unitCases;
101
+ view(cut: UnitCut, files: readonly string[], lines: (p: string) => number): CutView;
102
+ lineCounter(): (p: string) => number;
103
+ /** The saved cut and the draft, each re-checked against the repo as it is
104
+ * now — so a saved cut the repo has outgrown (a new top-level directory no
105
+ * unit claims) shows up here instead of being silently skipped later. */
106
+ status(): CutStatus;
107
+ /**
108
+ * Store a proposal as the draft, replacing any earlier draft (never the
109
+ * saved cut). `raw` is the companion's proposal — `{units, ignored?}` — or
110
+ * undefined to take the deterministic candidates as they are (vendored
111
+ * trees ignored). Refused when it is structurally wrong; save-blocking
112
+ * conditions are allowed in a draft and reported.
113
+ */
114
+ propose(raw?: unknown): {
115
+ ok: true;
116
+ draft: CutView;
117
+ } | Refusal;
118
+ /**
119
+ * Apply the operator's corrections to the draft — starting one from the
120
+ * saved cut when there is no draft — all-or-nothing: a refused op, or a
121
+ * result that is structurally wrong, leaves the stored draft as it was.
122
+ */
123
+ adjust(ops: unknown): {
124
+ ok: true;
125
+ draft: CutView;
126
+ } | Refusal;
127
+ /**
128
+ * Promote the draft to the unit cut. Refused unless it is a complete
129
+ * partition of the repo as it is now — every file in exactly one unit or
130
+ * deliberately ignored, no unit left empty. The cut it replaces is kept as
131
+ * `previous`.
132
+ */
133
+ save(): {
134
+ ok: true;
135
+ saved: CutView;
136
+ } | Refusal;
137
+ /** The saved cut, for every later survey and scan; null when none is saved
138
+ * (or the file cannot be read — `status()` says which). */
139
+ savedCut(): SavedCut | null;
140
+ /**
141
+ * The saved cut as cases: every unit's reviewable files (optionally only
142
+ * those `include` keeps — a scan's stage 1 drops tests and migrations),
143
+ * split to fit the case budget, each case under its unit's name. Refused
144
+ * when there is no saved cut: a survey or scan never runs on a guess.
145
+ */
146
+ cases(include?: (path: string) => boolean): {
147
+ ok: true;
148
+ cases: CasePlan[];
149
+ } | Refusal;
150
+ }
151
+ /** What a scan reads of the unit cut: the saved cut, and why there is none. */
152
+ export type UnitCutStatusPort = Pick<UnitCutStore, "savedCut" | "status">;
153
+ /** The unit-cut verbs `qcr scan units` and `/qcr-scan units` call. */
154
+ export type UnitCutPort = Pick<UnitCutStore, "status" | "propose" | "adjust" | "save">;
155
+ //# sourceMappingURL=unitcutstore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unitcutstore.d.ts","sourceRoot":"","sources":["../../../src/scan/unitcutstore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,381 @@
1
+ // The unit cut, stored: the saved cut every survey and scan reads by, the cut
2
+ // it replaced, and at most one draft (the companion's proposal as the
3
+ // operator adjusts it), in `<state home>/setup/unit-cut.json`, tmp+rename
4
+ // atomic through the state port. A saved cut is never touched by a propose or
5
+ // an adjust — only `save` replaces it. An unreadable file is reported and
6
+ // refuses every write: it may hold the operator's saved cut, and silently
7
+ // starting fresh over it would lose that.
8
+ //
9
+ // Its ports are the checkout (read-only), the state home and the clock, and
10
+ // nothing else: the setup engine (engine.ts) owns one for its views, and a
11
+ // scan host with no setup engine (the pi plugin's /qcr-scan) builds one of its
12
+ // own over the same file.
13
+ import { isSweepSkipped } from "../heuristics.js";
14
+ import { unitCandidates, vendoredRoots } from "./facts.js";
15
+ import { DEFAULT_CASE_BUDGET, applyOps, assign, checkCut, normalizeCut, splitUnit, } from "./unitcut.js";
16
+ // ---- the persisted file ------------------------------------------------------
17
+ export const UNIT_CUT_FILE = "setup/unit-cut.json";
18
+ export const UNIT_CUT_VERSION = 1;
19
+ /** Why a stored cut is not one this version can read, or null when it is (or
20
+ * is absent). Structure only — the partition itself is `checkCut`'s. */
21
+ function cutShapeError(cut) {
22
+ if (cut === null)
23
+ return null;
24
+ if (typeof cut !== "object")
25
+ return "is not an object";
26
+ const c = cut;
27
+ const strings = (v) => Array.isArray(v) && v.every((x) => typeof x === "string");
28
+ if (!Array.isArray(c.units))
29
+ return "has no `units` array";
30
+ for (const [i, u] of c.units.entries()) {
31
+ const unit = (u ?? {});
32
+ if (typeof unit.name !== "string" ||
33
+ !strings(unit.roots) ||
34
+ typeof unit.kind !== "string" ||
35
+ typeof unit.note !== "string") {
36
+ return `units[${i}] is not {name, roots, kind, note}`;
37
+ }
38
+ }
39
+ if (!strings(c.ignored))
40
+ return "has no `ignored` array of paths";
41
+ return null;
42
+ }
43
+ /** The cut setup offers when none is saved: the candidates as units, the
44
+ * vendored roots ignored. */
45
+ export function candidateCut(candidates, files) {
46
+ return {
47
+ units: candidates.map((c) => ({ name: c.name, roots: c.roots, kind: c.kind, note: c.reason })),
48
+ ignored: vendoredRoots(files),
49
+ };
50
+ }
51
+ export class UnitCutStore {
52
+ ports;
53
+ budget;
54
+ constructor(ports,
55
+ /** How much one case of the unit view may read. */
56
+ caseBudget = DEFAULT_CASE_BUDGET) {
57
+ this.ports = ports;
58
+ this.budget = caseBudget;
59
+ }
60
+ files() {
61
+ const listed = this.ports.repo.listFiles();
62
+ return listed === null ? null : [...listed].sort();
63
+ }
64
+ noRepo() {
65
+ return {
66
+ ok: false,
67
+ errors: [
68
+ `no readable checkout at ${this.ports.repo.location} — is the reviewed repo mounted?`,
69
+ ],
70
+ };
71
+ }
72
+ // -- the file --
73
+ load() {
74
+ const empty = {
75
+ version: UNIT_CUT_VERSION,
76
+ saved: null,
77
+ previous: null,
78
+ draft: null,
79
+ };
80
+ let text;
81
+ try {
82
+ text = this.ports.state.read(UNIT_CUT_FILE);
83
+ }
84
+ catch (err) {
85
+ return {
86
+ file: empty,
87
+ error: `${UNIT_CUT_FILE} in ${this.ports.state.location} cannot be read: ${String(err)}`,
88
+ };
89
+ }
90
+ if (text === null)
91
+ return { file: empty, error: null };
92
+ try {
93
+ const raw = JSON.parse(text);
94
+ if (typeof raw !== "object" || raw === null || raw.version !== UNIT_CUT_VERSION) {
95
+ throw new Error(`unknown version ${JSON.stringify(raw?.version)}`);
96
+ }
97
+ const file = {
98
+ version: UNIT_CUT_VERSION,
99
+ saved: raw.saved ?? null,
100
+ previous: raw.previous ?? null,
101
+ draft: raw.draft ?? null,
102
+ };
103
+ // A hand-edited file must be reported, never crash a view: every later
104
+ // reader (assign, splitUnit) takes the shape on trust.
105
+ for (const key of ["saved", "previous", "draft"]) {
106
+ const bad = cutShapeError(file[key]);
107
+ if (bad !== null)
108
+ throw new Error(`\`${key}\` ${bad}`);
109
+ }
110
+ return { file, error: null };
111
+ }
112
+ catch (err) {
113
+ return {
114
+ file: empty,
115
+ error: `${UNIT_CUT_FILE} in ${this.ports.state.location} is not a unit cut this version reads (${String(err)}) — ` +
116
+ "nothing will overwrite it; move it aside to start over",
117
+ };
118
+ }
119
+ }
120
+ store(file) {
121
+ this.ports.state.write(UNIT_CUT_FILE, `${JSON.stringify(file, null, 2)}\n`);
122
+ }
123
+ /** Load for a write: an unreadable file refuses rather than being replaced. */
124
+ loadForWrite() {
125
+ const { file, error } = this.load();
126
+ return error === null ? { file } : { ok: false, errors: [error] };
127
+ }
128
+ // -- views --
129
+ /** A unit's case plans over its reviewable (not sweep-skipped) files. */
130
+ unitCases(name, owned, lines) {
131
+ return splitUnit(name, owned.filter((f) => !isSweepSkipped(f)), lines, this.budget);
132
+ }
133
+ view(cut, files, lines) {
134
+ const { errors, blocking_save } = checkCut(cut, files);
135
+ // A cut with structural errors (a hand-edited file) still gets a
136
+ // best-effort view, with the errors beside it.
137
+ const a = assign(cut, files);
138
+ const sizeErrors = [];
139
+ const units = cut.units.map((u) => {
140
+ const owned = a.byUnit.get(u.name) ?? [];
141
+ const reviewable = owned.filter((f) => !isSweepSkipped(f));
142
+ let cases = [];
143
+ let unavailable = false;
144
+ try {
145
+ cases = this.unitCases(u.name, owned, lines);
146
+ }
147
+ catch (err) {
148
+ unavailable = true;
149
+ sizeErrors.push(String(err));
150
+ }
151
+ return {
152
+ name: u.name,
153
+ kind: u.kind,
154
+ roots: u.roots,
155
+ note: u.note,
156
+ files: owned.length,
157
+ reviewable: reviewable.length,
158
+ lines: unavailable ? null : cases.reduce((n, c) => n + c.lines, 0),
159
+ cases: unavailable
160
+ ? null
161
+ : cases.map((c) => ({
162
+ id: c.id,
163
+ files: c.files.length,
164
+ lines: c.lines,
165
+ over_budget: c.over_budget,
166
+ })),
167
+ };
168
+ });
169
+ return {
170
+ units,
171
+ ignored: cut.ignored,
172
+ ignored_files: a.ignored.length,
173
+ unassigned: a.unassigned,
174
+ errors: [...errors, ...sizeErrors],
175
+ blocking_save,
176
+ };
177
+ }
178
+ lineCounter() {
179
+ const cache = new Map();
180
+ return (p) => {
181
+ let n = cache.get(p);
182
+ if (n === undefined) {
183
+ const measured = this.ports.repo.lines(p);
184
+ if (measured === null)
185
+ throw new Error(`line count UNKNOWN for ${p} — unreadable, binary or too large; no case or price can be inferred`);
186
+ n = measured;
187
+ cache.set(p, n);
188
+ }
189
+ return n;
190
+ };
191
+ }
192
+ /** The saved cut and the draft, each re-checked against the repo as it is
193
+ * now — so a saved cut the repo has outgrown (a new top-level directory no
194
+ * unit claims) shows up here instead of being silently skipped later. */
195
+ status() {
196
+ const { file, error } = this.load();
197
+ const problems = error === null ? [] : [error];
198
+ const files = this.files();
199
+ if (files === null)
200
+ problems.push(this.noRepo().errors[0]);
201
+ const head = files === null ? null : this.ports.repo.head();
202
+ const lines = this.lineCounter();
203
+ const see = (cut) => files === null
204
+ ? {
205
+ units: cut.units.map((u) => ({
206
+ ...u,
207
+ files: null,
208
+ reviewable: null,
209
+ lines: null,
210
+ cases: null,
211
+ })),
212
+ ignored: cut.ignored,
213
+ ignored_files: null,
214
+ unassigned: null,
215
+ errors: [],
216
+ blocking_save: [],
217
+ }
218
+ : this.view(cut, files, lines);
219
+ return {
220
+ ok: problems.length === 0,
221
+ problems,
222
+ cut_file_unreadable: error !== null,
223
+ saved: file.saved
224
+ ? {
225
+ ...see(file.saved),
226
+ saved_at: file.saved.saved_at,
227
+ head: file.saved.head,
228
+ files_at_save: file.saved.files,
229
+ }
230
+ : null,
231
+ draft: file.draft
232
+ ? { ...see(file.draft), updated_at: file.draft.updated_at, source: file.draft.source }
233
+ : null,
234
+ has_previous: file.previous !== null,
235
+ repo_files: files?.length ?? null,
236
+ head,
237
+ };
238
+ }
239
+ // -- the three verbs --
240
+ /**
241
+ * Store a proposal as the draft, replacing any earlier draft (never the
242
+ * saved cut). `raw` is the companion's proposal — `{units, ignored?}` — or
243
+ * undefined to take the deterministic candidates as they are (vendored
244
+ * trees ignored). Refused when it is structurally wrong; save-blocking
245
+ * conditions are allowed in a draft and reported.
246
+ */
247
+ propose(raw) {
248
+ const files = this.files();
249
+ if (files === null)
250
+ return this.noRepo();
251
+ const loaded = this.loadForWrite();
252
+ if ("ok" in loaded)
253
+ return loaded;
254
+ let cut;
255
+ let source;
256
+ if (raw === undefined || raw === null || (typeof raw === "object" && !("units" in raw))) {
257
+ cut = candidateCut(unitCandidates(files), files);
258
+ source = "candidates";
259
+ }
260
+ else {
261
+ const n = normalizeCut(raw);
262
+ if (!n.ok)
263
+ return n;
264
+ cut = n.cut;
265
+ source = "companion";
266
+ }
267
+ const problems = checkCut(cut, files);
268
+ if (problems.errors.length > 0)
269
+ return { ok: false, errors: problems.errors };
270
+ loaded.file.draft = { ...cut, updated_at: this.ports.clock().toISOString(), source };
271
+ this.store(loaded.file);
272
+ return { ok: true, draft: this.view(cut, files, this.lineCounter()) };
273
+ }
274
+ /**
275
+ * Apply the operator's corrections to the draft — starting one from the
276
+ * saved cut when there is no draft — all-or-nothing: a refused op, or a
277
+ * result that is structurally wrong, leaves the stored draft as it was.
278
+ */
279
+ adjust(ops) {
280
+ if (!Array.isArray(ops) || ops.length === 0) {
281
+ return { ok: false, errors: ["`ops` must be a non-empty array of adjust operations"] };
282
+ }
283
+ const files = this.files();
284
+ if (files === null)
285
+ return this.noRepo();
286
+ const loaded = this.loadForWrite();
287
+ if ("ok" in loaded)
288
+ return loaded;
289
+ const base = loaded.file.draft ?? loaded.file.saved;
290
+ if (!base)
291
+ return { ok: false, errors: ["there is no unit cut to adjust yet — propose one first"] };
292
+ const applied = applyOps({ units: base.units, ignored: base.ignored }, ops);
293
+ if (!applied.ok)
294
+ return applied;
295
+ const problems = checkCut(applied.cut, files);
296
+ if (problems.errors.length > 0)
297
+ return { ok: false, errors: problems.errors };
298
+ loaded.file.draft = {
299
+ ...applied.cut,
300
+ updated_at: this.ports.clock().toISOString(),
301
+ source: "adjusted",
302
+ };
303
+ this.store(loaded.file);
304
+ return { ok: true, draft: this.view(applied.cut, files, this.lineCounter()) };
305
+ }
306
+ /**
307
+ * Promote the draft to the unit cut. Refused unless it is a complete
308
+ * partition of the repo as it is now — every file in exactly one unit or
309
+ * deliberately ignored, no unit left empty. The cut it replaces is kept as
310
+ * `previous`.
311
+ */
312
+ save() {
313
+ const files = this.files();
314
+ if (files === null)
315
+ return this.noRepo();
316
+ const loaded = this.loadForWrite();
317
+ if ("ok" in loaded)
318
+ return loaded;
319
+ const draft = loaded.file.draft;
320
+ if (!draft) {
321
+ return {
322
+ ok: false,
323
+ errors: [
324
+ loaded.file.saved
325
+ ? "no draft to save — the saved cut is already in use; adjust it to start a draft"
326
+ : "no draft to save — propose a unit cut first",
327
+ ],
328
+ };
329
+ }
330
+ const cut = { units: draft.units, ignored: draft.ignored };
331
+ const problems = checkCut(cut, files);
332
+ if (problems.errors.length > 0 || problems.blocking_save.length > 0) {
333
+ return { ok: false, errors: [...problems.errors, ...problems.blocking_save] };
334
+ }
335
+ loaded.file.previous = loaded.file.saved;
336
+ loaded.file.saved = {
337
+ ...cut,
338
+ saved_at: this.ports.clock().toISOString(),
339
+ head: this.ports.repo.head(),
340
+ files: files.length,
341
+ };
342
+ loaded.file.draft = null;
343
+ this.store(loaded.file);
344
+ return { ok: true, saved: this.view(cut, files, this.lineCounter()) };
345
+ }
346
+ // -- reuse --
347
+ /** The saved cut, for every later survey and scan; null when none is saved
348
+ * (or the file cannot be read — `status()` says which). */
349
+ savedCut() {
350
+ return this.load().file.saved;
351
+ }
352
+ /**
353
+ * The saved cut as cases: every unit's reviewable files (optionally only
354
+ * those `include` keeps — a scan's stage 1 drops tests and migrations),
355
+ * split to fit the case budget, each case under its unit's name. Refused
356
+ * when there is no saved cut: a survey or scan never runs on a guess.
357
+ */
358
+ cases(include = () => true) {
359
+ const files = this.files();
360
+ if (files === null)
361
+ return this.noRepo();
362
+ const { file, error } = this.load();
363
+ if (error !== null)
364
+ return { ok: false, errors: [error] };
365
+ if (!file.saved)
366
+ return { ok: false, errors: ["no saved unit cut — propose, adjust and save one first"] };
367
+ const a = assign(file.saved, files);
368
+ const lines = this.lineCounter();
369
+ const cases = [];
370
+ try {
371
+ for (const u of file.saved.units) {
372
+ cases.push(...this.unitCases(u.name, (a.byUnit.get(u.name) ?? []).filter(include), lines));
373
+ }
374
+ }
375
+ catch (err) {
376
+ return { ok: false, errors: [String(err)] };
377
+ }
378
+ return { ok: true, cases };
379
+ }
380
+ }
381
+ //# sourceMappingURL=unitcutstore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unitcutstore.js","sourceRoot":"","sources":["../../../src/scan/unitcutstore.ts"],"names":[],"mappings":"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"}