@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.
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/bin/graphit +1 -1
- package/bin/graphit.ps1 +1 -1
- package/dist/api/client.d.ts +8 -0
- package/dist/api/client.js +24 -2
- package/dist/api/client.js.map +1 -1
- package/dist/commands/connector/ui-only.d.ts +12 -0
- package/dist/commands/connector/ui-only.js +28 -0
- package/dist/commands/connector/ui-only.js.map +1 -0
- package/dist/commands/connector.js +2 -14
- package/dist/commands/connector.js.map +1 -1
- package/dist/commands/dashboard.d.ts +14 -0
- package/dist/commands/dashboard.js +52 -1
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/kb-repo-token.d.ts +17 -0
- package/dist/commands/kb-repo-token.js +122 -0
- package/dist/commands/kb-repo-token.js.map +1 -0
- package/dist/commands/kb-repo.d.ts +29 -0
- package/dist/commands/kb-repo.js +407 -0
- package/dist/commands/kb-repo.js.map +1 -0
- package/dist/commands/kb.js +133 -0
- package/dist/commands/kb.js.map +1 -1
- package/dist/output/format.js +77 -1
- package/dist/output/format.js.map +1 -1
- package/dist/skill-guard.js +5 -1
- package/dist/skill-guard.js.map +1 -1
- package/dist/update-check.d.ts +18 -0
- package/dist/update-check.js +54 -4
- package/dist/update-check.js.map +1 -1
- package/package.json +1 -1
- package/scripts/generate-tool-manifest.mjs +1 -1
- package/scripts/verb-policy-source.json +138 -2
- package/skills/graphit/SKILL.md +26 -6
- package/skills/graphit/VERSION.json +1 -1
- package/skills/graphit/references/chart-patterns.md +1 -5
- package/skills/graphit/references/chart-selection.md +1 -1
- package/skills/graphit/references/data-sources.md +7 -3
- package/skills/graphit/references/filters.md +1 -1
- package/skills/graphit/references/kb-actions.md +4 -0
- package/skills/graphit/references/kb-scope.md +4 -0
- package/skills/graphit/references/onboarding.md +1 -1
- package/skills/graphit/references/operations.md +1 -1
- package/skills/graphit/references/repo-kb.md +101 -0
- package/skills/graphit/references/runtime.md +1 -1
- package/skills/graphit/references/semantic-authoring.md +3 -1
- package/skills/graphit/references/state-contract.md +2 -2
- 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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"}
|