@inerrata-corporation/errata 2.0.0-dev.39 → 2.0.0-dev.40

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 (2) hide show
  1. package/errata.mjs +166 -5
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -20857,6 +20857,18 @@ var init_client = __esm({
20857
20857
  async me() {
20858
20858
  return this.json("GET", "/v2/me");
20859
20859
  }
20860
+ // ─── acting-agent switching (gateway control plane, #898) ───────────
20861
+ /** Agents the authenticated user may act as, plus their default agent.
20862
+ * Authenticated with the caller's console-signed gateway JWT. */
20863
+ async actableAgents() {
20864
+ return this.json("GET", "/api/gate/actable-agents");
20865
+ }
20866
+ /** Mint a fresh gateway JWT stamped with `handle` (authz-checked + audited
20867
+ * server-side). The returned `token` bears the acting-agent identity for
20868
+ * subsequent cloud calls. Authenticated with the caller's base JWT. */
20869
+ async actAs(handle2) {
20870
+ return this.json("POST", "/api/gate/act-as", { handle: handle2 });
20871
+ }
20860
20872
  // ─── ingest ────────────────────────────────────────────────────────
20861
20873
  /** Upload one outbox batch (projected onto the reconciled wire) and fold
20862
20874
  * the per-decision response into flush accounting.
@@ -21337,7 +21349,8 @@ function defaultConfig() {
21337
21349
  notifications: true,
21338
21350
  onboardedAt: null,
21339
21351
  machineId: null,
21340
- updateChannel: "dev"
21352
+ updateChannel: "dev",
21353
+ activeAgent: null
21341
21354
  };
21342
21355
  }
21343
21356
  function loadConfig() {
@@ -21372,6 +21385,19 @@ function machineId() {
21372
21385
  saveConfig({ ...cfg, machineId: id });
21373
21386
  return id;
21374
21387
  }
21388
+ function getActiveAgent(cfg = loadConfig()) {
21389
+ return cfg.activeAgent ?? null;
21390
+ }
21391
+ function setActiveAgent(agent, cfg = loadConfig()) {
21392
+ const next = { ...cfg, activeAgent: { handle: agent.handle, id: agent.id } };
21393
+ saveConfig(next);
21394
+ return next;
21395
+ }
21396
+ function clearActiveAgent(cfg = loadConfig()) {
21397
+ const next = { ...cfg, activeAgent: null };
21398
+ saveConfig(next);
21399
+ return next;
21400
+ }
21375
21401
  var DEFAULT_CLOUD_URL;
21376
21402
  var init_config = __esm({
21377
21403
  "src/config.ts"() {
@@ -37436,8 +37462,8 @@ function buildWebUi(deps) {
37436
37462
  const arrText = Array.isArray(respObj["content"]) ? respObj["content"].map(
37437
37463
  (c2) => c2 && typeof c2 === "object" && typeof c2["text"] === "string" ? c2["text"] : ""
37438
37464
  ).join("\n") : "";
37439
- const errText = typeof rawResp === "string" ? rawResp : typeof respObj["error"] === "string" ? respObj["error"] : typeof respObj["message"] === "string" ? respObj["message"] : typeof respObj["stderr"] === "string" ? respObj["stderr"] : typeof respObj["content"] === "string" ? respObj["content"] : arrText;
37440
- const errorTokens = errText.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).slice(0, 20);
37465
+ const errText2 = typeof rawResp === "string" ? rawResp : typeof respObj["error"] === "string" ? respObj["error"] : typeof respObj["message"] === "string" ? respObj["message"] : typeof respObj["stderr"] === "string" ? respObj["stderr"] : typeof respObj["content"] === "string" ? respObj["content"] : arrText;
37466
+ const errorTokens = errText2.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).slice(0, 20);
37441
37467
  if (errorTokens.length > 0) {
37442
37468
  deps.onToolError({
37443
37469
  tool,
@@ -37446,7 +37472,7 @@ function buildWebUi(deps) {
37446
37472
  exitCode: numericExit ?? 1,
37447
37473
  ts: Date.now()
37448
37474
  });
37449
- recallCtx = recallForError(deps.store, errText);
37475
+ recallCtx = recallForError(deps.store, errText2);
37450
37476
  }
37451
37477
  }
37452
37478
  }
@@ -42478,7 +42504,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
42478
42504
  }
42479
42505
 
42480
42506
  // src/engine.ts
42481
- var DAEMON_VERSION = true ? "2.0.0-dev.39" : "2.0.0-alpha.0";
42507
+ var DAEMON_VERSION = true ? "2.0.0-dev.40" : "2.0.0-alpha.0";
42482
42508
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
42483
42509
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
42484
42510
  var GIT_OP_MUTE_MS = 4e3;
@@ -45202,6 +45228,114 @@ init_src4();
45202
45228
  init_config();
45203
45229
  init_src6();
45204
45230
  init_cloud_auth();
45231
+
45232
+ // src/agent-switch.ts
45233
+ function parseUseArgs(args2) {
45234
+ const positional = [];
45235
+ let clear = false;
45236
+ for (const arg of args2) {
45237
+ if (arg === "--none" || arg === "--clear") {
45238
+ clear = true;
45239
+ continue;
45240
+ }
45241
+ if (arg.startsWith("--")) continue;
45242
+ positional.push(arg);
45243
+ }
45244
+ if (clear) return { kind: "clear" };
45245
+ const handle2 = positional[0];
45246
+ if (!handle2) return { kind: "show" };
45247
+ return { kind: "set", handle: handle2 };
45248
+ }
45249
+ function normalizeHandle(handle2) {
45250
+ return handle2.trim().replace(/^@/, "").toLowerCase();
45251
+ }
45252
+ function findActable(agents, handle2) {
45253
+ const want = normalizeHandle(handle2);
45254
+ return agents.find((a) => normalizeHandle(a.handle) === want) ?? null;
45255
+ }
45256
+ async function runUse(action, ctx) {
45257
+ switch (action.kind) {
45258
+ case "clear":
45259
+ return runClear(ctx);
45260
+ case "show":
45261
+ return runShow(ctx);
45262
+ case "set":
45263
+ return runSet(action.handle, ctx);
45264
+ }
45265
+ }
45266
+ function runClear(ctx) {
45267
+ const active = ctx.getActiveAgent();
45268
+ ctx.clearActiveAgent();
45269
+ if (active) {
45270
+ ctx.log(`no longer acting as ${active.handle} \u2014 the daemon acts as your default identity`);
45271
+ } else {
45272
+ ctx.log(`already on the default identity \u2014 nothing to clear`);
45273
+ }
45274
+ return 0;
45275
+ }
45276
+ async function runShow(ctx) {
45277
+ const active = ctx.getActiveAgent();
45278
+ ctx.log(active ? `active agent: ${active.handle} (id ${active.id})` : `active agent: (default identity)`);
45279
+ if (!ctx.loggedIn) {
45280
+ ctx.log(` log in to list the agents you can act as: errata login`);
45281
+ return 0;
45282
+ }
45283
+ let resp;
45284
+ try {
45285
+ resp = await ctx.actableAgents();
45286
+ } catch (err2) {
45287
+ ctx.log(` couldn't list actable agents: ${errText(err2)}`);
45288
+ return 1;
45289
+ }
45290
+ printActable(resp, active, ctx);
45291
+ return 0;
45292
+ }
45293
+ async function runSet(handle2, ctx) {
45294
+ if (!ctx.loggedIn) {
45295
+ ctx.log(`not logged in \u2014 run \`errata login\` first, then \`errata use ${handle2}\``);
45296
+ return 1;
45297
+ }
45298
+ let resp;
45299
+ try {
45300
+ resp = await ctx.actableAgents();
45301
+ } catch (err2) {
45302
+ ctx.log(`couldn't verify \`${handle2}\`: ${errText(err2)}`);
45303
+ return 1;
45304
+ }
45305
+ const match2 = findActable(resp.agents, handle2);
45306
+ if (!match2) {
45307
+ ctx.log(`unknown agent: ${handle2}`);
45308
+ if (resp.agents.length === 0) {
45309
+ ctx.log(` you can't act as any agents yet.`);
45310
+ } else {
45311
+ ctx.log(` agents you can act as: ${resp.agents.map((a) => a.handle).join(", ")}`);
45312
+ }
45313
+ return 2;
45314
+ }
45315
+ ctx.setActiveAgent({ handle: match2.handle, id: match2.id });
45316
+ ctx.log(`now acting as ${match2.handle} (id ${match2.id}) \u2014 saved; persists across daemon restarts`);
45317
+ return 0;
45318
+ }
45319
+ function printActable(resp, active, ctx) {
45320
+ if (resp.agents.length === 0) {
45321
+ ctx.log(` (no agents you can act as)`);
45322
+ return;
45323
+ }
45324
+ ctx.log(` agents you can act as:`);
45325
+ for (const a of resp.agents) {
45326
+ const marks = [];
45327
+ if (active && a.id === active.id) marks.push("active");
45328
+ if (a.id === resp.defaultAgentId) marks.push("default");
45329
+ const suffix = marks.length ? ` (${marks.join(", ")})` : "";
45330
+ const scope = a.scope ? ` \xB7 ${a.scope}` : "";
45331
+ ctx.log(` ${a.handle}${scope}${suffix}`);
45332
+ }
45333
+ }
45334
+ function errText(err2) {
45335
+ return err2 instanceof Error ? err2.message : String(err2);
45336
+ }
45337
+
45338
+ // src/cli.ts
45205
45339
  init_cloud_endpoint_policy();
45206
45340
 
45207
45341
  // src/oauth-login.ts
@@ -45446,6 +45580,8 @@ async function main() {
45446
45580
  return cmdLogin();
45447
45581
  case "logout":
45448
45582
  return cmdLogout();
45583
+ case "use":
45584
+ return cmdUse(rest);
45449
45585
  case "review":
45450
45586
  return cmdReview();
45451
45587
  case "tick":
@@ -45570,6 +45706,9 @@ Commands:
45570
45706
  surface (navigation, problems, claims, burst, health)
45571
45707
  login Sign in with the cloud (OAuth by default; --device for legacy device-code)
45572
45708
  logout Clear local cloud credentials
45709
+ use [<handle>] Set the sticky session active agent the daemon acts as.
45710
+ No arg lists the agents you can act as + the current one;
45711
+ --none (or --clear) reverts to your default identity.
45573
45712
  sync now Flush outbox to the cloud once
45574
45713
  privacy Show what is collected/scrubbed + your consent state
45575
45714
  consent <channel> <on|off>
@@ -45772,6 +45911,10 @@ async function cmdStatus() {
45772
45911
  console.log(` cloud:`);
45773
45912
  console.log(` url: ${cfg.cloudUrl}`);
45774
45913
  console.log(` logged in: ${hasCloudCredential(cfg) ? `yes (${cfg.email})` : "no"}`);
45914
+ const active = getActiveAgent(cfg);
45915
+ console.log(
45916
+ ` active agent: ${active ? `${active.handle} (acting-as; \`errata use --none\` to clear)` : "default identity"}`
45917
+ );
45775
45918
  const inspection = await inspectCloudEndpoint(cfg.cloudUrl);
45776
45919
  const decision = evaluateCloudEndpoint(cfg.cloudUrl, inspection);
45777
45920
  const service = inspection.service ? ` \xB7 service ${inspection.service}` : "";
@@ -46048,6 +46191,24 @@ async function cmdLogout() {
46048
46191
  saveConfig(cfg);
46049
46192
  console.log(`logged out`);
46050
46193
  }
46194
+ async function cmdUse(args2) {
46195
+ const cfg = loadConfig();
46196
+ const action = parseUseArgs(args2);
46197
+ const ctx = {
46198
+ loggedIn: hasCloudCredential(cfg),
46199
+ actableAgents: () => authedCloudClient(loadConfig()).actableAgents(),
46200
+ getActiveAgent: () => getActiveAgent(),
46201
+ setActiveAgent: (agent) => {
46202
+ setActiveAgent(agent);
46203
+ },
46204
+ clearActiveAgent: () => {
46205
+ clearActiveAgent();
46206
+ },
46207
+ log: (line) => console.log(line)
46208
+ };
46209
+ const code = await runUse(action, ctx);
46210
+ if (code !== 0) process.exitCode = code;
46211
+ }
46051
46212
  async function cmdReview() {
46052
46213
  const paths = workspacePaths(ROOT);
46053
46214
  if (!existsSync20(paths.reviewQueue)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.0-dev.39",
3
+ "version": "2.0.0-dev.40",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {