codebase-snapshot 0.0.0-stage → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1242 -0
- package/LICENSE +21 -0
- package/README.md +276 -2
- package/SECURITY.md +110 -0
- package/dist/bin.js +9840 -0
- package/dist/chunk-FJ4RQYY2.js +7885 -0
- package/dist/cli.cjs +9822 -0
- package/dist/cli.d.cts +124 -0
- package/dist/cli.d.ts +124 -0
- package/dist/cli.js +1931 -0
- package/dist/index.cjs +7973 -0
- package/dist/index.d.cts +710 -0
- package/dist/index.d.ts +710 -0
- package/dist/index.js +3 -0
- package/dist/types-Ca4PmkiQ.d.cts +491 -0
- package/dist/types-Ca4PmkiQ.d.ts +491 -0
- package/docs/agent.md +135 -0
- package/docs/cli.md +437 -0
- package/docs/configuration.md +424 -0
- package/docs/how-to-context-budget.md +90 -0
- package/docs/how-to-feed-a-repo-to-claude.md +122 -0
- package/docs/install.md +196 -0
- package/docs/output.md +264 -0
- package/docs/troubleshooting.md +384 -0
- package/docs/vs-code2prompt.md +66 -0
- package/docs/vs-gitingest.md +69 -0
- package/docs/vs-repomix.md +83 -0
- package/package.json +112 -4
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { ARTIFACT_NAMES, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PRESETS, PromptCancelled, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, isBinaryBuffer, isBinaryExtension, isBinaryFile, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot } from './chunk-FJ4RQYY2.js';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
type Mode = "generate" | "validate" | "report";
|
|
2
|
+
type OutputFormat = "text" | "json";
|
|
3
|
+
/**
|
|
4
|
+
* How files are discovered.
|
|
5
|
+
*
|
|
6
|
+
* `auto` lists files through git when git can do it and walks the tree otherwise; `git` and `walk`
|
|
7
|
+
* force one path. It is part of the manifest's recorded settings because it decides which files a
|
|
8
|
+
* snapshot contains — the same repository scanned both ways is two different snapshots.
|
|
9
|
+
*/
|
|
10
|
+
type DiscoveryMode = "auto" | "git" | "walk";
|
|
11
|
+
/**
|
|
12
|
+
* How a file's bytes became text.
|
|
13
|
+
*
|
|
14
|
+
* Absent from a `FileEntry` means plain UTF-8, which is the overwhelmingly common case. The other
|
|
15
|
+
* values are recorded because they change what the artifact actually contains: `utf-16le`/`utf-16be`
|
|
16
|
+
* files were transcoded, and `utf-8-lossy` files carry U+FFFD where their undecodable bytes were.
|
|
17
|
+
*/
|
|
18
|
+
type TextEncoding = "utf-8" | "utf-8-lossy" | "utf-16le" | "utf-16be";
|
|
19
|
+
/**
|
|
20
|
+
* How much of a file made it into the snapshot.
|
|
21
|
+
* `full` – the complete file body was emitted.
|
|
22
|
+
* `preview` – the body was truncated (by lines and/or bytes) before emission.
|
|
23
|
+
*/
|
|
24
|
+
type InclusionMode = "full" | "preview";
|
|
25
|
+
interface SourceSummary {
|
|
26
|
+
directives: string[];
|
|
27
|
+
imports: string[];
|
|
28
|
+
exports: string[];
|
|
29
|
+
/** Module specifiers re-exported wholesale via `export * from "..."`. */
|
|
30
|
+
reExports: string[];
|
|
31
|
+
functions: string[];
|
|
32
|
+
classes: string[];
|
|
33
|
+
interfaces: string[];
|
|
34
|
+
types: string[];
|
|
35
|
+
enums: string[];
|
|
36
|
+
variables: string[];
|
|
37
|
+
reactComponents: string[];
|
|
38
|
+
hooks: string[];
|
|
39
|
+
routeHandlers: string[];
|
|
40
|
+
/** Number of parser diagnostics, present only when the file has syntax errors. */
|
|
41
|
+
parseErrors?: number;
|
|
42
|
+
}
|
|
43
|
+
interface JsonSummary {
|
|
44
|
+
shape: string;
|
|
45
|
+
itemCount: number | null;
|
|
46
|
+
keys: string[];
|
|
47
|
+
sampleKeys: string[];
|
|
48
|
+
}
|
|
49
|
+
interface MarkdownSummary {
|
|
50
|
+
headings: string[];
|
|
51
|
+
frontmatterKeys: string[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* How a summary was produced.
|
|
55
|
+
*
|
|
56
|
+
* `ast` — a real parser (TypeScript compiler; the script block of a
|
|
57
|
+
* Vue/Svelte/Astro component).
|
|
58
|
+
* `structural` — a real grammar for a data format (JSON, Markdown).
|
|
59
|
+
* `heuristic` — line patterns. Useful, but not a parse, and never presented
|
|
60
|
+
* as one.
|
|
61
|
+
*/
|
|
62
|
+
type SummaryQuality = "ast" | "structural" | "heuristic";
|
|
63
|
+
/**
|
|
64
|
+
* Why a discovered path was not emitted.
|
|
65
|
+
*
|
|
66
|
+
* Every reason below is produced by the scanner; nothing in the type is
|
|
67
|
+
* aspirational. `asset` was removed because no code path ever emitted it.
|
|
68
|
+
*/
|
|
69
|
+
type SkipReason = "binary" | "read-error" | "not-file"
|
|
70
|
+
/** A credential-bearing name (`.env`, `*.pem`, `.npmrc`, …). */
|
|
71
|
+
| "sensitive-file"
|
|
72
|
+
/** The path itself matched a secret rule; the emitted path is span-masked. */
|
|
73
|
+
| "sensitive-path"
|
|
74
|
+
/** A directory link (never followed), or a link to neither file nor directory. */
|
|
75
|
+
| "symlink"
|
|
76
|
+
/** A file link whose target resolves outside the scanned root. */
|
|
77
|
+
| "outside-root"
|
|
78
|
+
/** Excluded by a `.gitignore` in a scan without git. */
|
|
79
|
+
| "gitignore"
|
|
80
|
+
/** Excluded by a built-in rule: the ignore list, a preset, or an output dir. */
|
|
81
|
+
| "default-ignore"
|
|
82
|
+
/** Excluded by the user's own `excludePatterns` or `include` allow-list. */
|
|
83
|
+
| "excluded"
|
|
84
|
+
/**
|
|
85
|
+
* A directory that belongs to another repository: a nested checkout or a submodule.
|
|
86
|
+
*
|
|
87
|
+
* A submodule is a single gitlink entry, so `stat` reports a directory where a file was
|
|
88
|
+
* expected — which used to be recorded as the generic `not-file`, implying the path was a
|
|
89
|
+
* socket or a FIFO rather than a repository whose contents are simply somebody else's.
|
|
90
|
+
*/
|
|
91
|
+
| "nested-repository";
|
|
92
|
+
interface SkipRecord {
|
|
93
|
+
/** Path as it may be shown in an artifact: secret spans are masked. */
|
|
94
|
+
path: string;
|
|
95
|
+
reason: SkipReason;
|
|
96
|
+
detail?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* One scanned file. Field names are canonical and unique by design:
|
|
100
|
+
* earlier releases carried `path`/`relativePath`, `sizeBytes`/`bytes` and
|
|
101
|
+
* `hashSha256`/`sha256` aliases that could only ever agree.
|
|
102
|
+
*/
|
|
103
|
+
interface FileEntry {
|
|
104
|
+
relativePath: string;
|
|
105
|
+
sizeBytes: number;
|
|
106
|
+
lines: number;
|
|
107
|
+
hashSha256: string;
|
|
108
|
+
part: string;
|
|
109
|
+
layer: string;
|
|
110
|
+
kind: string;
|
|
111
|
+
language: string;
|
|
112
|
+
inclusionMode: InclusionMode;
|
|
113
|
+
isLarge: boolean;
|
|
114
|
+
isPreviewTruncated: boolean;
|
|
115
|
+
/** Line count of the file on disk. */
|
|
116
|
+
originalLines: number;
|
|
117
|
+
/** Lines actually emitted into the snapshot. */
|
|
118
|
+
includedLines: number;
|
|
119
|
+
/** UTF-8 bytes of file content actually emitted into the snapshot. */
|
|
120
|
+
includedBytes: number;
|
|
121
|
+
summary?: SourceSummary | JsonSummary | MarkdownSummary;
|
|
122
|
+
/** How the summary was produced. Absent when there is no summary. */
|
|
123
|
+
summaryQuality?: SummaryQuality;
|
|
124
|
+
/** True when the summary alone was too large for the part budget and was dropped. */
|
|
125
|
+
summaryOmitted?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* How the file's bytes were decoded. Absent means plain UTF-8. Present when the file was
|
|
128
|
+
* transcoded from UTF-16, or when it was not valid UTF-8 and lost bytes to U+FFFD.
|
|
129
|
+
*/
|
|
130
|
+
encoding?: TextEncoding;
|
|
131
|
+
/** Emitted body after redaction/truncation. Never serialized into the manifest. */
|
|
132
|
+
content?: string;
|
|
133
|
+
}
|
|
134
|
+
interface PartFileEntry {
|
|
135
|
+
relativePath: string;
|
|
136
|
+
sourceBytes: number;
|
|
137
|
+
includedBytes: number;
|
|
138
|
+
lines: number;
|
|
139
|
+
layer: string;
|
|
140
|
+
kind: string;
|
|
141
|
+
}
|
|
142
|
+
interface PartMetadata {
|
|
143
|
+
index: number;
|
|
144
|
+
filename: string;
|
|
145
|
+
/** Exact UTF-8 byte length of the emitted part file. */
|
|
146
|
+
byteSize: number;
|
|
147
|
+
sha256: string;
|
|
148
|
+
lines: number;
|
|
149
|
+
fileCount: number;
|
|
150
|
+
layersCovered: string[];
|
|
151
|
+
includedFiles: PartFileEntry[];
|
|
152
|
+
}
|
|
153
|
+
interface SecretRule {
|
|
154
|
+
rule: string;
|
|
155
|
+
pattern: RegExp;
|
|
156
|
+
/**
|
|
157
|
+
* Index of the capture group that holds the secret, when the rule has to match
|
|
158
|
+
* its surrounding context to identify one (`password: "…"`). Redaction then
|
|
159
|
+
* masks only that group, so the key and the rest of the line survive.
|
|
160
|
+
*/
|
|
161
|
+
valueGroup?: number;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Shape accepted for `secrets.customPatterns`.
|
|
165
|
+
*
|
|
166
|
+
* A bare `RegExp` or string is accepted because it is the documented form; the
|
|
167
|
+
* object form exists to name a rule. `valueGroup` is only useful with the object
|
|
168
|
+
* form, since a bare pattern has no group to name.
|
|
169
|
+
*/
|
|
170
|
+
type SecretRuleInput = {
|
|
171
|
+
rule: string;
|
|
172
|
+
pattern: RegExp | string;
|
|
173
|
+
valueGroup?: number;
|
|
174
|
+
} | RegExp | string;
|
|
175
|
+
/**
|
|
176
|
+
* A detected secret. Deliberately carries no excerpt of the matched source:
|
|
177
|
+
* the previous `snippet` field was the vector by which raw credentials were
|
|
178
|
+
* written into `reports/audit.md`.
|
|
179
|
+
*/
|
|
180
|
+
interface SecretFinding {
|
|
181
|
+
/**
|
|
182
|
+
* Every rule that matched this line, in rule-table order.
|
|
183
|
+
*
|
|
184
|
+
* One finding is one *line*, not one (line, rule) pair. A single line can match two rules — an
|
|
185
|
+
* unquoted `AUTH_TOKEN=<value>` assignment matches both `credential-assignment-unquoted` and
|
|
186
|
+
* `env-secret-assignment` — and reporting it twice doubled the figure a user is asked to explain,
|
|
187
|
+
* in the CLI summary and in `reports/audit.md` alike.
|
|
188
|
+
*/
|
|
189
|
+
rules: string[];
|
|
190
|
+
line: number;
|
|
191
|
+
path?: string;
|
|
192
|
+
}
|
|
193
|
+
interface ManifestTotals {
|
|
194
|
+
candidateFiles: number;
|
|
195
|
+
includedFiles: number;
|
|
196
|
+
fullFiles: number;
|
|
197
|
+
previewFiles: number;
|
|
198
|
+
skippedFiles: number;
|
|
199
|
+
totalSourceBytes: number;
|
|
200
|
+
totalContentBytes: number;
|
|
201
|
+
partCount: number;
|
|
202
|
+
warningCount: number;
|
|
203
|
+
/**
|
|
204
|
+
* Lines whose values were masked, counted once per line.
|
|
205
|
+
*
|
|
206
|
+
* Separate from `warningCount` because they are not the same event: a warning says the snapshot
|
|
207
|
+
* may surprise you, while a redaction says the tool did its job. Folding them together made a
|
|
208
|
+
* clean repository report `Warnings: 156` and left the summary's own slice of ten looking like
|
|
209
|
+
* a truncated warning list.
|
|
210
|
+
*/
|
|
211
|
+
redactedLines: number;
|
|
212
|
+
}
|
|
213
|
+
interface ManifestArtifact {
|
|
214
|
+
byteSize: number;
|
|
215
|
+
sha256: string;
|
|
216
|
+
}
|
|
217
|
+
interface ManifestIndexes {
|
|
218
|
+
routes: Array<{
|
|
219
|
+
path: string;
|
|
220
|
+
methods: string[];
|
|
221
|
+
part: string;
|
|
222
|
+
}>;
|
|
223
|
+
components: Array<{
|
|
224
|
+
path: string;
|
|
225
|
+
symbols: string[];
|
|
226
|
+
part: string;
|
|
227
|
+
layer: string;
|
|
228
|
+
}>;
|
|
229
|
+
handlers: Array<{
|
|
230
|
+
path: string;
|
|
231
|
+
exports: string[];
|
|
232
|
+
part: string;
|
|
233
|
+
}>;
|
|
234
|
+
features: Array<{
|
|
235
|
+
name: string;
|
|
236
|
+
files: number;
|
|
237
|
+
}>;
|
|
238
|
+
imports: {
|
|
239
|
+
byFile: Array<{
|
|
240
|
+
path: string;
|
|
241
|
+
imports: string[];
|
|
242
|
+
exports: string[];
|
|
243
|
+
}>;
|
|
244
|
+
centralFiles: Array<{
|
|
245
|
+
path: string;
|
|
246
|
+
importedByCount: number;
|
|
247
|
+
}>;
|
|
248
|
+
};
|
|
249
|
+
directives: Array<{
|
|
250
|
+
path: string;
|
|
251
|
+
directives: string[];
|
|
252
|
+
}>;
|
|
253
|
+
}
|
|
254
|
+
/** Effective configuration recorded so `validate` can detect config drift. */
|
|
255
|
+
interface ManifestConfigSnapshot {
|
|
256
|
+
/** Digest of the effective settings; see `configDigest`. */
|
|
257
|
+
digest?: string;
|
|
258
|
+
maxPartBytes: number;
|
|
259
|
+
largeFileBytes: number;
|
|
260
|
+
previewHeadLines: number;
|
|
261
|
+
previewTailLines: number;
|
|
262
|
+
includeMonolith: boolean;
|
|
263
|
+
includeSensitiveFiles: boolean;
|
|
264
|
+
/** How files were discovered; `undefined` on manifests written before this was recorded. */
|
|
265
|
+
discovery?: DiscoveryMode;
|
|
266
|
+
artifacts: ResolvedArtifacts;
|
|
267
|
+
include: string[];
|
|
268
|
+
preset: string;
|
|
269
|
+
layersMode: "merge" | "replace";
|
|
270
|
+
budgets: ResolvedBudgets;
|
|
271
|
+
excludePatterns: string[];
|
|
272
|
+
layers: string[];
|
|
273
|
+
kinds: string[];
|
|
274
|
+
}
|
|
275
|
+
interface Manifest {
|
|
276
|
+
schemaVersion: string;
|
|
277
|
+
generatedAt: string;
|
|
278
|
+
/**
|
|
279
|
+
* Present only in the manifest embedded in `full-codebase.json`.
|
|
280
|
+
*
|
|
281
|
+
* That file cannot record its own sha256, so its embedded copy leaves `artifacts.fullJson` null
|
|
282
|
+
* and points at `manifest.json` for the real digest instead of writing a number that describes
|
|
283
|
+
* different bytes. The shipped manifest never carries this field.
|
|
284
|
+
*/
|
|
285
|
+
selfReference?: string;
|
|
286
|
+
generator: {
|
|
287
|
+
name: string;
|
|
288
|
+
version: string;
|
|
289
|
+
};
|
|
290
|
+
git: {
|
|
291
|
+
branch: string;
|
|
292
|
+
commit: string;
|
|
293
|
+
isDirty: boolean;
|
|
294
|
+
};
|
|
295
|
+
budgets: {
|
|
296
|
+
maxPartBytes: number;
|
|
297
|
+
largeFileBytes: number;
|
|
298
|
+
};
|
|
299
|
+
config: ManifestConfigSnapshot;
|
|
300
|
+
counts: {
|
|
301
|
+
totalFiles: number;
|
|
302
|
+
totalSizeBytes: number;
|
|
303
|
+
totalLines: number;
|
|
304
|
+
partsCount: number;
|
|
305
|
+
skippedCount: number;
|
|
306
|
+
largeFileCount: number;
|
|
307
|
+
truncatedPreviewCount: number;
|
|
308
|
+
};
|
|
309
|
+
totals: ManifestTotals;
|
|
310
|
+
fingerprint: string;
|
|
311
|
+
validation: {
|
|
312
|
+
status: "passed" | "failed";
|
|
313
|
+
errors: string[];
|
|
314
|
+
};
|
|
315
|
+
artifacts: {
|
|
316
|
+
fullJson: ManifestArtifact | null;
|
|
317
|
+
fullMarkdown: ManifestArtifact | null;
|
|
318
|
+
};
|
|
319
|
+
layers: Record<string, number>;
|
|
320
|
+
kinds: Record<string, number>;
|
|
321
|
+
indexes: ManifestIndexes;
|
|
322
|
+
parts: PartMetadata[];
|
|
323
|
+
files: FileEntry[];
|
|
324
|
+
skipped: SkipRecord[];
|
|
325
|
+
warnings: string[];
|
|
326
|
+
}
|
|
327
|
+
interface LayerRule {
|
|
328
|
+
name: string;
|
|
329
|
+
match: string | RegExp | ((filePath: string) => boolean);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Which snapshot artifacts get written.
|
|
333
|
+
*
|
|
334
|
+
* Everything a developer opens is produced by default; each entry exists only so
|
|
335
|
+
* a single artifact can be switched off without disabling the rest. `monolith`
|
|
336
|
+
* is the one exception, because it duplicates the entire payload: it follows
|
|
337
|
+
* `includeMonolith` (off by default) unless set here explicitly.
|
|
338
|
+
*/
|
|
339
|
+
interface ArtifactSelection {
|
|
340
|
+
/** `README.md` — the orientation page for humans and models. */
|
|
341
|
+
readme?: boolean;
|
|
342
|
+
/** `manifest.json` — the registry `validate` and `report` read. */
|
|
343
|
+
manifest?: boolean;
|
|
344
|
+
/** `parts/part-XXX.md` — the partitioned code payload. */
|
|
345
|
+
parts?: boolean;
|
|
346
|
+
/** `reports/navigation.md` — file-to-part lookup index. */
|
|
347
|
+
navigation?: boolean;
|
|
348
|
+
/** `reports/project-tree.md` — ASCII repository tree. */
|
|
349
|
+
projectTree?: boolean;
|
|
350
|
+
/** `reports/audit.md` — security, layer, kind and skip findings. */
|
|
351
|
+
audit?: boolean;
|
|
352
|
+
/** `full-codebase.{json,md}` — one file per format, the whole payload again. */
|
|
353
|
+
monolith?: boolean;
|
|
354
|
+
}
|
|
355
|
+
/** Every artifact decision made concrete. */
|
|
356
|
+
type ResolvedArtifacts = Required<ArtifactSelection>;
|
|
357
|
+
interface KindRule {
|
|
358
|
+
kind: string;
|
|
359
|
+
match: string | RegExp | ((filePath: string) => boolean);
|
|
360
|
+
}
|
|
361
|
+
/** A byte budget: either raw bytes or a human-readable size such as `"120k"`. */
|
|
362
|
+
type ByteSize = number | string;
|
|
363
|
+
/** Per-layer part budgets. Unlisted layers fall back to `default`. */
|
|
364
|
+
interface BudgetConfig {
|
|
365
|
+
default?: ByteSize;
|
|
366
|
+
byLayer?: Record<string, ByteSize>;
|
|
367
|
+
}
|
|
368
|
+
/** Every budget resolved to concrete byte counts. */
|
|
369
|
+
interface ResolvedBudgets {
|
|
370
|
+
default: number;
|
|
371
|
+
byLayer: Record<string, number>;
|
|
372
|
+
}
|
|
373
|
+
/** Lifecycle hooks. Not serialized into the manifest (functions are not data). */
|
|
374
|
+
interface HooksConfig {
|
|
375
|
+
/** Runs once after a successful generate, with the manifest that was written. */
|
|
376
|
+
afterGenerate?: (manifest: Manifest) => void;
|
|
377
|
+
}
|
|
378
|
+
interface SnapshotConfig {
|
|
379
|
+
cwd?: string;
|
|
380
|
+
branch?: string;
|
|
381
|
+
outDir?: string;
|
|
382
|
+
tmpDir?: string;
|
|
383
|
+
/** Raw bytes, or a human-readable size (`"120k"`, `"1.5mb"`). */
|
|
384
|
+
maxPartBytes?: ByteSize;
|
|
385
|
+
largeFileBytes?: ByteSize;
|
|
386
|
+
previewHeadLines?: number;
|
|
387
|
+
previewTailLines?: number;
|
|
388
|
+
includeMonolith?: boolean;
|
|
389
|
+
maxMonolithBytes?: ByteSize | null;
|
|
390
|
+
/** Opt in to emitting `.env`/`*.pem`/`.npmrc`/credential files. Default false. */
|
|
391
|
+
includeSensitiveFiles?: boolean;
|
|
392
|
+
/** Allow-list of globs. When non-empty, only matching files are included. */
|
|
393
|
+
include?: string[];
|
|
394
|
+
/** Force a preset by name instead of auto-detecting one. */
|
|
395
|
+
preset?: string;
|
|
396
|
+
/** Switch individual snapshot artifacts off. Everything is on by default. */
|
|
397
|
+
artifacts?: ArtifactSelection;
|
|
398
|
+
/**
|
|
399
|
+
* How user `layers`/`kinds` interact with the detected preset (default
|
|
400
|
+
* `"merge"`): user rules are evaluated first, then the preset fills the gaps.
|
|
401
|
+
* `"replace"` discards the preset entirely.
|
|
402
|
+
*/
|
|
403
|
+
layersMode?: "merge" | "replace";
|
|
404
|
+
/** Per-layer part budgets. */
|
|
405
|
+
budgets?: BudgetConfig;
|
|
406
|
+
hooks?: HooksConfig;
|
|
407
|
+
layers?: LayerRule[];
|
|
408
|
+
kinds?: KindRule[];
|
|
409
|
+
excludePatterns?: string[];
|
|
410
|
+
secrets?: {
|
|
411
|
+
customPatterns?: SecretRuleInput[];
|
|
412
|
+
disableDefaultPatterns?: boolean;
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
interface ResolvedSnapshotConfig {
|
|
416
|
+
cwd: string;
|
|
417
|
+
branch: string;
|
|
418
|
+
outDir: string;
|
|
419
|
+
tmpDir: string;
|
|
420
|
+
maxPartBytes: number;
|
|
421
|
+
largeFileBytes: number;
|
|
422
|
+
previewHeadLines: number;
|
|
423
|
+
previewTailLines: number;
|
|
424
|
+
includeMonolith: boolean;
|
|
425
|
+
maxMonolithBytes: number | null;
|
|
426
|
+
includeSensitiveFiles: boolean;
|
|
427
|
+
/**
|
|
428
|
+
* How files are discovered; `auto` picks git when it can list files and walks the tree otherwise.
|
|
429
|
+
* Optional because a resolved config can arrive from an older caller that never named it — every
|
|
430
|
+
* reader treats `undefined` as `auto`, so the effective mode is never guessed twice.
|
|
431
|
+
*/
|
|
432
|
+
discovery?: DiscoveryMode;
|
|
433
|
+
/** Empty means "no allow-list"; every discovered file is a candidate. */
|
|
434
|
+
include: string[];
|
|
435
|
+
/** The preset that was resolved (detected or forced). */
|
|
436
|
+
preset: string;
|
|
437
|
+
/** Ecosystem ignores contributed by the preset, merged with `excludePatterns`. */
|
|
438
|
+
presetExclude: string[];
|
|
439
|
+
artifacts: ResolvedArtifacts;
|
|
440
|
+
layersMode: "merge" | "replace";
|
|
441
|
+
budgets: ResolvedBudgets;
|
|
442
|
+
hooks: HooksConfig;
|
|
443
|
+
layers: LayerRule[];
|
|
444
|
+
kinds: KindRule[];
|
|
445
|
+
excludePatterns: string[];
|
|
446
|
+
secretRules: SecretRule[];
|
|
447
|
+
}
|
|
448
|
+
interface CliOptions {
|
|
449
|
+
mode: Mode;
|
|
450
|
+
format: OutputFormat;
|
|
451
|
+
dryRun: boolean;
|
|
452
|
+
cwd?: string;
|
|
453
|
+
outDir?: string;
|
|
454
|
+
includeMonolith?: boolean;
|
|
455
|
+
includeSensitiveFiles?: boolean;
|
|
456
|
+
maxMonolithBytes?: number | null;
|
|
457
|
+
maxPartBytes?: number;
|
|
458
|
+
largeFileBytes?: number;
|
|
459
|
+
/** Artifact names to suppress for this invocation (`--skip-artifacts`). */
|
|
460
|
+
skipArtifacts?: string[];
|
|
461
|
+
}
|
|
462
|
+
interface ValidationDrift {
|
|
463
|
+
missingInSnapshot: string[];
|
|
464
|
+
missingOnDisk: string[];
|
|
465
|
+
/** Files that exist but could not be read, so their content could not be verified. */
|
|
466
|
+
unreadable: string[];
|
|
467
|
+
hashMismatches: Array<{
|
|
468
|
+
path: string;
|
|
469
|
+
diskHash: string;
|
|
470
|
+
snapshotHash: string;
|
|
471
|
+
}>;
|
|
472
|
+
/** Emitted `parts/*.md` that are missing or no longer match their recorded hash. */
|
|
473
|
+
partIssues: Array<{
|
|
474
|
+
part: string;
|
|
475
|
+
issue: string;
|
|
476
|
+
}>;
|
|
477
|
+
/** `counts`/`totals`/`budgets` that disagree with the rest of the manifest. */
|
|
478
|
+
totalsMismatches: string[];
|
|
479
|
+
/** Effective-configuration differences between the manifest and the current run. */
|
|
480
|
+
configMismatches: string[];
|
|
481
|
+
}
|
|
482
|
+
interface ValidationResult {
|
|
483
|
+
valid: boolean;
|
|
484
|
+
manifestPresent: boolean;
|
|
485
|
+
drift: ValidationDrift;
|
|
486
|
+
errors: string[];
|
|
487
|
+
/** Non-fatal observations (e.g. branch moved on). */
|
|
488
|
+
warnings: string[];
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export type { ArtifactSelection as A, ByteSize as B, CliOptions as C, DiscoveryMode as D, FileEntry as F, HooksConfig as H, InclusionMode as I, JsonSummary as J, KindRule as K, LayerRule as L, MarkdownSummary as M, OutputFormat as O, PartMetadata as P, ResolvedSnapshotConfig as R, SecretRule as S, TextEncoding as T, ValidationResult as V, SkipRecord as a, SourceSummary as b, SnapshotConfig as c, SecretFinding as d, Manifest as e, BudgetConfig as f, ManifestArtifact as g, ManifestConfigSnapshot as h, ManifestIndexes as i, ManifestTotals as j, Mode as k, PartFileEntry as l, ResolvedArtifacts as m, ResolvedBudgets as n, SecretRuleInput as o, SkipReason as p, SummaryQuality as q, ValidationDrift as r };
|