@cleocode/core 2026.9.9 → 2026.9.10

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 (41) hide show
  1. package/dist/compliance/protocol-rules.d.ts.map +1 -1
  2. package/dist/compliance/protocol-rules.js +3 -1
  3. package/dist/compliance/protocol-rules.js.map +1 -1
  4. package/dist/docs/export-document.js +29 -0
  5. package/dist/docs/export-document.js.map +1 -1
  6. package/dist/git/work-tree.d.ts +119 -14
  7. package/dist/git/work-tree.d.ts.map +1 -1
  8. package/dist/git/work-tree.js +265 -35
  9. package/dist/git/work-tree.js.map +1 -1
  10. package/dist/internal.d.ts +1 -0
  11. package/dist/internal.d.ts.map +1 -1
  12. package/dist/internal.js +2 -0
  13. package/dist/internal.js.map +1 -1
  14. package/dist/llm/plugin-facade.js +29 -0
  15. package/dist/llm/plugin-facade.js.map +1 -1
  16. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  17. package/dist/orchestration/spawn-prompt.js +9 -4
  18. package/dist/orchestration/spawn-prompt.js.map +1 -1
  19. package/dist/release/pr-evidence.d.ts +7 -1
  20. package/dist/release/pr-evidence.d.ts.map +1 -1
  21. package/dist/release/pr-evidence.js +14 -4
  22. package/dist/release/pr-evidence.js.map +1 -1
  23. package/dist/selfimprove/fix-gen.js +29 -0
  24. package/dist/selfimprove/fix-gen.js.map +1 -1
  25. package/dist/session/engine-ops.d.ts.map +1 -1
  26. package/dist/session/engine-ops.js +36 -4
  27. package/dist/session/engine-ops.js.map +1 -1
  28. package/dist/tasks/evidence.d.ts +36 -3
  29. package/dist/tasks/evidence.d.ts.map +1 -1
  30. package/dist/tasks/evidence.js +60 -11
  31. package/dist/tasks/evidence.js.map +1 -1
  32. package/dist/tasks/gate-preview.d.ts +73 -0
  33. package/dist/tasks/gate-preview.d.ts.map +1 -0
  34. package/dist/tasks/gate-preview.js +119 -0
  35. package/dist/tasks/gate-preview.js.map +1 -0
  36. package/dist/tasks/gate-runner.d.ts.map +1 -1
  37. package/dist/tasks/gate-runner.js +131 -5
  38. package/dist/tasks/gate-runner.js.map +1 -1
  39. package/package.json +13 -13
  40. package/schemas/project-context.schema.json +12 -0
  41. package/templates/CLEO-INJECTION.md +12 -1
@@ -1,6 +1,7 @@
1
1
  /**
2
- * Whether a directory can host a `git`/`gh` evidence invocation, and what to
3
- * say when it cannot (gh#1462).
2
+ * Whether a directory can host a `git`/`gh` evidence invocation, which tree to
3
+ * run in when the CLEO root is not itself a checkout, and what to say when no
4
+ * tree can be found (gh#1462).
4
5
  *
5
6
  * `pr:` and `commit:` atoms shell out to `gh` / `git` from a working directory.
6
7
  * `gh` does its OWN repo discovery: it walks up from its cwd and, finding no
@@ -30,35 +31,139 @@
30
31
  */
31
32
  export declare const E_EVIDENCE_GIT_ROOT: "E_EVIDENCE_GIT_ROOT";
32
33
  /**
33
- * True when `dir` is inside a git work tree — its own checkout or a descendant
34
- * of one, since git walks up. False when the directory is missing, is not a
35
- * work tree, or `git` itself cannot be spawned.
34
+ * Environment variable naming the checkout that evidence tools must run in.
35
+ *
36
+ * The CLEO-specific override, and the one the failure message points at. It
37
+ * beats every other signal because it is the only one that can only have been
38
+ * set on purpose for this invocation.
39
+ *
40
+ * @task T12308
41
+ */
42
+ export declare const EVIDENCE_GIT_ROOT_ENV = "CLEO_EVIDENCE_GIT_ROOT";
43
+ /**
44
+ * True when `dir` is inside a git work tree of its own — its own checkout or a
45
+ * descendant of one, since git walks up. False when the directory is missing,
46
+ * is not a work tree, or `git` itself cannot be spawned.
47
+ *
48
+ * Ambient `GIT_DIR`/`GIT_WORK_TREE` are ignored on purpose; see
49
+ * {@link GIT_AMBIENT_REPO_VARS}.
36
50
  *
37
51
  * @param dir - Directory the tools would run in.
38
52
  * @task gh#1462
39
53
  */
40
54
  export declare function isGitWorkTree(dir: string): boolean;
55
+ /**
56
+ * Absolute toplevel of the checkout containing `dir`, or `null` when there is
57
+ * none.
58
+ *
59
+ * @param dir - Directory to resolve from.
60
+ * @task T12308
61
+ */
62
+ export declare function gitToplevel(dir: string): string | null;
63
+ /**
64
+ * Every git work tree directly below `dir`, in stable sorted order.
65
+ *
66
+ * One level only, on purpose. A CLEO root that parents its checkouts — the
67
+ * layout gh#1462 reports — has the repositories as direct children, while a
68
+ * recursive search would descend into `node_modules` and vendored trees.
69
+ * Dot-directories are skipped so `.cleo/`, `.git/` and editor state are never
70
+ * candidates.
71
+ *
72
+ * @param dir - Candidate parent directory (the CLEO store root).
73
+ * @returns Canonical absolute paths; empty when there are none.
74
+ * @task T12308
75
+ */
76
+ export declare function findNestedGitWorkTrees(dir: string): string[];
41
77
  /**
42
78
  * The single git work tree directly below `dir`, or `null` when there is none
43
79
  * or more than one.
44
80
  *
45
- * One level only, on purpose. A CLEO root that parents its checkout — the
46
- * layout gh#1462 reports — has the repository as a direct child, while a
47
- * recursive search would descend into `node_modules` and vendored trees and
48
- * would still have to guess which repository a `pr:` atom was about. Ambiguity
49
- * returns `null` so the caller can report it instead of picking one.
81
+ * Ambiguity returns `null` so the caller can report it — or disambiguate with
82
+ * {@link findWorkTreeContainingCommit} — instead of picking one.
50
83
  *
51
84
  * @param dir - Candidate parent directory (the CLEO store root).
52
85
  * @task gh#1462
53
86
  */
54
87
  export declare function findNestedGitWorkTree(dir: string): string | null;
55
88
  /**
56
- * Reason text for {@link E_EVIDENCE_GIT_ROOT}: names the directory that was
57
- * tried and the two environment variables that pin a checkout CLEO could not
58
- * find on its own.
89
+ * The one candidate checkout that contains `sha`, or `null` when none or
90
+ * several do.
91
+ *
92
+ * This is what makes a multi-repo CLEO root resolvable WITHOUT configuration:
93
+ * a `commit:` atom is a statement about exactly one repository, and "which of
94
+ * these checkouts has this object" has a single correct answer almost always.
95
+ * Several matches (shared history) or none stay unresolved rather than being
96
+ * guessed, so the caller reports the ambiguity.
97
+ *
98
+ * @param candidates - Checkouts to search, e.g. from {@link findNestedGitWorkTrees}.
99
+ * @param sha - Commit SHA the evidence is about.
100
+ * @task T12308
101
+ */
102
+ export declare function findWorkTreeContainingCommit(candidates: readonly string[], sha: string): string | null;
103
+ /** An evidence git root the operator declared, and where the declaration came from. */
104
+ export interface DeclaredEvidenceGitRoot {
105
+ /** Absolute path exactly as declared (resolved against the store root when relative). */
106
+ path: string;
107
+ /** Human-readable provenance, used verbatim in failure text. */
108
+ source: string;
109
+ }
110
+ /**
111
+ * The checkout the operator declared for evidence execution, if any.
112
+ *
113
+ * Precedence, most to least specific:
114
+ *
115
+ * 1. `CLEO_EVIDENCE_GIT_ROOT` — set for this invocation, for this purpose.
116
+ * 2. `GIT_WORK_TREE` — git's own override, and the one the old failure text
117
+ * advertised. It is honoured by RUNNING in that tree, which is the part
118
+ * that was missing: setting it alone never helped, because every tool
119
+ * still ran with its cwd at the CLEO root.
120
+ * 3. `.cleo/project-context.json` → `evidence.gitRoot` — the durable,
121
+ * committed answer for a root that parents several repositories.
122
+ *
123
+ * The result is NOT validated here. A declared path that is not a work tree
124
+ * must fail loudly and by name rather than falling back to a different tree
125
+ * and attesting against it, so validation belongs to the caller's guard.
126
+ *
127
+ * @param storeRoot - CLEO store root; relative declarations resolve against it.
128
+ * @param env - Environment to read. Defaults to the current process env.
129
+ * @task T12308
130
+ */
131
+ export declare function resolveDeclaredEvidenceGitRoot(storeRoot: string, env?: NodeJS.ProcessEnv): DeclaredEvidenceGitRoot | null;
132
+ /** Context that makes {@link describeMissingGitWorkTree} name the actual fix. */
133
+ export interface MissingGitWorkTreeContext {
134
+ /** CLEO store root, when it differs from the directory that was tried. */
135
+ storeRoot?: string;
136
+ /** Checkouts found directly below the store root. */
137
+ candidates?: readonly string[];
138
+ /** Provenance of a declared root that turned out not to be a work tree. */
139
+ declaredFrom?: string;
140
+ }
141
+ /**
142
+ * Reason text for {@link E_EVIDENCE_GIT_ROOT}.
143
+ *
144
+ * The previous text offered `GIT_DIR`/`GIT_WORK_TREE` as the remedy. That
145
+ * advice could not work: the guard asks whether the *current directory* is
146
+ * inside a work tree, and the CLEO root never is, so following it produced the
147
+ * identical error and left the reader with nothing to try. Every branch here
148
+ * therefore names a remedy that has a test proving it resolves the layout.
59
149
  *
60
150
  * @param dir - Directory the tools would have run in.
151
+ * @param context - What else is known about the layout.
61
152
  * @task gh#1462
153
+ * @task T12308
154
+ */
155
+ export declare function describeMissingGitWorkTree(dir: string, context?: MissingGitWorkTreeContext): string;
156
+ /**
157
+ * The complete {@link E_EVIDENCE_GIT_ROOT} reason for a store root whose
158
+ * resolved execution root turned out not to be a checkout.
159
+ *
160
+ * Composed here, beside the resolution inputs it reports on, so the message
161
+ * and the resolution order cannot drift apart: a declaration that was honoured
162
+ * is named, otherwise the sibling checkouts that made the choice ambiguous are.
163
+ *
164
+ * @param storeRoot - Absolute CLEO store root.
165
+ * @param executionRoot - Root the tools would have run in.
166
+ * @task T12308
62
167
  */
63
- export declare function describeMissingGitWorkTree(dir: string): string;
168
+ export declare function describeUnusableEvidenceGitRoot(storeRoot: string, executionRoot: string): string;
64
169
  //# sourceMappingURL=work-tree.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"work-tree.d.ts","sourceRoot":"","sources":["../../src/git/work-tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,EAAG,qBAA8B,CAAC;AAElE;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAWlD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqBhE;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ9D"}
1
+ {"version":3,"file":"work-tree.d.ts","sourceRoot":"","sources":["../../src/git/work-tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,EAAG,qBAA8B,CAAC;AAElE;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,2BAA2B,CAAC;AAgE9D;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGtD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGhE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAQf;AAED,uFAAuF;AACvF,MAAM,WAAW,uBAAuB;IACtC,yFAAyF;IACzF,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;CAChB;AA4BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,uBAAuB,GAAG,IAAI,CAmBhC;AAED,iFAAiF;AACjF,MAAM,WAAW,yBAAyB;IACxC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,yBAA8B,GACtC,MAAM,CA8CR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAOhG"}
@@ -1,6 +1,7 @@
1
1
  /**
2
- * Whether a directory can host a `git`/`gh` evidence invocation, and what to
3
- * say when it cannot (gh#1462).
2
+ * Whether a directory can host a `git`/`gh` evidence invocation, which tree to
3
+ * run in when the CLEO root is not itself a checkout, and what to say when no
4
+ * tree can be found (gh#1462).
4
5
  *
5
6
  * `pr:` and `commit:` atoms shell out to `gh` / `git` from a working directory.
6
7
  * `gh` does its OWN repo discovery: it walks up from its cwd and, finding no
@@ -19,8 +20,8 @@
19
20
  * @task gh#1462
20
21
  */
21
22
  import { execFileSync } from 'node:child_process';
22
- import { existsSync, readdirSync, realpathSync } from 'node:fs';
23
- import { join } from 'node:path';
23
+ import { existsSync, readdirSync, readFileSync, realpathSync } from 'node:fs';
24
+ import { isAbsolute, join, resolve } from 'node:path';
24
25
  /**
25
26
  * Error code for "no git work tree at or above the evidence execution root".
26
27
  *
@@ -33,79 +34,308 @@ import { join } from 'node:path';
33
34
  */
34
35
  export const E_EVIDENCE_GIT_ROOT = 'E_EVIDENCE_GIT_ROOT';
35
36
  /**
36
- * True when `dir` is inside a git work tree — its own checkout or a descendant
37
- * of one, since git walks up. False when the directory is missing, is not a
38
- * work tree, or `git` itself cannot be spawned.
37
+ * Environment variable naming the checkout that evidence tools must run in.
39
38
  *
40
- * @param dir - Directory the tools would run in.
41
- * @task gh#1462
39
+ * The CLEO-specific override, and the one the failure message points at. It
40
+ * beats every other signal because it is the only one that can only have been
41
+ * set on purpose for this invocation.
42
+ *
43
+ * @task T12308
42
44
  */
43
- export function isGitWorkTree(dir) {
45
+ export const EVIDENCE_GIT_ROOT_ENV = 'CLEO_EVIDENCE_GIT_ROOT';
46
+ /**
47
+ * Git's own repo-pointing variables, removed before any DISCOVERY probe.
48
+ *
49
+ * `git rev-parse --is-inside-work-tree` answers about the *ambient* repository
50
+ * when `GIT_DIR`/`GIT_WORK_TREE` are set, not about `dir`. That is precisely
51
+ * what made the remediation this module used to print unusable: from a parent
52
+ * of the checkout, `GIT_DIR=<repo>/.git GIT_WORK_TREE=<repo> git rev-parse
53
+ * --is-inside-work-tree` prints `false` (cwd is outside the declared tree) and
54
+ * exits 0, so the guard rejected the very layout the advice was meant to fix.
55
+ *
56
+ * Probes therefore ask the unambiguous question — "is THIS directory in a
57
+ * checkout of its own" — and the declared roots are honoured explicitly, by
58
+ * {@link resolveDeclaredEvidenceGitRoot}, rather than by hoping git's ambient
59
+ * state happens to agree.
60
+ *
61
+ * @task T12308
62
+ */
63
+ const GIT_AMBIENT_REPO_VARS = [
64
+ 'GIT_DIR',
65
+ 'GIT_WORK_TREE',
66
+ 'GIT_COMMON_DIR',
67
+ 'GIT_INDEX_FILE',
68
+ 'GIT_OBJECT_DIRECTORY',
69
+ ];
70
+ /**
71
+ * A copy of `env` with git's ambient repo-pointing variables removed.
72
+ *
73
+ * @param env - Source environment. Defaults to the current process env.
74
+ * @returns Environment safe for directory-discovery probes.
75
+ * @task T12308
76
+ */
77
+ function discoveryEnv(env = process.env) {
78
+ const copy = { ...env };
79
+ for (const key of GIT_AMBIENT_REPO_VARS)
80
+ delete copy[key];
81
+ return copy;
82
+ }
83
+ /** Run a `git` probe in `dir`, returning trimmed stdout or `null` on any failure. */
84
+ function gitProbe(dir, args) {
44
85
  try {
45
- const out = execFileSync('git', ['rev-parse', '--is-inside-work-tree'], {
86
+ const out = execFileSync('git', [...args], {
46
87
  cwd: dir,
47
88
  encoding: 'utf-8',
89
+ env: discoveryEnv(),
48
90
  stdio: ['ignore', 'pipe', 'ignore'],
49
91
  });
50
- return out.trim() === 'true';
92
+ return out.trim();
93
+ }
94
+ catch {
95
+ return null;
96
+ }
97
+ }
98
+ /** Resolve symlinks where possible, falling back to a plain absolute path. */
99
+ function canonical(path) {
100
+ try {
101
+ return realpathSync(path);
51
102
  }
52
103
  catch {
53
- return false;
104
+ return resolve(path);
54
105
  }
55
106
  }
56
107
  /**
57
- * The single git work tree directly below `dir`, or `null` when there is none
58
- * or more than one.
108
+ * True when `dir` is inside a git work tree of its own — its own checkout or a
109
+ * descendant of one, since git walks up. False when the directory is missing,
110
+ * is not a work tree, or `git` itself cannot be spawned.
59
111
  *
60
- * One level only, on purpose. A CLEO root that parents its checkout — the
61
- * layout gh#1462 reports — has the repository as a direct child, while a
62
- * recursive search would descend into `node_modules` and vendored trees and
63
- * would still have to guess which repository a `pr:` atom was about. Ambiguity
64
- * returns `null` so the caller can report it instead of picking one.
112
+ * Ambient `GIT_DIR`/`GIT_WORK_TREE` are ignored on purpose; see
113
+ * {@link GIT_AMBIENT_REPO_VARS}.
65
114
  *
66
- * @param dir - Candidate parent directory (the CLEO store root).
115
+ * @param dir - Directory the tools would run in.
67
116
  * @task gh#1462
68
117
  */
69
- export function findNestedGitWorkTree(dir) {
118
+ export function isGitWorkTree(dir) {
119
+ return gitProbe(dir, ['rev-parse', '--is-inside-work-tree']) === 'true';
120
+ }
121
+ /**
122
+ * Absolute toplevel of the checkout containing `dir`, or `null` when there is
123
+ * none.
124
+ *
125
+ * @param dir - Directory to resolve from.
126
+ * @task T12308
127
+ */
128
+ export function gitToplevel(dir) {
129
+ const top = gitProbe(dir, ['rev-parse', '--show-toplevel']);
130
+ return top === null || top.length === 0 ? null : canonical(top);
131
+ }
132
+ /**
133
+ * Every git work tree directly below `dir`, in stable sorted order.
134
+ *
135
+ * One level only, on purpose. A CLEO root that parents its checkouts — the
136
+ * layout gh#1462 reports — has the repositories as direct children, while a
137
+ * recursive search would descend into `node_modules` and vendored trees.
138
+ * Dot-directories are skipped so `.cleo/`, `.git/` and editor state are never
139
+ * candidates.
140
+ *
141
+ * @param dir - Candidate parent directory (the CLEO store root).
142
+ * @returns Canonical absolute paths; empty when there are none.
143
+ * @task T12308
144
+ */
145
+ export function findNestedGitWorkTrees(dir) {
70
146
  let entries;
71
147
  try {
72
148
  entries = readdirSync(dir);
73
149
  }
74
150
  catch {
75
- return null;
151
+ return [];
76
152
  }
77
153
  const found = [];
78
154
  for (const entry of entries) {
79
155
  if (entry.startsWith('.'))
80
156
  continue;
157
+ if (entry === 'node_modules')
158
+ continue;
81
159
  const child = join(dir, entry);
82
160
  if (!existsSync(join(child, '.git')))
83
161
  continue;
84
- found.push(child);
162
+ found.push(canonical(child));
85
163
  }
86
- const only = found[0];
87
- if (only === undefined || found.length !== 1)
164
+ return found.sort();
165
+ }
166
+ /**
167
+ * The single git work tree directly below `dir`, or `null` when there is none
168
+ * or more than one.
169
+ *
170
+ * Ambiguity returns `null` so the caller can report it — or disambiguate with
171
+ * {@link findWorkTreeContainingCommit} — instead of picking one.
172
+ *
173
+ * @param dir - Candidate parent directory (the CLEO store root).
174
+ * @task gh#1462
175
+ */
176
+ export function findNestedGitWorkTree(dir) {
177
+ const found = findNestedGitWorkTrees(dir);
178
+ return found.length === 1 ? found[0] : null;
179
+ }
180
+ /**
181
+ * The one candidate checkout that contains `sha`, or `null` when none or
182
+ * several do.
183
+ *
184
+ * This is what makes a multi-repo CLEO root resolvable WITHOUT configuration:
185
+ * a `commit:` atom is a statement about exactly one repository, and "which of
186
+ * these checkouts has this object" has a single correct answer almost always.
187
+ * Several matches (shared history) or none stay unresolved rather than being
188
+ * guessed, so the caller reports the ambiguity.
189
+ *
190
+ * @param candidates - Checkouts to search, e.g. from {@link findNestedGitWorkTrees}.
191
+ * @param sha - Commit SHA the evidence is about.
192
+ * @task T12308
193
+ */
194
+ export function findWorkTreeContainingCommit(candidates, sha) {
195
+ if (!/^[0-9a-f]{7,40}$/i.test(sha))
88
196
  return null;
197
+ const matches = [];
198
+ for (const candidate of candidates) {
199
+ if (gitProbe(candidate, ['cat-file', '-e', `${sha}^{commit}`]) !== null)
200
+ matches.push(candidate);
201
+ }
202
+ return matches.length === 1 ? matches[0] : null;
203
+ }
204
+ /**
205
+ * Read `evidence.gitRoot` out of `.cleo/project-context.json`.
206
+ *
207
+ * Parsed here with a bare `readFileSync` rather than through
208
+ * `loadProjectContext` so this module stays a leaf: the evidence resolver is
209
+ * synchronous and sits below the agents layer, and a static import back into
210
+ * it would close a cycle. A malformed or absent file simply yields `null` —
211
+ * this tier has always been optional.
212
+ *
213
+ * @param storeRoot - CLEO store root holding `.cleo/`.
214
+ * @task T12308
215
+ */
216
+ function readConfiguredGitRoot(storeRoot) {
89
217
  try {
90
- return realpathSync(only);
218
+ const raw = readFileSync(join(storeRoot, '.cleo', 'project-context.json'), 'utf-8');
219
+ const parsed = JSON.parse(raw);
220
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
221
+ return null;
222
+ const evidence = parsed.evidence;
223
+ if (evidence === null || typeof evidence !== 'object' || Array.isArray(evidence))
224
+ return null;
225
+ const gitRoot = evidence.gitRoot;
226
+ return typeof gitRoot === 'string' && gitRoot.trim().length > 0 ? gitRoot.trim() : null;
91
227
  }
92
228
  catch {
93
- return only;
229
+ return null;
94
230
  }
95
231
  }
96
232
  /**
97
- * Reason text for {@link E_EVIDENCE_GIT_ROOT}: names the directory that was
98
- * tried and the two environment variables that pin a checkout CLEO could not
99
- * find on its own.
233
+ * The checkout the operator declared for evidence execution, if any.
234
+ *
235
+ * Precedence, most to least specific:
236
+ *
237
+ * 1. `CLEO_EVIDENCE_GIT_ROOT` — set for this invocation, for this purpose.
238
+ * 2. `GIT_WORK_TREE` — git's own override, and the one the old failure text
239
+ * advertised. It is honoured by RUNNING in that tree, which is the part
240
+ * that was missing: setting it alone never helped, because every tool
241
+ * still ran with its cwd at the CLEO root.
242
+ * 3. `.cleo/project-context.json` → `evidence.gitRoot` — the durable,
243
+ * committed answer for a root that parents several repositories.
244
+ *
245
+ * The result is NOT validated here. A declared path that is not a work tree
246
+ * must fail loudly and by name rather than falling back to a different tree
247
+ * and attesting against it, so validation belongs to the caller's guard.
248
+ *
249
+ * @param storeRoot - CLEO store root; relative declarations resolve against it.
250
+ * @param env - Environment to read. Defaults to the current process env.
251
+ * @task T12308
252
+ */
253
+ export function resolveDeclaredEvidenceGitRoot(storeRoot, env = process.env) {
254
+ const fromEnv = (key) => {
255
+ const value = env[key]?.trim();
256
+ if (value === undefined || value.length === 0)
257
+ return null;
258
+ return {
259
+ path: isAbsolute(value) ? value : resolve(storeRoot, value),
260
+ source: `${key}=${value}`,
261
+ };
262
+ };
263
+ const explicit = fromEnv(EVIDENCE_GIT_ROOT_ENV) ?? fromEnv('GIT_WORK_TREE');
264
+ if (explicit !== null)
265
+ return explicit;
266
+ const configured = readConfiguredGitRoot(storeRoot);
267
+ if (configured === null)
268
+ return null;
269
+ return {
270
+ path: isAbsolute(configured) ? configured : resolve(storeRoot, configured),
271
+ source: `.cleo/project-context.json evidence.gitRoot="${configured}"`,
272
+ };
273
+ }
274
+ /**
275
+ * Reason text for {@link E_EVIDENCE_GIT_ROOT}.
276
+ *
277
+ * The previous text offered `GIT_DIR`/`GIT_WORK_TREE` as the remedy. That
278
+ * advice could not work: the guard asks whether the *current directory* is
279
+ * inside a work tree, and the CLEO root never is, so following it produced the
280
+ * identical error and left the reader with nothing to try. Every branch here
281
+ * therefore names a remedy that has a test proving it resolves the layout.
100
282
  *
101
283
  * @param dir - Directory the tools would have run in.
284
+ * @param context - What else is known about the layout.
102
285
  * @task gh#1462
286
+ * @task T12308
103
287
  */
104
- export function describeMissingGitWorkTree(dir) {
105
- return (`No git work tree at or above ${dir}, so git and gh cannot run there. ` +
288
+ export function describeMissingGitWorkTree(dir, context = {}) {
289
+ const { storeRoot, candidates = [], declaredFrom } = context;
290
+ if (declaredFrom !== undefined) {
291
+ return (`Declared evidence git root ${dir} (from ${declaredFrom}) is not a git work tree, ` +
292
+ `so git and gh cannot run there. CLEO honours the declaration rather than ` +
293
+ `silently measuring a different checkout. Point it at a directory that is ` +
294
+ `inside a git repository, or unset it to let CLEO resolve one.`);
295
+ }
296
+ const head = `No git work tree at or above ${dir}, so git and gh cannot run there. ` +
106
297
  `This is a directory/layout problem — not a failing PR, a missing commit, ` +
107
- `or a broken gh. If the checkout lives elsewhere, point the tools at it ` +
108
- `explicitly: GIT_DIR=<repo>/.git GIT_WORK_TREE=<repo> cleo verify ... ` +
298
+ `or a broken gh.`;
299
+ if (candidates.length > 1) {
300
+ const root = storeRoot ?? dir;
301
+ return (`${head} The CLEO root ${root} parents ${candidates.length} checkouts ` +
302
+ `(${candidates.join(', ')}), and this atom does not say which one it is about, ` +
303
+ `so CLEO will not guess. Declare it once, durably, by adding to ` +
304
+ `${join(root, '.cleo', 'project-context.json')}: ` +
305
+ `"evidence": { "gitRoot": "<subdirectory>" } — or, for a single invocation, ` +
306
+ `${EVIDENCE_GIT_ROOT_ENV}=<repo> cleo verify ... . ` +
307
+ `(A commit: atom naming a SHA that exists in exactly one of these checkouts ` +
308
+ `resolves automatically and needs no configuration.)`);
309
+ }
310
+ if (candidates.length === 1) {
311
+ return (`${head} The one checkout below the CLEO root, ${candidates[0]}, could not be used. ` +
312
+ `Run the command from inside it, or declare it with ` +
313
+ `${EVIDENCE_GIT_ROOT_ENV}=${candidates[0]}.`);
314
+ }
315
+ return (`${head} No checkout was found below the CLEO root either. If the repository ` +
316
+ `lives elsewhere, declare it: ${EVIDENCE_GIT_ROOT_ENV}=<repo> cleo verify ... , ` +
317
+ `or add "evidence": { "gitRoot": "<path>" } to ` +
318
+ `${join(storeRoot ?? dir, '.cleo', 'project-context.json')} ` +
109
319
  `(or run the command from inside the checkout).`);
110
320
  }
321
+ /**
322
+ * The complete {@link E_EVIDENCE_GIT_ROOT} reason for a store root whose
323
+ * resolved execution root turned out not to be a checkout.
324
+ *
325
+ * Composed here, beside the resolution inputs it reports on, so the message
326
+ * and the resolution order cannot drift apart: a declaration that was honoured
327
+ * is named, otherwise the sibling checkouts that made the choice ambiguous are.
328
+ *
329
+ * @param storeRoot - Absolute CLEO store root.
330
+ * @param executionRoot - Root the tools would have run in.
331
+ * @task T12308
332
+ */
333
+ export function describeUnusableEvidenceGitRoot(storeRoot, executionRoot) {
334
+ const declared = resolveDeclaredEvidenceGitRoot(storeRoot);
335
+ return describeMissingGitWorkTree(executionRoot, {
336
+ storeRoot,
337
+ candidates: findNestedGitWorkTrees(storeRoot),
338
+ ...(declared === null ? {} : { declaredFrom: declared.source }),
339
+ });
340
+ }
111
341
  //# sourceMappingURL=work-tree.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"work-tree.js","sourceRoot":"","sources":["../../src/git/work-tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAA8B,CAAC;AAElE;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,EAAE;YACtE,GAAG,EAAE,GAAG;YACR,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAAE,SAAS;QAC/C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B,CAAC,GAAW;IACpD,OAAO,CACL,gCAAgC,GAAG,oCAAoC;QACvE,2EAA2E;QAC3E,yEAAyE;QACzE,uEAAuE;QACvE,gDAAgD,CACjD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"work-tree.js","sourceRoot":"","sources":["../../src/git/work-tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAA8B,CAAC;AAElE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,qBAAqB,GAAG;IAC5B,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,gBAAgB;IAChB,sBAAsB;CACd,CAAC;AAEX;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,MAAyB,OAAO,CAAC,GAAG;IACxD,MAAM,IAAI,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IACxB,KAAK,MAAM,GAAG,IAAI,qBAAqB;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,qFAAqF;AACrF,SAAS,QAAQ,CAAC,GAAW,EAAE,IAAuB;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE;YACzC,GAAG,EAAE,GAAG;YACR,QAAQ,EAAE,OAAO;YACjB,GAAG,EAAE,YAAY,EAAE;YACnB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC,KAAK,MAAM,CAAC;AAC1E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC5D,OAAO,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAChD,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACpC,IAAI,KAAK,KAAK,cAAc;YAAE,SAAS;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAAE,SAAS;QAC/C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,MAAM,KAAK,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,4BAA4B,CAC1C,UAA6B,EAC7B,GAAW;IAEX,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,GAAG,WAAW,CAAC,CAAC,KAAK,IAAI;YACrE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAUD;;;;;;;;;;;GAWG;AACH,SAAS,qBAAqB,CAAC,SAAiB;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,sBAAsB,CAAC,EAAE,OAAO,CAAC,CAAC;QACpF,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QACxF,MAAM,QAAQ,GAAI,MAAiC,CAAC,QAAQ,CAAC;QAC7D,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9F,MAAM,OAAO,GAAI,QAAkC,CAAC,OAAO,CAAC;QAC5D,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,8BAA8B,CAC5C,SAAiB,EACjB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAkC,EAAE;QAC9D,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3D,OAAO;YACL,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC;YAC3D,MAAM,EAAE,GAAG,GAAG,IAAI,KAAK,EAAE;SAC1B,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,OAAO,CAAC,qBAAqB,CAAC,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;IAC5E,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,QAAQ,CAAC;IAEvC,MAAM,UAAU,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;IACpD,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC;QAC1E,MAAM,EAAE,gDAAgD,UAAU,GAAG;KACtE,CAAC;AACJ,CAAC;AAYD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,0BAA0B,CACxC,GAAW,EACX,UAAqC,EAAE;IAEvC,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,EAAE,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAE7D,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,CACL,8BAA8B,GAAG,UAAU,YAAY,4BAA4B;YACnF,2EAA2E;YAC3E,2EAA2E;YAC3E,+DAA+D,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GACR,gCAAgC,GAAG,oCAAoC;QACvE,2EAA2E;QAC3E,iBAAiB,CAAC;IAEpB,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,SAAS,IAAI,GAAG,CAAC;QAC9B,OAAO,CACL,GAAG,IAAI,kBAAkB,IAAI,YAAY,UAAU,CAAC,MAAM,aAAa;YACvE,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,uDAAuD;YAChF,iEAAiE;YACjE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,sBAAsB,CAAC,IAAI;YAClD,6EAA6E;YAC7E,GAAG,qBAAqB,4BAA4B;YACpD,6EAA6E;YAC7E,qDAAqD,CACtD,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CACL,GAAG,IAAI,0CAA0C,UAAU,CAAC,CAAC,CAAC,uBAAuB;YACrF,qDAAqD;YACrD,GAAG,qBAAqB,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,CAC7C,CAAC;IACJ,CAAC;IAED,OAAO,CACL,GAAG,IAAI,uEAAuE;QAC9E,gCAAgC,qBAAqB,4BAA4B;QACjF,gDAAgD;QAChD,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,EAAE,OAAO,EAAE,sBAAsB,CAAC,GAAG;QAC7D,gDAAgD,CACjD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,+BAA+B,CAAC,SAAiB,EAAE,aAAqB;IACtF,MAAM,QAAQ,GAAG,8BAA8B,CAAC,SAAS,CAAC,CAAC;IAC3D,OAAO,0BAA0B,CAAC,aAAa,EAAE;QAC/C,SAAS;QACT,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC;QAC7C,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;KAChE,CAAC,CAAC;AACL,CAAC"}
@@ -324,6 +324,7 @@ export { validateLabels } from './tasks/add.js';
324
324
  export { computeTaskView, computeTaskViews } from './tasks/compute-task-view.js';
325
325
  export { type AtomValidation, CALLSITE_COVERAGE_LABEL, CANONICAL_TOOLS, checkCallsiteCoverageAtom, checkEngineMigrationLocDrop, checkGateEvidenceMinimum, checkGateEvidenceMinimumDetailed, composeGateEvidence, ENGINE_MIGRATION_MIN_REDUCTION_PCT, type EvidenceTool, GATE_EVIDENCE_MINIMUMS, isValidToolName, type ParsedAtom, type ParsedEvidence, parseEvidence, type RevalidateOptions, type RevalidationResult, revalidateEvidence, TOOL_COMMANDS, VALID_TOOLS, validateAtom, } from './tasks/evidence.js';
326
326
  export { appendForceBypassLine, appendGateAuditLine, type ForceBypassRecord, type GateAuditRecord, getForceBypassPath, getGateAuditPath, } from './tasks/gate-audit.js';
327
+ export { previewTaskGates, type TaskGatePreview } from './tasks/gate-preview.js';
327
328
  export type { RunGatesOptions } from './tasks/gate-runner.js';
328
329
  export { extractTypedGates, runGates } from './tasks/gate-runner.js';
329
330
  export type { BuildGenericTreeOptions, GenericTreeEdgeType, GenericTreeMetadata, GenericTreeResult, } from './tasks/generic-tree.js';