@graphit/cli 0.2.331 → 0.2.348

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.
Files changed (50) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/README.md +1 -1
  5. package/bin/graphit +1 -1
  6. package/bin/graphit.ps1 +1 -1
  7. package/dist/api/client.d.ts +8 -0
  8. package/dist/api/client.js +24 -2
  9. package/dist/api/client.js.map +1 -1
  10. package/dist/commands/connector/ui-only.d.ts +12 -0
  11. package/dist/commands/connector/ui-only.js +28 -0
  12. package/dist/commands/connector/ui-only.js.map +1 -0
  13. package/dist/commands/connector.js +2 -14
  14. package/dist/commands/connector.js.map +1 -1
  15. package/dist/commands/dashboard.d.ts +14 -0
  16. package/dist/commands/dashboard.js +52 -1
  17. package/dist/commands/dashboard.js.map +1 -1
  18. package/dist/commands/kb-repo-token.d.ts +17 -0
  19. package/dist/commands/kb-repo-token.js +122 -0
  20. package/dist/commands/kb-repo-token.js.map +1 -0
  21. package/dist/commands/kb-repo.d.ts +29 -0
  22. package/dist/commands/kb-repo.js +407 -0
  23. package/dist/commands/kb-repo.js.map +1 -0
  24. package/dist/commands/kb.js +133 -0
  25. package/dist/commands/kb.js.map +1 -1
  26. package/dist/output/format.js +77 -1
  27. package/dist/output/format.js.map +1 -1
  28. package/dist/skill-guard.js +5 -1
  29. package/dist/skill-guard.js.map +1 -1
  30. package/dist/update-check.d.ts +18 -0
  31. package/dist/update-check.js +54 -4
  32. package/dist/update-check.js.map +1 -1
  33. package/package.json +1 -1
  34. package/scripts/generate-tool-manifest.mjs +1 -1
  35. package/scripts/verb-policy-source.json +138 -2
  36. package/skills/graphit/SKILL.md +26 -6
  37. package/skills/graphit/VERSION.json +1 -1
  38. package/skills/graphit/references/chart-patterns.md +1 -5
  39. package/skills/graphit/references/chart-selection.md +1 -1
  40. package/skills/graphit/references/data-sources.md +7 -3
  41. package/skills/graphit/references/filters.md +1 -1
  42. package/skills/graphit/references/kb-actions.md +4 -0
  43. package/skills/graphit/references/kb-scope.md +4 -0
  44. package/skills/graphit/references/onboarding.md +1 -1
  45. package/skills/graphit/references/operations.md +1 -1
  46. package/skills/graphit/references/repo-kb.md +101 -0
  47. package/skills/graphit/references/runtime.md +1 -1
  48. package/skills/graphit/references/semantic-authoring.md +3 -1
  49. package/skills/graphit/references/state-contract.md +2 -2
  50. package/skills/graphit/references/templates.md +68 -0
@@ -0,0 +1,122 @@
1
+ import { apiClient } from "../api/client.js";
2
+ import { errorOutput, note, output } from "../output/format.js";
3
+ // Project #289 Phase 8 (ARCH-10): the CI machine principal. An org admin mints a
4
+ // token once (the server keeps only a hash, bound to the org and its bound
5
+ // repository; the cleartext is printed on that one output and never again), the
6
+ // pipeline holds it as a secret, and `kb repo verify|apply --token` presents it
7
+ // instead of a login. `kb:verify` reaches verify and status; `kb:apply` reaches
8
+ // verify, apply and status. The token is the pipeline's authority to CALL - the
9
+ // change's humans still pass the approval check, so it never stands in for a
10
+ // reviewer.
11
+ const TOKENS_PATH = "/api/v1/cli/kb/repo/tokens";
12
+ // The server's shape is `gkb.<v|a>.<org>.<token_id>.<secret>`; dots join the
13
+ // segments because org ids and urlsafe secrets may both carry `_` and `-`.
14
+ export const MACHINE_TOKEN_PREFIX = "gkb.";
15
+ export const MACHINE_TOKEN_SCOPES = ["kb:verify", "kb:apply"];
16
+ const METADATA_COLUMNS = [
17
+ "token_id",
18
+ "scope",
19
+ "repo",
20
+ "created_at",
21
+ "created_by_email",
22
+ "last_used_at",
23
+ "revoked_at",
24
+ ];
25
+ // `--token` (interactive) or the GRAPHIT_TOKEN environment variable (CI) carries
26
+ // the cleartext a mint printed. Anything else - a login session, a pasted token
27
+ // id, an empty or unset CI secret - is refused here, before any request would
28
+ // carry it to the server.
29
+ export function assertMachineToken(token) {
30
+ if (typeof token !== "string" ||
31
+ !token.startsWith(MACHINE_TOKEN_PREFIX) ||
32
+ token.length === MACHINE_TOKEN_PREFIX.length) {
33
+ throw new Error(`--token or GRAPHIT_TOKEN must be a machine token minted by \`kb repo token mint\` (it starts with ${MACHINE_TOKEN_PREFIX}); ` +
34
+ "a login session, a token id or an empty value is not accepted");
35
+ }
36
+ return token;
37
+ }
38
+ export function assertMachineTokenScope(scope) {
39
+ if (!MACHINE_TOKEN_SCOPES.includes(scope)) {
40
+ throw new Error(`--scope must be ${MACHINE_TOKEN_SCOPES.join(" or ")}`);
41
+ }
42
+ return scope;
43
+ }
44
+ // The list route answers `{tokens: [...]}` or a bare array; either way only
45
+ // metadata leaves here. A `token` member is dropped unread: the cleartext
46
+ // exists on the mint output and nowhere else.
47
+ export function tokenListRows(payload) {
48
+ const rows = Array.isArray(payload)
49
+ ? payload
50
+ : payload?.tokens;
51
+ if (!Array.isArray(rows))
52
+ return [];
53
+ const metadata = [];
54
+ for (const row of rows) {
55
+ if (!row || typeof row !== "object")
56
+ continue;
57
+ const entry = {};
58
+ for (const [key, value] of Object.entries(row)) {
59
+ if (key !== "token")
60
+ entry[key] = value;
61
+ }
62
+ metadata.push(entry);
63
+ }
64
+ return metadata;
65
+ }
66
+ // Intentionally not named `register*` (see kb-repo.ts): this attaches the
67
+ // `token` group under `kb repo` and is called by attachKBRepoCommands.
68
+ export function attachKBRepoTokenCommands(repo) {
69
+ const token = repo
70
+ .command("token")
71
+ .description("CI machine tokens (org admin): mint one display-once token per pipeline job, list their metadata, revoke");
72
+ token
73
+ .command("mint")
74
+ .description("Mint a display-once CI machine token (org admin); scope kb:verify or kb:apply")
75
+ .requiredOption("--scope <scope>", "kb:verify (the PR job: verify + status) or kb:apply (the merge job: verify, apply, status)")
76
+ .action(async function () {
77
+ try {
78
+ const scope = assertMachineTokenScope(this.opts().scope);
79
+ const minted = await apiClient.post(TOKENS_PATH, { scope });
80
+ note(" Shown once: store the token as a CI secret now. It cannot be displayed again; " +
81
+ "if it is lost, revoke it and mint another.");
82
+ output(this, {
83
+ token: minted.token,
84
+ token_id: minted.token_id,
85
+ scope: minted.scope,
86
+ repo: minted.repo ?? null,
87
+ created_at: minted.created_at ?? null,
88
+ display_once: true,
89
+ }, { keyValue: true });
90
+ }
91
+ catch (error) {
92
+ errorOutput(error);
93
+ }
94
+ });
95
+ token
96
+ .command("list")
97
+ .description("List CI machine tokens: metadata only, never the secret")
98
+ .action(async function () {
99
+ try {
100
+ const payload = await apiClient.get(TOKENS_PATH);
101
+ output(this, tokenListRows(payload), { columns: METADATA_COLUMNS });
102
+ }
103
+ catch (error) {
104
+ errorOutput(error);
105
+ }
106
+ });
107
+ token
108
+ .command("revoke <token-id>")
109
+ .description("Revoke a CI machine token (org admin)")
110
+ .action(async function (tokenId) {
111
+ try {
112
+ if (tokenId.startsWith(MACHINE_TOKEN_PREFIX)) {
113
+ throw new Error("revoke takes the token id from `kb repo token list`, never the token itself");
114
+ }
115
+ output(this, await apiClient.post(`${TOKENS_PATH}/${encodeURIComponent(tokenId)}/revoke`, {}));
116
+ }
117
+ catch (error) {
118
+ errorOutput(error);
119
+ }
120
+ });
121
+ }
122
+ //# sourceMappingURL=kb-repo-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kb-repo-token.js","sourceRoot":"","sources":["../../src/commands/kb-repo-token.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { Command } from "commander";
2
+ export declare const KB_REPO_EXIT_FAILED = 1;
3
+ export declare const KB_REPO_EXIT_REFUSED = 2;
4
+ export declare const KB_REPO_EXIT_TIMEOUT = 3;
5
+ export declare const MACHINE_TOKEN_ENV = "GRAPHIT_TOKEN";
6
+ export interface OperationStatus {
7
+ operation_id: string;
8
+ kind?: "verify" | "apply";
9
+ status: "preparing" | "queued" | "running" | "waiting_child" | "succeeded" | "refused" | "failed_retryable" | "failed";
10
+ stage: string;
11
+ plan_id?: string | null;
12
+ local_only?: boolean;
13
+ completed_components: number;
14
+ total_components: number;
15
+ report?: ({
16
+ verdict?: string;
17
+ } & Record<string, unknown>) | null;
18
+ error?: {
19
+ code?: string;
20
+ detail?: string;
21
+ } | null;
22
+ }
23
+ export declare function pollDelayMs(elapsedMs: number, intervalMs: number): number;
24
+ export declare function resolveMachineToken(flag: unknown, env?: NodeJS.ProcessEnv): string | undefined;
25
+ export declare function repoExitCode(status: OperationStatus): number;
26
+ export declare function collectCheckout(checkout: string): Record<string, string>;
27
+ export declare function checkoutIsDirty(checkout: string): boolean | undefined;
28
+ export declare function writeExportedDatasources(out: string, files: Record<string, string>): string[];
29
+ export declare function attachKBRepoCommands(kb: Command): void;
@@ -0,0 +1,407 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
3
+ import { join, relative, resolve, sep } from "node:path";
4
+ import { apiClient, setMachineToken } from "../api/client.js";
5
+ import { errorOutput, note, output } from "../output/format.js";
6
+ import { assertMachineToken, attachKBRepoTokenCommands } from "./kb-repo-token.js";
7
+ // The repository-owned Knowledge Base verbs. `kb repo verify` returns a plan
8
+ // for a `.graphit/` tree at an exact commit; `kb repo apply` applies one. Both
9
+ // poll a durable server operation; exit codes are stable so CI can gate on
10
+ // them: 0 pass, 1 failed, 2 refused or a failing verdict, 3 stopped waiting.
11
+ export const KB_REPO_EXIT_FAILED = 1;
12
+ export const KB_REPO_EXIT_REFUSED = 2;
13
+ export const KB_REPO_EXIT_TIMEOUT = 3;
14
+ const DEFAULT_POLL_INTERVAL_MS = 1_000;
15
+ const DEFAULT_TIMEOUT_MS = 30 * 60_000;
16
+ // After the first minute an operation is doing real work (compile, apply children);
17
+ // polling every second from then on only burns the caller's rate bucket and writes
18
+ // the machine token's last_used_at at Firestore's per-document ceiling.
19
+ const POLL_BACKOFF_AFTER_MS = 60_000;
20
+ const SLOW_POLL_INTERVAL_MS = 5_000;
21
+ // CI hands the machine token through the environment so it never enters argv
22
+ // (process listings, shell traces, the CA-guard re-exec). `--token` stays for
23
+ // interactive use.
24
+ export const MACHINE_TOKEN_ENV = "GRAPHIT_TOKEN";
25
+ const GRAPHIT_DIR = ".graphit";
26
+ const MAX_FILE_BYTES = 8 * 1024 * 1024;
27
+ function positiveMilliseconds(raw, fallback, flag) {
28
+ if (raw === undefined)
29
+ return fallback;
30
+ if (!/^[1-9]\d*$/.test(raw))
31
+ throw new Error(`${flag} must be a positive integer`);
32
+ return Number(raw);
33
+ }
34
+ // The delay before the next status read: the caller's interval for the first
35
+ // minute, then at least five seconds. Exported for the test, pure on purpose.
36
+ export function pollDelayMs(elapsedMs, intervalMs) {
37
+ return elapsedMs < POLL_BACKOFF_AFTER_MS ? intervalMs : Math.max(intervalMs, SLOW_POLL_INTERVAL_MS);
38
+ }
39
+ // The machine token for this process: `--token` when given (any value, so an
40
+ // empty flag is refused rather than ignored), else the environment variable CI
41
+ // sets, else nothing and the login stays the credential. An empty or unset CI
42
+ // secret therefore fails typed here instead of silently falling back to a login
43
+ // that does not exist on the runner.
44
+ export function resolveMachineToken(flag, env = process.env) {
45
+ if (flag !== undefined)
46
+ return assertMachineToken(flag);
47
+ const fromEnv = env[MACHINE_TOKEN_ENV];
48
+ if (fromEnv !== undefined)
49
+ return assertMachineToken(fromEnv);
50
+ return undefined;
51
+ }
52
+ // A verify succeeds as an OPERATION even when its plan fails: the plan is the
53
+ // result. The exit code reads the verdict, so a failing verdict cancels a
54
+ // pipeline the same way a refusal does.
55
+ export function repoExitCode(status) {
56
+ if (status.status === "succeeded") {
57
+ return status.report?.verdict === "fail" ? KB_REPO_EXIT_REFUSED : 0;
58
+ }
59
+ if (status.status === "refused")
60
+ return KB_REPO_EXIT_REFUSED;
61
+ return KB_REPO_EXIT_FAILED;
62
+ }
63
+ async function pollOperation(statusPath, options) {
64
+ const { intervalMs, timeoutMs } = options;
65
+ const started = Date.now();
66
+ let lastStage = "";
67
+ while (Date.now() - started < timeoutMs) {
68
+ let status;
69
+ try {
70
+ status = await apiClient.get(statusPath);
71
+ }
72
+ catch (error) {
73
+ // A deterministic refusal of the status read (concealed operation, no
74
+ // permission, switch off) will never turn into a result; surface it now
75
+ // instead of polling silently to the timeout. Network and 5xx keep polling.
76
+ const httpStatus = error.status;
77
+ if (typeof httpStatus === "number" && httpStatus >= 400 && httpStatus < 500 && httpStatus !== 429) {
78
+ throw error;
79
+ }
80
+ await new Promise((resolve) => setTimeout(resolve, pollDelayMs(Date.now() - started, intervalMs)));
81
+ continue;
82
+ }
83
+ if (status.stage !== lastStage) {
84
+ const progress = status.total_components
85
+ ? ` (${status.completed_components}/${status.total_components} components)`
86
+ : "";
87
+ note(` ${status.stage}${progress}`);
88
+ lastStage = status.stage;
89
+ }
90
+ if (["succeeded", "refused", "failed"].includes(status.status))
91
+ return status;
92
+ await new Promise((resolve) => setTimeout(resolve, pollDelayMs(Date.now() - started, intervalMs)));
93
+ }
94
+ return null;
95
+ }
96
+ function walk(root, dir, into) {
97
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
98
+ const full = join(dir, entry.name);
99
+ if (entry.isSymbolicLink())
100
+ continue;
101
+ if (entry.isDirectory()) {
102
+ walk(root, full, into);
103
+ continue;
104
+ }
105
+ if (!entry.isFile())
106
+ continue;
107
+ if (statSync(full).size > MAX_FILE_BYTES) {
108
+ throw new Error(`${relative(root, full)} is over 8 MiB; the repository tree must stay text-sized`);
109
+ }
110
+ into[relative(root, full).split(sep).join("/")] = readFileSync(full, "utf-8");
111
+ }
112
+ }
113
+ function provenanceSourcePaths(files) {
114
+ const paths = new Set();
115
+ for (const [path, text] of Object.entries(files)) {
116
+ if (!path.startsWith(`${GRAPHIT_DIR}/provenance/`) || !path.endsWith(".json"))
117
+ continue;
118
+ let payload;
119
+ try {
120
+ payload = JSON.parse(text);
121
+ }
122
+ catch {
123
+ continue; // the server refuses a malformed shard with its typed code
124
+ }
125
+ for (const doc of Object.keys(payload.sources ?? {}))
126
+ paths.add(doc);
127
+ }
128
+ return [...paths].sort();
129
+ }
130
+ // Materialize a checkout the way the server materializes a commit archive:
131
+ // `.graphit/**` plus exactly the source documents the provenance shards name.
132
+ // Nothing else on disk leaves the machine.
133
+ export function collectCheckout(checkout) {
134
+ const root = resolve(checkout);
135
+ const graphitDir = join(root, GRAPHIT_DIR);
136
+ if (!existsSync(graphitDir) || !statSync(graphitDir).isDirectory()) {
137
+ throw new Error(`No ${GRAPHIT_DIR}/ tree under ${root}. Set up the repository from Claude Code with the graphit skill first.`);
138
+ }
139
+ const files = {};
140
+ walk(root, graphitDir, files);
141
+ for (const doc of provenanceSourcePaths(files)) {
142
+ const full = resolve(root, doc);
143
+ if (!full.startsWith(root + sep) || !existsSync(full) || !statSync(full).isFile())
144
+ continue;
145
+ files[doc] = readFileSync(full, "utf-8");
146
+ }
147
+ return files;
148
+ }
149
+ function git(checkout, args) {
150
+ try {
151
+ return execFileSync("git", ["-C", checkout, ...args], {
152
+ encoding: "utf-8",
153
+ stdio: ["ignore", "pipe", "ignore"],
154
+ }).trim();
155
+ }
156
+ catch {
157
+ return undefined;
158
+ }
159
+ }
160
+ export function checkoutIsDirty(checkout) {
161
+ const status = git(checkout, ["status", "--porcelain", "--", GRAPHIT_DIR]);
162
+ return status === undefined ? undefined : status.length > 0;
163
+ }
164
+ // Write the server's `datasources/<name>.ds.yml` + `<name>.sql` pairs into one
165
+ // directory. File names come from the server (the source's lower-cased name)
166
+ // and are still refused here if they could leave `out` - defence in depth,
167
+ // never the only check.
168
+ export function writeExportedDatasources(out, files) {
169
+ const root = resolve(out);
170
+ mkdirSync(root, { recursive: true });
171
+ const written = [];
172
+ for (const [name, text] of Object.entries(files)) {
173
+ if (name.includes("/") || name.includes("\\") || name.startsWith(".") || name.includes("..")) {
174
+ throw new Error(`refusing to write ${name}: not a plain file name`);
175
+ }
176
+ if (!name.endsWith(".ds.yml") && !name.endsWith(".sql")) {
177
+ throw new Error(`refusing to write ${name}: not a definition file`);
178
+ }
179
+ writeFileSync(join(root, name), text, "utf-8");
180
+ written.push(name);
181
+ }
182
+ return written.sort();
183
+ }
184
+ async function runAndPoll(command, path, body, opts) {
185
+ const intervalMs = positiveMilliseconds(opts.pollIntervalMs, DEFAULT_POLL_INTERVAL_MS, "--poll-interval-ms");
186
+ const timeoutMs = positiveMilliseconds(opts.timeoutMs, DEFAULT_TIMEOUT_MS, "--timeout-ms");
187
+ const accepted = await apiClient.post(path, body, { timeoutMs: 120_000 });
188
+ note(` queued ${accepted.operation_id}`);
189
+ const terminal = await pollOperation(accepted.status_path, { intervalMs, timeoutMs });
190
+ if (terminal === null) {
191
+ output(command, {
192
+ operation_id: accepted.operation_id,
193
+ status: "timed_out",
194
+ detail: "The operation is still running; poll the returned operation id",
195
+ });
196
+ process.exitCode = KB_REPO_EXIT_TIMEOUT;
197
+ return;
198
+ }
199
+ output(command, terminal.report ?? terminal);
200
+ process.exitCode = repoExitCode(terminal);
201
+ }
202
+ // Intentionally not named `register*`: the generated Commander walk invokes
203
+ // every exported registrar as a top-level command. This attaches the `repo`
204
+ // group under `kb` and is called by registerKBCommands.
205
+ export function attachKBRepoCommands(kb) {
206
+ const repo = kb
207
+ .command("repo")
208
+ .description("Repository-owned Knowledge Base: verify a commit's .graphit/ tree into a plan, apply a plan");
209
+ repo
210
+ .command("verify")
211
+ .description("Compute the plan for a .graphit/ tree: identity + access, their semantic layer through provenance, " +
212
+ "validity + completeness, and the KB/DS/dashboard actions. Any refusal exits 2 (a CI check fails). " +
213
+ "--sha pulls the commit from the bound provider (CI); --path uploads a local checkout and yields a " +
214
+ "local-only plan that can never be applied")
215
+ .option("--sha <sha>", "Commit to verify; the server pulls its archive from the bound repository")
216
+ .option("--pr <id>", "Pull request the commit belongs to (with --sha)")
217
+ .option("--path <checkout>", "Local checkout to upload (CLI-only; the plan is local-only)")
218
+ .option("--allow-dirty", "Upload a checkout whose .graphit/ has uncommitted changes")
219
+ .option("--kind <kind>", "Plan kind: sync (default) or migration", "sync")
220
+ .option("--token <token>", "Machine token minted by `kb repo token mint` (CI); replaces the login")
221
+ .option("--poll-interval-ms <n>", "Status poll interval", String(DEFAULT_POLL_INTERVAL_MS))
222
+ .option("--timeout-ms <n>", "Maximum wait", String(DEFAULT_TIMEOUT_MS))
223
+ .action(async function () {
224
+ try {
225
+ const opts = this.opts();
226
+ if ((opts.sha && opts.path) || (!opts.sha && !opts.path)) {
227
+ throw new Error("Provide exactly one of --sha <sha> or --path <checkout>");
228
+ }
229
+ if (!["sync", "migration"].includes(opts.kind)) {
230
+ throw new Error("--kind must be sync or migration");
231
+ }
232
+ const machineToken = resolveMachineToken(opts.token);
233
+ if (machineToken !== undefined)
234
+ setMachineToken(machineToken);
235
+ if (opts.path) {
236
+ const dirty = checkoutIsDirty(opts.path);
237
+ if (dirty === true && !opts.allowDirty) {
238
+ throw new Error(".graphit/ has uncommitted changes; commit them or pass --allow-dirty to upload the working tree");
239
+ }
240
+ const files = collectCheckout(opts.path);
241
+ const head = git(opts.path, ["rev-parse", "HEAD"]);
242
+ note(" local-only plan, not applyable: apply reads the bound provider, never an upload");
243
+ await runAndPoll(this, "/api/v1/cli/kb/repo/verify", {
244
+ files,
245
+ commit_sha: head && /^[0-9a-f]{7,64}$/.test(head) ? head : undefined,
246
+ source_label: `local checkout${dirty ? " (dirty)" : ""}`,
247
+ kind: opts.kind,
248
+ }, opts);
249
+ return;
250
+ }
251
+ await runAndPoll(this, "/api/v1/cli/kb/repo/verify", { commit_sha: opts.sha, pr_id: opts.pr, kind: opts.kind }, opts);
252
+ }
253
+ catch (error) {
254
+ errorOutput(error);
255
+ }
256
+ });
257
+ repo
258
+ .command("show")
259
+ .description("Show the repository binding: ownership mode, bound repository, branch, connection, last applied commit")
260
+ .action(async function () {
261
+ try {
262
+ output(this, await apiClient.get("/api/v1/cli/kb/repo"));
263
+ }
264
+ catch (error) {
265
+ errorOutput(error);
266
+ }
267
+ });
268
+ repo
269
+ .command("mode <mode>")
270
+ .description("Set KB ownership (org admin): managed = direct writes; manual = the repository owns shared KB assets " +
271
+ "and Data Source definitions (changes via pull request). A non-empty managed KB refuses manual")
272
+ .action(async function (mode) {
273
+ try {
274
+ if (!["managed", "manual"].includes(mode)) {
275
+ throw new Error("mode must be managed or manual");
276
+ }
277
+ output(this, await apiClient.post("/api/v1/cli/kb/repo/mode", { mode }));
278
+ }
279
+ catch (error) {
280
+ errorOutput(error);
281
+ }
282
+ });
283
+ repo
284
+ .command("bind")
285
+ .description("Bind the owning repository to a provider connection (org admin); the connection must name that repository")
286
+ .requiredOption("--connection <id>", "Git connection id (graphit connector list)")
287
+ .requiredOption("--repo <owner/name>", "Repository slug the connection names")
288
+ .option("--branch <name>", "Base branch verify and apply are bound to", "main")
289
+ .option("--approved-sha <sha>", "The only commit the migration apply accepts (founder-run migrations)")
290
+ .action(async function () {
291
+ try {
292
+ const opts = this.opts();
293
+ const body = {
294
+ connection_id: opts.connection,
295
+ repo: opts.repo,
296
+ base_branch: opts.branch,
297
+ };
298
+ if (opts.approvedSha)
299
+ body.approved_commit_sha = opts.approvedSha;
300
+ output(this, await apiClient.post("/api/v1/cli/kb/repo/bind", body));
301
+ }
302
+ catch (error) {
303
+ errorOutput(error);
304
+ }
305
+ });
306
+ repo
307
+ .command("identities")
308
+ .description("List git identities (org admin): linked, unlinked, and accounts the last plans could not link")
309
+ .action(async function () {
310
+ try {
311
+ output(this, await apiClient.get("/api/v1/cli/kb/repo/identities"));
312
+ }
313
+ catch (error) {
314
+ errorOutput(error);
315
+ }
316
+ });
317
+ repo
318
+ .command("link-identity <provider> <account> <member-email>")
319
+ .description("Link a provider account (login or account id) to the member with that email (org admin)")
320
+ .action(async function (provider, account, memberEmail) {
321
+ try {
322
+ if (!["github", "bitbucket"].includes(provider)) {
323
+ throw new Error("provider must be github or bitbucket");
324
+ }
325
+ output(this, await apiClient.post("/api/v1/cli/kb/repo/identities/link", {
326
+ provider,
327
+ account,
328
+ member_email: memberEmail,
329
+ }));
330
+ }
331
+ catch (error) {
332
+ errorOutput(error);
333
+ }
334
+ });
335
+ repo
336
+ .command("unlink-identity <provider> <account>")
337
+ .description("Unlink a provider account from its member (org admin); leaves a tombstone the silent email match cannot cross")
338
+ .action(async function (provider, account) {
339
+ try {
340
+ if (!["github", "bitbucket"].includes(provider)) {
341
+ throw new Error("provider must be github or bitbucket");
342
+ }
343
+ output(this, await apiClient.post("/api/v1/cli/kb/repo/identities/unlink", {
344
+ provider,
345
+ account,
346
+ }));
347
+ }
348
+ catch (error) {
349
+ errorOutput(error);
350
+ }
351
+ });
352
+ repo
353
+ .command("export-datasources")
354
+ .description("Write the live Data Source definitions as datasources/<name>.ds.yml + <name>.sql (org admin): " +
355
+ "the mirror an org commits before entering manual mode; byte-identical when nothing differs")
356
+ .requiredOption("--out <dir>", "Directory to write into (the repository's .graphit/datasources)")
357
+ .action(async function () {
358
+ try {
359
+ const opts = this.opts();
360
+ const exported = await apiClient.get("/api/v1/cli/kb/repo/datasources");
361
+ const written = writeExportedDatasources(opts.out, exported.files ?? {});
362
+ output(this, {
363
+ out: resolve(opts.out),
364
+ definitions: exported.count ?? written.length / 2,
365
+ written,
366
+ skipped: exported.skipped ?? [],
367
+ });
368
+ }
369
+ catch (error) {
370
+ errorOutput(error);
371
+ }
372
+ });
373
+ repo
374
+ .command("apply")
375
+ .description("Apply a plan (org admin). --plan applies a saved plan id; --sha re-verifies the commit and applies " +
376
+ "the fresh plan in one call (the merge job). Refuses a stale plan, a changed tree, a failing verdict " +
377
+ "or a local-only plan; a concurrent apply on the same repository waits")
378
+ .option("--plan <id>", "Plan id returned by kb repo verify")
379
+ .option("--sha <sha>", "Commit to verify and apply; the server pulls its archive")
380
+ .option("--pr <id>", "Pull request the commit belongs to (with --sha)")
381
+ .option("--kind <kind>", "Plan kind: sync (default) or migration", "sync")
382
+ .option("--token <token>", "Machine token minted by `kb repo token mint` (CI); replaces the login")
383
+ .option("--poll-interval-ms <n>", "Status poll interval", String(DEFAULT_POLL_INTERVAL_MS))
384
+ .option("--timeout-ms <n>", "Maximum wait", String(DEFAULT_TIMEOUT_MS))
385
+ .action(async function () {
386
+ try {
387
+ const opts = this.opts();
388
+ if ((opts.plan && opts.sha) || (!opts.plan && !opts.sha)) {
389
+ throw new Error("Provide exactly one of --plan <id> or --sha <sha>");
390
+ }
391
+ if (!["sync", "migration"].includes(opts.kind)) {
392
+ throw new Error("--kind must be sync or migration");
393
+ }
394
+ const machineToken = resolveMachineToken(opts.token);
395
+ if (machineToken !== undefined)
396
+ setMachineToken(machineToken);
397
+ await runAndPoll(this, "/api/v1/cli/kb/repo/apply", opts.plan
398
+ ? { plan_id: opts.plan }
399
+ : { commit_sha: opts.sha, pr_id: opts.pr, kind: opts.kind }, opts);
400
+ }
401
+ catch (error) {
402
+ errorOutput(error);
403
+ }
404
+ });
405
+ attachKBRepoTokenCommands(repo);
406
+ }
407
+ //# sourceMappingURL=kb-repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kb-repo.js","sourceRoot":"","sources":["../../src/commands/kb-repo.ts"],"names":[],"mappings":"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"}