@bragi-gmbh/codebus 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/codebus.js +2 -0
- package/dist/binding-guard.js +97 -0
- package/dist/binding-guard.js.map +1 -0
- package/dist/client.js +94 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/ack.js +47 -0
- package/dist/commands/ack.js.map +1 -0
- package/dist/commands/archive.js +21 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/as.js +299 -0
- package/dist/commands/as.js.map +1 -0
- package/dist/commands/ask.js +189 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/auth.js +33 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/checkin.js +235 -0
- package/dist/commands/checkin.js.map +1 -0
- package/dist/commands/decision.js +52 -0
- package/dist/commands/decision.js.map +1 -0
- package/dist/commands/digest.js +117 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/doctor.js +106 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/factory.js +191 -0
- package/dist/commands/factory.js.map +1 -0
- package/dist/commands/github-login.js +205 -0
- package/dist/commands/github-login.js.map +1 -0
- package/dist/commands/graph.js +88 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/health.js +34 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/inbox.js +83 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/ingest.js +553 -0
- package/dist/commands/ingest.js.map +1 -0
- package/dist/commands/init.js +97 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install.js +520 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/invite.js +152 -0
- package/dist/commands/invite.js.map +1 -0
- package/dist/commands/jira.js +237 -0
- package/dist/commands/jira.js.map +1 -0
- package/dist/commands/join.js +96 -0
- package/dist/commands/join.js.map +1 -0
- package/dist/commands/links.js +66 -0
- package/dist/commands/links.js.map +1 -0
- package/dist/commands/login.js +84 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/morning.js +121 -0
- package/dist/commands/morning.js.map +1 -0
- package/dist/commands/next.js +66 -0
- package/dist/commands/next.js.map +1 -0
- package/dist/commands/onboarding.js +109 -0
- package/dist/commands/onboarding.js.map +1 -0
- package/dist/commands/pack.js +276 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/plan-gh.js +425 -0
- package/dist/commands/plan-gh.js.map +1 -0
- package/dist/commands/plan.js +465 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/pr.js +88 -0
- package/dist/commands/pr.js.map +1 -0
- package/dist/commands/question.js +142 -0
- package/dist/commands/question.js.map +1 -0
- package/dist/commands/read.js +84 -0
- package/dist/commands/read.js.map +1 -0
- package/dist/commands/refs.js +357 -0
- package/dist/commands/refs.js.map +1 -0
- package/dist/commands/reply.js +38 -0
- package/dist/commands/reply.js.map +1 -0
- package/dist/commands/repo.js +1198 -0
- package/dist/commands/repo.js.map +1 -0
- package/dist/commands/report.js +41 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/resolve-refs.js +21 -0
- package/dist/commands/resolve-refs.js.map +1 -0
- package/dist/commands/resolve.js +93 -0
- package/dist/commands/resolve.js.map +1 -0
- package/dist/commands/send.js +168 -0
- package/dist/commands/send.js.map +1 -0
- package/dist/commands/sent.js +22 -0
- package/dist/commands/sent.js.map +1 -0
- package/dist/commands/session.js +426 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/statusline.js +43 -0
- package/dist/commands/statusline.js.map +1 -0
- package/dist/commands/task.js +140 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/commands/tick.js +233 -0
- package/dist/commands/tick.js.map +1 -0
- package/dist/commands/upgrade.js +76 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/watch.js +169 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/commands/whoami.js +27 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config.js +103 -0
- package/dist/config.js.map +1 -0
- package/dist/directives.js +102 -0
- package/dist/directives.js.map +1 -0
- package/dist/errors.js +110 -0
- package/dist/errors.js.map +1 -0
- package/dist/git-hooks.js +116 -0
- package/dist/git-hooks.js.map +1 -0
- package/dist/graph-bootstrap.js +95 -0
- package/dist/graph-bootstrap.js.map +1 -0
- package/dist/graph-remote.js +889 -0
- package/dist/graph-remote.js.map +1 -0
- package/dist/graph.js +335 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +1 -0
- package/dist/kit/graph-publish.mjs +400 -0
- package/dist/mail-latency.js +120 -0
- package/dist/mail-latency.js.map +1 -0
- package/dist/mcp-registry.js +859 -0
- package/dist/mcp-registry.js.map +1 -0
- package/dist/mcp.js +193 -0
- package/dist/mcp.js.map +1 -0
- package/dist/output.js +12 -0
- package/dist/output.js.map +1 -0
- package/dist/positioning.js +21 -0
- package/dist/positioning.js.map +1 -0
- package/dist/rolestore.js +89 -0
- package/dist/rolestore.js.map +1 -0
- package/dist/session.js +49 -0
- package/dist/session.js.map +1 -0
- package/dist/sessionstore.js +736 -0
- package/dist/sessionstore.js.map +1 -0
- package/dist/version-check.js +97 -0
- package/dist/version-check.js.map +1 -0
- package/package.json +47 -0
package/bin/codebus.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Shared directory-binding safety guard (FM-7, docs/plans/
|
|
2
|
+
// codebus-v2-reliability.md §2.3 + §6.1). Used by BOTH commands that can
|
|
3
|
+
// create a directory binding today — `codebus as --bind` (the only one, per
|
|
4
|
+
// the owner's locked decision: checkin stops auto-binding directories) — and
|
|
5
|
+
// kept in its own module so a future second writer never has to reimplement
|
|
6
|
+
// or diverge from it. Two independent hazards, one guard:
|
|
7
|
+
//
|
|
8
|
+
// 1. GENERIC_DIRS: a fixed list of directory names too common to trust as a
|
|
9
|
+
// machine-wide identity anchor (field incident: a checkin from /tmp bound
|
|
10
|
+
// the literal pattern 'tmp', which then matched EVERY tmp dir on the
|
|
11
|
+
// machine — unrelated sessions silently resolved as that agent).
|
|
12
|
+
// 2. Uniqueness-by-recorded-path: a fixed list can never catch a
|
|
13
|
+
// real-but-shared name — 'CodeBus' slipped it (a genuine, specific name
|
|
14
|
+
// that still recurs across clones/checkouts) and ended up bound
|
|
15
|
+
// machine-wide. Instead of guessing more names onto the list, track the
|
|
16
|
+
// actual directory each bare-basename binding was recorded from
|
|
17
|
+
// (Binding.boundFrom, rolestore.ts); a second bind of the same basename
|
|
18
|
+
// from a DIFFERENT recorded path means the pattern is genuinely ambiguous
|
|
19
|
+
// — refuse and point at a full-path pattern instead (which globToRegExp
|
|
20
|
+
// matches against the whole absolute path, not just the basename).
|
|
21
|
+
//
|
|
22
|
+
// That comparison only fires when the EXISTING binding has a boundFrom to
|
|
23
|
+
// compare against. A legacy binding (written before this field existed, so
|
|
24
|
+
// `boundFrom` is simply absent — every pre-existing roles.json entry keeps
|
|
25
|
+
// loading unchanged, by design) has no recorded path at all, and the old
|
|
26
|
+
// check's `!!b.boundFrom` term silently treated "no provenance" as "no
|
|
27
|
+
// conflict" — a second `as --bind` of the same bare basename from a
|
|
28
|
+
// DIFFERENT clone would sail through and silently replace the legacy
|
|
29
|
+
// mapping, which is exactly the takeover this guard exists to stop. There
|
|
30
|
+
// is no way to tell "same directory, re-bound" from "different directory,
|
|
31
|
+
// ambiguous" without a recorded path to compare against, so a matching
|
|
32
|
+
// legacy binding fails closed unconditionally: bind it again only via an
|
|
33
|
+
// explicit `as --unbind` first, or sidestep the ambiguity with a full-path
|
|
34
|
+
// pattern.
|
|
35
|
+
//
|
|
36
|
+
// Round-2 review: the legacy check used `.find()`, which only inspects the
|
|
37
|
+
// FIRST binding matching `pattern` — a store can (and, once one write path
|
|
38
|
+
// has a bug, does) hold more than one binding for the same pattern, e.g.
|
|
39
|
+
// [{pattern:'lane', role:'new', boundFrom:'/same/lane'},
|
|
40
|
+
// {pattern:'lane', role:'legacy'}]. `.find()` stops at the first (safe,
|
|
41
|
+
// provenanced) entry and never looks at the second (legacy, unprovenanced)
|
|
42
|
+
// one, so `bindRole` sails through and silently overwrites/duplicates the
|
|
43
|
+
// legacy mapping — the exact takeover the legacy check above exists to
|
|
44
|
+
// stop. Every binding matching `pattern` is now collected and checked: if
|
|
45
|
+
// ANY of them lacks boundFrom, the whole bind is refused, regardless of
|
|
46
|
+
// where it sits in the list.
|
|
47
|
+
export const GENERIC_DIRS = new Set([
|
|
48
|
+
"tmp", "temp", "src", "lib", "bin", "cli", "app", "web", "api", "test",
|
|
49
|
+
"tests", "build", "dist", "out", "home", "work", "code", "repo", "repos",
|
|
50
|
+
"dev", "docs", "scripts", "packages", "desktop", "documents", "downloads",
|
|
51
|
+
]);
|
|
52
|
+
/**
|
|
53
|
+
* Guard a candidate (pattern, cwd) pair BEFORE it's written as a binding.
|
|
54
|
+
* Only bare-basename patterns (no `/`) are checked — a full-path pattern is
|
|
55
|
+
* already unambiguous by construction.
|
|
56
|
+
*/
|
|
57
|
+
export function checkBindingSafety(store, pattern, cwd) {
|
|
58
|
+
if (pattern.includes("/"))
|
|
59
|
+
return { ok: true };
|
|
60
|
+
const lower = pattern.toLowerCase();
|
|
61
|
+
if (GENERIC_DIRS.has(lower)) {
|
|
62
|
+
return {
|
|
63
|
+
ok: false,
|
|
64
|
+
reason: `'${pattern}' is too generic a name to bind — it would match every '${pattern}' directory on ` +
|
|
65
|
+
`the machine. Use a full-path pattern instead: --pattern '${cwd}'`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// ALL bindings matching this pattern, not just the first — a store can
|
|
69
|
+
// hold more than one entry for the same pattern (a prior bug, a hand-edited
|
|
70
|
+
// file, a partially-applied migration), and a legacy one hiding behind a
|
|
71
|
+
// provenanced one must still be caught.
|
|
72
|
+
const matches = (store.bindings ?? []).filter((b) => b.pattern === pattern);
|
|
73
|
+
const legacy = matches.find((b) => !b.boundFrom);
|
|
74
|
+
if (legacy) {
|
|
75
|
+
// Legacy binding, no recorded source directory — cannot prove this is a
|
|
76
|
+
// same-directory re-bind rather than a different clone silently stealing
|
|
77
|
+
// the mapping, so refuse unconditionally rather than guess. Fail closed.
|
|
78
|
+
return {
|
|
79
|
+
ok: false,
|
|
80
|
+
reason: `'${pattern}' is already bound to '${legacy.role}' from a legacy entry with no recorded source ` +
|
|
81
|
+
`directory — binding it again from ${cwd} could silently replace a DIFFERENT directory's mapping (there's ` +
|
|
82
|
+
`no provenance to check it against). Either remove the legacy binding first (codebus as --unbind ` +
|
|
83
|
+
`'${pattern}') or use a full-path pattern instead: --pattern '${cwd}'`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const conflict = matches.find((b) => b.boundFrom !== cwd);
|
|
87
|
+
if (conflict) {
|
|
88
|
+
return {
|
|
89
|
+
ok: false,
|
|
90
|
+
reason: `'${pattern}' is already bound from a different directory (${conflict.boundFrom}) — binding it ` +
|
|
91
|
+
`again from ${cwd} would make the pattern ambiguous between the two. Use a full-path pattern instead: ` +
|
|
92
|
+
`--pattern '${cwd}'`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return { ok: true };
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=binding-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-guard.js","sourceRoot":"","sources":["../src/binding-guard.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createClient } from "@supabase/supabase-js";
|
|
2
|
+
import { getSession } from "./session.js";
|
|
3
|
+
import { CodebusError } from "./errors.js";
|
|
4
|
+
export async function makeCtx(cfg) {
|
|
5
|
+
// supabase-js needs an apikey; resolved by config (flags > env > config file).
|
|
6
|
+
const ANON = cfg.anonKey ?? "";
|
|
7
|
+
// cfg.assume: the token is the AUTHOR's credential and the session is minted
|
|
8
|
+
// server-side AS the named role (auth edge function ownership check).
|
|
9
|
+
const session = await getSession(cfg.url, cfg.token, fetch, ANON, cfg.assume);
|
|
10
|
+
if (cfg.agent && cfg.agent !== session.agent.slug)
|
|
11
|
+
throw new CodebusError(`--agent/CODEBUS_AGENT='${cfg.agent}' does not match the authenticated agent '${session.agent.slug}' (check CODEBUS_TOKEN)`);
|
|
12
|
+
const supabase = createClient(cfg.url, ANON, {
|
|
13
|
+
global: { headers: { Authorization: `Bearer ${session.jwt}`, apikey: ANON } },
|
|
14
|
+
auth: { persistSession: false, autoRefreshToken: false },
|
|
15
|
+
});
|
|
16
|
+
// Realtime authenticates separately from the HTTP headers above; without this,
|
|
17
|
+
// `watch` subscriptions connect as anon and RLS hides the agent's changes.
|
|
18
|
+
supabase.realtime.setAuth(session.jwt);
|
|
19
|
+
return { supabase, agentSlug: session.agent.slug, workspaceSlug: cfg.workspace, identitySource: cfg.identitySource };
|
|
20
|
+
}
|
|
21
|
+
/** True when `ctx`'s identity came from this directory's default binding
|
|
22
|
+
* rather than something the caller actually asserted (a flag, env token, or
|
|
23
|
+
* THIS session's own checkin). Safe in a directory one agent alone owns;
|
|
24
|
+
* unsafe the moment that directory is shared, since a fresh session's very
|
|
25
|
+
* first command — before it has checked in — silently inherits whichever
|
|
26
|
+
* agent the directory happens to default to. Callers that render one
|
|
27
|
+
* identity's private data (inbox, read, next) should warn on this. */
|
|
28
|
+
export function identityIsGuessed(ctx) {
|
|
29
|
+
return ctx.identitySource === "cwd-binding";
|
|
30
|
+
}
|
|
31
|
+
export const guessedIdentityWarning = (ctx, what = "results") => `⚠ codebus: these ${what} belong to '${ctx.agentSlug}', via this directory's DEFAULT binding — not an identity you asserted. ` +
|
|
32
|
+
`If you are not '${ctx.agentSlug}', STOP and run: codebus checkin <your-name>\n`;
|
|
33
|
+
// Resolves a workspace slug to its id (member-visible under RLS).
|
|
34
|
+
export async function workspaceId(ctx) {
|
|
35
|
+
const { data, error } = await ctx.supabase.from("workspaces").select("id").eq("slug", ctx.workspaceSlug).single();
|
|
36
|
+
if (error || !data)
|
|
37
|
+
throw new CodebusError(`workspace not found or not a member: ${ctx.workspaceSlug}`);
|
|
38
|
+
return data.id;
|
|
39
|
+
}
|
|
40
|
+
// Resolves an optional project slug to its id within a workspace.
|
|
41
|
+
export async function projectId(ctx, ws, slug) {
|
|
42
|
+
if (!slug)
|
|
43
|
+
return null;
|
|
44
|
+
const { data, error } = await ctx.supabase.from("projects").select("id").eq("workspace_id", ws).eq("slug", slug).single();
|
|
45
|
+
if (error || !data)
|
|
46
|
+
throw new CodebusError(`project not found in workspace: ${slug}`);
|
|
47
|
+
return data.id;
|
|
48
|
+
}
|
|
49
|
+
// Resolves an optional repo slug to its id within a workspace.
|
|
50
|
+
//
|
|
51
|
+
// Round-20 review finding (CONFIRMED, PR #55 comment 3827670905): this used
|
|
52
|
+
// to be a bare `.eq("slug", slug)` lookup — it neither rejected a retired
|
|
53
|
+
// row nor followed `retired_into`, so any of this function's callers
|
|
54
|
+
// (repo.ts's statusAction via the `resolveRepoIdBySlug` alias, pr.ts,
|
|
55
|
+
// jira.ts, question.ts, plan.ts) resolved a retired `-dup-<n>` loser slug
|
|
56
|
+
// (collapse_duplicate_repo_group renames a loser, never deletes it) to
|
|
57
|
+
// that dead repo_id instead of transparently following the chain to its
|
|
58
|
+
// canonical repo — the exact class of bug the round-17 `graph_resolve_
|
|
59
|
+
// repo_id` fix (0070_repo_connect.sql) already closed for every graph
|
|
60
|
+
// query RPC. Fixed here, in this ONE shared helper, by delegating to that
|
|
61
|
+
// same RPC (`security invoker`, granted to `authenticated`, already called
|
|
62
|
+
// this way from graph-remote.ts) rather than re-implementing its bounded
|
|
63
|
+
// retired_into-chain walk client-side — every caller above gets the fix
|
|
64
|
+
// for free, with no change to their own code. `ws` is kept in the
|
|
65
|
+
// signature for interface stability (every caller already derives it from
|
|
66
|
+
// this same `ctx` via `workspaceId()` above, so `ctx.workspaceSlug` names
|
|
67
|
+
// the identical workspace) even though the RPC call below no longer reads
|
|
68
|
+
// it directly. The not-found error message is deliberately preserved
|
|
69
|
+
// verbatim rather than passed through from the RPC's own exception text,
|
|
70
|
+
// so this remains a pure internal-resolution swap with no user-visible
|
|
71
|
+
// wording change for the (unaffected, already-correct) "truly unknown
|
|
72
|
+
// slug" case.
|
|
73
|
+
//
|
|
74
|
+
// Deliberately does NOT surface a "resolved to canonical slug" redirect
|
|
75
|
+
// note the way ingest.ts's resolveConnectedRepo/`repo connect` do — this
|
|
76
|
+
// function returns a bare id, not a row a caller could compare requested-
|
|
77
|
+
// vs-resolved against, and giving it that would mean widening this shared
|
|
78
|
+
// helper's return shape plus touching every one of the 5 call sites' own
|
|
79
|
+
// human-mode output — materially larger than closing the correctness gap
|
|
80
|
+
// itself. The resolution is correct either way; only the redirect UX is
|
|
81
|
+
// narrower here than on the ingest/connect paths.
|
|
82
|
+
export async function repoId(ctx, ws, slug) {
|
|
83
|
+
if (!slug)
|
|
84
|
+
return null;
|
|
85
|
+
const { data, error } = await ctx.supabase.rpc("graph_resolve_repo_id", {
|
|
86
|
+
p_caller: "codebus-cli",
|
|
87
|
+
p_repo_slug: slug,
|
|
88
|
+
p_workspace_slug: ctx.workspaceSlug,
|
|
89
|
+
});
|
|
90
|
+
if (error || !data)
|
|
91
|
+
throw new CodebusError(`repo not found in workspace: ${slug}`);
|
|
92
|
+
return data;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { resolveConfig } from "../config.js";
|
|
2
|
+
import { makeCtx, workspaceId } from "../client.js";
|
|
3
|
+
import { CodebusError } from "../errors.js";
|
|
4
|
+
// `codebus ack <id>` — explicit handled-marker (delivery gap #5). Replying
|
|
5
|
+
// already marks the original handled for the replier (0048 trigger); `ack` is
|
|
6
|
+
// the other lawful way to clear a message from every unread surface — for
|
|
7
|
+
// mail that needed no reply (an FYI, a broadcast note) but was actually acted
|
|
8
|
+
// on / read and dealt with. Mirrors archive.ts's shape (resolve, update own
|
|
9
|
+
// recipient row, done); the mr_update RLS policy (0007) already scopes the
|
|
10
|
+
// update to the caller's own row.
|
|
11
|
+
export async function ackCmd(idOrDisplay, o) {
|
|
12
|
+
const ctx = await makeCtx(resolveConfig(o));
|
|
13
|
+
const isDisplay = /^CB-MSG-/i.test(idOrDisplay);
|
|
14
|
+
const sel = isDisplay ? "display_id" : "id";
|
|
15
|
+
const val = isDisplay ? idOrDisplay.toUpperCase() : idOrDisplay;
|
|
16
|
+
// display ids are only unique per workspace (bus_counters, 0004) — scope
|
|
17
|
+
// the display_id lookup, or a multi-workspace agent could ack the WRONG
|
|
18
|
+
// workspace's message when two workspaces happen to share a display_id.
|
|
19
|
+
let q = ctx.supabase.from("messages").select("id").eq(sel, val);
|
|
20
|
+
if (isDisplay)
|
|
21
|
+
q = q.eq("workspace_id", await workspaceId(ctx));
|
|
22
|
+
const { data: msg, error } = await q.single();
|
|
23
|
+
if (error || !msg)
|
|
24
|
+
throw new CodebusError(`message not found: ${idOrDisplay}`);
|
|
25
|
+
// Review MAJOR finding #6: the update's error/rowcount used to be ignored
|
|
26
|
+
// entirely — a caller who is NOT a recipient of this message (mr_update
|
|
27
|
+
// RLS, 0007, scopes updates to `agent_id = current_agent_id()`) matched zero
|
|
28
|
+
// rows, got no error back from PostgREST, and still printed a success
|
|
29
|
+
// message claiming the message was acked/handled. Select the row back
|
|
30
|
+
// (`.select()`) so the actual affected-row count is visible, and fail
|
|
31
|
+
// loudly on either an error or an empty result.
|
|
32
|
+
const { data: updated, error: uerr } = await ctx.supabase
|
|
33
|
+
.from("message_recipients")
|
|
34
|
+
.update({ handled_at: new Date().toISOString() })
|
|
35
|
+
.eq("message_id", msg.id)
|
|
36
|
+
.select("message_id");
|
|
37
|
+
if (uerr)
|
|
38
|
+
throw new CodebusError(`ack failed: ${uerr.message}`);
|
|
39
|
+
if (!updated || updated.length === 0) {
|
|
40
|
+
throw new CodebusError(`ack failed: you are not a recipient of ${idOrDisplay} (nothing to ack)`);
|
|
41
|
+
}
|
|
42
|
+
if (o.json)
|
|
43
|
+
console.log(JSON.stringify({ acked: idOrDisplay }));
|
|
44
|
+
else
|
|
45
|
+
console.log(`acked ${idOrDisplay} (handled)`);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ack.js","sourceRoot":"","sources":["../../src/commands/ack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAa,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,2EAA2E;AAC3E,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,kCAAkC;AAClC,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,WAAmB,EAAE,CAAiC;IACjF,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IAChE,yEAAyE;IACzE,wEAAwE;IACxE,wEAAwE;IACxE,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChE,IAAI,SAAS;QAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9C,IAAI,KAAK,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,YAAY,CAAC,sBAAsB,WAAW,EAAE,CAAC,CAAC;IAC/E,0EAA0E;IAC1E,wEAAwE;IACxE,6EAA6E;IAC7E,sEAAsE;IACtE,sEAAsE;IACtE,sEAAsE;IACtE,gDAAgD;IAChD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ;SACtD,IAAI,CAAC,oBAAoB,CAAC;SAC1B,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;SAChD,EAAE,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE,CAAC;SACxB,MAAM,CAAC,YAAY,CAAC,CAAC;IACxB,IAAI,IAAI;QAAE,MAAM,IAAI,YAAY,CAAC,eAAe,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,YAAY,CAAC,0CAA0C,WAAW,mBAAmB,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,CAAC,CAAC,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;;QAC3D,OAAO,CAAC,GAAG,CAAC,SAAS,WAAW,YAAY,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { resolveConfig } from "../config.js";
|
|
2
|
+
import { makeCtx, workspaceId } from "../client.js";
|
|
3
|
+
import { CodebusError } from "../errors.js";
|
|
4
|
+
export async function archiveCmd(idOrDisplay, o) {
|
|
5
|
+
const ctx = await makeCtx(resolveConfig(o));
|
|
6
|
+
const isDisplay = /^CB-MSG-/i.test(idOrDisplay);
|
|
7
|
+
const sel = isDisplay ? "display_id" : "id";
|
|
8
|
+
const val = isDisplay ? idOrDisplay.toUpperCase() : idOrDisplay;
|
|
9
|
+
// display ids are only unique per workspace (bus_counters, 0004) — scope
|
|
10
|
+
// the display_id lookup, or a multi-workspace agent can archive the WRONG
|
|
11
|
+
// workspace's message when two workspaces happen to share a display_id.
|
|
12
|
+
let q = ctx.supabase.from("messages").select("id").eq(sel, val);
|
|
13
|
+
if (isDisplay)
|
|
14
|
+
q = q.eq("workspace_id", await workspaceId(ctx));
|
|
15
|
+
const { data: msg, error } = await q.single();
|
|
16
|
+
if (error || !msg)
|
|
17
|
+
throw new CodebusError(`message not found: ${idOrDisplay}`);
|
|
18
|
+
await ctx.supabase.from("message_recipients").update({ archived_at: new Date().toISOString() }).eq("message_id", msg.id);
|
|
19
|
+
console.log(`archived ${idOrDisplay}`);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/commands/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAa,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,WAAmB,EAAE,CAAY;IAChE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IAChE,yEAAyE;IACzE,0EAA0E;IAC1E,wEAAwE;IACxE,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChE,IAAI,SAAS;QAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9C,IAAI,KAAK,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,YAAY,CAAC,sBAAsB,WAAW,EAAE,CAAC,CAAC;IAC/E,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACzH,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,EAAE,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { resolveConfig } from "../config.js";
|
|
3
|
+
import { makeCtx } from "../client.js";
|
|
4
|
+
import { render } from "../output.js";
|
|
5
|
+
import { CodebusError } from "../errors.js";
|
|
6
|
+
// `codebus as <role> -- <cmd>` — run a command as a specific bus role.
|
|
7
|
+
//
|
|
8
|
+
// Why this exists: a session must never own its identity. provision_my_agent()
|
|
9
|
+
// mints a NEW principal per call, which is how nihviid-claude / nihviid-web /
|
|
10
|
+
// nihviid-default got created — the "address-book graveyard" the founding brief
|
|
11
|
+
// bans. Roles are durable and few; sessions are ephemeral and many. This command
|
|
12
|
+
// binds an ephemeral session to a durable role for the life of one process, via
|
|
13
|
+
// CODEBUS_TOKEN in the child env (config.ts precedence: flags > env > file).
|
|
14
|
+
//
|
|
15
|
+
// Tokens are stored ONCE, verified at write time, and never printed again.
|
|
16
|
+
// This is deliberately a local token store, not real credential delegation: N
|
|
17
|
+
// long-lived role tokens on disk is acceptable for one machine and one human,
|
|
18
|
+
// and becomes a liability the moment other people are involved. The proper fix
|
|
19
|
+
// is a server-side assume_role() issuing short-lived JWTs — no such primitive
|
|
20
|
+
// exists yet, so this is honest scaffolding, not the finished thing.
|
|
21
|
+
export { rolesFile, loadRoles, saveRoles } from "../rolestore.js";
|
|
22
|
+
import { rolesFile, loadRoles, saveRoles, inferRole } from "../rolestore.js";
|
|
23
|
+
import { checkBindingSafety } from "../binding-guard.js";
|
|
24
|
+
/**
|
|
25
|
+
* The child env for a role entry — exported for the regression suite (FM-5).
|
|
26
|
+
* A nested `codebus as roleA -- codebus as roleB -- cmd` (or simply running
|
|
27
|
+
* `as` from inside a session that already has CODEBUS_AGENT/CODEBUS_ASSUME
|
|
28
|
+
* set) must not leak the OUTER identity pin into the child: spreading the
|
|
29
|
+
* base env and overlaying only ONE of {CODEBUS_TOKEN, CODEBUS_ASSUME} left
|
|
30
|
+
* CODEBUS_AGENT and/or the other of {CODEBUS_TOKEN, CODEBUS_ASSUME} in place
|
|
31
|
+
* whenever the parent process happened to have them set — a raw-token role
|
|
32
|
+
* would then fail the identity check against a stale CODEBUS_AGENT, and an
|
|
33
|
+
* {assume} role's token-backed child would authenticate under the WRONG
|
|
34
|
+
* assumed role via a stale CODEBUS_ASSUME. Delete every conflicting inherited
|
|
35
|
+
* var first, then set exactly the one shape this entry actually has.
|
|
36
|
+
*/
|
|
37
|
+
export function childEnvFor(entry, base = process.env) {
|
|
38
|
+
const env = { ...base };
|
|
39
|
+
delete env.CODEBUS_TOKEN;
|
|
40
|
+
delete env.CODEBUS_AGENT;
|
|
41
|
+
delete env.CODEBUS_ASSUME;
|
|
42
|
+
if (entry.token)
|
|
43
|
+
env.CODEBUS_TOKEN = entry.token;
|
|
44
|
+
else
|
|
45
|
+
env.CODEBUS_ASSUME = entry.assume;
|
|
46
|
+
return env;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Read a secret without echoing it. Tokens must never reach argv — argv leaks
|
|
50
|
+
* into shell history and `ps` output — so --set always prompts or reads a pipe.
|
|
51
|
+
*/
|
|
52
|
+
async function readSecret(prompt) {
|
|
53
|
+
const stdin = process.stdin;
|
|
54
|
+
if (!stdin.isTTY) {
|
|
55
|
+
// piped / CI: consume stdin as the token
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
let data = "";
|
|
58
|
+
stdin.setEncoding("utf8");
|
|
59
|
+
stdin.on("data", (c) => (data += c));
|
|
60
|
+
stdin.on("end", () => resolve(data.trim()));
|
|
61
|
+
stdin.on("error", reject);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// Prompt on stderr so stdout stays clean for piping.
|
|
65
|
+
process.stderr.write(prompt);
|
|
66
|
+
return new Promise((resolve) => {
|
|
67
|
+
let buf = "";
|
|
68
|
+
stdin.setRawMode(true);
|
|
69
|
+
stdin.resume();
|
|
70
|
+
stdin.setEncoding("utf8");
|
|
71
|
+
const onData = (ch) => {
|
|
72
|
+
if (ch === "\r" || ch === "\n" || ch === "\u0004") {
|
|
73
|
+
stdin.setRawMode(false);
|
|
74
|
+
stdin.pause();
|
|
75
|
+
stdin.removeListener("data", onData);
|
|
76
|
+
process.stderr.write("\n");
|
|
77
|
+
resolve(buf);
|
|
78
|
+
}
|
|
79
|
+
else if (ch === "\u0003") {
|
|
80
|
+
stdin.setRawMode(false);
|
|
81
|
+
process.stderr.write("\n");
|
|
82
|
+
process.exit(130); // ctrl-c
|
|
83
|
+
}
|
|
84
|
+
else if (ch === "\u007f" || ch === "\b") {
|
|
85
|
+
buf = buf.slice(0, -1);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
buf += ch;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
stdin.on("data", onData);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Store a role's token. Verifies the token authenticates AS the named role
|
|
96
|
+
* before writing — a token stored under the wrong name would silently make
|
|
97
|
+
* every future session act as the wrong identity, which is far worse than
|
|
98
|
+
* failing here.
|
|
99
|
+
*/
|
|
100
|
+
async function setRole(role, o) {
|
|
101
|
+
const token = await readSecret(`token for ${role} (not echoed): `);
|
|
102
|
+
if (!token)
|
|
103
|
+
throw new CodebusError("no token provided");
|
|
104
|
+
const cfg = resolveConfig({ url: o.url, anonKey: o.anonKey, token });
|
|
105
|
+
let authed;
|
|
106
|
+
try {
|
|
107
|
+
const ctx = await makeCtx(cfg);
|
|
108
|
+
authed = ctx.agentSlug;
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
throw new CodebusError(`token rejected: ${e.message}`);
|
|
112
|
+
}
|
|
113
|
+
if (authed !== role) {
|
|
114
|
+
throw new CodebusError(`token authenticates as '${authed}', not '${role}'. ` +
|
|
115
|
+
`Store it under its real name (codebus as --set ${authed}) or use the right token.`);
|
|
116
|
+
}
|
|
117
|
+
const store = loadRoles();
|
|
118
|
+
const existed = !!store.roles[role];
|
|
119
|
+
store.roles[role] = { token, agent: authed, added_at: new Date().toISOString() };
|
|
120
|
+
saveRoles(store);
|
|
121
|
+
console.log(`${existed ? "updated" : "stored"} ${role} (verified as ${authed}) → ${rolesFile()}`);
|
|
122
|
+
}
|
|
123
|
+
function listRoles(o) {
|
|
124
|
+
const store = loadRoles();
|
|
125
|
+
const rows = Object.entries(store.roles).map(([role, e]) => ({
|
|
126
|
+
role, agent: e.agent, added_at: e.added_at,
|
|
127
|
+
}));
|
|
128
|
+
if (!rows.length) {
|
|
129
|
+
console.log(`no roles bound yet — add one with: codebus as --set <role>`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
console.log(render(rows, { json: !!o.json })); // never renders tokens
|
|
133
|
+
}
|
|
134
|
+
function forgetRole(role) {
|
|
135
|
+
const store = loadRoles();
|
|
136
|
+
if (!store.roles[role])
|
|
137
|
+
throw new CodebusError(`no such bound role: ${role}`);
|
|
138
|
+
delete store.roles[role];
|
|
139
|
+
saveRoles(store);
|
|
140
|
+
console.log(`forgot ${role}`);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Bind a directory pattern to a role, so `codebus as -- <cmd>` needs no role.
|
|
144
|
+
* The ONLY command that creates directory bindings (owner decision §6.1,
|
|
145
|
+
* docs/plans/codebus-v2-reliability.md — checkin stops auto-binding). Guarded
|
|
146
|
+
* against generic basenames and cross-directory name collisions
|
|
147
|
+
* (binding-guard.ts, FM-7) — both catch the same underlying hazard: a bare
|
|
148
|
+
* basename pattern matching more than the one directory the human meant.
|
|
149
|
+
*/
|
|
150
|
+
function bindRole(role, pattern) {
|
|
151
|
+
const store = loadRoles();
|
|
152
|
+
if (!store.roles[role]) {
|
|
153
|
+
throw new CodebusError(`role '${role}' has no stored token yet — run: codebus as --set ${role}`);
|
|
154
|
+
}
|
|
155
|
+
// Default to the current directory's basename as a pattern rather than its
|
|
156
|
+
// full path: the enclosing dir is usually the lane, and a basename pattern
|
|
157
|
+
// survives the worktree being recreated elsewhere.
|
|
158
|
+
const cwd = process.cwd();
|
|
159
|
+
const pat = pattern ?? (cwd.split("/").filter(Boolean).pop() ?? cwd);
|
|
160
|
+
const guard = checkBindingSafety(store, pat, cwd);
|
|
161
|
+
if (!guard.ok)
|
|
162
|
+
throw new CodebusError(guard.reason);
|
|
163
|
+
store.bindings = (store.bindings ?? []).filter((b) => b.pattern !== pat);
|
|
164
|
+
store.bindings.push({ pattern: pat, role, boundFrom: cwd });
|
|
165
|
+
saveRoles(store);
|
|
166
|
+
console.log(`bound ${pat} → ${role}`);
|
|
167
|
+
}
|
|
168
|
+
function unbindPattern(pattern) {
|
|
169
|
+
const store = loadRoles();
|
|
170
|
+
const before = (store.bindings ?? []).length;
|
|
171
|
+
store.bindings = (store.bindings ?? []).filter((b) => b.pattern !== pattern);
|
|
172
|
+
if (store.bindings.length === before) {
|
|
173
|
+
throw new CodebusError(`no binding for pattern: ${pattern}`);
|
|
174
|
+
}
|
|
175
|
+
saveRoles(store);
|
|
176
|
+
console.log(`unbound ${pattern}`);
|
|
177
|
+
}
|
|
178
|
+
function listBindings(o) {
|
|
179
|
+
const store = loadRoles();
|
|
180
|
+
const rows = (store.bindings ?? []).map((b) => ({ pattern: b.pattern, role: b.role }));
|
|
181
|
+
if (!rows.length) {
|
|
182
|
+
console.log(`no path bindings — add one with: codebus as --bind <role> [--pattern '<glob>']`);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const hit = inferRole(store, process.cwd());
|
|
186
|
+
console.log(render(rows, { json: !!o.json }));
|
|
187
|
+
console.log(hit ? `\ncwd matches: ${hit.pattern} → ${hit.role}` : `\ncwd matches: (none)`);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Exec a child process bound to a role. Inherits stdio so interactive tools
|
|
191
|
+
* (claude, codex) behave normally, and propagates the child's exit code so
|
|
192
|
+
* this is transparent in scripts and wrappers.
|
|
193
|
+
*
|
|
194
|
+
* Returns a Promise that never itself resolves — index.ts's top-level
|
|
195
|
+
* `program.parseAsync().then(() => process.exit(0))` would otherwise race
|
|
196
|
+
* ahead of the child (commander's action returns as soon as spawn() is
|
|
197
|
+
* called, long before the child finishes) and always exit 0 regardless of
|
|
198
|
+
* the child's real outcome. The event handlers below call process.exit(...)
|
|
199
|
+
* directly with the real code/signal once the child is actually done, which
|
|
200
|
+
* terminates the process before that outer `.then` ever runs.
|
|
201
|
+
*/
|
|
202
|
+
function runAs(role, argv) {
|
|
203
|
+
const store = loadRoles();
|
|
204
|
+
const entry = store.roles[role];
|
|
205
|
+
if (!entry) {
|
|
206
|
+
const known = Object.keys(store.roles);
|
|
207
|
+
throw new CodebusError(`role '${role}' is not bound. ${known.length ? `Bound: ${known.join(", ")}. ` : ""}` +
|
|
208
|
+
`Add it with: codebus as --set ${role}`);
|
|
209
|
+
}
|
|
210
|
+
if (!argv.length)
|
|
211
|
+
throw new CodebusError(`nothing to run — usage: codebus as ${role} -- <command> [args…]`);
|
|
212
|
+
if (!entry.token && !entry.assume) {
|
|
213
|
+
throw new CodebusError(`role '${role}' has neither a token nor an assume target — re-add it with: codebus as --set ${role}`);
|
|
214
|
+
}
|
|
215
|
+
const childEnv = childEnvFor(entry); // FM-5: never leaks a stale outer identity pin, see childEnvFor
|
|
216
|
+
const [cmd, ...rest] = argv;
|
|
217
|
+
const child = spawn(cmd, rest, {
|
|
218
|
+
stdio: "inherit",
|
|
219
|
+
// CODEBUS_TOKEN overrides the config file's identity for this process tree.
|
|
220
|
+
// CODEBUS_AGENT is deliberately NOT set: config.ts treats a mismatch between
|
|
221
|
+
// it and the authenticated agent as a hard error, and the token is already
|
|
222
|
+
// authoritative. Setting both invites a confusing failure for no benefit.
|
|
223
|
+
// An {assume} entry has no token to export — CODEBUS_ASSUME names the role
|
|
224
|
+
// instead, and each child mints its session from the author's config.json
|
|
225
|
+
// credential (config.ts threads it; spreading an undefined CODEBUS_TOKEN
|
|
226
|
+
// here would silently run the child as the AUTHOR, the exact misfire `as`
|
|
227
|
+
// exists to prevent).
|
|
228
|
+
env: childEnv,
|
|
229
|
+
});
|
|
230
|
+
child.on("error", (e) => {
|
|
231
|
+
console.error(`error: cannot run '${cmd}': ${e.message}`);
|
|
232
|
+
process.exit(127);
|
|
233
|
+
});
|
|
234
|
+
child.on("exit", (code, signal) => {
|
|
235
|
+
if (signal)
|
|
236
|
+
process.kill(process.pid, signal);
|
|
237
|
+
else
|
|
238
|
+
process.exit(code ?? 0);
|
|
239
|
+
});
|
|
240
|
+
return new Promise(() => { });
|
|
241
|
+
}
|
|
242
|
+
export function registerAs(program, g) {
|
|
243
|
+
g(program.command("as"))
|
|
244
|
+
.description("run a command as a bus role (codebus as <role> -- <cmd>)")
|
|
245
|
+
.argument("[role]", "bound role slug")
|
|
246
|
+
.option("--set <role>", "store a token for a role (prompts; never echoed)")
|
|
247
|
+
.option("--list", "list bound roles (never prints tokens)")
|
|
248
|
+
.option("--forget <role>", "remove a bound role")
|
|
249
|
+
.option("--bind <role>", "bind a directory pattern to a role (default: this dir's name)")
|
|
250
|
+
.option("--pattern <glob>", "pattern for --bind (e.g. 'wt-playkit-*')")
|
|
251
|
+
.option("--unbind <pattern>", "remove a path→role binding")
|
|
252
|
+
.option("--bindings", "list path→role bindings and what cwd resolves to")
|
|
253
|
+
.allowUnknownOption() // everything after `--` belongs to the child
|
|
254
|
+
.action(async (role, o) => {
|
|
255
|
+
if (o.set)
|
|
256
|
+
return setRole(o.set, o);
|
|
257
|
+
if (o.list)
|
|
258
|
+
return listRoles(o);
|
|
259
|
+
if (o.forget)
|
|
260
|
+
return forgetRole(o.forget);
|
|
261
|
+
if (o.bind)
|
|
262
|
+
return bindRole(o.bind, o.pattern);
|
|
263
|
+
if (o.unbind)
|
|
264
|
+
return unbindPattern(o.unbind);
|
|
265
|
+
if (o.bindings)
|
|
266
|
+
return listBindings(o);
|
|
267
|
+
// Read the child argv straight from process.argv: commander's own
|
|
268
|
+
// parsing of `--` passthrough varies with option placement, and getting
|
|
269
|
+
// this wrong would silently run the wrong command.
|
|
270
|
+
const dd = process.argv.indexOf("--");
|
|
271
|
+
const childArgv = dd >= 0 ? process.argv.slice(dd + 1) : [];
|
|
272
|
+
// Commander fills the [role] positional from the FIRST token after `--`
|
|
273
|
+
// (so `as -- echo hi` arrives as role='echo'), which would silently treat
|
|
274
|
+
// the child command as a role name. Only trust `role` if it actually
|
|
275
|
+
// appears before `--` in argv.
|
|
276
|
+
const beforeDD = dd >= 0 ? process.argv.slice(0, dd) : process.argv;
|
|
277
|
+
let resolved = role !== undefined && beforeDD.includes(role) ? role : undefined;
|
|
278
|
+
// No explicit role → infer from cwd. This is the zero-touch path: a
|
|
279
|
+
// session in a bound worktree needs no role argument at all.
|
|
280
|
+
if (!resolved) {
|
|
281
|
+
const store = loadRoles();
|
|
282
|
+
const hit = inferRole(store, process.cwd());
|
|
283
|
+
if (!hit) {
|
|
284
|
+
const bound = Object.keys(store.roles);
|
|
285
|
+
throw new CodebusError(`no role bound for ${process.cwd()}.\n` +
|
|
286
|
+
(bound.length
|
|
287
|
+
? ` bind it: codebus as --bind <role> [--pattern '<glob>'] (stored roles: ${bound.join(", ")})\n`
|
|
288
|
+
: ` add one: codebus as --set <role>\n`) +
|
|
289
|
+
` or name it: codebus as <role> -- <command>`);
|
|
290
|
+
}
|
|
291
|
+
resolved = hit.role;
|
|
292
|
+
// Say which rule fired — silent inference of identity is how you end
|
|
293
|
+
// up acting as the wrong agent without noticing.
|
|
294
|
+
console.error(`codebus: ${hit.pattern} → ${resolved}`);
|
|
295
|
+
}
|
|
296
|
+
await runAs(resolved, childArgv);
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=as.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"as.js","sourceRoot":"","sources":["../../src/commands/as.ts"],"names":[],"mappings":"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"}
|