@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,187 @@
|
|
|
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 { createHash } from "node:crypto";
|
|
36
|
+
import { existsSync, statSync } from "node:fs";
|
|
37
|
+
import { mkdir, mkdtemp, readFile, rename, rm } from "node:fs/promises";
|
|
38
|
+
import { tmpdir } from "node:os";
|
|
39
|
+
import { join, resolve } from "node:path";
|
|
40
|
+
import { generatePack } from "@opencodehub/pack";
|
|
41
|
+
import { openStore, resolveDbPath } from "@opencodehub/storage";
|
|
42
|
+
import { runPack } from "./pack.js";
|
|
43
|
+
/** Default token budget when `--budget` is omitted. */
|
|
44
|
+
export const DEFAULT_BUDGET_TOKENS = 100_000;
|
|
45
|
+
/** Default tokenizer identifier when `--tokenizer` is omitted. */
|
|
46
|
+
export const DEFAULT_TOKENIZER_ID = "openai:o200k_base@tiktoken-0.8.0";
|
|
47
|
+
/** Default engine when `--engine` is omitted — the new `@opencodehub/pack` BOM. */
|
|
48
|
+
export const DEFAULT_ENGINE = "pack";
|
|
49
|
+
export async function runCodePack(args = {}) {
|
|
50
|
+
const repoPath = resolve(args.repo ?? process.cwd());
|
|
51
|
+
const engine = args.engine ?? DEFAULT_ENGINE;
|
|
52
|
+
if (engine === "repomix") {
|
|
53
|
+
return runRepomixEngine(repoPath, args);
|
|
54
|
+
}
|
|
55
|
+
return runPackEngine(repoPath, args);
|
|
56
|
+
}
|
|
57
|
+
async function runPackEngine(repoPath, args) {
|
|
58
|
+
const budget = args.budget ?? DEFAULT_BUDGET_TOKENS;
|
|
59
|
+
const tokenizer = args.tokenizer ?? DEFAULT_TOKENIZER_ID;
|
|
60
|
+
const generate = args._generatePack ?? generatePack;
|
|
61
|
+
// Production: open a read-only graph store via the backend-agnostic
|
|
62
|
+
// factory; tests inject `_store` to skip the native binding entirely.
|
|
63
|
+
const dbPath = resolveDbPath(repoPath);
|
|
64
|
+
if (args._store === undefined && !existsSync(dbPath)) {
|
|
65
|
+
throw new Error(`codehub code-pack: no graph index at ${dbPath}. ` +
|
|
66
|
+
"Run `codehub analyze` first to populate the store.");
|
|
67
|
+
}
|
|
68
|
+
const ownsStore = args._store === undefined;
|
|
69
|
+
// Composed-store envelope used only when this command owns lifecycle.
|
|
70
|
+
// Holds it here so the finally block can close graph + temporal in
|
|
71
|
+
// deterministic order without re-running the factory.
|
|
72
|
+
const owned = ownsStore
|
|
73
|
+
? await (async () => {
|
|
74
|
+
const composed = await openStore({ path: dbPath, backend: "auto", readOnly: true });
|
|
75
|
+
await composed.graph.open();
|
|
76
|
+
return composed;
|
|
77
|
+
})()
|
|
78
|
+
: undefined;
|
|
79
|
+
// generatePack consumes `Store` (= `OpenStoreResult`) so the
|
|
80
|
+
// embeddings sidecar can dispatch on `store.backend`. Tests
|
|
81
|
+
// historically passed an `IGraphStore` stub via `_store`; route that
|
|
82
|
+
// through the `internal.graphOnly` seam which auto-wraps it into a
|
|
83
|
+
// no-op-temporal Store with `backend: "duck"` (the sidecar then
|
|
84
|
+
// resolves to absent unless the stub duck-types
|
|
85
|
+
// `exportEmbeddingsParquet` itself).
|
|
86
|
+
const composedStore = isStoreShape(args._store)
|
|
87
|
+
? args._store
|
|
88
|
+
: (owned ?? undefined);
|
|
89
|
+
const graphOnlyStub = isStoreShape(args._store)
|
|
90
|
+
? undefined
|
|
91
|
+
: args._store;
|
|
92
|
+
// Stage in a temp dir; we don't know `packHash` until generatePack returns,
|
|
93
|
+
// and the canonical layout puts the hash in the directory name.
|
|
94
|
+
const stagingDir = await mkdtemp(join(tmpdir(), "codehub-code-pack-"));
|
|
95
|
+
try {
|
|
96
|
+
const manifest = await generate({
|
|
97
|
+
repoPath,
|
|
98
|
+
outDir: stagingDir,
|
|
99
|
+
budgetTokens: budget,
|
|
100
|
+
tokenizerId: tokenizer,
|
|
101
|
+
}, composedStore !== undefined
|
|
102
|
+
? { store: composedStore }
|
|
103
|
+
: { graphOnly: graphOnlyStub });
|
|
104
|
+
const finalOutDir = args.outDir !== undefined
|
|
105
|
+
? resolve(args.outDir)
|
|
106
|
+
: join(repoPath, ".codehub", "packs", manifest.packHash);
|
|
107
|
+
// If `--out-dir` was supplied, honor it as the literal final path; otherwise
|
|
108
|
+
// build the canonical .codehub/packs/<hash>/ layout. Either way, ensure the
|
|
109
|
+
// parent exists, then move the staging dir into place.
|
|
110
|
+
await mkdir(join(finalOutDir, ".."), { recursive: true });
|
|
111
|
+
if (existsSync(finalOutDir)) {
|
|
112
|
+
// Idempotent re-runs land on the same packHash — clear the old dir so
|
|
113
|
+
// `rename` succeeds atomically. The rm is recursive because the
|
|
114
|
+
// staging contents are non-empty.
|
|
115
|
+
await rm(finalOutDir, { recursive: true, force: true });
|
|
116
|
+
}
|
|
117
|
+
await rename(stagingDir, finalOutDir);
|
|
118
|
+
// BOM item count = manifest.files[].length (skeleton, file-tree, deps,
|
|
119
|
+
// ast-chunks, xrefs, findings, licenses, [embeddings.parquet]) + 1 for
|
|
120
|
+
// the manifest itself. The readme.md is consumer-facing metadata and is
|
|
121
|
+
// not part of the manifest hash preimage; we still report it as an
|
|
122
|
+
// on-disk artifact downstream by walking the dir, but the BOM count
|
|
123
|
+
// tracks the deterministic items only.
|
|
124
|
+
const bomItemCount = manifest.files.length + 1;
|
|
125
|
+
return {
|
|
126
|
+
outDir: finalOutDir,
|
|
127
|
+
packHash: manifest.packHash,
|
|
128
|
+
bomItemCount,
|
|
129
|
+
manifest,
|
|
130
|
+
engine: "pack",
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
if (owned !== undefined) {
|
|
135
|
+
await owned.close();
|
|
136
|
+
}
|
|
137
|
+
// Best-effort cleanup of the staging dir if we never renamed it (e.g.
|
|
138
|
+
// generatePack threw). `rm` with `force` swallows ENOENT.
|
|
139
|
+
await rm(stagingDir, { recursive: true, force: true });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async function runRepomixEngine(repoPath, args) {
|
|
143
|
+
const repomix = args._runRepomix ?? runPack;
|
|
144
|
+
const result = await repomix(repoPath, {});
|
|
145
|
+
// Build a CodePackResult-shaped envelope so callers can reason about
|
|
146
|
+
// either engine uniformly. `packHash` is a sha256 over the file's bytes,
|
|
147
|
+
// which gives operators a deterministic identifier even though repomix
|
|
148
|
+
// does not emit a manifest. `bomItemCount` is 1 — repomix is a
|
|
149
|
+
// single-file snapshot, not the 9-item BOM.
|
|
150
|
+
const bytes = await readFile(result.outputPath);
|
|
151
|
+
const packHash = createHash("sha256").update(bytes).digest("hex");
|
|
152
|
+
return {
|
|
153
|
+
outDir: repoPath,
|
|
154
|
+
packHash,
|
|
155
|
+
bomItemCount: 1,
|
|
156
|
+
manifest: null,
|
|
157
|
+
engine: "repomix",
|
|
158
|
+
repomixOutputPath: result.outputPath,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Read the on-disk size of `path`. Exported so the CLI's user-facing
|
|
163
|
+
* recap can format byte counts without re-walking the dir tree.
|
|
164
|
+
*/
|
|
165
|
+
export function statSizeOrZero(path) {
|
|
166
|
+
try {
|
|
167
|
+
return statSync(path).size;
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Discriminate between the composed {@link Store} and a bare
|
|
175
|
+
* {@link IGraphStore} stub. Tests historically passed a flat IGraphStore
|
|
176
|
+
* via `_store`; production passes the full Store envelope from
|
|
177
|
+
* {@link openStore}. We detect the envelope shape by the presence of
|
|
178
|
+
* `graph` + `temporal` + `backend` so both paths flow through the
|
|
179
|
+
* sidecar dispatch correctly.
|
|
180
|
+
*/
|
|
181
|
+
function isStoreShape(s) {
|
|
182
|
+
if (s === undefined)
|
|
183
|
+
return false;
|
|
184
|
+
const obj = s;
|
|
185
|
+
return typeof obj.backend === "string" && obj.graph !== undefined && obj.temporal !== undefined;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=code-pack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-pack.js","sourceRoot":"","sources":["../../src/commands/code-pack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub context <symbol>` — 360-degree view of a single symbol.
|
|
3
|
+
*
|
|
4
|
+
* Resolves the target by exact name against the graph, filtering out
|
|
5
|
+
* synthetic import-tracking stubs (`filePath = '<external>'` and
|
|
6
|
+
* `kind = 'CodeElement'`) that carry no caller/callee edges. Optional
|
|
7
|
+
* `targetUid`, `filePath`, and `kind` narrow same-named candidates.
|
|
8
|
+
* When exact-name yields zero rows we fall back to the BM25 index so
|
|
9
|
+
* concept-phrase queries still work; when it yields more than one row
|
|
10
|
+
* and no disambiguator narrows the set, we surface the candidate list.
|
|
11
|
+
*
|
|
12
|
+
* This command is graph-only — the lifecycle owner
|
|
13
|
+
* (`openStoreForCommand`) constructs the composed `Store` envelope, but
|
|
14
|
+
* `runContext` reaches through `store.graph` for every read so the
|
|
15
|
+
* `IGraphStore` typed-finder surface stays the only contract.
|
|
16
|
+
*/
|
|
17
|
+
import { type OpenStoreResult } from "./open-store.js";
|
|
18
|
+
export interface ContextOptions {
|
|
19
|
+
readonly repo?: string;
|
|
20
|
+
readonly home?: string;
|
|
21
|
+
readonly json?: boolean;
|
|
22
|
+
readonly targetUid?: string;
|
|
23
|
+
readonly filePath?: string;
|
|
24
|
+
readonly kind?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ContextRuntimeHooks {
|
|
27
|
+
readonly openStore?: (opts: ContextOptions) => Promise<OpenStoreResult>;
|
|
28
|
+
}
|
|
29
|
+
export declare function runContext(symbol: string, opts?: ContextOptions, hooks?: ContextRuntimeHooks): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,KAAK,eAAe,EAAuB,MAAM,iBAAiB,CAAC;AAE5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;CACzE;AAyJD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,cAAmB,EACzB,KAAK,GAAE,mBAAwB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA0Hf"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub context <symbol>` — 360-degree view of a single symbol.
|
|
3
|
+
*
|
|
4
|
+
* Resolves the target by exact name against the graph, filtering out
|
|
5
|
+
* synthetic import-tracking stubs (`filePath = '<external>'` and
|
|
6
|
+
* `kind = 'CodeElement'`) that carry no caller/callee edges. Optional
|
|
7
|
+
* `targetUid`, `filePath`, and `kind` narrow same-named candidates.
|
|
8
|
+
* When exact-name yields zero rows we fall back to the BM25 index so
|
|
9
|
+
* concept-phrase queries still work; when it yields more than one row
|
|
10
|
+
* and no disambiguator narrows the set, we surface the candidate list.
|
|
11
|
+
*
|
|
12
|
+
* This command is graph-only — the lifecycle owner
|
|
13
|
+
* (`openStoreForCommand`) constructs the composed `Store` envelope, but
|
|
14
|
+
* `runContext` reaches through `store.graph` for every read so the
|
|
15
|
+
* `IGraphStore` typed-finder surface stays the only contract.
|
|
16
|
+
*/
|
|
17
|
+
import { openStoreForCommand } from "./open-store.js";
|
|
18
|
+
/**
|
|
19
|
+
* Find Process-kind partners reachable from the target via `PROCESS_STEP`
|
|
20
|
+
* edges. Mirrors the post-A-6c MCP equivalent in
|
|
21
|
+
* `packages/mcp/src/tools/context.ts:567` so the two surfaces stay in
|
|
22
|
+
* lockstep on edge semantics + ordering.
|
|
23
|
+
*/
|
|
24
|
+
async function fetchProcessParticipation(graph, targetId) {
|
|
25
|
+
const [outEdges, inEdges] = await Promise.all([
|
|
26
|
+
graph.listEdgesByType("PROCESS_STEP", { fromIds: [targetId] }),
|
|
27
|
+
graph.listEdgesByType("PROCESS_STEP", { toIds: [targetId] }),
|
|
28
|
+
]);
|
|
29
|
+
const partnerIds = new Set();
|
|
30
|
+
for (const e of [...outEdges, ...inEdges]) {
|
|
31
|
+
const id = e.from === targetId ? e.to : e.from;
|
|
32
|
+
partnerIds.add(id);
|
|
33
|
+
}
|
|
34
|
+
if (partnerIds.size === 0)
|
|
35
|
+
return [];
|
|
36
|
+
const partners = await graph.listNodes({ ids: [...partnerIds] });
|
|
37
|
+
const partnerById = new Map();
|
|
38
|
+
for (const p of partners)
|
|
39
|
+
partnerById.set(p.id, p);
|
|
40
|
+
const dedup = new Map();
|
|
41
|
+
for (const e of [...outEdges, ...inEdges]) {
|
|
42
|
+
const partnerId = e.from === targetId ? e.to : e.from;
|
|
43
|
+
const partner = partnerById.get(partnerId);
|
|
44
|
+
if (!partner || partner.kind !== "Process")
|
|
45
|
+
continue;
|
|
46
|
+
if (dedup.has(partner.id))
|
|
47
|
+
continue;
|
|
48
|
+
const inferredLabelRaw = partner.inferredLabel;
|
|
49
|
+
const label = typeof inferredLabelRaw === "string" && inferredLabelRaw.length > 0
|
|
50
|
+
? inferredLabelRaw
|
|
51
|
+
: partner.name;
|
|
52
|
+
const stepRaw = e.step;
|
|
53
|
+
const stepNum = typeof stepRaw === "number" && Number.isFinite(stepRaw) && stepRaw > 0
|
|
54
|
+
? Math.trunc(stepRaw)
|
|
55
|
+
: null;
|
|
56
|
+
dedup.set(partner.id, { label, step: stepNum });
|
|
57
|
+
}
|
|
58
|
+
const items = Array.from(dedup.entries()).map(([id, v]) => ({
|
|
59
|
+
id,
|
|
60
|
+
label: v.label,
|
|
61
|
+
step: v.step,
|
|
62
|
+
}));
|
|
63
|
+
// Match the prior `ORDER BY r.step` then deterministic id tiebreak.
|
|
64
|
+
items.sort((a, b) => {
|
|
65
|
+
const as = a.step ?? Number.POSITIVE_INFINITY;
|
|
66
|
+
const bs = b.step ?? Number.POSITIVE_INFINITY;
|
|
67
|
+
if (as !== bs)
|
|
68
|
+
return as - bs;
|
|
69
|
+
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
70
|
+
});
|
|
71
|
+
return items.slice(0, 20);
|
|
72
|
+
}
|
|
73
|
+
function nodeToResolved(n) {
|
|
74
|
+
return {
|
|
75
|
+
nodeId: n.id,
|
|
76
|
+
name: n.name,
|
|
77
|
+
kind: n.kind,
|
|
78
|
+
filePath: n.filePath,
|
|
79
|
+
score: 0,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function searchResultToResolvedNode(r) {
|
|
83
|
+
return {
|
|
84
|
+
nodeId: r.nodeId,
|
|
85
|
+
name: r.name,
|
|
86
|
+
kind: r.kind,
|
|
87
|
+
filePath: r.filePath,
|
|
88
|
+
score: r.score,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async function resolveTarget(graph, symbol, opts) {
|
|
92
|
+
if (opts.targetUid !== undefined && opts.targetUid.length > 0) {
|
|
93
|
+
const list = await graph.listNodes({ ids: [opts.targetUid], limit: 1 });
|
|
94
|
+
const node = list[0];
|
|
95
|
+
if (!node)
|
|
96
|
+
return { kind: "not_found" };
|
|
97
|
+
return { kind: "resolved", target: nodeToResolved(node), alternates: [] };
|
|
98
|
+
}
|
|
99
|
+
// Name-keyed lookup with optional kind narrowing. The `file_path != '<external>'
|
|
100
|
+
// AND kind != 'CodeElement'` invariants from the legacy SQL are now applied
|
|
101
|
+
// post-finder so we don't need a `NOT IN` shape. The MCP-side migration in
|
|
102
|
+
// `packages/mcp/src/tools/context.ts:418-429` pioneered this pattern.
|
|
103
|
+
const listOpts = opts.kind !== undefined && opts.kind.length > 0 ? { kinds: [opts.kind] } : {};
|
|
104
|
+
let candidates = await graph.listNodesByName(symbol, listOpts);
|
|
105
|
+
// Drop synthetic import stubs.
|
|
106
|
+
candidates = candidates.filter((n) => n.filePath !== "<external>" && n.kind !== "CodeElement");
|
|
107
|
+
// Optional file-path substring narrow (LIKE %x%).
|
|
108
|
+
if (opts.filePath !== undefined && opts.filePath.length > 0) {
|
|
109
|
+
const sub = opts.filePath;
|
|
110
|
+
candidates = candidates.filter((n) => n.filePath.includes(sub));
|
|
111
|
+
}
|
|
112
|
+
// Match prior `ORDER BY file_path LIMIT 25`.
|
|
113
|
+
const sorted = [...candidates].sort((a, b) => a.filePath < b.filePath ? -1 : a.filePath > b.filePath ? 1 : 0);
|
|
114
|
+
const sliced = sorted.slice(0, 25);
|
|
115
|
+
if (sliced.length === 1) {
|
|
116
|
+
const head = sliced[0];
|
|
117
|
+
if (!head)
|
|
118
|
+
return { kind: "not_found" };
|
|
119
|
+
return { kind: "resolved", target: nodeToResolved(head), alternates: [] };
|
|
120
|
+
}
|
|
121
|
+
if (sliced.length > 1) {
|
|
122
|
+
return { kind: "ambiguous", candidates: sliced.map(nodeToResolved) };
|
|
123
|
+
}
|
|
124
|
+
const fallback = await graph.search({ text: symbol, limit: 5 });
|
|
125
|
+
if (fallback.length === 0)
|
|
126
|
+
return { kind: "not_found" };
|
|
127
|
+
const [head, ...rest] = fallback;
|
|
128
|
+
if (head === undefined)
|
|
129
|
+
return { kind: "not_found" };
|
|
130
|
+
return {
|
|
131
|
+
kind: "resolved",
|
|
132
|
+
target: searchResultToResolvedNode(head),
|
|
133
|
+
alternates: rest.map(searchResultToResolvedNode),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
export async function runContext(symbol, opts = {}, hooks = {}) {
|
|
137
|
+
const openStore = hooks.openStore ?? openStoreForCommand;
|
|
138
|
+
const { store, repoPath } = await openStore(opts);
|
|
139
|
+
const graph = store.graph;
|
|
140
|
+
try {
|
|
141
|
+
const resolution = await resolveTarget(graph, symbol, opts);
|
|
142
|
+
if (resolution.kind === "not_found") {
|
|
143
|
+
if (opts.json) {
|
|
144
|
+
console.log(JSON.stringify({
|
|
145
|
+
repoPath,
|
|
146
|
+
target: null,
|
|
147
|
+
callers: [],
|
|
148
|
+
callees: [],
|
|
149
|
+
processes: [],
|
|
150
|
+
alternateCandidates: [],
|
|
151
|
+
}, null, 2));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
console.warn(`context: no symbol matching "${symbol}" in ${repoPath}`);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (resolution.kind === "ambiguous") {
|
|
158
|
+
const candidates = resolution.candidates.slice(0, 10);
|
|
159
|
+
if (opts.json) {
|
|
160
|
+
console.log(JSON.stringify({
|
|
161
|
+
repoPath,
|
|
162
|
+
ambiguous: true,
|
|
163
|
+
candidates: resolution.candidates,
|
|
164
|
+
}, null, 2));
|
|
165
|
+
process.exitCode = 1;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
console.warn(`context: "${symbol}" matched ${resolution.candidates.length} symbols in ${repoPath}. Re-call with --target-uid, --file-path, or --kind.`);
|
|
169
|
+
for (let i = 0; i < candidates.length; i += 1) {
|
|
170
|
+
const c = candidates[i];
|
|
171
|
+
if (!c)
|
|
172
|
+
continue;
|
|
173
|
+
console.warn(` ${i + 1}. [${c.kind}] ${c.name} — ${c.filePath} (${c.nodeId})`);
|
|
174
|
+
}
|
|
175
|
+
if (resolution.candidates.length > candidates.length) {
|
|
176
|
+
console.warn(` … ${resolution.candidates.length - candidates.length} more`);
|
|
177
|
+
}
|
|
178
|
+
process.exitCode = 1;
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const target = resolution.target;
|
|
182
|
+
const [up, down, processes] = await Promise.all([
|
|
183
|
+
graph.traverse({
|
|
184
|
+
startId: target.nodeId,
|
|
185
|
+
direction: "up",
|
|
186
|
+
maxDepth: 1,
|
|
187
|
+
relationTypes: ["CALLS"],
|
|
188
|
+
}),
|
|
189
|
+
graph.traverse({
|
|
190
|
+
startId: target.nodeId,
|
|
191
|
+
direction: "down",
|
|
192
|
+
maxDepth: 1,
|
|
193
|
+
relationTypes: ["CALLS"],
|
|
194
|
+
}),
|
|
195
|
+
fetchProcessParticipation(graph, target.nodeId),
|
|
196
|
+
]);
|
|
197
|
+
if (opts.json) {
|
|
198
|
+
console.log(JSON.stringify({
|
|
199
|
+
repoPath,
|
|
200
|
+
target,
|
|
201
|
+
callers: up,
|
|
202
|
+
callees: down,
|
|
203
|
+
processes,
|
|
204
|
+
alternateCandidates: resolution.alternates,
|
|
205
|
+
}, null, 2));
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
console.warn(`context: ${target.name} (${target.kind}) — ${target.filePath}`);
|
|
209
|
+
console.log("");
|
|
210
|
+
console.log(`Inbound (depth 1): ${up.length}`);
|
|
211
|
+
for (const r of up)
|
|
212
|
+
console.log(` ← ${r.nodeId}`);
|
|
213
|
+
console.log("");
|
|
214
|
+
console.log(`Outbound (depth 1): ${down.length}`);
|
|
215
|
+
for (const r of down)
|
|
216
|
+
console.log(` → ${r.nodeId}`);
|
|
217
|
+
if (processes.length > 0) {
|
|
218
|
+
console.log("");
|
|
219
|
+
console.log(`Processes (${processes.length}):`);
|
|
220
|
+
for (const p of processes) {
|
|
221
|
+
const stepLabel = p.step !== null ? `step ${p.step}` : "participant";
|
|
222
|
+
console.log(` ⊿ ${p.label} — ${stepLabel} (${p.id})`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (resolution.alternates.length > 0) {
|
|
226
|
+
console.log("");
|
|
227
|
+
console.log(`Other candidates for "${symbol}":`);
|
|
228
|
+
for (const c of resolution.alternates) {
|
|
229
|
+
console.log(` - ${c.name} (${c.kind}) — ${c.filePath}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
finally {
|
|
234
|
+
await store.close();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub detect-changes` — map a git diff onto affected graph symbols.
|
|
3
|
+
*
|
|
4
|
+
* Delegates to `@opencodehub/analysis.runDetectChanges`. The CLI layer
|
|
5
|
+
* only resolves the scope flag, runs git against the repo, and formats
|
|
6
|
+
* the result. Useful from CI (GitHub Actions, GitLab CI) without
|
|
7
|
+
* launching the MCP server.
|
|
8
|
+
*
|
|
9
|
+
* Exit codes:
|
|
10
|
+
* 0 — diff produced zero affected symbols (risk: LOW or empty diff).
|
|
11
|
+
* 1 — diff produced HIGH or CRITICAL risk. Operators configure CI
|
|
12
|
+
* gates to fail on non-zero.
|
|
13
|
+
* Any risk tier MEDIUM or below stays on exit 0 so informational runs
|
|
14
|
+
* are non-blocking.
|
|
15
|
+
*/
|
|
16
|
+
export interface DetectChangesOptions {
|
|
17
|
+
readonly scope?: "unstaged" | "staged" | "all" | "compare";
|
|
18
|
+
readonly compareRef?: string;
|
|
19
|
+
readonly repo?: string;
|
|
20
|
+
readonly home?: string;
|
|
21
|
+
readonly json?: boolean;
|
|
22
|
+
/** When true, fail (exit 1) on any non-LOW risk. Default: HIGH+CRIT only. */
|
|
23
|
+
readonly strict?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function runDetectChangesCmd(opts?: DetectChangesOptions): Promise<void>;
|
|
26
|
+
//# sourceMappingURL=detect-changes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-changes.d.ts","sourceRoot":"","sources":["../../src/commands/detect-changes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IAC3D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAsB,mBAAmB,CAAC,IAAI,GAAE,oBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DxF"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub detect-changes` — map a git diff onto affected graph symbols.
|
|
3
|
+
*
|
|
4
|
+
* Delegates to `@opencodehub/analysis.runDetectChanges`. The CLI layer
|
|
5
|
+
* only resolves the scope flag, runs git against the repo, and formats
|
|
6
|
+
* the result. Useful from CI (GitHub Actions, GitLab CI) without
|
|
7
|
+
* launching the MCP server.
|
|
8
|
+
*
|
|
9
|
+
* Exit codes:
|
|
10
|
+
* 0 — diff produced zero affected symbols (risk: LOW or empty diff).
|
|
11
|
+
* 1 — diff produced HIGH or CRITICAL risk. Operators configure CI
|
|
12
|
+
* gates to fail on non-zero.
|
|
13
|
+
* Any risk tier MEDIUM or below stays on exit 0 so informational runs
|
|
14
|
+
* are non-blocking.
|
|
15
|
+
*/
|
|
16
|
+
import { runDetectChanges } from "@opencodehub/analysis";
|
|
17
|
+
import { openStoreForCommand } from "./open-store.js";
|
|
18
|
+
export async function runDetectChangesCmd(opts = {}) {
|
|
19
|
+
const scope = opts.scope ?? "all";
|
|
20
|
+
if (scope === "compare" && (opts.compareRef === undefined || opts.compareRef.length === 0)) {
|
|
21
|
+
console.error("codehub detect-changes: --scope=compare requires --compare-ref <git-ref> (e.g. origin/main)");
|
|
22
|
+
process.exitCode = 2;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const { store, repoPath } = await openStoreForCommand(opts);
|
|
26
|
+
try {
|
|
27
|
+
const q = { scope, repoPath };
|
|
28
|
+
if (opts.compareRef !== undefined)
|
|
29
|
+
q.compareRef = opts.compareRef;
|
|
30
|
+
const result = await runDetectChanges(store.graph, q);
|
|
31
|
+
if (opts.json) {
|
|
32
|
+
console.log(JSON.stringify(result, null, 2));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const { summary, changedFiles, affectedSymbols, affectedProcesses } = result;
|
|
36
|
+
console.log(`detect-changes: ${summary.fileCount} file(s), ${summary.symbolCount} symbol(s), ${summary.processCount} process(es) affected. Risk: ${summary.risk}.`);
|
|
37
|
+
if (changedFiles.length > 0) {
|
|
38
|
+
console.log("Changed files:");
|
|
39
|
+
for (const f of changedFiles.slice(0, 30))
|
|
40
|
+
console.log(` • ${f}`);
|
|
41
|
+
if (changedFiles.length > 30) {
|
|
42
|
+
console.log(` … ${changedFiles.length - 30} more`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (affectedSymbols.length > 0) {
|
|
46
|
+
console.log(`Affected symbols (${affectedSymbols.length}):`);
|
|
47
|
+
for (const s of affectedSymbols.slice(0, 50)) {
|
|
48
|
+
console.log(` • ${s.name} [${s.kind}] — ${s.filePath}`);
|
|
49
|
+
}
|
|
50
|
+
if (affectedSymbols.length > 50) {
|
|
51
|
+
console.log(` … ${affectedSymbols.length - 50} more`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (affectedProcesses.length > 0) {
|
|
55
|
+
console.log(`Affected processes (${affectedProcesses.length}):`);
|
|
56
|
+
for (const p of affectedProcesses) {
|
|
57
|
+
console.log(` ⊿ ${p.name} — ${p.entryPointFile}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const risk = result.summary.risk;
|
|
62
|
+
const blockOn = opts.strict
|
|
63
|
+
? new Set(["MEDIUM", "HIGH", "CRITICAL"])
|
|
64
|
+
: new Set(["HIGH", "CRITICAL"]);
|
|
65
|
+
if (blockOn.has(risk)) {
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
await store.close();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=detect-changes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-changes.js","sourceRoot":"","sources":["../../src/commands/detect-changes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub doctor` — environment probe.
|
|
3
|
+
*
|
|
4
|
+
* Runs every `Check` registered in `CHECKS`, prints a table, and exits
|
|
5
|
+
* with a status code that maps to the worst result seen:
|
|
6
|
+
*
|
|
7
|
+
* 0 all ok
|
|
8
|
+
* 1 at least one warn (non-blocking)
|
|
9
|
+
* 2 at least one fail (blocking — something is broken)
|
|
10
|
+
*
|
|
11
|
+
* Checks are strictly diagnostic — they never auto-heal. Each one returns
|
|
12
|
+
* a `hint` string the user can copy-paste when things are off.
|
|
13
|
+
*/
|
|
14
|
+
export type CheckStatus = "ok" | "warn" | "fail";
|
|
15
|
+
export interface CheckResult {
|
|
16
|
+
readonly status: CheckStatus;
|
|
17
|
+
readonly message: string;
|
|
18
|
+
readonly hint?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface Check {
|
|
21
|
+
readonly name: string;
|
|
22
|
+
run(): Promise<CheckResult>;
|
|
23
|
+
}
|
|
24
|
+
export interface DoctorOptions {
|
|
25
|
+
/** Override HOME so tests can point at a fake dotdir. */
|
|
26
|
+
readonly home?: string;
|
|
27
|
+
/** Skip checks that rely on native bindings (e.g. in CI sandboxes). */
|
|
28
|
+
readonly skipNative?: boolean;
|
|
29
|
+
/** Override the repo root when resolving workspace packages. */
|
|
30
|
+
readonly repoRoot?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface DoctorReport {
|
|
33
|
+
readonly rows: readonly {
|
|
34
|
+
readonly name: string;
|
|
35
|
+
readonly result: CheckResult;
|
|
36
|
+
}[];
|
|
37
|
+
readonly exitCode: 0 | 1 | 2;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Entry point invoked by `codehub doctor`. Prints the table and sets
|
|
41
|
+
* `process.exitCode`. Also returns the structured report so tests and
|
|
42
|
+
* acceptance scripts can assert the outcome without parsing stdout.
|
|
43
|
+
*/
|
|
44
|
+
export declare function runDoctor(opts?: DoctorOptions): Promise<DoctorReport>;
|
|
45
|
+
/**
|
|
46
|
+
* Ordered list of environment probes. Order matters only for the output
|
|
47
|
+
* table — runs are independent, but we surface foundational checks first
|
|
48
|
+
* (Node, pnpm, native bindings) so the user can fix a broken foundation
|
|
49
|
+
* before worrying about downstream extras.
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildChecks(opts?: DoctorOptions): readonly Check[];
|
|
52
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;KAAE,EAAE,CAAC;IAClF,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CA2B/E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,aAAkB,GAAG,SAAS,KAAK,EAAE,CA2CtE"}
|