@karmaniverous/stan-core 0.5.0 → 0.6.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.
@@ -1,3 +1,77 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Defines deterministic selection report types for archive/diff operations and
5
+ * a safe surfacing helper; no filesystem IO; used by adapters for reporting.
6
+ * @module
7
+ */
8
+ /**
9
+ * Selection counts for a single archive/diff/meta operation.
10
+ *
11
+ * Meanings:
12
+ * - candidates: initial input set size for the operation (e.g. listFiles() size,
13
+ * or allowlist length as provided by the caller).
14
+ * - selected: pre-classifier selected set size (e.g. after filterFiles(), or
15
+ * the de-duped allowlist).
16
+ * - archived: post-classifier list size passed to tar.create().
17
+ * - excludedBinaries: count excluded by classifier (binary detection).
18
+ * - largeText: count flagged by classifier (included, but warned).
19
+ */
20
+ type SelectionReportCounts = {
21
+ candidates: number;
22
+ selected: number;
23
+ archived: number;
24
+ excludedBinaries: number;
25
+ largeText: number;
26
+ };
27
+ /**
28
+ * Deterministic, presentation-free selection report surfaced via callback.
29
+ *
30
+ * Notes:
31
+ * - `outputFile` is an absolute path.
32
+ * - `hasWarnings` is derived from classifier counts (binaries excluded and/or
33
+ * large text flagged), not from any warnings string.
34
+ */
35
+ type SelectionReport = {
36
+ kind: 'archive';
37
+ mode: 'denylist' | 'allowlist';
38
+ stanPath: string;
39
+ outputFile: string;
40
+ includeOutputDir: boolean;
41
+ hasWarnings: boolean;
42
+ counts: SelectionReportCounts;
43
+ } | {
44
+ kind: 'diff';
45
+ mode: 'denylist' | 'allowlist';
46
+ stanPath: string;
47
+ outputFile: string;
48
+ includeOutputDirInDiff: boolean;
49
+ updateSnapshot: 'never' | 'createIfMissing' | 'replace';
50
+ snapshotExists: boolean;
51
+ /**
52
+ * Size of the base selection set from which changes were computed
53
+ * (e.g. filtered selection or allowlist after de-dupe).
54
+ */
55
+ baseSelected: number;
56
+ sentinelUsed: boolean;
57
+ hasWarnings: boolean;
58
+ counts: SelectionReportCounts;
59
+ } | {
60
+ kind: 'meta';
61
+ mode: 'allowlist';
62
+ stanPath: string;
63
+ outputFile: string;
64
+ hasWarnings: false;
65
+ counts: SelectionReportCounts;
66
+ };
67
+
68
+ /**
69
+ * Creates full archives (`archive.tar`) from selected repo files; excludes
70
+ * binaries, surfaces warnings via callback, and maintains `archive.prev.tar`;
71
+ * performs filesystem IO; no console output.
72
+ * @module
73
+ */
74
+
1
75
  /** Options to control archive creation. */
2
76
  type CreateArchiveOptions = {
3
77
  /** When true, include the `stanPath/output` directory inside the archive. */
@@ -7,34 +81,17 @@ type CreateArchiveOptions = {
7
81
  * Written to `stanPath/output/<fileName>`.
8
82
  */
9
83
  fileName?: string;
10
- /** Allow‑list globs; when provided, overrides excludes. */
84
+ /** Additive allow‑list globs (can re-include gitignored files); excludes and reserved denials still win. */
11
85
  includes?: string[];
12
86
  /**
13
- * Deny‑list globs. Defaults include `.git`, `node_modules`, and STAN
14
- * workspace rules. These are applied only when `includes` is empty.
87
+ * Deny‑list globs (hard denials). These always apply and take precedence over
88
+ * includes.
15
89
  */
16
90
  excludes?: string[];
17
91
  /** Optional callback for archive classifier warnings (engine remains silent by default). */
18
92
  onArchiveWarnings?: (text: string) => void;
19
- /**
20
- * High‑precedence re‑includes (subject to reserved denials and output exclusion).
21
- * Anchors re-include paths even when excluded by `.gitignore` or `excludes`,
22
- * but they never override reserved workspace denials:
23
- * - `<stanPath>/diff/**`, `<stanPath>/patch/**`
24
- * - `<stanPath>/output/{archive.tar,archive.diff.tar,archive.warnings.txt}`
25
- * - `.git/**`
26
- *
27
- * @example
28
- * ```ts
29
- * // Force-include README.md even if repo excludes would drop it:
30
- * await createArchive(cwd, '.stan', {
31
- * includes: [],
32
- * excludes: ['README.md'],
33
- * anchors: ['README.md'],
34
- * });
35
- * ```
36
- */
37
- anchors?: string[];
93
+ /** Optional callback for a deterministic selection report (engine remains silent by default). */
94
+ onSelectionReport?: (report: SelectionReport) => void;
38
95
  };
39
96
  /**
40
97
  * Create `stanPath/output/archive.tar` (or custom file name) from the repo root.
@@ -44,12 +101,53 @@ type CreateArchiveOptions = {
44
101
  * const tarPath = await createArchive(process.cwd(), '.stan', {
45
102
  * includeOutputDir: false,
46
103
  * excludes: ['**\/.tsbuild/**'],
47
- * anchors: ['README.md', 'docs/index.md'], // re-include anchors
104
+ * includes: ['README.md', 'docs/index.md'], // re-include even if gitignored
48
105
  * });
49
106
  * ```
50
107
  */
51
108
  declare function createArchive(cwd: string, stanPath: string, options?: CreateArchiveOptions): Promise<string>;
52
109
 
110
+ /**
111
+ * Creates a full archive from an explicit allowlist of repo-relative files;
112
+ * excludes binaries via classifier, maintains `archive.prev.tar`, and surfaces
113
+ * warnings via callback; filesystem IO only; no console output.
114
+ * @module
115
+ */
116
+
117
+ type CreateArchiveFromFilesOptions = {
118
+ /** When true, include the `stanPath/output` directory inside the archive. */
119
+ includeOutputDir?: boolean;
120
+ /**
121
+ * Archive file name. If provided without `.tar`, the suffix is added.
122
+ * Written to `stanPath/output/<fileName>`.
123
+ */
124
+ fileName?: string;
125
+ /** Optional callback for archive classifier warnings (engine remains silent by default). */
126
+ onArchiveWarnings?: (text: string) => void;
127
+ /** Optional callback for a deterministic selection report (engine remains silent by default). */
128
+ onSelectionReport?: (report: SelectionReport) => void;
129
+ };
130
+
131
+ /**
132
+ * Creates a "meta" archive (system docs + dependency meta, plus optional
133
+ * dependency state and repo-root base files); excludes staged payloads by
134
+ * omission and excludes `<stanPath>/system/.docs.meta.json`; filesystem IO only.
135
+ * @module
136
+ */
137
+
138
+ declare function createMetaArchive(cwd: string, stanPath: string, selection?: {
139
+ includes?: string[];
140
+ excludes?: string[];
141
+ }, options?: {
142
+ /** Optional callback for a deterministic selection report (engine remains silent by default). */
143
+ onSelectionReport?: (report: SelectionReport) => void;
144
+ }): Promise<string>;
145
+
146
+ /**
147
+ * Public defaults for STAN configuration (e.g. default `stanPath`); pure
148
+ * constants (no side effects).
149
+ * @module
150
+ */
53
151
  /** Public default STAN path for consumers and internal use. */
54
152
  declare const DEFAULT_STAN_PATH = ".stan";
55
153
  /** Default command to open modified files after patch apply. */
@@ -63,6 +161,11 @@ declare const DEFAULT_OPEN_COMMAND = "code -g {file}";
63
161
  */
64
162
  declare const findConfigPathSync: (cwd: string) => string | null;
65
163
 
164
+ /**
165
+ * Public types for the engine config surface (`stan-core` block); used by
166
+ * loaders and callers; no runtime code.
167
+ * @module
168
+ */
66
169
  type ContextConfig = {
67
170
  /** STAN workspace directory (e.g., ".stan"). */
68
171
  stanPath: string;
@@ -102,7 +205,7 @@ declare const resolveStanPath: (cwd: string) => Promise<string>;
102
205
  *
103
206
  * Behavior:
104
207
  * - Always ensure `stanPath/output` and `stanPath/diff` exist.
105
- * - Also ensure `stanPath/patch` exists so archives can include it.
208
+ * - Also ensure `stanPath/patch` exists so patch tooling has a stable workspace.
106
209
  * - When `keep === false`, copy `output/archive.tar` to `diff/archive.prev.tar`
107
210
  * if present, then clear only the `output` directory.
108
211
  *
@@ -113,6 +216,12 @@ declare const resolveStanPath: (cwd: string) => Promise<string>;
113
216
  */
114
217
  declare const ensureOutputDir: (cwd: string, stanPath: string, keep?: boolean) => Promise<string>;
115
218
 
219
+ /**
220
+ * Creates diff archives and manages snapshot state; computes sha256 file hashes;
221
+ * writes snapshot/sentinel files; performs filesystem IO; no console output.
222
+ * @module
223
+ */
224
+
116
225
  type SnapshotUpdateMode = 'never' | 'createIfMissing' | 'replace';
117
226
  /**
118
227
  * Compute (and optionally update) the snapshot file in <stanPath>/diff/.
@@ -121,28 +230,25 @@ type SnapshotUpdateMode = 'never' | 'createIfMissing' | 'replace';
121
230
  * @param args - Object with:
122
231
  * - cwd: Repo root.
123
232
  * - stanPath: STAN workspace folder.
124
- * - includes: Allow‑list globs (overrides excludes).
233
+ * - includes: Additive allow‑list globs (can re-include gitignored files); excludes still win.
125
234
  * - excludes: Deny‑list globs.
126
- * - anchors: High‑precedence re‑includes (subject to reserved/output).
127
235
  *
128
236
  * @example
129
237
  * ```ts
130
- * // Seed snapshot using anchors to keep README.md even when excluded:
238
+ * // Seed snapshot using includes to bring back gitignored files:
131
239
  * await writeArchiveSnapshot({
132
240
  * cwd: process.cwd(),
133
241
  * stanPath: '.stan',
134
- * excludes: ['README.md'],
135
- * anchors: ['README.md'],
242
+ * includes: ['README.md'],
136
243
  * });
137
244
  * ```
138
245
  * @returns Absolute path to the `.archive.snapshot.json` file.
139
246
  */
140
- declare function writeArchiveSnapshot({ cwd, stanPath, includes, excludes, anchors, }: {
247
+ declare function writeArchiveSnapshot({ cwd, stanPath, includes, excludes, }: {
141
248
  cwd: string;
142
249
  stanPath: string;
143
250
  includes?: string[];
144
251
  excludes?: string[];
145
- anchors?: string[];
146
252
  }): Promise<string>;
147
253
  /**
148
254
  * Create a diff tar at <stanPath>/output/<baseName>.diff.tar.
@@ -151,33 +257,30 @@ declare function writeArchiveSnapshot({ cwd, stanPath, includes, excludes, ancho
151
257
  * - Snapshot update behavior is controlled by updateSnapshot.
152
258
  * - When includeOutputDirInDiff === true, also include the entire <stanPath>/output tree
153
259
  * (excluding <stanPath>/diff and the two archive files) regardless of change list length.
154
- * - Always include <stanPath>/patch in the diff archive.
155
260
  *
156
261
  * @param args - Object with:
157
262
  * - cwd: Repo root.
158
263
  * - stanPath: STAN workspace folder.
159
264
  * - baseName: Base archive name (e.g., `archive` -\> `archive.diff.tar`).
160
- * - includes: Allow‑list globs (overrides excludes).
161
- * - excludes: Deny‑list globs.
162
- * - anchors: High‑precedence re‑includes (subject to reserved/output).
265
+ * - includes: Additive allow‑list globs (can re-include gitignored files); excludes still win.
266
+ * - excludes: Deny‑list globs (hard denials; take precedence over includes).
163
267
  * - updateSnapshot: Controls when the snapshot file is replaced.
164
268
  * - includeOutputDirInDiff: When true, include `stanPath/output` in the diff.
165
269
  * @returns `{ diffPath }` absolute path to the diff archive.
166
270
  *
167
271
  * @example
168
272
  * ```ts
169
- * // Diff archive with anchors to retain docs/overview.md:
273
+ * // Diff archive with includes to bring back gitignored files:
170
274
  * const { diffPath } = await createArchiveDiff({
171
275
  * cwd: process.cwd(),
172
276
  * stanPath: '.stan',
173
277
  * baseName: 'archive',
174
- * excludes: ['docs/**'],
175
- * anchors: ['docs/overview.md'],
278
+ * includes: ['docs/overview.md'],
176
279
  * updateSnapshot: 'createIfMissing',
177
280
  * });
178
281
  * ```
179
282
  */
180
- declare function createArchiveDiff({ cwd, stanPath, baseName, includes, excludes, updateSnapshot, includeOutputDirInDiff, anchors, onArchiveWarnings, }: {
283
+ declare function createArchiveDiff({ cwd, stanPath, baseName, includes, excludes, updateSnapshot, includeOutputDirInDiff, onArchiveWarnings, onSelectionReport, }: {
181
284
  cwd: string;
182
285
  stanPath: string;
183
286
  baseName: string;
@@ -185,32 +288,22 @@ declare function createArchiveDiff({ cwd, stanPath, baseName, includes, excludes
185
288
  excludes?: string[];
186
289
  updateSnapshot?: SnapshotUpdateMode;
187
290
  includeOutputDirInDiff?: boolean;
188
- anchors?: string[];
189
291
  onArchiveWarnings?: (text: string) => void;
292
+ onSelectionReport?: (report: SelectionReport) => void;
190
293
  }): Promise<{
191
294
  diffPath: string;
192
295
  }>;
193
296
 
194
- /** src/stan/validate/response.ts
195
- * Response-format validator for assistant replies.
196
- *
197
- * Also validates optional "### File Ops" pre-ops block (verbs/arity/path rules).
198
- *
199
- * Checks (initial):
200
- * - One Patch per file.
201
- * - Each Patch block contains exactly one "diff --git a/<path> b/<path>" header.
202
- * - When both are present for a given file, "Patch" precedes "Full Listing".
203
- * - "## Commit Message" exists and is the final section.
204
- * - If any non‑docs Patch exists, there is also a Patch for ".stan/system/stan.todo.md".
205
- */
206
297
  /**
207
- * Kind tag for validator blocks. Exported so it appears in generated
208
- * documentation and to eliminate TypeDoc’s “referenced but not documented” warning.
298
+ * Types for response validation (blocks, options, results); used by parser and
299
+ * validator logic.
300
+ * @module
209
301
  */
210
302
  type BlockKind = 'patch' | 'full' | 'commit';
211
303
  type Block = {
212
304
  kind: BlockKind;
213
- /** Repo-relative target path for patch/listing blocks; undefined for commit. */ path?: string;
305
+ /** Repo-relative target path for patch/listing blocks; undefined for commit. */
306
+ path?: string;
214
307
  /** Start index (character offset) in the source for ordering checks. */
215
308
  start: number;
216
309
  /** Block body (content between its heading and the next heading). */
@@ -221,19 +314,14 @@ type ValidationResult = {
221
314
  errors: string[];
222
315
  warnings: string[];
223
316
  };
224
- /** Validate an assistant reply body against response-format rules. */
225
- declare const validateResponseMessage: (text: string) => ValidationResult;
226
- /** Throw on validation failure (convenience API). */
227
- declare const validateOrThrow: (text: string) => void;
228
- declare const __internal: {
229
- extractBlocks: (text: string) => Block[];
230
- parseDiffHeaders: (body: string) => Array<{
231
- a: string;
232
- b: string;
233
- }>;
234
- isCommitLast: (text: string) => boolean;
317
+ type ValidateResponseOptions = {
318
+ dependencyMode?: boolean;
319
+ stanPath?: string;
235
320
  };
236
321
 
322
+ declare const validateResponseMessage: (text: string, options?: ValidateResponseOptions) => ValidationResult;
323
+ declare const validateOrThrow: (text: string) => void;
324
+
237
325
  /**
238
326
  * Detect and clean a patch payload from clipboard/file/argument.
239
327
  * - Unwraps chat fences and BEGIN/END PATCH banners when they wrap the entire payload.
@@ -242,6 +330,10 @@ declare const __internal: {
242
330
  */
243
331
  declare const detectAndCleanPatch: (input: string) => string;
244
332
 
333
+ /**
334
+ * Types for File Ops parsing and execution.
335
+ * @module
336
+ */
245
337
  type FileOp = {
246
338
  verb: 'mv';
247
339
  src: string;
@@ -266,20 +358,19 @@ type FileOpsPlan = {
266
358
  };
267
359
  type OpResult = {
268
360
  verb: FileOp['verb'];
269
- src?: string;
270
- dest?: string;
271
361
  status: 'ok' | 'failed';
272
- errno?: string;
273
362
  message?: string;
274
363
  };
275
- /** Parse the optional "### File Ops" fenced block from a reply body. */
276
- declare const parseFileOpsBlock: (source: string) => FileOpsPlan;
364
+
277
365
  /** Execute File Ops with safety checks. Returns per-op results and overall ok. */
278
- declare const executeFileOps: (cwd: string, ops: FileOp[], dryRun?: boolean) => Promise<{
366
+ declare const executeFileOps: (cwd: string, ops: FileOp[], dryRun?: boolean, stanPath?: string) => Promise<{
279
367
  ok: boolean;
280
368
  results: OpResult[];
281
369
  }>;
282
370
 
371
+ /** Parse the optional "### File Ops" fenced block from a reply body. */
372
+ declare const parseFileOpsBlock: (source: string, stanPath?: string) => FileOpsPlan;
373
+
283
374
  type AttemptCapture = {
284
375
  label: string;
285
376
  code: number;
@@ -293,6 +384,12 @@ type ApplyResult = {
293
384
  captures: AttemptCapture[];
294
385
  };
295
386
 
387
+ /**
388
+ * Applies unified diffs via jsdiff ("diff" library) fallback; reads/writes
389
+ * files; preserves EOL; supports sandbox check-mode; refuses writes under
390
+ * <stanPath>/imports/**.
391
+ * @module
392
+ */
296
393
  type JsDiffOutcome = {
297
394
  okFiles: string[];
298
395
  failed: Array<{
@@ -307,6 +404,7 @@ declare const applyWithJsDiff: (args: {
307
404
  cleaned: string;
308
405
  check: boolean;
309
406
  sandboxRoot?: string;
407
+ stanPath?: string;
310
408
  }) => Promise<JsDiffOutcome>;
311
409
 
312
410
  type PipelineOutcome = {
@@ -322,6 +420,8 @@ declare const applyPatchPipeline: (args: {
322
420
  check: boolean;
323
421
  /** Attempt order; defaults to [1,0] (p1 then p0). */
324
422
  stripOrder?: number[];
423
+ /** When provided, enables protection rules scoped to this workspace (e.g., imports read-only). */
424
+ stanPath?: string;
325
425
  }) => Promise<PipelineOutcome>;
326
426
 
327
427
  type ImportsMap = Record<string, string[]>;
@@ -341,6 +441,554 @@ declare const prepareImports: (args: {
341
441
  onStage?: (label: string, files: string[]) => void;
342
442
  }) => Promise<void>;
343
443
 
444
+ /**
445
+ * Defines dependency graph meta/state schemas (Zod) for context mode; pure
446
+ * validation/types; no filesystem IO; deterministic formats.
447
+ *
448
+ * Dependency graph mode: on-disk JSON formats for:
449
+ * - .stan/context/dependency.state.json (assistant-authored selection intent)
450
+ * - .stan/context/dependency.meta.json (assistant-facing dependency graph)
451
+ *
452
+ * Requirements:
453
+ * - Node IDs are repo-relative POSIX paths.
454
+ * - State entries support string | [nodeId, depth] | [nodeId, depth, edgeKinds[]]
455
+ * with defaults depth=0, edgeKinds=['runtime','type','dynamic'].
456
+ * - Meta may include locatorAbs ONLY for abs/outside-root nodes.
457
+ * @module
458
+ */
459
+
460
+ /** Edge kinds recorded in dependency meta and used by dependency state. */
461
+ declare const dependencyEdgeTypeSchema: z.ZodEnum<{
462
+ type: "type";
463
+ runtime: "runtime";
464
+ dynamic: "dynamic";
465
+ }>;
466
+ type DependencyEdgeType = z.infer<typeof dependencyEdgeTypeSchema>;
467
+ /** A raw entry as stored in dependency.state.json. */
468
+ declare const dependencyStateEntrySchema: z.ZodUnion<readonly [z.ZodString, z.ZodTuple<[z.ZodString, z.ZodNumber], null>, z.ZodTuple<[z.ZodString, z.ZodNumber, z.ZodArray<z.ZodEnum<{
469
+ type: "type";
470
+ runtime: "runtime";
471
+ dynamic: "dynamic";
472
+ }>>], null>]>;
473
+ type DependencyStateEntry = z.infer<typeof dependencyStateEntrySchema>;
474
+ /** Normalized internal representation of a state entry (defaults applied). */
475
+ type NormalizedDependencyStateEntry = {
476
+ nodeId: string;
477
+ depth: number;
478
+ edgeKinds: DependencyEdgeType[];
479
+ };
480
+ declare const dependencyStateFileSchema: z.ZodObject<{
481
+ include: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodTuple<[z.ZodString, z.ZodNumber], null>, z.ZodTuple<[z.ZodString, z.ZodNumber, z.ZodArray<z.ZodEnum<{
482
+ type: "type";
483
+ runtime: "runtime";
484
+ dynamic: "dynamic";
485
+ }>>], null>]>>;
486
+ exclude: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodTuple<[z.ZodString, z.ZodNumber], null>, z.ZodTuple<[z.ZodString, z.ZodNumber, z.ZodArray<z.ZodEnum<{
487
+ type: "type";
488
+ runtime: "runtime";
489
+ dynamic: "dynamic";
490
+ }>>], null>]>>>;
491
+ }, z.core.$strict>;
492
+ type DependencyStateFile = z.infer<typeof dependencyStateFileSchema>;
493
+ /** Parse and normalize state entries (defaults applied; stable edgeKinds). */
494
+ declare const parseDependencyStateFile: (raw: unknown) => {
495
+ include: NormalizedDependencyStateEntry[];
496
+ exclude: NormalizedDependencyStateEntry[];
497
+ };
498
+ /** Dependency meta edge record (minimal, assistant-facing). */
499
+ declare const dependencyMetaEdgeSchema: z.ZodObject<{
500
+ target: z.ZodString;
501
+ kind: z.ZodEnum<{
502
+ type: "type";
503
+ runtime: "runtime";
504
+ dynamic: "dynamic";
505
+ }>;
506
+ resolution: z.ZodOptional<z.ZodEnum<{
507
+ explicit: "explicit";
508
+ implicit: "implicit";
509
+ }>>;
510
+ }, z.core.$strict>;
511
+ type DependencyMetaEdge = z.infer<typeof dependencyMetaEdgeSchema>;
512
+ /** Dependency meta node (assistant-facing). */
513
+ declare const dependencyMetaNodeSchema: z.ZodObject<{
514
+ kind: z.ZodEnum<{
515
+ source: "source";
516
+ external: "external";
517
+ builtin: "builtin";
518
+ missing: "missing";
519
+ }>;
520
+ metadata: z.ZodOptional<z.ZodObject<{
521
+ size: z.ZodOptional<z.ZodNumber>;
522
+ hash: z.ZodOptional<z.ZodString>;
523
+ }, z.core.$strict>>;
524
+ description: z.ZodOptional<z.ZodString>;
525
+ locatorAbs: z.ZodOptional<z.ZodString>;
526
+ }, z.core.$strict>;
527
+ type DependencyMetaNode = z.infer<typeof dependencyMetaNodeSchema>;
528
+ /**
529
+ * Dependency meta file (assistant-facing).
530
+ *
531
+ * Notes:
532
+ * - node IDs are repo-relative POSIX paths.
533
+ * - edges is a complete map (key exists for every nodeId; empty array OK).
534
+ */
535
+ declare const dependencyMetaFileSchema: z.ZodObject<{
536
+ schemaVersion: z.ZodNumber;
537
+ nodes: z.ZodRecord<z.ZodString, z.ZodObject<{
538
+ kind: z.ZodEnum<{
539
+ source: "source";
540
+ external: "external";
541
+ builtin: "builtin";
542
+ missing: "missing";
543
+ }>;
544
+ metadata: z.ZodOptional<z.ZodObject<{
545
+ size: z.ZodOptional<z.ZodNumber>;
546
+ hash: z.ZodOptional<z.ZodString>;
547
+ }, z.core.$strict>>;
548
+ description: z.ZodOptional<z.ZodString>;
549
+ locatorAbs: z.ZodOptional<z.ZodString>;
550
+ }, z.core.$strict>>;
551
+ edges: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
552
+ target: z.ZodString;
553
+ kind: z.ZodEnum<{
554
+ type: "type";
555
+ runtime: "runtime";
556
+ dynamic: "dynamic";
557
+ }>;
558
+ resolution: z.ZodOptional<z.ZodEnum<{
559
+ explicit: "explicit";
560
+ implicit: "implicit";
561
+ }>>;
562
+ }, z.core.$strict>>>;
563
+ }, z.core.$strict>;
564
+ type DependencyMetaFile = z.infer<typeof dependencyMetaFileSchema>;
565
+
566
+ /**
567
+ * Computes context-mode allowlist plans (Base + dependency closure), applying
568
+ * explicit excludes as hard denials and identifying stageable external nodeIds
569
+ * under <stanPath>/context/npm/** and <stanPath>/context/abs/**; filesystem IO
570
+ * only; no console output.
571
+ * @module
572
+ */
573
+
574
+ type ContextModeSelection = {
575
+ includes?: string[];
576
+ excludes?: string[];
577
+ };
578
+ type ContextAllowlistPlan = {
579
+ /** Base (system + dependency meta/state + repo-root base files). */
580
+ baseFiles: string[];
581
+ /** All selected nodeIds from dependency state closure (after excludes/reserved). */
582
+ selectedNodeIds: string[];
583
+ /** External nodeIds that must be staged into <stanPath>/context/**. */
584
+ stageNodeIds: string[];
585
+ /** Final allowlist (Base + selected closure; after excludes/reserved). */
586
+ allowlistFiles: string[];
587
+ /** True when dependency.state.json existed on disk and was used implicitly. */
588
+ usedDiskState: boolean;
589
+ };
590
+ /**
591
+ * Compute context-mode Base and allowlist selection.
592
+ *
593
+ * Base definition (v1):
594
+ * - system docs under <stanPath>/system/** (excluding <stanPath>/system/.docs.meta.json)
595
+ * - dependency meta at <stanPath>/context/dependency.meta.json (required)
596
+ * - dependency state at <stanPath>/context/dependency.state.json (when present)
597
+ * - plus repo-root files selected by current selection config (top-level files only)
598
+ *
599
+ * Allowlist:
600
+ * - Base + selected dependency closure (repo-local nodeIds + staged externals)
601
+ * - apply explicit excludes as hard denials
602
+ * - reserved denials always win
603
+ */
604
+ declare const computeContextAllowlistPlan: (args: {
605
+ cwd: string;
606
+ stanPath: string;
607
+ meta: Pick<DependencyMetaFile, "nodes" | "edges">;
608
+ state?: unknown;
609
+ selection?: ContextModeSelection;
610
+ }) => Promise<ContextAllowlistPlan>;
611
+
612
+ /**
613
+ * Types for dependency graph build and normalization.
614
+ * @module
615
+ */
616
+
617
+ type BuildDependencyMetaArgs = {
618
+ cwd: string;
619
+ stanPath: string;
620
+ selection?: {
621
+ includes?: string[];
622
+ excludes?: string[];
623
+ };
624
+ nodeDescriptionLimit?: number;
625
+ nodeDescriptionTags?: string[];
626
+ maxErrors?: number;
627
+ };
628
+ type NodeSource = {
629
+ kind: 'repo';
630
+ } | {
631
+ kind: 'npm';
632
+ sourceAbs: string;
633
+ pkgName: string;
634
+ pkgVersion: string;
635
+ pathInPackage: string;
636
+ } | {
637
+ kind: 'abs';
638
+ sourceAbs: string;
639
+ locatorAbs: string;
640
+ };
641
+ type BuildDependencyMetaResult = {
642
+ meta: DependencyMetaFile;
643
+ sources: Record<string, NodeSource>;
644
+ warnings: string[];
645
+ stats?: {
646
+ modules: number;
647
+ edges: number;
648
+ dirty: number;
649
+ };
650
+ };
651
+
652
+ declare const buildDependencyMeta: (args: BuildDependencyMetaArgs) => Promise<BuildDependencyMetaResult>;
653
+
654
+ type StageDependencyContextArgs = {
655
+ cwd: string;
656
+ stanPath: string;
657
+ /** Parsed dependency meta (usually produced by buildDependencyMeta). */
658
+ meta: {
659
+ nodes: Record<string, DependencyMetaNode | undefined>;
660
+ };
661
+ /**
662
+ * Optional source map (usually from buildDependencyMeta). If absent, abs
663
+ * nodes can still be staged via meta.nodes[nodeId].locatorAbs.
664
+ */
665
+ sources?: Record<string, NodeSource>;
666
+ /**
667
+ * Optional subset of nodeIds to stage (e.g., a selection closure).
668
+ * If omitted, stages all nodeIds present in sources (filtered to stageable).
669
+ */
670
+ nodeIds?: string[];
671
+ /**
672
+ * When true, clears <stanPath>/context/npm and <stanPath>/context/abs before staging.
673
+ * Does NOT touch dependency.meta.json or dependency.state.json.
674
+ */
675
+ clean?: boolean;
676
+ };
677
+ type StagedEntry = {
678
+ nodeId: string;
679
+ sourceAbs: string;
680
+ destAbs: string;
681
+ hash: string;
682
+ size: number;
683
+ };
684
+ type StageDependencyContextResult = {
685
+ staged: StagedEntry[];
686
+ skipped: string[];
687
+ };
688
+ declare const stageDependencyContext: (args: StageDependencyContextArgs) => Promise<StageDependencyContextResult>;
689
+
690
+ /**
691
+ * Orchestrates dependency-graph archive flows (stage context + force includes);
692
+ * calls archive/diff helpers; filesystem IO only; no console output.
693
+ *
694
+ * Dependency graph mode: orchestration helpers for CLI-facing archive flows.
695
+ *
696
+ * Requirements:
697
+ * - Stage dependency external bytes (npm + abs) into <stanPath>/context/** before archiving.
698
+ * - Prefer staging ONLY the selected nodeId set derived from dependency state closure to avoid bloat.
699
+ * - Ensure <stanPath>/context/** is included in archives even when gitignored (use includes).
700
+ * - No console I/O; keep behavior deterministic.
701
+ * @module
702
+ */
703
+
704
+ type DependencyContextMeta = Pick<DependencyMetaFile, 'edges'> & {
705
+ nodes: Record<string, DependencyMetaNode | undefined>;
706
+ };
707
+ type DependencyContextInputs = {
708
+ meta: DependencyContextMeta;
709
+ /**
710
+ * Dependency selection state (assistant-authored).
711
+ * When present, used to compute a selected closure and stage only those nodes.
712
+ * When absent, staging falls back to "all stageable nodes in sources".
713
+ */
714
+ state?: unknown;
715
+ /**
716
+ * Node source locators (produced by buildDependencyMeta).
717
+ * Strongly recommended for npm nodes; abs nodes may also be staged using locatorAbs from meta.
718
+ */
719
+ sources?: Record<string, NodeSource>;
720
+ };
721
+ type PrepareDependencyContextResult = {
722
+ /** Include globs required to include <stanPath>/context/** even if gitignored. */
723
+ includes: string[];
724
+ /** Node IDs selected by state closure (empty when state not provided). */
725
+ selectedNodeIds: string[];
726
+ /** Node IDs that should be staged (subset of selected, stageable only). */
727
+ stageNodeIds: string[];
728
+ };
729
+ declare const prepareDependencyContext: (args: {
730
+ stanPath: string;
731
+ meta: DependencyContextMeta;
732
+ state?: unknown;
733
+ /** Optional override when state is omitted (default: stage all stageable nodes in sources). */
734
+ nodeIdsWhenNoState?: string[];
735
+ }) => PrepareDependencyContextResult;
736
+ type StagePreparedDependencyContextResult = PrepareDependencyContextResult & {
737
+ stage: StageDependencyContextResult;
738
+ };
739
+ declare const stagePreparedDependencyContext: (args: {
740
+ cwd: string;
741
+ stanPath: string;
742
+ meta: DependencyContextMeta;
743
+ sources?: Record<string, NodeSource>;
744
+ plan: PrepareDependencyContextResult;
745
+ clean?: boolean;
746
+ }) => Promise<StagePreparedDependencyContextResult>;
747
+ type CreateArchiveWithDependencyContextResult = StagePreparedDependencyContextResult & {
748
+ archivePath: string;
749
+ };
750
+ declare const createArchiveWithDependencyContext: (args: {
751
+ cwd: string;
752
+ stanPath: string;
753
+ dependency: DependencyContextInputs & {
754
+ clean?: boolean;
755
+ };
756
+ archive?: CreateArchiveOptions;
757
+ }) => Promise<CreateArchiveWithDependencyContextResult>;
758
+ type CreateArchiveDiffWithDependencyContextResult = StagePreparedDependencyContextResult & {
759
+ diffPath: string;
760
+ };
761
+ declare const createArchiveDiffWithDependencyContext: (args: {
762
+ cwd: string;
763
+ stanPath: string;
764
+ dependency: DependencyContextInputs & {
765
+ clean?: boolean;
766
+ };
767
+ diff: {
768
+ baseName: string;
769
+ includes?: string[];
770
+ excludes?: string[];
771
+ updateSnapshot?: SnapshotUpdateMode;
772
+ includeOutputDirInDiff?: boolean;
773
+ onArchiveWarnings?: (text: string) => void;
774
+ };
775
+ }) => Promise<CreateArchiveDiffWithDependencyContextResult>;
776
+
777
+ /**
778
+ * Computes a deterministic size report for a context-mode allowlist (Base +
779
+ * dependency closure). Uses dependency meta `metadata.size` (bytes) when
780
+ * available and falls back to `stat()` for repo files; no file-body reads.
781
+ * @module
782
+ */
783
+
784
+ type BudgetSource = 'meta' | 'stat' | 'missing';
785
+ type BudgetEntry = {
786
+ /** Repo-relative POSIX path. */
787
+ path: string;
788
+ /** Size in bytes (0 when unknown/missing). */
789
+ bytes: number;
790
+ /** Where the bytes estimate came from. */
791
+ source: BudgetSource;
792
+ };
793
+ type ContextAllowlistBudget = {
794
+ /** Total number of allowlisted paths. */
795
+ files: number;
796
+ /** Total bytes across allowlisted paths. */
797
+ totalBytes: number;
798
+ /** Deterministic heuristic: totalBytes / 4. */
799
+ estimatedTokens: number;
800
+ /** Budgeting breakdown by set membership. */
801
+ breakdown: {
802
+ baseOnly: {
803
+ files: number;
804
+ bytes: number;
805
+ };
806
+ closureOnly: {
807
+ files: number;
808
+ bytes: number;
809
+ };
810
+ overlap: {
811
+ files: number;
812
+ bytes: number;
813
+ };
814
+ };
815
+ /** Largest allowlisted entries by byte size (descending). */
816
+ largest: BudgetEntry[];
817
+ /** Deterministic warnings (missing sizes, missing files, invalid metadata). */
818
+ warnings: string[];
819
+ };
820
+ /**
821
+ * Summarize the byte size of a context allowlist deterministically.
822
+ *
823
+ * @param args - Inputs object (repo root, allowlist plan, dependency meta nodes
824
+ * map, and optional max count for largest entries).
825
+ */
826
+ declare const summarizeContextAllowlistBudget: (args: {
827
+ cwd: string;
828
+ plan: {
829
+ baseFiles: ReadonlyArray<string>;
830
+ selectedNodeIds: ReadonlyArray<string>;
831
+ allowlistFiles: ReadonlyArray<string>;
832
+ };
833
+ meta: Pick<DependencyMetaFile, "nodes">;
834
+ topN?: number;
835
+ }) => Promise<ContextAllowlistBudget>;
836
+
837
+ /**
838
+ * Orchestrates context-mode allowlist-only archiving (Base + dependency closure)
839
+ * by staging selected external node bytes under <stanPath>/context/** and then
840
+ * creating full/diff archives from the computed allowlist; filesystem IO only;
841
+ * no console output.
842
+ * @module
843
+ */
844
+
845
+ type CreateContextArchiveOptions = Pick<CreateArchiveFromFilesOptions, 'fileName' | 'onArchiveWarnings'> & {
846
+ /** Context mode should remain allowlist-only; output dir inclusion is rarely desired. */
847
+ includeOutputDir?: false;
848
+ };
849
+ type CreateContextArchiveResult = {
850
+ archivePath: string;
851
+ plan: Awaited<ReturnType<typeof computeContextAllowlistPlan>>;
852
+ stage: StageDependencyContextResult;
853
+ };
854
+ declare const createContextArchiveWithDependencyContext: (args: {
855
+ cwd: string;
856
+ stanPath: string;
857
+ dependency: {
858
+ meta: Pick<DependencyMetaFile, "nodes" | "edges">;
859
+ state?: unknown;
860
+ sources?: Record<string, NodeSource>;
861
+ clean?: boolean;
862
+ };
863
+ selection?: ContextModeSelection;
864
+ archive?: CreateContextArchiveOptions;
865
+ }) => Promise<CreateContextArchiveResult>;
866
+ type CreateContextArchiveDiffResult = {
867
+ diffPath: string;
868
+ plan: Awaited<ReturnType<typeof computeContextAllowlistPlan>>;
869
+ stage: StageDependencyContextResult;
870
+ };
871
+ declare const createContextArchiveDiffWithDependencyContext: (args: {
872
+ cwd: string;
873
+ stanPath: string;
874
+ dependency: {
875
+ meta: Pick<DependencyMetaFile, "nodes" | "edges">;
876
+ state?: unknown;
877
+ sources?: Record<string, NodeSource>;
878
+ clean?: boolean;
879
+ };
880
+ selection?: ContextModeSelection;
881
+ diff: {
882
+ baseName: string;
883
+ updateSnapshot?: SnapshotUpdateMode;
884
+ includeOutputDirInDiff?: boolean;
885
+ onArchiveWarnings?: (text: string) => void;
886
+ };
887
+ }) => Promise<CreateContextArchiveDiffResult>;
888
+
889
+ /**
890
+ * Computes dependency selection closure from meta+state (depth + edgeKinds);
891
+ * deterministic BFS; pure graph traversal; no filesystem IO.
892
+ *
893
+ * Dependency graph mode: compute selected node IDs from:
894
+ * - dependency.meta.json edges
895
+ * - dependency.state.json include/exclude entries
896
+ *
897
+ * Requirements:
898
+ * - Depth semantics: 0 =\> node only (no traversal).
899
+ * - Traverse outgoing edges only, restricted by edgeKinds.
900
+ * - Deterministic selection: stable ordering across runs for identical inputs.
901
+ * - Excludes win: subtract after includes using same traversal semantics.
902
+ * @module
903
+ */
904
+
905
+ /**
906
+ * Expand a single state entry into a set of nodeIds (node + closure).
907
+ * BFS is used so depth is intuitive and deterministic.
908
+ */
909
+ declare const expandEntry: (meta: Pick<DependencyMetaFile, "edges">, entry: NormalizedDependencyStateEntry) => Set<string>;
910
+ /**
911
+ * Compute final selected nodeIds from include/exclude entries.
912
+ * Excludes win (subtract after includes).
913
+ */
914
+ declare const computeSelectedNodeIds: (args: {
915
+ meta: Pick<DependencyMetaFile, "edges">;
916
+ include: NormalizedDependencyStateEntry[];
917
+ exclude: NormalizedDependencyStateEntry[];
918
+ }) => string[];
919
+
920
+ /**
921
+ * Public types for dependency selection validation (undo/redo seam); used by
922
+ * validators and callers; no runtime code.
923
+ * @module
924
+ */
925
+ type DependencyValidationMismatch = {
926
+ nodeId: string;
927
+ kind: 'npm';
928
+ reason: 'invalid-nodeId' | 'meta-missing' | 'metadata-missing' | 'package-not-found' | 'package-version-mismatch' | 'file-missing' | 'hash-mismatch' | 'size-mismatch';
929
+ pkgName?: string;
930
+ pkgVersion?: string;
931
+ pathInPackage?: string;
932
+ expectedHash?: string;
933
+ actualHash?: string;
934
+ expectedSize?: number;
935
+ actualSize?: number;
936
+ candidates?: string[];
937
+ } | {
938
+ nodeId: string;
939
+ kind: 'abs';
940
+ reason: 'meta-missing' | 'metadata-missing' | 'locator-missing' | 'file-missing' | 'hash-mismatch' | 'size-mismatch';
941
+ locatorAbs?: string;
942
+ expectedHash?: string;
943
+ actualHash?: string;
944
+ expectedSize?: number;
945
+ actualSize?: number;
946
+ };
947
+ type ValidateDependencySelectionResult = {
948
+ ok: boolean;
949
+ selectedNodeIds: string[];
950
+ checkedNodeIds: string[];
951
+ mismatches: DependencyValidationMismatch[];
952
+ };
953
+
954
+ /**
955
+ * Validate that the selected dependency set (from meta+state closure) can be
956
+ * satisfied by the current environment.
957
+ *
958
+ * - Computes selected node IDs from meta+state closure (excludes win).
959
+ * - Validates external nodes only:
960
+ * - npm nodes under `<stanPath>/context/npm/**` by locating `<pkgName>\@<pkgVersion>`
961
+ * in the current install and hashing `<pathInPackage>`.
962
+ * - abs nodes under `<stanPath>/context/abs/**` by hashing `locatorAbs`.
963
+ *
964
+ * @param args - Validation inputs.
965
+ * @returns Validation result with deterministic mismatches.
966
+ */
967
+ declare const validateDependencySelection: (args: {
968
+ cwd: string;
969
+ stanPath: string;
970
+ meta: Pick<DependencyMetaFile, "nodes" | "edges">;
971
+ state: unknown;
972
+ }) => Promise<ValidateDependencySelectionResult>;
973
+ /**
974
+ * Validate dependency selection and throw on mismatch (strict undo/redo seam).
975
+ *
976
+ * @param args - Validation inputs.
977
+ * @returns Resolves when validation passes; throws when mismatches exist.
978
+ */
979
+ declare const validateDependencySelectionOrThrow: (args: {
980
+ cwd: string;
981
+ stanPath: string;
982
+ meta: Pick<DependencyMetaFile, "nodes" | "edges">;
983
+ state: unknown;
984
+ }) => Promise<void>;
985
+
986
+ declare const writeDependencyMetaFile: (args: {
987
+ cwd: string;
988
+ stanPath: string;
989
+ meta: DependencyMetaFile;
990
+ }) => Promise<string>;
991
+
344
992
  /**
345
993
  * Compile an engine‑parity matcher that returns true when any pattern matches.
346
994
  *
@@ -374,5 +1022,5 @@ declare const assembleSystemMonolith: (cwd: string, stanPath: string) => Promise
374
1022
 
375
1023
  declare const CORE_VERSION: string;
376
1024
 
377
- export { CORE_VERSION, DEFAULT_OPEN_COMMAND, DEFAULT_STAN_PATH, __internal, applyPatchPipeline, applyWithJsDiff, assembleSystemMonolith, createArchive, createArchiveDiff, detectAndCleanPatch, ensureOutputDir, executeFileOps, findConfigPathSync, getPackagedSystemPromptPath, loadConfig, loadConfigSync, makeGlobMatcher, parseFileOpsBlock, prepareImports, resolveStanPath, resolveStanPathSync, validateOrThrow, validateResponseMessage, writeArchiveSnapshot };
378
- export type { ApplyResult, AssembleResult, AttemptCapture, Block, BlockKind, ContextConfig, CreateArchiveOptions, FileOp, FileOpsPlan, ImportsMap, JsDiffOutcome, OpResult, PipelineOutcome, SnapshotUpdateMode, ValidationResult };
1025
+ export { CORE_VERSION, DEFAULT_OPEN_COMMAND, DEFAULT_STAN_PATH, applyPatchPipeline, applyWithJsDiff, assembleSystemMonolith, buildDependencyMeta, computeContextAllowlistPlan, computeSelectedNodeIds, createArchive, createArchiveDiff, createArchiveDiffWithDependencyContext, createArchiveWithDependencyContext, createContextArchiveDiffWithDependencyContext, createContextArchiveWithDependencyContext, createMetaArchive, dependencyEdgeTypeSchema, dependencyMetaEdgeSchema, dependencyMetaFileSchema, dependencyMetaNodeSchema, dependencyStateEntrySchema, dependencyStateFileSchema, detectAndCleanPatch, ensureOutputDir, executeFileOps, expandEntry, findConfigPathSync, getPackagedSystemPromptPath, loadConfig, loadConfigSync, makeGlobMatcher, parseDependencyStateFile, parseFileOpsBlock, prepareDependencyContext, prepareImports, resolveStanPath, resolveStanPathSync, stageDependencyContext, stagePreparedDependencyContext, summarizeContextAllowlistBudget, validateDependencySelection, validateDependencySelectionOrThrow, validateOrThrow, validateResponseMessage, writeArchiveSnapshot, writeDependencyMetaFile };
1026
+ export type { ApplyResult, AssembleResult, AttemptCapture, Block, BlockKind, BudgetEntry, BudgetSource, BuildDependencyMetaArgs, BuildDependencyMetaResult, ContextAllowlistBudget, ContextAllowlistPlan, ContextConfig, ContextModeSelection, CreateArchiveDiffWithDependencyContextResult, CreateArchiveFromFilesOptions, CreateArchiveOptions, CreateArchiveWithDependencyContextResult, CreateContextArchiveDiffResult, CreateContextArchiveOptions, CreateContextArchiveResult, DependencyContextInputs, DependencyContextMeta, DependencyEdgeType, DependencyMetaEdge, DependencyMetaFile, DependencyMetaNode, DependencyStateEntry, DependencyStateFile, DependencyValidationMismatch, FileOp, FileOpsPlan, ImportsMap, JsDiffOutcome, NodeSource, NormalizedDependencyStateEntry, OpResult, PipelineOutcome, PrepareDependencyContextResult, SelectionReport, SelectionReportCounts, SnapshotUpdateMode, StageDependencyContextArgs, StageDependencyContextResult, StagePreparedDependencyContextResult, StagedEntry, ValidateDependencySelectionResult, ValidateResponseOptions, ValidationResult };