codebase-snapshot 0.9.4 → 0.9.5
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 +38 -0
- package/README.md +1 -1
- package/dist/bin.js +190 -102
- package/dist/{chunk-EWZYK3VX.js → chunk-4AHHSNGG.js} +3 -3
- package/dist/{chunk-FCWD4LY7.js → chunk-B336MMNC.js} +188 -99
- package/dist/cli.cjs +190 -102
- package/dist/cli.js +5 -6
- package/dist/index.cjs +186 -97
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp.cjs +1 -1
- package/dist/mcp.js +2 -2
- package/docs/cli.md +12 -2
- package/docs/mcp.md +3 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5488,7 +5488,7 @@ function validateSnapshot(configInput) {
|
|
|
5488
5488
|
|
|
5489
5489
|
// src/version.ts
|
|
5490
5490
|
var GENERATOR_NAME = "codebase-snapshot";
|
|
5491
|
-
var GENERATOR_VERSION = "0.9.
|
|
5491
|
+
var GENERATOR_VERSION = "0.9.5";
|
|
5492
5492
|
var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
|
|
5493
5493
|
function isOurGeneratorName(name) {
|
|
5494
5494
|
if (typeof name !== "string") return false;
|
|
@@ -6061,6 +6061,12 @@ var PromptCancelled = class extends Error {
|
|
|
6061
6061
|
this.name = "PromptCancelled";
|
|
6062
6062
|
}
|
|
6063
6063
|
};
|
|
6064
|
+
var PromptBack = class extends Error {
|
|
6065
|
+
constructor() {
|
|
6066
|
+
super("Prompt back");
|
|
6067
|
+
this.name = "PromptBack";
|
|
6068
|
+
}
|
|
6069
|
+
};
|
|
6064
6070
|
function defaultIO() {
|
|
6065
6071
|
return { input: process.stdin, output: process.stdout };
|
|
6066
6072
|
}
|
|
@@ -6084,35 +6090,40 @@ function choiceLine(choice, active) {
|
|
|
6084
6090
|
const hint = choice.hint ? ` ${choice.hint}` : "";
|
|
6085
6091
|
return ` ${marker(active)} ${choice.label}${hint}`;
|
|
6086
6092
|
}
|
|
6087
|
-
function
|
|
6093
|
+
function listFooter(base, allowBack) {
|
|
6094
|
+
return allowBack ? `${base} \xB7 \u2190 back` : base;
|
|
6095
|
+
}
|
|
6096
|
+
function renderSelect(message, choices, index, allowBack = false) {
|
|
6088
6097
|
const lines = [`\u25C6 ${message}`, ""];
|
|
6089
6098
|
choices.forEach((choice, position) => lines.push(choiceLine(choice, position === index)));
|
|
6090
|
-
lines.push("", "
|
|
6099
|
+
lines.push("", ` ${listFooter("\u2191\u2193 move \xB7 enter select", allowBack)}`);
|
|
6091
6100
|
return lines.join("\n");
|
|
6092
6101
|
}
|
|
6093
|
-
function renderMultiSelect(message, choices, index, selected) {
|
|
6102
|
+
function renderMultiSelect(message, choices, index, selected, allowBack = false) {
|
|
6094
6103
|
const lines = [`\u25C6 ${message}`, ""];
|
|
6095
6104
|
choices.forEach((choice, position) => {
|
|
6096
6105
|
const box = selected.has(position) ? "\u25FC" : "\u25FB";
|
|
6097
6106
|
const hint = choice.hint ? ` ${choice.hint}` : "";
|
|
6098
6107
|
lines.push(` ${marker(position === index)} ${box} ${choice.label}${hint}`);
|
|
6099
6108
|
});
|
|
6100
|
-
lines.push("", "
|
|
6109
|
+
lines.push("", ` ${listFooter("\u2191\u2193 move \xB7 space toggle \xB7 enter confirm", allowBack)}`);
|
|
6101
6110
|
return lines.join("\n");
|
|
6102
6111
|
}
|
|
6103
|
-
function renderConfirm(message, value) {
|
|
6112
|
+
function renderConfirm(message, value, allowBack = false) {
|
|
6113
|
+
const footer = allowBack ? "\u2190\u2192 or y/n \xB7 enter confirm \xB7 b back" : "\u2190\u2192 or y/n \xB7 enter confirm";
|
|
6104
6114
|
return [
|
|
6105
6115
|
`\u25C6 ${message}`,
|
|
6106
6116
|
"",
|
|
6107
6117
|
` ${marker(value)} Yes`,
|
|
6108
6118
|
` ${marker(!value)} No`,
|
|
6109
6119
|
"",
|
|
6110
|
-
|
|
6120
|
+
` ${footer}`
|
|
6111
6121
|
].join("\n");
|
|
6112
6122
|
}
|
|
6113
|
-
function renderText(message, value, error) {
|
|
6123
|
+
function renderText(message, value, error, allowBack = false) {
|
|
6114
6124
|
const lines = [`\u25C6 ${message}`, "", ` ${value || "\u258F"}`];
|
|
6115
6125
|
if (error) lines.push("", ` \u2716 ${error}`);
|
|
6126
|
+
if (allowBack) lines.push("", " enter confirm \xB7 \u2190 back");
|
|
6116
6127
|
return lines.join("\n");
|
|
6117
6128
|
}
|
|
6118
6129
|
function keyReader(input) {
|
|
@@ -6161,14 +6172,18 @@ var Frame = class {
|
|
|
6161
6172
|
function isCancel(key) {
|
|
6162
6173
|
return key.ctrl === true && key.name === "c" || key.ctrl === true && key.name === "d";
|
|
6163
6174
|
}
|
|
6175
|
+
function isListBack(key, allowBack) {
|
|
6176
|
+
return allowBack && (key.name === "left" || key.name === "b");
|
|
6177
|
+
}
|
|
6164
6178
|
async function select(io, message, choices, options = {}) {
|
|
6165
6179
|
if (choices.length === 0) throw new Error("select() requires at least one choice.");
|
|
6180
|
+
const allowBack = options.allowBack === true;
|
|
6166
6181
|
const fallbackIndex = Math.max(
|
|
6167
6182
|
0,
|
|
6168
6183
|
choices.findIndex((choice) => choice.value === options.defaultValue)
|
|
6169
6184
|
);
|
|
6170
6185
|
if (!isInteractive(io)) {
|
|
6171
|
-
io.output.write(`${renderSelect(message, choices, fallbackIndex)}
|
|
6186
|
+
io.output.write(`${renderSelect(message, choices, fallbackIndex, allowBack)}
|
|
6172
6187
|
`);
|
|
6173
6188
|
return choices[fallbackIndex].value;
|
|
6174
6189
|
}
|
|
@@ -6177,9 +6192,10 @@ async function select(io, message, choices, options = {}) {
|
|
|
6177
6192
|
let index = fallbackIndex;
|
|
6178
6193
|
try {
|
|
6179
6194
|
for (; ; ) {
|
|
6180
|
-
frame.draw(renderSelect(message, choices, index));
|
|
6195
|
+
frame.draw(renderSelect(message, choices, index, allowBack));
|
|
6181
6196
|
const key = await reader.next();
|
|
6182
6197
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6198
|
+
if (isListBack(key, allowBack)) throw new PromptBack();
|
|
6183
6199
|
if (key.name === "up") index = moveSelection(index, -1, choices.length);
|
|
6184
6200
|
else if (key.name === "down") index = moveSelection(index, 1, choices.length);
|
|
6185
6201
|
else if (key.name === "return" || key.name === "enter") {
|
|
@@ -6188,18 +6204,22 @@ async function select(io, message, choices, options = {}) {
|
|
|
6188
6204
|
} else if (key.name === "j") index = moveSelection(index, 1, choices.length);
|
|
6189
6205
|
else if (key.name === "k") index = moveSelection(index, -1, choices.length);
|
|
6190
6206
|
}
|
|
6207
|
+
} catch (error) {
|
|
6208
|
+
frame.erase();
|
|
6209
|
+
throw error;
|
|
6191
6210
|
} finally {
|
|
6192
6211
|
reader.close();
|
|
6193
6212
|
}
|
|
6194
6213
|
}
|
|
6195
6214
|
async function multiSelect(io, message, choices, options = {}) {
|
|
6215
|
+
const allowBack = options.allowBack === true;
|
|
6196
6216
|
const selected = /* @__PURE__ */ new Set();
|
|
6197
6217
|
choices.forEach((choice, position) => {
|
|
6198
6218
|
if (options.defaults?.includes(choice.value)) selected.add(position);
|
|
6199
6219
|
});
|
|
6200
6220
|
const result = () => choices.filter((_, position) => selected.has(position)).map((choice) => choice.value);
|
|
6201
6221
|
if (!isInteractive(io)) {
|
|
6202
|
-
io.output.write(`${renderMultiSelect(message, choices, 0, selected)}
|
|
6222
|
+
io.output.write(`${renderMultiSelect(message, choices, 0, selected, allowBack)}
|
|
6203
6223
|
`);
|
|
6204
6224
|
return result();
|
|
6205
6225
|
}
|
|
@@ -6208,9 +6228,10 @@ async function multiSelect(io, message, choices, options = {}) {
|
|
|
6208
6228
|
let index = 0;
|
|
6209
6229
|
try {
|
|
6210
6230
|
for (; ; ) {
|
|
6211
|
-
frame.draw(renderMultiSelect(message, choices, index, selected));
|
|
6231
|
+
frame.draw(renderMultiSelect(message, choices, index, selected, allowBack));
|
|
6212
6232
|
const key = await reader.next();
|
|
6213
6233
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6234
|
+
if (isListBack(key, allowBack)) throw new PromptBack();
|
|
6214
6235
|
if (key.name === "up") index = moveSelection(index, -1, choices.length);
|
|
6215
6236
|
else if (key.name === "down") index = moveSelection(index, 1, choices.length);
|
|
6216
6237
|
else if (key.name === "space") {
|
|
@@ -6225,14 +6246,18 @@ async function multiSelect(io, message, choices, options = {}) {
|
|
|
6225
6246
|
return result();
|
|
6226
6247
|
}
|
|
6227
6248
|
}
|
|
6249
|
+
} catch (error) {
|
|
6250
|
+
frame.erase();
|
|
6251
|
+
throw error;
|
|
6228
6252
|
} finally {
|
|
6229
6253
|
reader.close();
|
|
6230
6254
|
}
|
|
6231
6255
|
}
|
|
6232
6256
|
async function confirm(io, message, options = {}) {
|
|
6257
|
+
const allowBack = options.allowBack === true;
|
|
6233
6258
|
let value = options.defaultValue ?? true;
|
|
6234
6259
|
if (!isInteractive(io)) {
|
|
6235
|
-
io.output.write(`${renderConfirm(message, value)}
|
|
6260
|
+
io.output.write(`${renderConfirm(message, value, allowBack)}
|
|
6236
6261
|
`);
|
|
6237
6262
|
return value;
|
|
6238
6263
|
}
|
|
@@ -6240,9 +6265,10 @@ async function confirm(io, message, options = {}) {
|
|
|
6240
6265
|
const reader = keyReader(io.input);
|
|
6241
6266
|
try {
|
|
6242
6267
|
for (; ; ) {
|
|
6243
|
-
frame.draw(renderConfirm(message, value));
|
|
6268
|
+
frame.draw(renderConfirm(message, value, allowBack));
|
|
6244
6269
|
const key = await reader.next();
|
|
6245
6270
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6271
|
+
if (allowBack && key.name === "b") throw new PromptBack();
|
|
6246
6272
|
if (key.name === "up" || key.name === "left") value = true;
|
|
6247
6273
|
else if (key.name === "down" || key.name === "right") value = false;
|
|
6248
6274
|
else if (key.name === "y") value = true;
|
|
@@ -6252,14 +6278,18 @@ async function confirm(io, message, options = {}) {
|
|
|
6252
6278
|
return value;
|
|
6253
6279
|
}
|
|
6254
6280
|
}
|
|
6281
|
+
} catch (error) {
|
|
6282
|
+
frame.erase();
|
|
6283
|
+
throw error;
|
|
6255
6284
|
} finally {
|
|
6256
6285
|
reader.close();
|
|
6257
6286
|
}
|
|
6258
6287
|
}
|
|
6259
6288
|
async function text(io, message, options = {}) {
|
|
6289
|
+
const allowBack = options.allowBack === true;
|
|
6260
6290
|
const fallback = options.defaultValue ?? "";
|
|
6261
6291
|
if (!isInteractive(io)) {
|
|
6262
|
-
io.output.write(`${renderText(message, fallback)}
|
|
6292
|
+
io.output.write(`${renderText(message, fallback, void 0, allowBack)}
|
|
6263
6293
|
`);
|
|
6264
6294
|
return fallback;
|
|
6265
6295
|
}
|
|
@@ -6269,9 +6299,10 @@ async function text(io, message, options = {}) {
|
|
|
6269
6299
|
let error;
|
|
6270
6300
|
try {
|
|
6271
6301
|
for (; ; ) {
|
|
6272
|
-
frame.draw(renderText(message, value, error));
|
|
6302
|
+
frame.draw(renderText(message, value, error, allowBack));
|
|
6273
6303
|
const key = await reader.next();
|
|
6274
6304
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6305
|
+
if (allowBack && key.name === "left") throw new PromptBack();
|
|
6275
6306
|
error = void 0;
|
|
6276
6307
|
if (key.name === "return" || key.name === "enter") {
|
|
6277
6308
|
const problem = options.validate ? options.validate(value) : null;
|
|
@@ -6292,6 +6323,9 @@ async function text(io, message, options = {}) {
|
|
|
6292
6323
|
}
|
|
6293
6324
|
if (_isPrintable(key)) value += _keyText(key);
|
|
6294
6325
|
}
|
|
6326
|
+
} catch (error_) {
|
|
6327
|
+
frame.erase();
|
|
6328
|
+
throw error_;
|
|
6295
6329
|
} finally {
|
|
6296
6330
|
reader.close();
|
|
6297
6331
|
}
|
|
@@ -6548,98 +6582,108 @@ async function runInit(options) {
|
|
|
6548
6582
|
{ value: "walk", label: "Go through each setting", hint: "every question starts on its default" },
|
|
6549
6583
|
{ value: "choose", label: "Pick a different preset", hint: "everything else stays at the defaults" }
|
|
6550
6584
|
];
|
|
6551
|
-
const
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
{
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
]
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6585
|
+
const baseInclude = [...answers.include];
|
|
6586
|
+
const baseExclude = [...answers.excludePatterns];
|
|
6587
|
+
let lastScope = "all";
|
|
6588
|
+
const artifactChoices = [
|
|
6589
|
+
{ value: "readme", label: "README.md", hint: "orientation page" },
|
|
6590
|
+
{ value: "manifest", label: "manifest.json", hint: "required by validate and report" },
|
|
6591
|
+
{ value: "parts", label: "parts/", hint: "the code payload" },
|
|
6592
|
+
{ value: "navigation", label: "reports/navigation.md", hint: "file \u2192 part index" },
|
|
6593
|
+
{ value: "projectTree", label: "reports/project-tree.md", hint: "ASCII tree" },
|
|
6594
|
+
{ value: "audit", label: "reports/audit.md", hint: "security and health findings" },
|
|
6595
|
+
{ value: "monolith", label: "full-codebase.json + .md", hint: "roughly doubles output" }
|
|
6596
|
+
];
|
|
6597
|
+
const scopeStep = async () => {
|
|
6598
|
+
for (; ; ) {
|
|
6599
|
+
const scope = await select(
|
|
6600
|
+
io,
|
|
6601
|
+
"What should go into the snapshot?",
|
|
6602
|
+
[
|
|
6603
|
+
{ value: "all", label: "Everything the scanner finds", hint: "recommended \xB7 respects .gitignore" },
|
|
6604
|
+
{ value: "folders", label: "Only specific folders\u2026" },
|
|
6605
|
+
{ value: "no-tests", label: "Everything, but skip tests" },
|
|
6606
|
+
{ value: "custom", label: "Let me write glob patterns" }
|
|
6607
|
+
],
|
|
6608
|
+
{ defaultValue: lastScope, allowBack: true }
|
|
6609
|
+
);
|
|
6610
|
+
lastScope = scope;
|
|
6611
|
+
answers.include = [...baseInclude];
|
|
6612
|
+
answers.excludePatterns = [...baseExclude];
|
|
6613
|
+
try {
|
|
6614
|
+
if (scope === "folders") {
|
|
6615
|
+
const dirs = topLevelDirs(options.cwd).slice(0, 40);
|
|
6616
|
+
if (dirs.length === 0) {
|
|
6617
|
+
notes.push("No top-level directories found; the snapshot will include everything.");
|
|
6618
|
+
} else {
|
|
6619
|
+
const chosen = await multiSelect(
|
|
6620
|
+
io,
|
|
6621
|
+
"Select folders",
|
|
6622
|
+
dirs.map((name) => ({ value: name, label: `${name}/` })),
|
|
6623
|
+
{ defaults: dirs, allowBack: true }
|
|
6624
|
+
);
|
|
6625
|
+
answers.include = chosen.map((name) => `${name}/**`);
|
|
6626
|
+
}
|
|
6627
|
+
} else if (scope === "no-tests") {
|
|
6628
|
+
answers.excludePatterns = [...baseExclude, "**/*.test.*", "**/*.spec.*", "tests", "test"];
|
|
6629
|
+
} else if (scope === "custom") {
|
|
6630
|
+
const raw = await text(io, "Glob patterns to include (comma separated)", {
|
|
6631
|
+
defaultValue: baseInclude.join(", "),
|
|
6632
|
+
allowBack: true
|
|
6633
|
+
});
|
|
6634
|
+
answers.include = raw.split(",").map((value) => value.trim()).filter(Boolean);
|
|
6635
|
+
}
|
|
6636
|
+
return;
|
|
6637
|
+
} catch (error) {
|
|
6638
|
+
if (error instanceof PromptBack) continue;
|
|
6639
|
+
throw error;
|
|
6592
6640
|
}
|
|
6593
|
-
} else if (scope === "no-tests") {
|
|
6594
|
-
answers.excludePatterns = [
|
|
6595
|
-
...answers.excludePatterns,
|
|
6596
|
-
"**/*.test.*",
|
|
6597
|
-
"**/*.spec.*",
|
|
6598
|
-
"tests",
|
|
6599
|
-
"test"
|
|
6600
|
-
];
|
|
6601
|
-
} else if (scope === "custom") {
|
|
6602
|
-
const raw = await text(io, "Glob patterns to include (comma separated)", {
|
|
6603
|
-
defaultValue: ""
|
|
6604
|
-
});
|
|
6605
|
-
answers.include = raw.split(",").map((value) => value.trim()).filter(Boolean);
|
|
6606
6641
|
}
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
validate: (value) => parseByteSize(value) === void 0 ? "Not a valid size." : null
|
|
6642
|
+
};
|
|
6643
|
+
const sizeStep = async () => {
|
|
6644
|
+
for (; ; ) {
|
|
6645
|
+
const currentBudget = String(answers.maxPartBytes);
|
|
6646
|
+
const sizeChoice = await select(io, "How large should each part be?", SIZE_CHOICES, {
|
|
6647
|
+
defaultValue: SIZE_CHOICES.some((choice) => choice.value === currentBudget) ? currentBudget : "custom",
|
|
6648
|
+
allowBack: true
|
|
6615
6649
|
});
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6650
|
+
if (sizeChoice !== "custom") {
|
|
6651
|
+
answers.maxPartBytes = sizeChoice;
|
|
6652
|
+
return;
|
|
6653
|
+
}
|
|
6654
|
+
try {
|
|
6655
|
+
const raw = await text(io, "Part size (e.g. 150k, 1.5mb, 900000)", {
|
|
6656
|
+
defaultValue: currentBudget,
|
|
6657
|
+
validate: (value) => parseByteSize(value) === void 0 ? "Not a valid size." : null,
|
|
6658
|
+
allowBack: true
|
|
6659
|
+
});
|
|
6660
|
+
answers.maxPartBytes = parseByteSize(raw) ?? answers.maxPartBytes;
|
|
6661
|
+
return;
|
|
6662
|
+
} catch (error) {
|
|
6663
|
+
if (error instanceof PromptBack) continue;
|
|
6664
|
+
throw error;
|
|
6665
|
+
}
|
|
6619
6666
|
}
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
{ value: "parts", label: "parts/", hint: "the code payload" },
|
|
6624
|
-
{ value: "navigation", label: "reports/navigation.md", hint: "file \u2192 part index" },
|
|
6625
|
-
{ value: "projectTree", label: "reports/project-tree.md", hint: "ASCII tree" },
|
|
6626
|
-
{ value: "audit", label: "reports/audit.md", hint: "security and health findings" },
|
|
6627
|
-
{ value: "monolith", label: "full-codebase.json + .md", hint: "roughly doubles output" }
|
|
6628
|
-
];
|
|
6629
|
-
const presetEnabled = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]);
|
|
6667
|
+
};
|
|
6668
|
+
const artifactsStep = async () => {
|
|
6669
|
+
const enabled = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]);
|
|
6630
6670
|
const selectedArtifacts = await multiSelect(
|
|
6631
6671
|
io,
|
|
6632
6672
|
"Which artifacts should be generated?",
|
|
6633
6673
|
artifactChoices,
|
|
6634
|
-
{ defaults:
|
|
6674
|
+
{ defaults: enabled, allowBack: true }
|
|
6635
6675
|
);
|
|
6636
6676
|
for (const name of ARTIFACT_NAMES) answers.artifacts[name] = selectedArtifacts.includes(name);
|
|
6637
|
-
|
|
6677
|
+
};
|
|
6678
|
+
const credentialsStep = async () => {
|
|
6638
6679
|
answers.includeSensitiveFiles = await confirm(
|
|
6639
6680
|
io,
|
|
6640
|
-
"Include credential files (.env, *.pem,
|
|
6641
|
-
{ defaultValue:
|
|
6681
|
+
"Include credential files (.env, *.pem, *.npmrc, *.ssh/)?",
|
|
6682
|
+
{ defaultValue: answers.includeSensitiveFiles, allowBack: true }
|
|
6642
6683
|
);
|
|
6684
|
+
};
|
|
6685
|
+
const reviewStep = async () => {
|
|
6686
|
+
const enabledCount = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]).length;
|
|
6643
6687
|
io.output.write("\n Review\n\n");
|
|
6644
6688
|
io.output.write(` project ${answers.preset}
|
|
6645
6689
|
`);
|
|
@@ -6654,8 +6698,53 @@ async function runInit(options) {
|
|
|
6654
6698
|
`);
|
|
6655
6699
|
io.output.write(" Will write snapshot.config with your answers, plus every other setting\n");
|
|
6656
6700
|
io.output.write(" at its default \u2014 so nothing is hidden behind the docs.\n\n");
|
|
6657
|
-
const proceed = await confirm(io, "Write this and continue?", {
|
|
6658
|
-
|
|
6701
|
+
const proceed = await confirm(io, "Write this and continue?", {
|
|
6702
|
+
defaultValue: true,
|
|
6703
|
+
allowBack: true
|
|
6704
|
+
});
|
|
6705
|
+
if (!proceed) throw new PromptBack();
|
|
6706
|
+
};
|
|
6707
|
+
const walk = async () => {
|
|
6708
|
+
const steps = [scopeStep, sizeStep, artifactsStep, credentialsStep, reviewStep];
|
|
6709
|
+
let index = 0;
|
|
6710
|
+
while (index < steps.length) {
|
|
6711
|
+
try {
|
|
6712
|
+
await steps[index]();
|
|
6713
|
+
index += 1;
|
|
6714
|
+
} catch (error) {
|
|
6715
|
+
if (!(error instanceof PromptBack)) throw error;
|
|
6716
|
+
if (index === 0) return false;
|
|
6717
|
+
index -= 1;
|
|
6718
|
+
io.output.write("\n");
|
|
6719
|
+
}
|
|
6720
|
+
}
|
|
6721
|
+
return true;
|
|
6722
|
+
};
|
|
6723
|
+
for (; ; ) {
|
|
6724
|
+
const pace = await select(io, "How should I set this up?", paceChoices, {
|
|
6725
|
+
defaultValue: fallback ? "choose" : "recommended"
|
|
6726
|
+
});
|
|
6727
|
+
if (pace === "choose") {
|
|
6728
|
+
try {
|
|
6729
|
+
answers.preset = await select(
|
|
6730
|
+
io,
|
|
6731
|
+
"What kind of project is this?",
|
|
6732
|
+
listPresetNames().map(
|
|
6733
|
+
(name) => resolvePresetChoice(fallback ? null : detected.presetName, name)
|
|
6734
|
+
),
|
|
6735
|
+
{ defaultValue: answers.preset, allowBack: true }
|
|
6736
|
+
);
|
|
6737
|
+
} catch (error) {
|
|
6738
|
+
if (error instanceof PromptBack) continue;
|
|
6739
|
+
throw error;
|
|
6740
|
+
}
|
|
6741
|
+
const chosen = detectPreset(options.cwd, answers.preset);
|
|
6742
|
+
answers.preset = chosen.presetName;
|
|
6743
|
+
reason = null;
|
|
6744
|
+
fallback = false;
|
|
6745
|
+
}
|
|
6746
|
+
if (pace === "walk" && !await walk()) continue;
|
|
6747
|
+
break;
|
|
6659
6748
|
}
|
|
6660
6749
|
}
|
|
6661
6750
|
const configText = renderConfig(answers);
|
package/dist/index.d.cts
CHANGED
|
@@ -422,7 +422,7 @@ declare function validateSnapshot(configInput: ResolvedSnapshotConfig | Snapshot
|
|
|
422
422
|
* `package.json` carries the same version; `npm run verify` compares the two.
|
|
423
423
|
*/
|
|
424
424
|
declare const GENERATOR_NAME = "codebase-snapshot";
|
|
425
|
-
declare const GENERATOR_VERSION = "0.9.
|
|
425
|
+
declare const GENERATOR_VERSION = "0.9.5";
|
|
426
426
|
|
|
427
427
|
declare const DEFAULT_SECRET_PATTERNS: SecretRule[];
|
|
428
428
|
|
package/dist/index.d.ts
CHANGED
|
@@ -422,7 +422,7 @@ declare function validateSnapshot(configInput: ResolvedSnapshotConfig | Snapshot
|
|
|
422
422
|
* `package.json` carries the same version; `npm run verify` compares the two.
|
|
423
423
|
*/
|
|
424
424
|
declare const GENERATOR_NAME = "codebase-snapshot";
|
|
425
|
-
declare const GENERATOR_VERSION = "0.9.
|
|
425
|
+
declare const GENERATOR_VERSION = "0.9.5";
|
|
426
426
|
|
|
427
427
|
declare const DEFAULT_SECRET_PATTERNS: SecretRule[];
|
|
428
428
|
|
package/dist/index.js
CHANGED
|
@@ -1,3 +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, firstRunMessage, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot } from './chunk-
|
|
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, firstRunMessage, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot } from './chunk-B336MMNC.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/mcp.cjs
CHANGED
|
@@ -6115,7 +6115,7 @@ function validateSnapshot(configInput) {
|
|
|
6115
6115
|
|
|
6116
6116
|
// src/version.ts
|
|
6117
6117
|
var GENERATOR_NAME = "codebase-snapshot";
|
|
6118
|
-
var GENERATOR_VERSION = "0.9.
|
|
6118
|
+
var GENERATOR_VERSION = "0.9.5";
|
|
6119
6119
|
var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
|
|
6120
6120
|
function isOurGeneratorName(name) {
|
|
6121
6121
|
if (typeof name !== "string") return false;
|
package/dist/mcp.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ERROR_CODES, LEGACY_PROTOCOL_VERSIONS, MAX_LINE_BYTES, METHOD, MODERN_PROTOCOL_VERSIONS, SERVER_INSTRUCTIONS, SUPPORTED_PROTOCOL_VERSIONS, buildPrompts, buildResourceProvider, buildTools, classifyRequest, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, runStdioServer, validateArguments } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { ERROR_CODES, LEGACY_PROTOCOL_VERSIONS, MAX_LINE_BYTES, METHOD, MODERN_PROTOCOL_VERSIONS, SERVER_INSTRUCTIONS, SUPPORTED_PROTOCOL_VERSIONS, buildPrompts, buildResourceProvider, buildTools, classifyRequest, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, runStdioServer, validateArguments } from './chunk-4AHHSNGG.js';
|
|
2
|
+
import './chunk-B336MMNC.js';
|
|
3
3
|
//# sourceMappingURL=mcp.js.map
|
|
4
4
|
//# sourceMappingURL=mcp.js.map
|
package/docs/cli.md
CHANGED
|
@@ -174,7 +174,7 @@ The whole first run in one command, with defaults and no prompts. This is the sa
|
|
|
174
174
|
🚀 Setup for: /path/to/repo
|
|
175
175
|
✅ Created snapshot.config.ts (preset: nextjs)
|
|
176
176
|
Added npm scripts: snapshot, snapshot:validate
|
|
177
|
-
Added devDependency: codebase-snapshot ^0.9.
|
|
177
|
+
Added devDependency: codebase-snapshot ^0.9.5
|
|
178
178
|
Added to .gitignore: snapshot/, snapshot.tmp/
|
|
179
179
|
⏳ Installing dependencies…
|
|
180
180
|
✅ Installed dependencies (npm install, 2.1s)
|
|
@@ -211,7 +211,7 @@ It also has three side effects on files you own, and it says so when it does the
|
|
|
211
211
|
```
|
|
212
212
|
✅ Created snapshot.config.ts (preset: node-lib)
|
|
213
213
|
Added npm scripts: snapshot, snapshot:validate
|
|
214
|
-
Added devDependency: codebase-snapshot ^0.9.
|
|
214
|
+
Added devDependency: codebase-snapshot ^0.9.5
|
|
215
215
|
Added to .gitignore: snapshot/, snapshot.tmp/
|
|
216
216
|
```
|
|
217
217
|
|
|
@@ -225,6 +225,16 @@ It also has three side effects on files you own, and it says so when it does the
|
|
|
225
225
|
- `snapshot/` and `snapshot.tmp/` are appended to `.gitignore` if they are not already listed;
|
|
226
226
|
the file is created if missing, and entries already present are not duplicated.
|
|
227
227
|
|
|
228
|
+
### Going back
|
|
229
|
+
|
|
230
|
+
At a terminal, `init` asks five questions and every one of them can be revisited: **`←`** goes back
|
|
231
|
+
on a list or a text field, **`b`** on a list or a confirmation. `text` takes `←` alone because `b` is
|
|
232
|
+
a character you may be typing, and `confirm` takes `b` alone because `←`/`→` already mean yes/no.
|
|
233
|
+
|
|
234
|
+
Back steps to the previous question with your earlier answer still selected; back from the first one
|
|
235
|
+
returns to *"How should I set this up?"*. Answering **No** at the review steps back rather than
|
|
236
|
+
abandoning the run — Ctrl+C is how you abandon.
|
|
237
|
+
|
|
228
238
|
Nothing else in the repository is touched: no `AGENTS.md`, no `.claude/`, no `.cursor/`. In a
|
|
229
239
|
repository with a `package.json` and no config, `git status` shows the config as the only new
|
|
230
240
|
file.
|
package/docs/mcp.md
CHANGED
|
@@ -10,7 +10,7 @@ walk — that the client sees.
|
|
|
10
10
|
## Start it
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npx -y codebase-snapshot@0.9.
|
|
13
|
+
npx -y codebase-snapshot@0.9.5 mcp
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
The server serves the directory it was started in. `--cwd <path>` points it elsewhere, and that
|
|
@@ -25,7 +25,7 @@ Claude Desktop and Cursor:
|
|
|
25
25
|
"mcpServers": {
|
|
26
26
|
"codebase-snapshot": {
|
|
27
27
|
"command": "npx",
|
|
28
|
-
"args": ["-y", "codebase-snapshot@0.9.
|
|
28
|
+
"args": ["-y", "codebase-snapshot@0.9.5", "mcp", "--cwd", "/absolute/path/to/repo"]
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -34,7 +34,7 @@ Claude Desktop and Cursor:
|
|
|
34
34
|
Claude Code registers the same thing from a shell:
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
claude mcp add codebase-snapshot -- npx -y codebase-snapshot@0.9.
|
|
37
|
+
claude mcp add codebase-snapshot -- npx -y codebase-snapshot@0.9.5 mcp --cwd /absolute/path/to/repo
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
On Windows, wrap the command as `cmd /c npx` with the same arguments — `npx` is a `.cmd` shim
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codebase-snapshot",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "Pack a codebase for an LLM into budgeted Markdown parts, with a manifest of every file and skip, and validate to prove the snapshot is current.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"codebase",
|