@bragi-gmbh/codebus 1.6.3 → 1.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/commands/factory-attention.js +3 -1
  2. package/dist/commands/factory-attention.js.map +1 -1
  3. package/dist/commands/feedback.js +30 -0
  4. package/dist/commands/feedback.js.map +1 -0
  5. package/dist/commands/friction.js +68 -0
  6. package/dist/commands/friction.js.map +1 -0
  7. package/dist/commands/gateway-policy.js +55 -0
  8. package/dist/commands/gateway-policy.js.map +1 -0
  9. package/dist/commands/gateway-status.js +37 -0
  10. package/dist/commands/gateway-status.js.map +1 -0
  11. package/dist/commands/graph-publish-cmd.js +58 -0
  12. package/dist/commands/graph-publish-cmd.js.map +1 -0
  13. package/dist/commands/graph-publish.js +118 -0
  14. package/dist/commands/graph-publish.js.map +1 -0
  15. package/dist/commands/graph.js +2 -0
  16. package/dist/commands/graph.js.map +1 -1
  17. package/dist/commands/inbox.js +1 -1
  18. package/dist/commands/inbox.js.map +1 -1
  19. package/dist/commands/plan-lint.js +45 -5
  20. package/dist/commands/plan-lint.js.map +1 -1
  21. package/dist/commands/reply.js +1 -1
  22. package/dist/commands/reply.js.map +1 -1
  23. package/dist/commands/send.js +13 -3
  24. package/dist/commands/send.js.map +1 -1
  25. package/dist/commands/task.js +23 -1
  26. package/dist/commands/task.js.map +1 -1
  27. package/dist/friction/capture.js +52 -0
  28. package/dist/friction/capture.js.map +1 -0
  29. package/dist/index.js +11 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/mcp-friction/capture.js +91 -0
  32. package/dist/mcp-friction/capture.js.map +1 -0
  33. package/dist/mcp-registry.js +65 -2
  34. package/dist/mcp-registry.js.map +1 -1
  35. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  * Console attention view over CLI (`factory-attention`) — routes a single read
3
3
  * through the attention_queue_v1(p_actor_login) RPC defined in 0109_attention_queue.sql.
4
4
  *
5
- * The projection yields six categories (ADR 0005: the console reads state over
5
+ * The projection yields eight categories (ADR 0005: the console reads state over
6
6
  * the API; each stuck/dead/over-cap/waiting-on-human item opens its details):
7
7
  * blocked-question execution reported BLOCKED, waiting on a human answer
8
8
  * stalled available non-terminal execution with a stale heartbeat
@@ -10,6 +10,8 @@
10
10
  * over-cap execution past its stage max_minutes cap (0098 deadline)
11
11
  * receipt-ruling proposed decision awaiting a human ruling (0003/0104)
12
12
  * gate-approval human plan gate to approve or release (0104/0107)
13
+ * lease-escalated escalated lease needing a human, routed to holder (0150/#348)
14
+ * lease-expired low-radius auto-close receipt, routed to holder (0150/#348)
13
15
  *
14
16
  * Positive fixture: attention_queue_v1_returns_user_items
15
17
  * — calling attention_queue_v1(p_actor_login) for the accountable person
@@ -1 +1 @@
1
- {"version":3,"file":"factory-attention.js","sourceRoot":"","sources":["../../src/commands/factory-attention.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"factory-attention.js","sourceRoot":"","sources":["../../src/commands/factory-attention.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { resolveConfig } from "../config.js";
2
+ import { makeCtx, workspaceId } from "../client.js";
3
+ import { render } from "../output.js";
4
+ import { captureFriction } from "../friction/capture.js";
5
+ export async function feedbackCmd(opts) {
6
+ const prose = opts.prose ?? "";
7
+ const cfg = await resolveConfig(opts);
8
+ const ctx = await makeCtx(cfg);
9
+ const ws = await workspaceId(ctx);
10
+ const expectedVsActual = [opts.expected, opts.actual].filter(Boolean).join(" | ") || undefined;
11
+ const result = await captureFriction(ctx.supabase, {
12
+ command_rpc: opts.command,
13
+ error_class: opts.errorClass,
14
+ expected_vs_actual: expectedVsActual,
15
+ cli_version: undefined,
16
+ workspace_id: ws,
17
+ prose,
18
+ });
19
+ console.log(render([{ ok: result.ok, recorded: result.ok, feedback: true, prose }], { json: !!opts.json }));
20
+ }
21
+ export function registerFeedback(program, g) {
22
+ const f = g(program.command("feedback")).description("record free-text friction feedback (never blocks)");
23
+ f.option("--prose <text>", "free-text feedback prose")
24
+ .option("--command <name>", "command that caused friction")
25
+ .option("--error-class <class>", "error class")
26
+ .option("--expected <text>", "what you expected")
27
+ .option("--actual <text>", "what actually happened")
28
+ .action((o, command) => feedbackCmd({ ...command.parent?.opts(), ...o }));
29
+ }
30
+ //# sourceMappingURL=feedback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/commands/feedback.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAa,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAOjC;IACC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,gBAAgB,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC;IAC/F,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE;QACjD,WAAW,EAAE,IAAI,CAAC,OAAO;QACzB,WAAW,EAAE,IAAI,CAAC,UAAU;QAC5B,kBAAkB,EAAE,gBAAgB;QACpC,WAAW,EAAE,SAAS;QACtB,YAAY,EAAE,EAAE;QAChB,KAAK;KACN,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC9G,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB,EAAE,CAA0B;IAC3E,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,mDAAmD,CAAC,CAAC;IAC1G,CAAC,CAAC,MAAM,CAAC,gBAAgB,EAAE,0BAA0B,CAAC;SACnD,MAAM,CAAC,kBAAkB,EAAE,8BAA8B,CAAC;SAC1D,MAAM,CAAC,uBAAuB,EAAE,aAAa,CAAC;SAC9C,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;SAChD,MAAM,CAAC,iBAAiB,EAAE,wBAAwB,CAAC;SACnD,MAAM,CAAC,CAAC,CAA4H,EAAE,OAAgB,EAAE,EAAE,CACzJ,WAAW,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,68 @@
1
+ import { resolveConfig } from "../config.js";
2
+ import { makeCtx } from "../client.js";
3
+ import { readFileSync, existsSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ // Fail-closed builtin defaults (plan §14 taxonomy + count>=3 in 7d, owner decision A).
7
+ export const FRICTION_DEFAULTS = {
8
+ threshold: { count: 3, window_days: 7 },
9
+ keywordCount: 24,
10
+ pathCount: 7,
11
+ };
12
+ function builtinThresholdDoc() {
13
+ try {
14
+ const here = dirname(fileURLToPath(import.meta.url));
15
+ const p = join(here, "..", "..", "..", "factory", "dev01", "lib", "friction", "thresholds.json");
16
+ if (existsSync(p))
17
+ return JSON.parse(readFileSync(p, "utf8"));
18
+ }
19
+ catch { /* fall through to defaults */ }
20
+ return { threshold: { count: 3, window_days: 7 } };
21
+ }
22
+ function frictionSection(policy) {
23
+ if (!policy || typeof policy !== "object")
24
+ return null;
25
+ const f = policy.friction;
26
+ return f && typeof f === "object" ? f : null;
27
+ }
28
+ export async function frictionConfigShow(o = {}) {
29
+ const builtin = builtinThresholdDoc();
30
+ const builtinThreshold = (builtin.threshold ?? builtin.cluster) ?? { count: 3, window_days: 7 };
31
+ const builtinKw = Array.isArray(builtin.sensitive_keywords) ? builtin.sensitive_keywords.length : FRICTION_DEFAULTS.keywordCount;
32
+ const builtinPaths = Array.isArray(builtin.sensitive_paths) ? builtin.sensitive_paths.length : FRICTION_DEFAULTS.pathCount;
33
+ let out = {
34
+ source: "builtin",
35
+ threshold: builtinThreshold,
36
+ keyword_count: builtinKw,
37
+ path_count: builtinPaths,
38
+ };
39
+ try {
40
+ const ctx = await makeCtx(resolveConfig(o));
41
+ const { data, error } = await ctx.supabase.from("gateway_policy").select("version,policy").eq("status", "active").order("version", { ascending: false }).limit(1).maybeSingle();
42
+ if (!error && data) {
43
+ const f = frictionSection(data.policy);
44
+ if (f) {
45
+ const t = (f.threshold ?? f.cluster);
46
+ const count = Number(t?.count);
47
+ const windowDays = Number(t?.window_days);
48
+ out = {
49
+ source: `gateway_policy v${data.version}`,
50
+ threshold: {
51
+ count: Number.isInteger(count) && count >= 1 ? count : builtinThreshold.count,
52
+ window_days: Number.isInteger(windowDays) && windowDays >= 1 ? windowDays : builtinThreshold.window_days,
53
+ },
54
+ keyword_count: Array.isArray(f.sensitive_keywords) ? f.sensitive_keywords.length : builtinKw,
55
+ path_count: Array.isArray(f.sensitive_paths) ? f.sensitive_paths.length : builtinPaths,
56
+ };
57
+ }
58
+ }
59
+ }
60
+ catch { /* bus unavailable => fail closed to builtin */ }
61
+ console.log(JSON.stringify(out, null, 2));
62
+ }
63
+ export function registerFriction(program, g) {
64
+ const f = g(program.command("friction").description("friction loop (report/classify/cluster config)"));
65
+ const cfg = g(f.command("config").description("friction threshold config (bus-served, fail-closed)"));
66
+ g(cfg.command("show").description("print active threshold + keyword/path counts")).action(() => frictionConfigShow());
67
+ }
68
+ //# sourceMappingURL=friction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"friction.js","sourceRoot":"","sources":["../../src/commands/friction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { resolveConfig } from "../config.js";
2
+ import { makeCtx } from "../client.js";
3
+ // `codebus gateway policy show|activate <version>|diff` and
4
+ // `codebus gateway limits set <agent> --cap --alert`.
5
+ export async function gatewayPolicyCmd(action, versionArg, o = {}) {
6
+ const ctx = await makeCtx(resolveConfig(o));
7
+ if (action === "show") {
8
+ const { data, error } = await ctx.supabase.from("gateway_policy").select("version,status,policy,note,activated_at").eq("status", "active").order("version", { ascending: false }).limit(1).maybeSingle();
9
+ if (error)
10
+ throw new Error(error.message);
11
+ console.log(JSON.stringify(data ?? null, null, 2));
12
+ return;
13
+ }
14
+ if (action === "activate") {
15
+ const v = Number(versionArg);
16
+ if (!Number.isInteger(v))
17
+ throw new Error("activate requires a <version> integer");
18
+ const { data, error } = await ctx.supabase.rpc("gateway_policy_activate", { p_version: v });
19
+ if (error)
20
+ throw new Error(error.message);
21
+ console.log(JSON.stringify(data ?? null, null, 2));
22
+ return;
23
+ }
24
+ if (action === "diff") {
25
+ const { data, error } = await ctx.supabase.from("gateway_policy").select("version,status,policy").order("version", { ascending: false }).limit(2);
26
+ if (error)
27
+ throw new Error(error.message);
28
+ console.log(JSON.stringify(data ?? [], null, 2));
29
+ return;
30
+ }
31
+ throw new Error("usage: codebus gateway policy show|activate <version>|diff");
32
+ }
33
+ export async function gatewayLimitsCmd(agent, o = {}) {
34
+ const ctx = await makeCtx(resolveConfig(o));
35
+ if (!agent)
36
+ throw new Error("usage: codebus gateway limits set <agent> --cap <usd> --alert <usd>");
37
+ const row = { agent_id: agent, updated_at: new Date().toISOString() };
38
+ if (o.cap !== undefined)
39
+ row.monthly_cap_usd = o.cap === "" ? null : Number(o.cap);
40
+ if (o.alert !== undefined)
41
+ row.alert_usd = o.alert === "" ? null : Number(o.alert);
42
+ const { data, error } = await ctx.supabase.from("gateway_agent_limits").upsert(row).select();
43
+ if (error)
44
+ throw new Error(error.message);
45
+ console.log(JSON.stringify(data ?? null, null, 2));
46
+ }
47
+ export function registerGatewayPolicy(gwCmd, g) {
48
+ const pol = g(gwCmd.command("policy").description("show/activate/diff gateway policy versions"));
49
+ g(pol.command("show").description("show active policy")).action(() => gatewayPolicyCmd("show"));
50
+ g(pol.command("activate").description("activate a draft version").argument("<version>")).action((v) => gatewayPolicyCmd("activate", v));
51
+ g(pol.command("diff").description("show latest two versions")).action(() => gatewayPolicyCmd("diff"));
52
+ const lim = g(gwCmd.command("limits").description("per-agent spend caps/alerts"));
53
+ g(lim.command("set").description("set cap/alert for an agent").argument("<agent>").option("--cap <usd>").option("--alert <usd>")).action((a, o) => gatewayLimitsCmd(a, o));
54
+ }
55
+ //# sourceMappingURL=gateway-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-policy.js","sourceRoot":"","sources":["../../src/commands/gateway-policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { resolveConfig } from "../config.js";
2
+ import { makeCtx } from "../client.js";
3
+ const ALERT_USD = Number(process.env.PERSON_BUDGET_ALERT_USD ?? 200);
4
+ const CAP_USD = Number(process.env.GATEWAY_PROGRAM_CAP_USD ?? 2000);
5
+ export function summarizeGatewaySpend(rows) {
6
+ const byModel = {};
7
+ let total = 0;
8
+ for (const r of rows) {
9
+ const c = Number(r.cost_usd) || 0;
10
+ total += c;
11
+ byModel[r.model] = (byModel[r.model] ?? 0) + c;
12
+ }
13
+ return { total, byModel, alert: total >= ALERT_USD, capped: total >= CAP_USD };
14
+ }
15
+ export async function gatewayStatusCmd(o) {
16
+ const ctx = await makeCtx(resolveConfig(o));
17
+ const { data, error } = await ctx.supabase.from("person_spend_v1").select("*");
18
+ if (error)
19
+ throw new Error(error.message);
20
+ const rows = (data ?? []);
21
+ const { total, byModel, alert, capped } = summarizeGatewaySpend(rows);
22
+ if (o.json) {
23
+ console.log(JSON.stringify({
24
+ total_usd: total, by_model: byModel,
25
+ alert_usd: ALERT_USD, alert, program_cap_usd: CAP_USD, capped, rows,
26
+ }, null, 2));
27
+ return;
28
+ }
29
+ console.log(`Gateway month-to-date spend: $${total.toFixed(2)} (${rows.length} person/model rows)`);
30
+ for (const [model, c] of Object.entries(byModel).sort((a, b) => b[1] - a[1]))
31
+ console.log(` ${model}: $${c.toFixed(2)}`);
32
+ if (alert)
33
+ console.log(`⚠ budget alert: total ≥ $${ALERT_USD}/person/month (alert-only; owner notified once)`);
34
+ if (capped)
35
+ console.log(`⛔ program cap $${CAP_USD} reached — gateway returns 402 until reset`);
36
+ }
37
+ //# sourceMappingURL=gateway-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-status.js","sourceRoot":"","sources":["../../src/commands/gateway-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAa,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,GAAG,CAAC,CAAC;AACrE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,IAAI,CAAC,CAAC;AAWpE,MAAM,UAAU,qBAAqB,CAAC,IAAuB;IAG3D,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAClC,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AACjF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,CAAiC;IACtE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/E,IAAI,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAsB,CAAC;IAC/C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACtE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO;YACnC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI;SACpE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACb,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,iCAAiC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,qBAAqB,CAAC,CAAC;IACpG,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9C,IAAI,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B,SAAS,iDAAiD,CAAC,CAAC;IAC/G,IAAI,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,4CAA4C,CAAC,CAAC;AACjG,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { CodebusError } from "../errors.js";
2
+ import { makeCtx } from "../client.js";
3
+ import { resolveConfig } from "../config.js";
4
+ import { loadLocalSnapshot } from "../graph.js";
5
+ import { resolveRemoteRepoSlug } from "../graph-remote.js";
6
+ import { graphPublishCore } from "./graph-publish.js";
7
+ async function publishAction(o) {
8
+ const cfg = resolveConfig(o);
9
+ const ctx = await makeCtx(cfg);
10
+ const repoRoot = o.repoRoot ?? process.cwd();
11
+ const snapshot = loadLocalSnapshot(repoRoot);
12
+ if (!snapshot) {
13
+ throw new CodebusError("No graphify-out/graph.json found (and no cached snapshot). Build one with graphify first, or run `codebus graph pull` to download the latest snapshot.", 1);
14
+ }
15
+ const { execSync } = await import("node:child_process");
16
+ let head = null;
17
+ try {
18
+ head = execSync("git rev-parse HEAD", { cwd: repoRoot, encoding: "utf-8" }).trim() || null;
19
+ }
20
+ catch {
21
+ head = null;
22
+ }
23
+ const repo = await resolveRemoteRepoSlug(ctx, repoRoot, o.repo);
24
+ const sha = o.sha ?? snapshot.built_at_commit ?? head;
25
+ if (!sha)
26
+ throw new CodebusError("graph publish: could not determine a source sha — pass --sha explicitly.", 1);
27
+ const result = await graphPublishCore(ctx, snapshot, {
28
+ repo,
29
+ sha,
30
+ runId: o.runId ?? `cli-${Date.now()}`,
31
+ dryRun: o.dryRun,
32
+ });
33
+ if (o.json) {
34
+ console.log(JSON.stringify(result, null, 2));
35
+ }
36
+ else if (result.dryRun) {
37
+ console.log(`dry-run: ${result.repo}@${result.sha.slice(0, 12)} validates (${result.nodeCount} nodes, ${result.edgeCount} edges) — nothing published`);
38
+ }
39
+ else if (result.status === "quarantined") {
40
+ console.log(`quarantined: ${result.repo}@${result.sha.slice(0, 12)} NOT promoted (poisoning-guard delta tripped). Last-good stays serving — a curator must review.`);
41
+ }
42
+ else if (result.status === "noop_already_ingested") {
43
+ console.log(`noop: ${result.repo}@${result.sha.slice(0, 12)} already ingested (version ${result.versionId})`);
44
+ }
45
+ else {
46
+ console.log(`published: ${result.repo}@${result.sha.slice(0, 12)} (version ${result.versionId}, ${result.nodeCount} nodes, ${result.edgeCount} edges)`);
47
+ }
48
+ }
49
+ export function registerGraphPublish(graphCmd, g) {
50
+ g(graphCmd.command("publish"))
51
+ .description("Publish the local graphify snapshot to the hub (member write path, issue #515)")
52
+ .option("--repo <slug>", "repo slug to publish to (auto-detected from git remote if omitted)")
53
+ .option("--sha <commit>", "source sha to publish under (default: snapshot built_at_commit, else HEAD)")
54
+ .option("--run-id <id>", "run id for provenance (default: cli-<timestamp>)")
55
+ .option("--dry-run", "validate only — report the head and validate without publishing")
56
+ .action((opts) => publishAction(opts));
57
+ }
58
+ //# sourceMappingURL=graph-publish-cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-publish-cmd.js","sourceRoot":"","sources":["../../src/commands/graph-publish-cmd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * graph-publish.ts — `codebus graph publish [--repo <slug>] [--sha <commit>] [--dry-run]`
3
+ *
4
+ * Issue #515: the server-side snapshot write path an agent can invoke.
5
+ * Reads the LOCAL graphify-out/graph.json snapshot (walk-up, same loader
6
+ * `graph status` uses), reports the tip first (graph_head_report_member —
7
+ * the member equivalent of the CI token path's step 1), resolves the
8
+ * current vocab version (graph_vocab_current, anon-readable), pre-validates
9
+ * locally (graph_ingest_validate_anon, the same step-4 pre-check
10
+ * scripts/graph-publish.mjs uses), then publishes via graph_ingest_member
11
+ * (member-gated wrapper around 0050/0063's graph_ingest_artifact — vocab
12
+ * gate, 25MB cap, poisoning-guard delta, atomic promotion).
13
+ *
14
+ * No ingest token needed: authorization comes from the caller's own
15
+ * authenticated membership (graph_resolve_repo_id + is_member), exactly
16
+ * like every query RPC. All network goes through the caller's Ctx
17
+ * (authenticated agent JWT only — member-gated, no elevated server credentials).
18
+ */
19
+ import { readFileSync, existsSync } from "node:fs";
20
+ import { join } from "node:path";
21
+ import { execSync } from "node:child_process";
22
+ import { CodebusError } from "../errors.js";
23
+ import { loadLocalSnapshot } from "../graph.js";
24
+ import { resolveRemoteRepoSlug } from "../graph-remote.js";
25
+ function localHeadSha(repoRoot) {
26
+ try {
27
+ return execSync("git rev-parse HEAD", { cwd: repoRoot, encoding: "utf-8" }).trim() || null;
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /**
34
+ * Publish the local graphify snapshot to the hub. Pure core (no
35
+ * console output, no process exit) so the MCP graph_publish tool shares
36
+ * this exact function — CLI/MCP parity by construction.
37
+ */
38
+ export async function graphPublishCore(ctx, snapshot, opts) {
39
+ const nodeCount = snapshot.nodes?.length ?? 0;
40
+ const edgeCount = (snapshot.links ?? snapshot.edges ?? []);
41
+ const edgeN = Array.isArray(edgeCount) ? edgeCount.length : 0;
42
+ // Step 1: report the head FIRST (same ordering as scripts/graph-publish.mjs —
43
+ // the hub learns the tip even if validation/ingest below fails).
44
+ const { error: headErr } = await ctx.supabase.rpc("graph_head_report_member", {
45
+ p_repo_slug: opts.repo,
46
+ p_sha: opts.sha,
47
+ p_run_id: opts.runId,
48
+ p_workspace_slug: ctx.workspaceSlug,
49
+ });
50
+ if (headErr)
51
+ throw new CodebusError(`graph publish: head report failed: ${headErr.message}`);
52
+ // Step 2: resolve the current vocab version (never hardcode — the
53
+ // vocabulary is the versioned artifact, same as graph-publish.mjs step 3).
54
+ const { data: vocabVersion, error: vocabErr } = await ctx.supabase.rpc("graph_vocab_current");
55
+ if (vocabErr)
56
+ throw new CodebusError(`graph publish: failed to resolve current vocab_version: ${vocabErr.message}`);
57
+ if (!vocabVersion)
58
+ throw new CodebusError("graph publish: no graph_vocab row has is_current=true — cannot publish");
59
+ // Step 3: pre-validate (same step-4 pre-check graph-publish.mjs uses) so
60
+ // a schema problem surfaces as a clearly-labeled VALIDATION failure.
61
+ const { error: validErr } = await ctx.supabase.rpc("graph_ingest_validate_anon", {
62
+ p_vocab_version: vocabVersion,
63
+ p_artifact: snapshot,
64
+ });
65
+ if (validErr)
66
+ throw new CodebusError(`graph publish: VALIDATION FAILED: ${validErr.message}`);
67
+ if (opts.dryRun) {
68
+ return { repo: opts.repo, sha: opts.sha, status: "dry-run", versionId: null, promoted: false, nodeCount, edgeCount: edgeN, dryRun: true };
69
+ }
70
+ // Step 4: publish. Atomic server-side; a rejection leaves last-good
71
+ // serving untouched (0050's own guarantee).
72
+ const { data, error } = await ctx.supabase.rpc("graph_ingest_member", {
73
+ p_repo_slug: opts.repo,
74
+ p_source_sha: opts.sha,
75
+ p_vocab_version: vocabVersion,
76
+ p_run_id: opts.runId,
77
+ p_workflow_ref: "codebus-cli-graph-publish",
78
+ p_artifact: snapshot,
79
+ p_workspace_slug: ctx.workspaceSlug,
80
+ });
81
+ if (error)
82
+ throw new CodebusError(`graph publish: INGEST FAILED: ${error.message}`);
83
+ const status = data?.status ?? "unknown";
84
+ return {
85
+ repo: opts.repo,
86
+ sha: opts.sha,
87
+ status,
88
+ versionId: data?.version_id ?? null,
89
+ promoted: status !== "quarantined" && status !== "noop_already_ingested" ? Boolean(data?.promoted ?? true) : false,
90
+ nodeCount,
91
+ edgeCount: edgeN,
92
+ dryRun: false,
93
+ };
94
+ }
95
+ /** Resolve CLI inputs (snapshot from disk, repo slug, sha) then publish. */
96
+ export async function graphPublishCmd(ctx, opts) {
97
+ const repoRoot = opts.repoRoot ?? process.cwd();
98
+ const snapshot = opts.snapshot !== undefined ? opts.snapshot : loadLocalSnapshot(repoRoot);
99
+ if (!snapshot) {
100
+ throw new CodebusError("No graphify-out/graph.json found (and no cached snapshot). Build one with graphify first, or run `codebus graph pull` to download the latest snapshot.", 1);
101
+ }
102
+ const repo = await resolveRemoteRepoSlug(ctx, repoRoot, opts.repo);
103
+ const sha = opts.sha ?? snapshot.built_at_commit ?? localHeadSha(repoRoot);
104
+ if (!sha) {
105
+ throw new CodebusError("graph publish: could not determine a source sha — pass --sha explicitly.", 1);
106
+ }
107
+ const runId = opts.runId ?? `cli-${Date.now()}`;
108
+ return graphPublishCore(ctx, snapshot, { repo, sha, runId, dryRun: opts.dryRun });
109
+ }
110
+ /** Read a snapshot file from disk (human-mode CLI path helper). */
111
+ export function readSnapshotFile(repoRoot) {
112
+ const direct = join(repoRoot, "graphify-out", "graph.json");
113
+ if (!existsSync(direct)) {
114
+ throw new CodebusError(`No graphify-out/graph.json found under ${repoRoot}.`, 1);
115
+ }
116
+ return JSON.parse(readFileSync(direct, "utf-8"));
117
+ }
118
+ //# sourceMappingURL=graph-publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-publish.js","sourceRoot":"","sources":["../../src/commands/graph-publish.ts"],"names":[],"mappings":"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"}
@@ -86,6 +86,7 @@ export async function graphStatusCmd(options) {
86
86
  throw new CodebusError(`Failed to get graph status: ${err instanceof Error ? err.message : String(err)}`, 1);
87
87
  }
88
88
  }
89
+ import { registerGraphPublish } from "./graph-publish-cmd.js";
89
90
  /**
90
91
  * Register the graph command.
91
92
  */
@@ -97,5 +98,6 @@ export function registerGraph(program, g) {
97
98
  g(graphCmd.command("pull"))
98
99
  .option("--sha <commit>", "pull the snapshot built at this commit (default: latest successful run on main)")
99
100
  .action((opts) => { void graphPullCmd(opts); });
101
+ registerGraphPublish(graphCmd, g);
100
102
  }
101
103
  //# sourceMappingURL=graph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/commands/graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/commands/graph.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@ import { SENDER_EMBED, senderDisplay } from "../sender.js";
22
22
  export async function fetchInbox(ctx, opts) {
23
23
  // recipient rows for me, joined to message body (RLS limits to my rows + member workspaces)
24
24
  let q = ctx.supabase.from("message_recipients")
25
- .select(`read_at, handled_at, archived_at, messages!inner(display_id, type, subject, body, headline, required_action, in_reply_to, from_agent_id, from_person_id, ${SENDER_EMBED}, created_at, project_id, workspace_id)`)
25
+ .select(`read_at, handled_at, archived_at, messages!inner(id, display_id, type, subject, body, headline, required_action, in_reply_to, from_agent_id, from_person_id, ${SENDER_EMBED}, created_at, project_id, workspace_id)`)
26
26
  .is("archived_at", null);
27
27
  if (opts.unread)
28
28
  q = q.is("handled_at", null);
@@ -1 +1 @@
1
- {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/commands/inbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/commands/inbox.ts"],"names":[],"mappings":"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"}
@@ -18,7 +18,10 @@ export function planCapsLabel(caps) {
18
18
  ? `caps decision ${caps.decision_display_id ?? caps.decision_id ?? "unknown"}`
19
19
  : "default caps; no approved plan-caps decision";
20
20
  }
21
- /** Offline fallback: caps declared on the plan object itself (lintPlanFile). */
21
+ /** Offline fallback: caps declared on the plan object itself (lintPlanFile).
22
+ * Use `--caps-from <decision json>` (a plan_caps_for / plan_caps_effective_v1
23
+ * row, e.g. from `codebus plan caps show --json`) to lint against server
24
+ * caps without a connection (issue #345). */
22
25
  export function planCapsFromObject(source) {
23
26
  const caps = object(object(source).caps);
24
27
  const positiveInt = (value) => typeof value === "number" && Number.isInteger(value) && value >= 1 ? value : null;
@@ -186,7 +189,8 @@ export function lintPlanFile(path, caps) {
186
189
  return { verdict: "fail", findings, path };
187
190
  }
188
191
  findings.push(...lintPlan(source, caps));
189
- return { verdict: findings.length === 0 ? "pass" : "fail", findings, path };
192
+ const effectiveCaps = caps ?? planCapsFromObject(source);
193
+ return { verdict: findings.length === 0 ? "pass" : "fail", findings, path, caps: effectiveCaps };
190
194
  }
191
195
  export async function lintPlanOnline(ctx, planRef, revisionDigest) {
192
196
  const ws = await workspaceId(ctx);
@@ -218,7 +222,7 @@ export async function lintPlanOnline(ctx, planRef, revisionDigest) {
218
222
  : DEFAULT_PLAN_CAPS;
219
223
  const findings = lintPlan(revision.document, caps);
220
224
  const result = {
221
- verdict: findings.length === 0 ? "pass" : "fail", findings, path: String(plan.source_ref ?? planRef),
225
+ verdict: findings.length === 0 ? "pass" : "fail", findings, path: String(plan.source_ref ?? planRef), caps,
222
226
  };
223
227
  const { error } = await ctx.supabase.rpc("plan_lint_report_record", {
224
228
  p_revision_id: plan.latest_revision_id,
@@ -230,18 +234,54 @@ export async function lintPlanOnline(ctx, planRef, revisionDigest) {
230
234
  throw new CodebusError(error.message);
231
235
  return result;
232
236
  }
237
+ /** Parse a caps-decision JSON file (plan_caps_for row) into PlanCaps (#345). */
238
+ export function planCapsFromFile(path) {
239
+ let raw;
240
+ try {
241
+ raw = JSON.parse(readFileSync(path, "utf8"));
242
+ }
243
+ catch (error) {
244
+ throw new CodebusError(`unable to read caps file '${path}': ${error instanceof Error ? error.message : String(error)}`);
245
+ }
246
+ const row = object(raw);
247
+ const num = (value) => typeof value === "number" && Number.isFinite(value) ? value
248
+ : typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value)) ? Number(value)
249
+ : null;
250
+ const budget = num(row.max_budget_usd);
251
+ const stages = num(row.max_stages);
252
+ if (budget == null || stages == null) {
253
+ throw new CodebusError(`caps file '${path}' must contain numeric max_budget_usd and max_stages (try 'codebus plan caps show --json > caps.json')`);
254
+ }
255
+ return {
256
+ max_budget_usd: budget,
257
+ max_stages: stages,
258
+ max_children_per_stage: row.max_children_per_stage == null ? null : num(row.max_children_per_stage),
259
+ decision_id: row.decision_id != null ? String(row.decision_id) : null,
260
+ decision_display_id: row.decision_display_id != null ? String(row.decision_display_id) : null,
261
+ source: row.source === "decision" ? "decision" : "default",
262
+ };
263
+ }
233
264
  export function registerPlanLint(plan) {
234
265
  plan.command("lint").argument("<path-or-plan>")
235
266
  .option("--offline", "perform deterministic local linting only")
236
267
  .option("--revision <digest>", "exact immutable revision digest for online evidence")
268
+ .option("--caps-from <file>", "caps decision JSON for offline lint (e.g. 'codebus plan caps show --json > caps.json'); prints the caps source")
237
269
  .option("--json", "JSON output")
238
270
  .action(async (path, options, command) => {
239
271
  if (!options.offline && !options.revision)
240
272
  throw new CodebusError("plan lint requires --offline or --revision");
273
+ if (options.capsFrom && !options.offline)
274
+ throw new CodebusError("--caps-from requires --offline");
275
+ const offlineCaps = options.capsFrom ? planCapsFromFile(options.capsFrom) : undefined;
241
276
  const result = options.offline
242
- ? lintPlanFile(path)
277
+ ? lintPlanFile(path, offlineCaps)
243
278
  : await lintPlanOnline(await makeCtx(resolveConfig(command.optsWithGlobals())), path, options.revision);
244
- console.log(options.json ? JSON.stringify(result, null, 2) : `${result.verdict}: ${result.findings.map((item) => item.code).join(", ") || "no findings"}`);
279
+ if (options.json) {
280
+ console.log(JSON.stringify(result, null, 2));
281
+ }
282
+ else {
283
+ console.log(`${result.verdict}: ${result.findings.map((item) => item.code).join(", ") || "no findings"} (${result.caps ? planCapsLabel(result.caps) : "caps source unknown"})`);
284
+ }
245
285
  if (result.verdict === "fail")
246
286
  throw new CodebusError(`plan lint failed: ${result.findings.map((item) => item.code).join(", ")}`);
247
287
  });