@botbuddy/cli 1.53.0 → 1.53.1
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/package.json +1 -1
- package/src/agent-doctor.mjs +5 -0
- package/src/agent-session.mjs +10 -1
- package/src/commands.mjs +1 -1
- package/src/stack.mjs +2 -1
- package/src/wait.mjs +5 -1
package/package.json
CHANGED
package/src/agent-doctor.mjs
CHANGED
|
@@ -83,6 +83,11 @@ export function repairFailureRecovery(code, error = null) {
|
|
|
83
83
|
if (code === "agent_tenant_immutable") {
|
|
84
84
|
return "this worktree's agent identity belongs to another tenant; run `bb setup` to register this tenant, then `bb doctor --fix`";
|
|
85
85
|
}
|
|
86
|
+
// BOT-2415: the cached session names a different agent than the one holding this
|
|
87
|
+
// worktree's technical name. Deterministic: a retry repeats the same conflict.
|
|
88
|
+
if (code === "agent_name_conflict") {
|
|
89
|
+
return "this worktree's cached session (.botbuddy/agent-state.json) names a different agent than the one holding the worktree's technical name; move that file aside, then run `bb doctor --fix`";
|
|
90
|
+
}
|
|
86
91
|
// BOT-1750 (Codex R9 P2): `session_mint_unauthorized` means a locally-unexpired
|
|
87
92
|
// client key was revoked/rejected server-side — only a fresh login replaces it, so
|
|
88
93
|
// point at `bb login`, not a binding repair (the binding is valid).
|
package/src/agent-session.mjs
CHANGED
|
@@ -345,6 +345,9 @@ export async function selfHealAgentSession({
|
|
|
345
345
|
branch: currentBranch || undefined,
|
|
346
346
|
ticket_id: ticketFromBranch(currentBranch),
|
|
347
347
|
agent_id: presentedAgentId ?? undefined,
|
|
348
|
+
// A rejected-token renewal may still own locks or leases under this agent.
|
|
349
|
+
// Ask the server to keep it; ordinary setup/doctor repair may adopt a holder.
|
|
350
|
+
...(renewal ? { preserve_agent_identity: true } : {}),
|
|
348
351
|
harness_session_id: presentedHarness ?? undefined,
|
|
349
352
|
harness: env.CLAUDE_CODE || env.CLAUDECODE ? "claude-code" : Object.keys(env).some((key) => key.startsWith("CODEX_")) ? "codex" : "cli",
|
|
350
353
|
model: env.BOTBUDDY_MODEL || undefined,
|
|
@@ -372,8 +375,14 @@ export async function selfHealAgentSession({
|
|
|
372
375
|
const typedCode = typeof response?.code === "string"
|
|
373
376
|
? response.code
|
|
374
377
|
: typeof data.code === "string" ? data.code : null;
|
|
375
|
-
|
|
378
|
+
// BOT-2415: a technical-name conflict is deterministic (the cached agent_id
|
|
379
|
+
// names a different agent than the one holding this worktree's name), so no
|
|
380
|
+
// retry fixes it. Recognise the typed refusal and an older server's raw 23505.
|
|
381
|
+
const nameConflict = typedCode === "agent_name_taken"
|
|
382
|
+
|| /agents_name_key/.test(String(response?.error ?? data.error ?? ""));
|
|
383
|
+
const code = ["agent_tenant_immutable", "session_identity_mismatch"].includes(typedCode)
|
|
376
384
|
? typedCode
|
|
385
|
+
: nameConflict ? "agent_name_conflict"
|
|
377
386
|
: response?.auth ? "session_mint_unauthorized" : "session_mint_failed";
|
|
378
387
|
// BOT-1891: name the credential (never its value) so `bb doctor` can point a
|
|
379
388
|
// rejected tier-2 key at rotation instead of `bb login`.
|
package/src/commands.mjs
CHANGED
|
@@ -568,7 +568,7 @@ function setupFailureRecovery(error) {
|
|
|
568
568
|
if (code === "tenant_binding_required" || code === "invalid_binding") {
|
|
569
569
|
return "fix the committed .botbuddy-agent.json binding, then retry `bb setup`";
|
|
570
570
|
}
|
|
571
|
-
if (code === "client_key_unavailable" || code === "session_mint_unauthorized") return repairFailureRecovery(code, error);
|
|
571
|
+
if (code === "client_key_unavailable" || code === "session_mint_unauthorized" || code === "agent_name_conflict") return repairFailureRecovery(code, error);
|
|
572
572
|
return "retry `bb setup`";
|
|
573
573
|
}
|
|
574
574
|
|
package/src/stack.mjs
CHANGED
|
@@ -985,7 +985,7 @@ export function retryingStackCall({
|
|
|
985
985
|
// taxonomy so automation sees AUTH/BACKEND, not a CLI-defect INTERNAL. Credential
|
|
986
986
|
// problems are AUTH (3); a transport/server mint failure is BACKEND (5); anything
|
|
987
987
|
// unrecognized stays INTERNAL (7).
|
|
988
|
-
const AUTH_ERROR_CODES = new Set(["client_key_required", "client_key_unavailable", "tenant_binding_required", "session_token_malformed", "session_mint_unauthorized", "session_identity_mismatch"]);
|
|
988
|
+
const AUTH_ERROR_CODES = new Set(["client_key_required", "client_key_unavailable", "tenant_binding_required", "session_token_malformed", "session_mint_unauthorized", "session_identity_mismatch", "agent_name_conflict"]);
|
|
989
989
|
// BOT-1750 (Codex R11 P2): `session_mint_invalid` is an incompatible/malformed SERVER
|
|
990
990
|
// response, not a credential problem — classify it with the transport/server failures.
|
|
991
991
|
const BACKEND_ERROR_CODES = new Set(["session_mint_failed", "session_mint_invalid"]);
|
|
@@ -1423,6 +1423,7 @@ export const PARK_AUTH_BUDGET_MS = 5 * 60_000;
|
|
|
1423
1423
|
// the regular auth budget; it is not evidence that the lease changed owner.
|
|
1424
1424
|
const DEFINITIVE_REAUTH_CODES = new Set([
|
|
1425
1425
|
"session_identity_mismatch", "client_key_required", "tenant_binding_required", "session_token_malformed", "agent_tenant_immutable",
|
|
1426
|
+
"agent_name_conflict",
|
|
1426
1427
|
]);
|
|
1427
1428
|
|
|
1428
1429
|
function abortableSleep(ms, signal) {
|
package/src/wait.mjs
CHANGED
|
@@ -20,6 +20,7 @@ import { fileURLToPath } from "node:url";
|
|
|
20
20
|
import { latestPublicCliCommand } from "./public-invocation.mjs";
|
|
21
21
|
import { AGENT_KEY_RE, readAgentSessionTokenEnv, legacyAgentAliasHint } from "./agent-key.mjs";
|
|
22
22
|
import { clearAgentState, hasAgentSessionRuntime, isRejectedCachedSession, resolveAgentSessionCredential, selfHealAgentSession } from "./agent-session.mjs";
|
|
23
|
+
import { repairFailureRecovery } from "./agent-doctor.mjs";
|
|
23
24
|
import { touchAgentStateExpiry } from "./agent-state.mjs";
|
|
24
25
|
import { SETUP_BLOCK } from "./setup-block.mjs";
|
|
25
26
|
import { createWaitCheckpointStore, WaitCheckpointError } from "./wait-checkpoint.mjs";
|
|
@@ -1679,7 +1680,10 @@ export async function runWait(argv, { recoveryLocalWaitId = null } = {}) {
|
|
|
1679
1680
|
opts.credentialSource = credential.source;
|
|
1680
1681
|
} catch (error) {
|
|
1681
1682
|
const code = error?.code ?? "session_mint_failed";
|
|
1682
|
-
|
|
1683
|
+
// BOT-2415: a stale cache naming another agent is not fixed by `bb setup` + retry.
|
|
1684
|
+
const recovery = code === "agent_name_conflict"
|
|
1685
|
+
? repairFailureRecovery(code)
|
|
1686
|
+
: code === "client_key_required"
|
|
1683
1687
|
? "run `bb setup` from this project worktree, then retry"
|
|
1684
1688
|
: code === "tenant_binding_required"
|
|
1685
1689
|
? "run from a configured project worktree, then run `bb setup` and retry"
|