@opencodehub/cli 0.1.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/LICENSE +202 -0
- package/README.md +85 -0
- package/dist/agent-context.d.ts +54 -0
- package/dist/agent-context.d.ts.map +1 -0
- package/dist/agent-context.js +122 -0
- package/dist/agent-context.js.map +1 -0
- package/dist/cobol-proleap-setup.d.ts +77 -0
- package/dist/cobol-proleap-setup.d.ts.map +1 -0
- package/dist/cobol-proleap-setup.js +289 -0
- package/dist/cobol-proleap-setup.js.map +1 -0
- package/dist/commands/analyze.d.ts +234 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +1096 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/augment.d.ts +48 -0
- package/dist/commands/augment.d.ts.map +1 -0
- package/dist/commands/augment.js +249 -0
- package/dist/commands/augment.js.map +1 -0
- package/dist/commands/baseline.d.ts +68 -0
- package/dist/commands/baseline.d.ts.map +1 -0
- package/dist/commands/baseline.js +110 -0
- package/dist/commands/baseline.js.map +1 -0
- package/dist/commands/bench.d.ts +54 -0
- package/dist/commands/bench.d.ts.map +1 -0
- package/dist/commands/bench.js +283 -0
- package/dist/commands/bench.js.map +1 -0
- package/dist/commands/ci-init.d.ts +37 -0
- package/dist/commands/ci-init.d.ts.map +1 -0
- package/dist/commands/ci-init.js +115 -0
- package/dist/commands/ci-init.js.map +1 -0
- package/dist/commands/clean.d.ts +13 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +38 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/code-pack.d.ts +105 -0
- package/dist/commands/code-pack.d.ts.map +1 -0
- package/dist/commands/code-pack.js +187 -0
- package/dist/commands/code-pack.js.map +1 -0
- package/dist/commands/context.d.ts +30 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +237 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/detect-changes.d.ts +26 -0
- package/dist/commands/detect-changes.d.ts.map +1 -0
- package/dist/commands/detect-changes.js +73 -0
- package/dist/commands/detect-changes.js.map +1 -0
- package/dist/commands/doctor.d.ts +52 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +472 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/find-enclosing-symbol.d.ts +67 -0
- package/dist/commands/find-enclosing-symbol.d.ts.map +1 -0
- package/dist/commands/find-enclosing-symbol.js +106 -0
- package/dist/commands/find-enclosing-symbol.js.map +1 -0
- package/dist/commands/group.d.ts +123 -0
- package/dist/commands/group.d.ts.map +1 -0
- package/dist/commands/group.js +448 -0
- package/dist/commands/group.js.map +1 -0
- package/dist/commands/impact.d.ts +23 -0
- package/dist/commands/impact.d.ts.map +1 -0
- package/dist/commands/impact.js +91 -0
- package/dist/commands/impact.js.map +1 -0
- package/dist/commands/index-repo.d.ts +39 -0
- package/dist/commands/index-repo.d.ts.map +1 -0
- package/dist/commands/index-repo.js +148 -0
- package/dist/commands/index-repo.js.map +1 -0
- package/dist/commands/ingest-sarif.d.ts +64 -0
- package/dist/commands/ingest-sarif.d.ts.map +1 -0
- package/dist/commands/ingest-sarif.js +381 -0
- package/dist/commands/ingest-sarif.js.map +1 -0
- package/dist/commands/init.d.ts +75 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +315 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +17 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +79 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/mcp.d.ts +8 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +28 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/open-store.d.ts +25 -0
- package/dist/commands/open-store.d.ts.map +1 -0
- package/dist/commands/open-store.js +47 -0
- package/dist/commands/open-store.js.map +1 -0
- package/dist/commands/pack.d.ts +35 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +83 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/query.d.ts +85 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +309 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/scan.d.ts +81 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +407 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/setup.d.ts +178 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +370 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/sql.d.ts +19 -0
- package/dist/commands/sql.d.ts.map +1 -0
- package/dist/commands/sql.js +51 -0
- package/dist/commands/sql.js.map +1 -0
- package/dist/commands/status.d.ts +13 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +66 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/verdict-render.d.ts +33 -0
- package/dist/commands/verdict-render.d.ts.map +1 -0
- package/dist/commands/verdict-render.js +123 -0
- package/dist/commands/verdict-render.js.map +1 -0
- package/dist/commands/verdict.d.ts +61 -0
- package/dist/commands/verdict.d.ts.map +1 -0
- package/dist/commands/verdict.js +146 -0
- package/dist/commands/verdict.js.map +1 -0
- package/dist/commands/wiki.d.ts +26 -0
- package/dist/commands/wiki.d.ts.map +1 -0
- package/dist/commands/wiki.js +74 -0
- package/dist/commands/wiki.js.map +1 -0
- package/dist/editors/claude-code.d.ts +23 -0
- package/dist/editors/claude-code.d.ts.map +1 -0
- package/dist/editors/claude-code.js +58 -0
- package/dist/editors/claude-code.js.map +1 -0
- package/dist/editors/codex.d.ts +22 -0
- package/dist/editors/codex.d.ts.map +1 -0
- package/dist/editors/codex.js +59 -0
- package/dist/editors/codex.js.map +1 -0
- package/dist/editors/cursor.d.ts +13 -0
- package/dist/editors/cursor.d.ts.map +1 -0
- package/dist/editors/cursor.js +21 -0
- package/dist/editors/cursor.js.map +1 -0
- package/dist/editors/index.d.ts +12 -0
- package/dist/editors/index.d.ts.map +1 -0
- package/dist/editors/index.js +11 -0
- package/dist/editors/index.js.map +1 -0
- package/dist/editors/opencode.d.ts +23 -0
- package/dist/editors/opencode.d.ts.map +1 -0
- package/dist/editors/opencode.js +61 -0
- package/dist/editors/opencode.js.map +1 -0
- package/dist/editors/types.d.ts +33 -0
- package/dist/editors/types.d.ts.map +1 -0
- package/dist/editors/types.js +19 -0
- package/dist/editors/types.js.map +1 -0
- package/dist/editors/windows-wrap.d.ts +19 -0
- package/dist/editors/windows-wrap.d.ts.map +1 -0
- package/dist/editors/windows-wrap.js +28 -0
- package/dist/editors/windows-wrap.js.map +1 -0
- package/dist/editors/windsurf.d.ts +12 -0
- package/dist/editors/windsurf.d.ts.map +1 -0
- package/dist/editors/windsurf.js +21 -0
- package/dist/editors/windsurf.js.map +1 -0
- package/dist/embedder-downloader.d.ts +87 -0
- package/dist/embedder-downloader.d.ts.map +1 -0
- package/dist/embedder-downloader.js +261 -0
- package/dist/embedder-downloader.js.map +1 -0
- package/dist/fs-atomic.d.ts +22 -0
- package/dist/fs-atomic.d.ts.map +1 -0
- package/dist/fs-atomic.js +28 -0
- package/dist/fs-atomic.js.map +1 -0
- package/dist/groups.d.ts +64 -0
- package/dist/groups.d.ts.map +1 -0
- package/dist/groups.js +172 -0
- package/dist/groups.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +703 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/is-indexed.d.ts +20 -0
- package/dist/lib/is-indexed.d.ts.map +1 -0
- package/dist/lib/is-indexed.js +35 -0
- package/dist/lib/is-indexed.js.map +1 -0
- package/dist/registry.d.ts +64 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +145 -0
- package/dist/registry.js.map +1 -0
- package/dist/scip-downloader.d.ts +138 -0
- package/dist/scip-downloader.d.ts.map +1 -0
- package/dist/scip-downloader.js +372 -0
- package/dist/scip-downloader.js.map +1 -0
- package/dist/scip-pins.d.ts +99 -0
- package/dist/scip-pins.d.ts.map +1 -0
- package/dist/scip-pins.js +195 -0
- package/dist/scip-pins.js.map +1 -0
- package/dist/skills-gen.d.ts +47 -0
- package/dist/skills-gen.d.ts.map +1 -0
- package/dist/skills-gen.js +292 -0
- package/dist/skills-gen.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub bench` — acceptance-gate dashboard.
|
|
3
|
+
*
|
|
4
|
+
* Wraps `scripts/acceptance.sh` so we can invoke each gate as a discrete
|
|
5
|
+
* listr2 task, capture its exit code, and render the final summary as a
|
|
6
|
+
* cli-table3. Gates are hard-coded here to match the script's output —
|
|
7
|
+
* changing the script requires a matching edit here.
|
|
8
|
+
*
|
|
9
|
+
* Exit codes:
|
|
10
|
+
* 0 every mandatory gate PASSED
|
|
11
|
+
* 1 at least one gate FAILED
|
|
12
|
+
* 2 the acceptance script could not be located
|
|
13
|
+
*
|
|
14
|
+
* Like `doctor`, this never auto-heals and never writes to the repo; it
|
|
15
|
+
* only reports.
|
|
16
|
+
*/
|
|
17
|
+
import { spawn } from "node:child_process";
|
|
18
|
+
import { access } from "node:fs/promises";
|
|
19
|
+
import { dirname, join, resolve } from "node:path";
|
|
20
|
+
import { fileURLToPath } from "node:url";
|
|
21
|
+
import Table from "cli-table3";
|
|
22
|
+
import { Listr } from "listr2";
|
|
23
|
+
/**
|
|
24
|
+
* Fixed roster of MVP acceptance gates. Order + ids mirror
|
|
25
|
+
* `scripts/acceptance.sh`; rendering is by this order so users see the
|
|
26
|
+
* same sequence whether they run the script directly or via `codehub
|
|
27
|
+
* bench`.
|
|
28
|
+
*/
|
|
29
|
+
export const MVP_GATES = [
|
|
30
|
+
{ id: "install", title: "pnpm install --frozen-lockfile" },
|
|
31
|
+
{ id: "build", title: "pnpm -r build" },
|
|
32
|
+
{ id: "tests", title: "pnpm -r test" },
|
|
33
|
+
{ id: "banned-strings", title: "banned-strings grep" },
|
|
34
|
+
{ id: "licenses", title: "license allowlist" },
|
|
35
|
+
{ id: "determinism", title: "determinism (double-run graphHash)" },
|
|
36
|
+
{ id: "incremental", title: "incremental reindex timings" },
|
|
37
|
+
{ id: "mcp-smoke", title: "MCP stdio boot smoke" },
|
|
38
|
+
{ id: "eval", title: "Python eval harness (moved to opencodehub-testbed)" },
|
|
39
|
+
{ id: "embeddings-determinism", title: "embeddings determinism" },
|
|
40
|
+
{ id: "incremental-timing", title: "incremental timing on 100-file fixture" },
|
|
41
|
+
{ id: "scanner-smoke", title: "scanner smoke (semgrep)" },
|
|
42
|
+
{ id: "sarif-validation", title: "SARIF schema validation" },
|
|
43
|
+
{ id: "license-audit-smoke", title: "license-audit smoke" },
|
|
44
|
+
{ id: "verdict-smoke", title: "verdict smoke (2-commit fixture)" },
|
|
45
|
+
{ id: "pack-determinism", title: "pack-determinism (code-pack ×2 → diff -r)" },
|
|
46
|
+
{ id: "m7-parity-audit", title: "m7-parity-audit (analyze ×2 backends → graphHash)" },
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* Entrypoint for `codehub bench`. Returns the structured report so
|
|
50
|
+
* acceptance tests can assert the outcome without scraping stdout.
|
|
51
|
+
*/
|
|
52
|
+
export async function runBench(opts = {}) {
|
|
53
|
+
const script = await locateAcceptanceScript(opts.acceptanceScript);
|
|
54
|
+
if (!script) {
|
|
55
|
+
console.error("codehub bench: scripts/acceptance.sh not found — set --acceptance or run from the repo root.");
|
|
56
|
+
process.exitCode = 2;
|
|
57
|
+
return { rows: [], exitCode: 2 };
|
|
58
|
+
}
|
|
59
|
+
const rows = MVP_GATES.map((g) => ({
|
|
60
|
+
id: g.id,
|
|
61
|
+
title: g.title,
|
|
62
|
+
status: "pending",
|
|
63
|
+
detail: "",
|
|
64
|
+
}));
|
|
65
|
+
// Kick acceptance.sh in the background. We stream stdout line-by-line
|
|
66
|
+
// and parse every `[PASS] …` / `[FAIL] …` marker to advance the matching
|
|
67
|
+
// row. Timing for soft gates is rendered verbatim in the `detail` cell.
|
|
68
|
+
const stream = runScript(script);
|
|
69
|
+
const listr = new Listr(MVP_GATES.map((gate, idx) => ({
|
|
70
|
+
title: gate.title,
|
|
71
|
+
task: async (_ctx, task) => {
|
|
72
|
+
// Wait for this row's completion. We don't advance rows ahead of
|
|
73
|
+
// the stream — each row completes when the script's emitter calls
|
|
74
|
+
// applyLine() with a matching marker. This keeps the UI honest.
|
|
75
|
+
await waitUntil(() => rows[idx]?.status !== "pending");
|
|
76
|
+
const row = rows[idx];
|
|
77
|
+
if (!row)
|
|
78
|
+
return;
|
|
79
|
+
task.title = `${gate.title} — ${row.detail}`;
|
|
80
|
+
if (row.status === "fail") {
|
|
81
|
+
throw new Error(row.detail || "FAIL");
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
})), {
|
|
85
|
+
concurrent: false,
|
|
86
|
+
exitOnError: false,
|
|
87
|
+
renderer: opts.silent ? "silent" : "default",
|
|
88
|
+
});
|
|
89
|
+
// Capture listr2 failures but do not rethrow — we assemble the final
|
|
90
|
+
// report regardless.
|
|
91
|
+
const listrPromise = listr.run().catch(() => {
|
|
92
|
+
/* failures already captured in rows[i].status === "fail" */
|
|
93
|
+
});
|
|
94
|
+
stream.onLine((line) => {
|
|
95
|
+
applyLine(rows, line);
|
|
96
|
+
});
|
|
97
|
+
const code = await stream.done;
|
|
98
|
+
// Flush any rows that never received a marker (e.g. script crashed).
|
|
99
|
+
for (const row of rows) {
|
|
100
|
+
if (row.status === "pending") {
|
|
101
|
+
row.status = "skipped";
|
|
102
|
+
row.detail = "no [PASS]/[FAIL] marker — script crashed or was killed";
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
await listrPromise;
|
|
106
|
+
printTable(rows);
|
|
107
|
+
const exitCode = rows.some((r) => r.status === "fail") || code !== 0 ? 1 : 0;
|
|
108
|
+
process.exitCode = exitCode;
|
|
109
|
+
return { rows, exitCode };
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Helpers
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
/** Split a stdout/stderr stream into lines regardless of chunk boundaries. */
|
|
115
|
+
function lineSplitter() {
|
|
116
|
+
let buf = "";
|
|
117
|
+
return {
|
|
118
|
+
push(chunk) {
|
|
119
|
+
buf += chunk;
|
|
120
|
+
const parts = buf.split("\n");
|
|
121
|
+
buf = parts.pop() ?? "";
|
|
122
|
+
return parts;
|
|
123
|
+
},
|
|
124
|
+
flush() {
|
|
125
|
+
if (buf.length === 0)
|
|
126
|
+
return [];
|
|
127
|
+
const out = [buf];
|
|
128
|
+
buf = "";
|
|
129
|
+
return out;
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function runScript(scriptPath) {
|
|
134
|
+
const child = spawn("bash", [scriptPath], {
|
|
135
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
136
|
+
cwd: dirname(dirname(scriptPath)), // assume scripts/ is a sibling of packages/
|
|
137
|
+
});
|
|
138
|
+
const listeners = [];
|
|
139
|
+
const stdoutSplit = lineSplitter();
|
|
140
|
+
const stderrSplit = lineSplitter();
|
|
141
|
+
const emit = (line) => {
|
|
142
|
+
for (const l of listeners)
|
|
143
|
+
l(line);
|
|
144
|
+
};
|
|
145
|
+
child.stdout.on("data", (d) => {
|
|
146
|
+
for (const line of stdoutSplit.push(d.toString("utf8")))
|
|
147
|
+
emit(line);
|
|
148
|
+
});
|
|
149
|
+
child.stderr.on("data", (d) => {
|
|
150
|
+
// We echo stderr so users see banner messages, but don't parse it for
|
|
151
|
+
// gate status — acceptance.sh writes its markers to stdout.
|
|
152
|
+
for (const _line of stderrSplit.push(d.toString("utf8"))) {
|
|
153
|
+
/* intentionally discarded */
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
const done = new Promise((resolveProm) => {
|
|
157
|
+
child.on("error", () => resolveProm(127));
|
|
158
|
+
child.on("close", (code) => {
|
|
159
|
+
for (const line of stdoutSplit.flush())
|
|
160
|
+
emit(line);
|
|
161
|
+
stderrSplit.flush();
|
|
162
|
+
resolveProm(code ?? 0);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
return {
|
|
166
|
+
onLine(cb) {
|
|
167
|
+
listeners.push(cb);
|
|
168
|
+
},
|
|
169
|
+
done,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Apply a single line from `acceptance.sh` to the gate table. We parse
|
|
174
|
+
* the `N/17: <title>` banner line to pick which row the next `[PASS] ...`
|
|
175
|
+
* or `[FAIL] ...` marker belongs to. Anything else is ignored (timing
|
|
176
|
+
* summaries live under a gate row as `......` notes).
|
|
177
|
+
*/
|
|
178
|
+
let currentGateIdx = -1;
|
|
179
|
+
export function applyLine(rows, rawLine) {
|
|
180
|
+
const line = rawLine.trimEnd();
|
|
181
|
+
const banner = /^\d+\/\d+:\s+(.*)$/.exec(line);
|
|
182
|
+
if (banner) {
|
|
183
|
+
const title = banner[1] ?? "";
|
|
184
|
+
const idx = rows.findIndex((r) => r.title === title);
|
|
185
|
+
if (idx >= 0)
|
|
186
|
+
currentGateIdx = idx;
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const passMatch = /^\s*\[PASS\]\s+(.*)$/.exec(line);
|
|
190
|
+
if (passMatch && currentGateIdx >= 0) {
|
|
191
|
+
const row = rows[currentGateIdx];
|
|
192
|
+
if (row) {
|
|
193
|
+
row.status = "pass";
|
|
194
|
+
row.detail = passMatch[1] ?? "";
|
|
195
|
+
}
|
|
196
|
+
currentGateIdx = -1;
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const failMatch = /^\s*\[FAIL\]\s+(.*)$/.exec(line);
|
|
200
|
+
if (failMatch && currentGateIdx >= 0) {
|
|
201
|
+
const row = rows[currentGateIdx];
|
|
202
|
+
if (row) {
|
|
203
|
+
row.status = "fail";
|
|
204
|
+
row.detail = failMatch[1] ?? "";
|
|
205
|
+
}
|
|
206
|
+
currentGateIdx = -1;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const skipMatch = /^\s*\[SKIP\]\s+(.*)$/.exec(line);
|
|
210
|
+
if (skipMatch && currentGateIdx >= 0) {
|
|
211
|
+
const row = rows[currentGateIdx];
|
|
212
|
+
if (row) {
|
|
213
|
+
row.status = "skipped";
|
|
214
|
+
row.detail = skipMatch[1] ?? "";
|
|
215
|
+
}
|
|
216
|
+
currentGateIdx = -1;
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async function waitUntil(predicate) {
|
|
221
|
+
while (!predicate()) {
|
|
222
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async function locateAcceptanceScript(override) {
|
|
226
|
+
if (override !== undefined) {
|
|
227
|
+
if (await pathExists(override))
|
|
228
|
+
return override;
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
// Walk up from this file to find scripts/acceptance.sh. The CLI ships
|
|
232
|
+
// at packages/cli/dist/commands/bench.js in the monorepo; scripts/ lives
|
|
233
|
+
// four levels above.
|
|
234
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
235
|
+
const candidates = [
|
|
236
|
+
resolve(here, "..", "..", "..", "..", "scripts", "acceptance.sh"),
|
|
237
|
+
resolve(process.cwd(), "scripts", "acceptance.sh"),
|
|
238
|
+
];
|
|
239
|
+
for (const c of candidates) {
|
|
240
|
+
if (await pathExists(c))
|
|
241
|
+
return c;
|
|
242
|
+
}
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
async function pathExists(path) {
|
|
246
|
+
try {
|
|
247
|
+
await access(path);
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function printTable(rows) {
|
|
255
|
+
const table = new Table({
|
|
256
|
+
head: ["GATE", "STATUS", "DETAIL"],
|
|
257
|
+
style: { head: [], border: [] },
|
|
258
|
+
colWidths: [36, 10, 72],
|
|
259
|
+
wordWrap: true,
|
|
260
|
+
});
|
|
261
|
+
for (const row of rows) {
|
|
262
|
+
const glyph = row.status === "pass"
|
|
263
|
+
? "PASS"
|
|
264
|
+
: row.status === "fail"
|
|
265
|
+
? "FAIL"
|
|
266
|
+
: row.status === "skipped"
|
|
267
|
+
? "SKIP"
|
|
268
|
+
: "?";
|
|
269
|
+
table.push([row.title, glyph, row.detail]);
|
|
270
|
+
}
|
|
271
|
+
const passed = rows.filter((r) => r.status === "pass").length;
|
|
272
|
+
const failed = rows.filter((r) => r.status === "fail").length;
|
|
273
|
+
const skipped = rows.filter((r) => r.status === "skipped").length;
|
|
274
|
+
console.log(table.toString());
|
|
275
|
+
console.log(`bench: ${passed}/${rows.length} passed, ${failed} failed, ${skipped} skipped`);
|
|
276
|
+
}
|
|
277
|
+
// Guard against `scripts` discovery confusion when the CLI is installed
|
|
278
|
+
// via `npm link` or similar.
|
|
279
|
+
export { locateAcceptanceScript, pathExists };
|
|
280
|
+
// Silence lint for the unused helper import; kept for future per-gate
|
|
281
|
+
// path joining.
|
|
282
|
+
void join;
|
|
283
|
+
//# sourceMappingURL=bench.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench.js","sourceRoot":"","sources":["../../src/commands/bench.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub ci-init` — emit opinionated CI workflow files for GitHub Actions
|
|
3
|
+
* and/or GitLab CI.
|
|
4
|
+
*
|
|
5
|
+
* Platform detection:
|
|
6
|
+
* - probes `.github/workflows/` (GitHub) and `.gitlab-ci.yml` (GitLab)
|
|
7
|
+
* - if both are absent, defaults to `github`
|
|
8
|
+
* - if both are present, defaults to `both`
|
|
9
|
+
* - `--platform <p>` always overrides detection
|
|
10
|
+
*
|
|
11
|
+
* Templates live under `src/commands/ci-templates/*.yml` and are copied into
|
|
12
|
+
* `dist/commands/ci-templates/` as a post-build step. Variables are
|
|
13
|
+
* substituted with plain `String.prototype.replaceAll` — no handlebars.
|
|
14
|
+
*
|
|
15
|
+
* Idempotence: re-running with identical args produces byte-identical files.
|
|
16
|
+
* Re-running against an existing file refuses unless `--force` is set, and
|
|
17
|
+
* the error lists every conflict.
|
|
18
|
+
*/
|
|
19
|
+
export interface CiInitCliOptions {
|
|
20
|
+
readonly repo?: string;
|
|
21
|
+
readonly platform?: "github" | "gitlab" | "both";
|
|
22
|
+
readonly force?: boolean;
|
|
23
|
+
readonly mainBranch?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function detectPlatform(repoRoot: string): Promise<"github" | "gitlab" | "both">;
|
|
26
|
+
export declare function interpolate(template: string, vars: {
|
|
27
|
+
readonly MAIN_BRANCH: string;
|
|
28
|
+
readonly REPO_NAME: string;
|
|
29
|
+
}): string;
|
|
30
|
+
interface RenderPlan {
|
|
31
|
+
readonly outputPath: string;
|
|
32
|
+
readonly contents: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function buildPlan(repoRoot: string, platform: "github" | "gitlab" | "both", mainBranch: string, repoName: string): Promise<readonly RenderPlan[]>;
|
|
35
|
+
export declare function runCiInit(opts: CiInitCliOptions): Promise<void>;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=ci-init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-init.d.ts","sourceRoot":"","sources":["../../src/commands/ci-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AA6CD,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC,CAM5F;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;IAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACjE,MAAM,CAQR;AAQD,UAAU,UAAU;IAClB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,EACtC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAShC;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCrE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub ci-init` — emit opinionated CI workflow files for GitHub Actions
|
|
3
|
+
* and/or GitLab CI.
|
|
4
|
+
*
|
|
5
|
+
* Platform detection:
|
|
6
|
+
* - probes `.github/workflows/` (GitHub) and `.gitlab-ci.yml` (GitLab)
|
|
7
|
+
* - if both are absent, defaults to `github`
|
|
8
|
+
* - if both are present, defaults to `both`
|
|
9
|
+
* - `--platform <p>` always overrides detection
|
|
10
|
+
*
|
|
11
|
+
* Templates live under `src/commands/ci-templates/*.yml` and are copied into
|
|
12
|
+
* `dist/commands/ci-templates/` as a post-build step. Variables are
|
|
13
|
+
* substituted with plain `String.prototype.replaceAll` — no handlebars.
|
|
14
|
+
*
|
|
15
|
+
* Idempotence: re-running with identical args produces byte-identical files.
|
|
16
|
+
* Re-running against an existing file refuses unless `--force` is set, and
|
|
17
|
+
* the error lists every conflict.
|
|
18
|
+
*/
|
|
19
|
+
import { access, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
20
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const TEMPLATES_DIR = join(HERE, "ci-templates");
|
|
24
|
+
const GITHUB_TEMPLATES = [
|
|
25
|
+
{
|
|
26
|
+
templateFile: "github-verdict.yml",
|
|
27
|
+
outputPath: (root) => join(root, ".github", "workflows", "opencodehub-verdict.yml"),
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
templateFile: "github-nightly.yml",
|
|
31
|
+
outputPath: (root) => join(root, ".github", "workflows", "opencodehub-nightly.yml"),
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
templateFile: "github-weekly.yml",
|
|
35
|
+
outputPath: (root) => join(root, ".github", "workflows", "opencodehub-weekly.yml"),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
templateFile: "github-rescan.yml",
|
|
39
|
+
outputPath: (root) => join(root, ".github", "workflows", "opencodehub-rescan.yml"),
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
const GITLAB_TEMPLATES = [
|
|
43
|
+
{
|
|
44
|
+
templateFile: "gitlab-ci.yml",
|
|
45
|
+
outputPath: (root) => join(root, ".gitlab-ci.yml"),
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
async function pathExists(p) {
|
|
49
|
+
try {
|
|
50
|
+
await access(p);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export async function detectPlatform(repoRoot) {
|
|
58
|
+
const hasGithub = await pathExists(join(repoRoot, ".github", "workflows"));
|
|
59
|
+
const hasGitlab = await pathExists(join(repoRoot, ".gitlab-ci.yml"));
|
|
60
|
+
if (hasGithub && hasGitlab)
|
|
61
|
+
return "both";
|
|
62
|
+
if (hasGitlab)
|
|
63
|
+
return "gitlab";
|
|
64
|
+
return "github";
|
|
65
|
+
}
|
|
66
|
+
export function interpolate(template, vars) {
|
|
67
|
+
return (template
|
|
68
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: literal token to substitute
|
|
69
|
+
.replaceAll("${MAIN_BRANCH}", vars.MAIN_BRANCH)
|
|
70
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: literal token to substitute
|
|
71
|
+
.replaceAll("${REPO_NAME}", vars.REPO_NAME));
|
|
72
|
+
}
|
|
73
|
+
function selectTemplates(platform) {
|
|
74
|
+
if (platform === "github")
|
|
75
|
+
return GITHUB_TEMPLATES;
|
|
76
|
+
if (platform === "gitlab")
|
|
77
|
+
return GITLAB_TEMPLATES;
|
|
78
|
+
return [...GITHUB_TEMPLATES, ...GITLAB_TEMPLATES];
|
|
79
|
+
}
|
|
80
|
+
export async function buildPlan(repoRoot, platform, mainBranch, repoName) {
|
|
81
|
+
const specs = selectTemplates(platform);
|
|
82
|
+
const out = [];
|
|
83
|
+
for (const spec of specs) {
|
|
84
|
+
const raw = await readFile(join(TEMPLATES_DIR, spec.templateFile), "utf8");
|
|
85
|
+
const rendered = interpolate(raw, { MAIN_BRANCH: mainBranch, REPO_NAME: repoName });
|
|
86
|
+
out.push({ outputPath: spec.outputPath(repoRoot), contents: rendered });
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
export async function runCiInit(opts) {
|
|
91
|
+
const repoRoot = resolve(opts.repo ?? process.cwd());
|
|
92
|
+
const mainBranch = opts.mainBranch ?? "main";
|
|
93
|
+
const repoName = basename(repoRoot);
|
|
94
|
+
const platform = opts.platform ?? (await detectPlatform(repoRoot));
|
|
95
|
+
const force = opts.force === true;
|
|
96
|
+
const plan = await buildPlan(repoRoot, platform, mainBranch, repoName);
|
|
97
|
+
if (!force) {
|
|
98
|
+
const conflicts = [];
|
|
99
|
+
for (const item of plan) {
|
|
100
|
+
if (await pathExists(item.outputPath)) {
|
|
101
|
+
conflicts.push(item.outputPath);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (conflicts.length > 0) {
|
|
105
|
+
const lines = conflicts.map((p) => ` - ${p}`).join("\n");
|
|
106
|
+
throw new Error(`codehub ci-init: refusing to overwrite ${conflicts.length} existing file(s):\n${lines}\nRe-run with --force to overwrite.`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
for (const item of plan) {
|
|
110
|
+
await mkdir(dirname(item.outputPath), { recursive: true });
|
|
111
|
+
await writeFile(item.outputPath, item.contents, "utf8");
|
|
112
|
+
}
|
|
113
|
+
console.warn(`codehub ci-init: wrote ${plan.length} workflow file(s) for platform=${platform} (main branch: ${mainBranch}).`);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=ci-init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-init.js","sourceRoot":"","sources":["../../src/commands/ci-init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub clean [path]` — delete the `.codehub/` directory for a repo, and
|
|
3
|
+
* remove the registry entry.
|
|
4
|
+
*
|
|
5
|
+
* `--all` clears every repo listed in the registry, then truncates the
|
|
6
|
+
* registry file.
|
|
7
|
+
*/
|
|
8
|
+
export interface CleanOptions {
|
|
9
|
+
readonly all?: boolean;
|
|
10
|
+
readonly home?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function runClean(path: string, opts?: CleanOptions): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=clean.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BnF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub clean [path]` — delete the `.codehub/` directory for a repo, and
|
|
3
|
+
* remove the registry entry.
|
|
4
|
+
*
|
|
5
|
+
* `--all` clears every repo listed in the registry, then truncates the
|
|
6
|
+
* registry file.
|
|
7
|
+
*/
|
|
8
|
+
import { rm } from "node:fs/promises";
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
|
+
import { resolveRepoMetaDir } from "@opencodehub/storage";
|
|
11
|
+
import { clearRegistry, findRegistryEntryByPath, readRegistry, removeFromRegistry, } from "../registry.js";
|
|
12
|
+
export async function runClean(path, opts = {}) {
|
|
13
|
+
const registryOpts = opts.home !== undefined ? { home: opts.home } : {};
|
|
14
|
+
if (opts.all) {
|
|
15
|
+
const registry = await readRegistry(registryOpts);
|
|
16
|
+
let count = 0;
|
|
17
|
+
for (const entry of Object.values(registry)) {
|
|
18
|
+
try {
|
|
19
|
+
await rm(resolveRepoMetaDir(entry.path), { recursive: true, force: true });
|
|
20
|
+
count += 1;
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
console.warn(`codehub clean: failed for ${entry.path}: ${err.message}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
await clearRegistry(registryOpts);
|
|
27
|
+
console.warn(`codehub clean --all: removed ${count} index(es).`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const repoPath = resolve(path);
|
|
31
|
+
await rm(resolveRepoMetaDir(repoPath), { recursive: true, force: true });
|
|
32
|
+
const entry = await findRegistryEntryByPath(repoPath, registryOpts);
|
|
33
|
+
if (entry !== undefined) {
|
|
34
|
+
await removeFromRegistry(entry.name, registryOpts);
|
|
35
|
+
}
|
|
36
|
+
console.warn(`codehub clean: removed index at ${repoPath}`);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=clean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.js","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,YAAY,EACZ,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAOxB,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAqB,EAAE;IAClE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAExE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3E,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,6BAA6B,KAAK,CAAC,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;QACD,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,gCAAgC,KAAK,aAAa,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,MAAM,uBAAuB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACpE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,mCAAmC,QAAQ,EAAE,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub code-pack [path]` — produce the deterministic 9-item BOM via
|
|
3
|
+
* `@opencodehub/pack`.
|
|
4
|
+
*
|
|
5
|
+
* Output goes to `<repo>/.codehub/packs/<packHash>/` so a pack's identity
|
|
6
|
+
* is encoded in its on-disk path. The function writes to a temp directory
|
|
7
|
+
* first, then renames into place once the manifest's `packHash` is known
|
|
8
|
+
* — this keeps the path-includes-hash invariant without requiring
|
|
9
|
+
* `generatePack` to know its own hash up front.
|
|
10
|
+
*
|
|
11
|
+
* Two engines are supported via the `--engine` flag:
|
|
12
|
+
* - `pack` (DEFAULT) — `@opencodehub/pack`'s `generatePack`. Opens a
|
|
13
|
+
* read-only graph store via `openStore({ readOnly: true })` and walks
|
|
14
|
+
* the indexed graph to produce the 8 mandatory BOM items + manifest +
|
|
15
|
+
* optional Parquet embeddings sidecar. The sidecar emitter lives in
|
|
16
|
+
* `@opencodehub/pack`; cli/ passes the composed `Store` and pack
|
|
17
|
+
* dispatches on `store.backend` (DuckDB COPY for `duck`, degraded
|
|
18
|
+
* stamp for `lbug` v1).
|
|
19
|
+
* - `repomix` — legacy single-file snapshot via `npx repomix`. Retained
|
|
20
|
+
* under an opt-in flag for one milestone before removal. Internally
|
|
21
|
+
* delegates to `runPack` so the repomix shell-out is implemented
|
|
22
|
+
* exactly once.
|
|
23
|
+
*
|
|
24
|
+
* The CLI surface is:
|
|
25
|
+
*
|
|
26
|
+
* codehub code-pack [path]
|
|
27
|
+
* [--budget <N>] token budget (default 100_000)
|
|
28
|
+
* [--tokenizer <ID>] "<vendor>:<name>@<pin>" (default openai:o200k_base@tiktoken-0.8.0)
|
|
29
|
+
* [--out-dir <DIR>] overrides the .codehub/packs/<packHash>/ default
|
|
30
|
+
* [--engine pack|repomix] default "pack"
|
|
31
|
+
*
|
|
32
|
+
* Exits non-zero on missing index (the pack engine requires `codehub
|
|
33
|
+
* analyze` to have already populated the graph store).
|
|
34
|
+
*/
|
|
35
|
+
import { generatePack, type PackManifest } from "@opencodehub/pack";
|
|
36
|
+
import { type IGraphStore, type Store } from "@opencodehub/storage";
|
|
37
|
+
import { runPack } from "./pack.js";
|
|
38
|
+
/** Default token budget when `--budget` is omitted. */
|
|
39
|
+
export declare const DEFAULT_BUDGET_TOKENS = 100000;
|
|
40
|
+
/** Default tokenizer identifier when `--tokenizer` is omitted. */
|
|
41
|
+
export declare const DEFAULT_TOKENIZER_ID = "openai:o200k_base@tiktoken-0.8.0";
|
|
42
|
+
/** Default engine when `--engine` is omitted — the new `@opencodehub/pack` BOM. */
|
|
43
|
+
export declare const DEFAULT_ENGINE: "pack" | "repomix";
|
|
44
|
+
export interface CodePackArgs {
|
|
45
|
+
/** Path to the repo. Defaults to `process.cwd()` when omitted. */
|
|
46
|
+
readonly repo?: string;
|
|
47
|
+
/** Token budget passed to the AST chunker. Defaults to 100_000. */
|
|
48
|
+
readonly budget?: number;
|
|
49
|
+
/** Tokenizer identifier ("<vendor>:<name>@<pin>"). */
|
|
50
|
+
readonly tokenizer?: string;
|
|
51
|
+
/** Override the `.codehub/packs/<packHash>/` default. */
|
|
52
|
+
readonly outDir?: string;
|
|
53
|
+
/** Engine: "pack" (default) or "repomix" (legacy opt-in). */
|
|
54
|
+
readonly engine?: "pack" | "repomix";
|
|
55
|
+
/**
|
|
56
|
+
* Test seam — inject a custom `generatePack` so unit tests don't need
|
|
57
|
+
* to load native DuckDB bindings. Production callers leave this
|
|
58
|
+
* unset.
|
|
59
|
+
*/
|
|
60
|
+
readonly _generatePack?: typeof generatePack;
|
|
61
|
+
/**
|
|
62
|
+
* Test seam — inject a pre-opened {@link Store} (or a graph-only
|
|
63
|
+
* stand-in via {@link IGraphStore}) so unit tests can stub the graph
|
|
64
|
+
* entirely. Production callers leave this unset; the command opens a
|
|
65
|
+
* composed store via `openStore` on demand. Backwards-compatible:
|
|
66
|
+
* tests that only need graph reads can keep passing a plain
|
|
67
|
+
* `IGraphStore` and the command auto-wraps it.
|
|
68
|
+
*/
|
|
69
|
+
readonly _store?: Store | IGraphStore;
|
|
70
|
+
/**
|
|
71
|
+
* Test seam — inject a custom `runPack` so unit tests don't actually
|
|
72
|
+
* shell-out to `npx repomix`. Production callers leave this unset.
|
|
73
|
+
*/
|
|
74
|
+
readonly _runRepomix?: typeof runPack;
|
|
75
|
+
}
|
|
76
|
+
export interface CodePackResult {
|
|
77
|
+
/** Final on-disk directory containing the BOM. */
|
|
78
|
+
readonly outDir: string;
|
|
79
|
+
/** SHA256 of the manifest's canonical JSON (excluding `packHash`). */
|
|
80
|
+
readonly packHash: string;
|
|
81
|
+
/**
|
|
82
|
+
* Number of artifacts on disk that contribute to the BOM (mandatory
|
|
83
|
+
* 8 BOM items + manifest = 9; +1 if the embeddings.parquet sidecar
|
|
84
|
+
* was emitted). For the repomix engine this is 1 — repomix produces a
|
|
85
|
+
* single output file rather than the 9-item BOM.
|
|
86
|
+
*/
|
|
87
|
+
readonly bomItemCount: number;
|
|
88
|
+
/** The pack manifest. `null` for the repomix engine — it does not produce one. */
|
|
89
|
+
readonly manifest: PackManifest | null;
|
|
90
|
+
/** Engine that produced the result. */
|
|
91
|
+
readonly engine: "pack" | "repomix";
|
|
92
|
+
/**
|
|
93
|
+
* On the repomix path, the absolute path of the single repomix output
|
|
94
|
+
* file. Undefined on the pack path (the pack engine writes a
|
|
95
|
+
* directory; consumers should walk `outDir`).
|
|
96
|
+
*/
|
|
97
|
+
readonly repomixOutputPath?: string;
|
|
98
|
+
}
|
|
99
|
+
export declare function runCodePack(args?: CodePackArgs): Promise<CodePackResult>;
|
|
100
|
+
/**
|
|
101
|
+
* Read the on-disk size of `path`. Exported so the CLI's user-facing
|
|
102
|
+
* recap can format byte counts without re-walking the dir tree.
|
|
103
|
+
*/
|
|
104
|
+
export declare function statSizeOrZero(path: string): number;
|
|
105
|
+
//# sourceMappingURL=code-pack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-pack.d.ts","sourceRoot":"","sources":["../../src/commands/code-pack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAOH,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,KAAK,WAAW,EAA4B,KAAK,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,SAAU,CAAC;AAE7C,kEAAkE;AAClE,eAAO,MAAM,oBAAoB,qCAAqC,CAAC;AAEvE,mFAAmF;AACnF,eAAO,MAAM,cAAc,EAAE,MAAM,GAAG,SAAkB,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,YAAY,CAAC;IAC7C;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,OAAO,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IACvC,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,wBAAsB,WAAW,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAQlF;AAuHD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMnD"}
|