@sema-agent/cli 1.0.76 → 1.0.77

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/sema-main.js CHANGED
@@ -39088,9 +39088,9 @@ var require_abort = __commonJS({
39088
39088
  "node_modules/asynckit/lib/abort.js"(exports2, module2) {
39089
39089
  module2.exports = abort;
39090
39090
  function abort(state4) {
39091
- Object.keys(state4.jobs).forEach(clean5.bind(state4)), state4.jobs = {};
39091
+ Object.keys(state4.jobs).forEach(clean6.bind(state4)), state4.jobs = {};
39092
39092
  }
39093
- function clean5(key) {
39093
+ function clean6(key) {
39094
39094
  typeof this.jobs[key] == "function" && this.jobs[key]();
39095
39095
  }
39096
39096
  }
@@ -55606,7 +55606,7 @@ function isRewindFamilyCode(code2) {
55606
55606
  function asModelFallbackReason(v2) {
55607
55607
  return v2 === MODEL_FALLBACK_INHERIT_NO_TIER_BINDING ? MODEL_FALLBACK_INHERIT_NO_TIER_BINDING : void 0;
55608
55608
  }
55609
- var LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, USAGE_WINDOW_EXHAUSTED, ENV_LIFETIME_EXPIRED, CONFIG_LIMIT_INVALID, CONFIG_STRATEGY_FIND_LIMIT_INVALID, CONFIG_STRATEGY_MAX_SIZE_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_REFUSAL_CODES, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, TOOL_END_INTERRUPTED_CODES, ACTIVE_RUN_BUSY_ERROR_CODE, STOP_PARK_ARBITER_UNREACHABLE, STOP_PARK_RESUME_WON, STOP_NOT_LANDED, STOP_NOT_LOCAL, STOP_PARKED, STOP_CONFLICT_CODES, OUTPUT_INVALID, REWIND_ERROR_CODE_PREFIXES, STREAM_MAX_DURATION, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, init_engineErrorCodes = __esm({
55609
+ var LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, USAGE_WINDOW_EXHAUSTED, ENV_LIFETIME_EXPIRED, CONFIG_LIMIT_INVALID, CONFIG_STRATEGY_FIND_LIMIT_INVALID, CONFIG_STRATEGY_MAX_SIZE_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_REFUSAL_CODES, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, TOOL_END_INTERRUPTED_CODES, ACTIVE_RUN_BUSY_ERROR_CODE, STOP_PARK_ARBITER_UNREACHABLE, STOP_PARK_RESUME_WON, STOP_NOT_LANDED, STOP_NOT_LOCAL, STOP_PARKED, STOP_CONFLICT_CODES, OUTPUT_INVALID, RESUME_AT_ERROR_CODE_PREFIX, REWIND_ERROR_CODE_PREFIXES, DRAINING_ERROR_CODE, SCENARIO_NOT_ALLOWED_ERROR_CODE, STREAM_MAX_DURATION, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, init_engineErrorCodes = __esm({
55610
55610
  "node_modules/@sema-agent/client-core/dist/engineErrorCodes.js"() {
55611
55611
  LIMITS_MAX_TOKENS_EXCEEDED = "limits.max_tokens_exceeded", LIMITS_MAX_COST_EXCEEDED = "limits.max_cost_exceeded", LIMITS_MAX_TURNS_EXCEEDED = "limits.max_turns_exceeded", LIMITS_MAX_WALLTIME_EXCEEDED = "limits.max_walltime_exceeded", USAGE_WINDOW_EXHAUSTED = "usage.window_exhausted", ENV_LIFETIME_EXPIRED = "env.lifetime_expired", CONFIG_LIMIT_INVALID = "config.limit_invalid", CONFIG_STRATEGY_FIND_LIMIT_INVALID = "config.strategy_find_limit_invalid", CONFIG_STRATEGY_MAX_SIZE_INVALID = "config.strategy_max_size_invalid", CONFIG_LIMIT_UNKNOWN_KEY = "config.limit_unknown_key", CONFIG_REFUSAL_CODES = /* @__PURE__ */ new Set([
55612
55612
  CONFIG_LIMIT_INVALID,
@@ -55624,8 +55624,8 @@ var LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TURNS_EXCEE
55624
55624
  STOP_NOT_LANDED,
55625
55625
  STOP_NOT_LOCAL,
55626
55626
  STOP_PARKED
55627
- ], OUTPUT_INVALID = "output.invalid", REWIND_ERROR_CODE_PREFIXES = ["resume_at.", "rewind_snapshot."];
55628
- STREAM_MAX_DURATION = "STREAM_MAX_DURATION", MODEL_FALLBACK_INHERIT_NO_TIER_BINDING = "inherit_no_tier_binding";
55627
+ ], OUTPUT_INVALID = "output.invalid", RESUME_AT_ERROR_CODE_PREFIX = "resume_at.", REWIND_ERROR_CODE_PREFIXES = [RESUME_AT_ERROR_CODE_PREFIX, "rewind_snapshot."];
55628
+ DRAINING_ERROR_CODE = "draining", SCENARIO_NOT_ALLOWED_ERROR_CODE = "scenario_not_allowed", STREAM_MAX_DURATION = "STREAM_MAX_DURATION", MODEL_FALLBACK_INHERIT_NO_TIER_BINDING = "inherit_no_tier_binding";
55629
55629
  }
55630
55630
  });
55631
55631
 
@@ -58146,6 +58146,15 @@ var SSE_HEARTBEAT_GRACE_ENV, SSE_GRACE_MIN_MS, SSE_GRACE_MAX_MS, SDK_DEFAULT_GRA
58146
58146
  }
58147
58147
  });
58148
58148
 
58149
+ // node_modules/@sema-agent/client-core/dist/principalWire.js
58150
+ function normalizeWirePrincipal(v2) {
58151
+ return v2 !== void 0 && v2.trim() !== "" ? v2 : void 0;
58152
+ }
58153
+ var init_principalWire = __esm({
58154
+ "node_modules/@sema-agent/client-core/dist/principalWire.js"() {
58155
+ }
58156
+ });
58157
+
58149
58158
  // node_modules/@sema-agent/client-core/dist/engineWireSdk.js
58150
58159
  import { AgentClient } from "@sema-agent/sdk";
58151
58160
  function isLoopbackWireUrl(url3) {
@@ -58164,10 +58173,11 @@ function wireAuthTokenFor(baseUrl, token) {
58164
58173
  }
58165
58174
  function makeEngineWireClient(cfg) {
58166
58175
  try {
58167
- let base = {
58176
+ let principal = normalizeWirePrincipal(cfg.principal), base = {
58168
58177
  baseUrl: cfg.baseUrl,
58169
58178
  // F-011 停发:缺席/空串=不给键(SDK 6.11 缺席=不发 x-agent-principal 头,owner-null)。
58170
- ...cfg.principal !== void 0 && cfg.principal !== "" ? { principal: cfg.principal } : {},
58179
+ // A-028.10(0.30.3):空串判升级为 trim 判(principalWire 同尺)——全空白值同罪,归缺席。
58180
+ ...principal !== void 0 ? { principal } : {},
58171
58181
  ...cfg.timeoutMs !== void 0 ? { timeoutMs: cfg.timeoutMs } : {},
58172
58182
  maxRetries: cfg.maxRetries ?? 0,
58173
58183
  ...cfg.fetchImpl ? { fetch: cfg.fetchImpl } : {}
@@ -58179,6 +58189,7 @@ function makeEngineWireClient(cfg) {
58179
58189
  }
58180
58190
  var init_engineWireSdk = __esm({
58181
58191
  "node_modules/@sema-agent/client-core/dist/engineWireSdk.js"() {
58192
+ init_principalWire();
58182
58193
  }
58183
58194
  });
58184
58195
 
@@ -60010,14 +60021,14 @@ function claimProbeLease(caller, remainingMs) {
60010
60021
  };
60011
60022
  }
60012
60023
  async function waitForClaimRelease(taskId, deps2) {
60013
- let now2 = typeof deps2.now == "function" ? deps2.now : () => Date.now(), sleep10 = typeof deps2.sleep == "function" ? deps2.sleep : claimPollSleep, budgetMs = Number.isFinite(deps2.budgetMs) && deps2.budgetMs > 0 ? deps2.budgetMs : 0, startedAt = now2(), deadline = startedAt + budgetMs, waited = () => now2() - startedAt, isAborted3 = () => deps2.signal?.aborted === !0, delay = CANCEL_POLL_START_MS, lastStatus = null;
60024
+ let now2 = typeof deps2.now == "function" ? deps2.now : () => Date.now(), sleep9 = typeof deps2.sleep == "function" ? deps2.sleep : claimPollSleep, budgetMs = Number.isFinite(deps2.budgetMs) && deps2.budgetMs > 0 ? deps2.budgetMs : 0, startedAt = now2(), deadline = startedAt + budgetMs, waited = () => now2() - startedAt, isAborted3 = () => deps2.signal?.aborted === !0, delay = CANCEL_POLL_START_MS, lastStatus = null;
60014
60025
  for (; ; ) {
60015
60026
  if (isAborted3())
60016
60027
  return { released: !1, waitedMs: waited(), aborted: !0, lastStatus };
60017
60028
  let remaining = deadline - now2();
60018
60029
  if (remaining <= 0)
60019
60030
  return { released: !1, waitedMs: waited(), aborted: !1, lastStatus };
60020
- if (await sleep10(Math.min(delay, remaining), deps2.signal), isAborted3())
60031
+ if (await sleep9(Math.min(delay, remaining), deps2.signal), isAborted3())
60021
60032
  return { released: !1, waitedMs: waited(), aborted: !0, lastStatus };
60022
60033
  delay = Math.min(Math.round(delay * 1.5), CANCEL_POLL_MAX_MS);
60023
60034
  let status3, lease = claimProbeLease(deps2.signal, deadline - now2());
@@ -60027,8 +60038,11 @@ async function waitForClaimRelease(taskId, deps2) {
60027
60038
  ...deps2.session !== void 0 ? { session: deps2.session } : {}
60028
60039
  }));
60029
60040
  } catch {
60030
- if (lastStatus = null, lease.release(), isAborted3())
60041
+ if (lease.release(), isAborted3())
60031
60042
  return { released: !1, waitedMs: waited(), aborted: !0, lastStatus };
60043
+ if (lease.signal.aborted)
60044
+ continue;
60045
+ lastStatus = null;
60032
60046
  continue;
60033
60047
  }
60034
60048
  if (lease.release(), lastStatus = status3, status3 !== null && CLAIM_RELEASED_STATES.includes(status3))
@@ -60042,6 +60056,22 @@ async function attemptActiveRunSelfHeal(signal, runs, deps2) {
60042
60056
  } catch {
60043
60057
  pending2 = !1;
60044
60058
  }
60059
+ let callerAborted = () => deps2?.signal?.aborted === !0;
60060
+ if (pending2 && typeof deps2?.listOwnedPendingApprovals == "function" && !callerAborted()) {
60061
+ let recheckCtl = new AbortController(), onCallerAbort = () => {
60062
+ recheckCtl.abort(deps2.signal?.reason);
60063
+ };
60064
+ deps2.signal?.addEventListener("abort", onCallerAbort, { once: !0 });
60065
+ try {
60066
+ await Promise.race([
60067
+ deps2.listOwnedPendingApprovals({ signal: recheckCtl.signal }),
60068
+ claimPollSleep(OWNED_PENDING_RECHECK_TIMEOUT_MS, recheckCtl.signal).then(() => null)
60069
+ ]) === 0 && !callerAborted() && (pending2 = !1);
60070
+ } catch {
60071
+ } finally {
60072
+ deps2.signal?.removeEventListener("abort", onCallerAbort), recheckCtl.abort(new Error("owned-pending recheck settled"));
60073
+ }
60074
+ }
60045
60075
  if (pending2)
60046
60076
  return { kind: "decision-pending", taskId: signal.activeTaskId };
60047
60077
  let taskId = signal.activeTaskId;
@@ -60235,13 +60265,13 @@ function activeRunBusyHeadlessRow(signal, copy2) {
60235
60265
  let startOver = `${freshSession.charAt(0).toUpperCase()}${freshSession.slice(1)}`;
60236
60266
  return `This session is locked by an earlier run${handle2} that was never released, so this message was NOT sent. Nothing here clears on its own. ${startOver}, or release the run on the engine: ${cancelPath}`;
60237
60267
  }
60238
- var PLAN_REVIEW_GATE_KIND, PLAN_REVIEW_GATE_KINDS, ASK_PARK_GATE_KINDS, PLAN_REVIEW_STATES, ASK_PARK_STATES, RUNNING_STATES, CLAIM_RELEASED_STATES, CLAIM_HELD_STATES, CANCEL_RELEASE_WAIT_MS, CANCEL_POLL_START_MS, CANCEL_POLL_MAX_MS, DEFAULT_WAY_OUT, DEFAULT_FRESH_SESSION, init_activeRunSelfHeal = __esm({
60268
+ var PLAN_REVIEW_GATE_KIND, PLAN_REVIEW_GATE_KINDS, ASK_PARK_GATE_KINDS, PLAN_REVIEW_STATES, ASK_PARK_STATES, RUNNING_STATES, CLAIM_RELEASED_STATES, CLAIM_HELD_STATES, CANCEL_RELEASE_WAIT_MS, OWNED_PENDING_RECHECK_TIMEOUT_MS, CANCEL_POLL_START_MS, CANCEL_POLL_MAX_MS, INTERACTIVE_WAY_OUT, DEFAULT_WAY_OUT, DEFAULT_FRESH_SESSION, init_activeRunSelfHeal = __esm({
60239
60269
  "node_modules/@sema-agent/client-core/dist/adapter/activeRunSelfHeal.js"() {
60240
60270
  init_abortableSleep();
60241
60271
  PLAN_REVIEW_GATE_KIND = "plan_review", PLAN_REVIEW_GATE_KINDS = [PLAN_REVIEW_GATE_KIND, "dry_run_review"], ASK_PARK_GATE_KINDS = ["human", "irreversible_ask", "policy_ask", "tool_approval"];
60242
60272
  PLAN_REVIEW_STATES = ["needs_review"], ASK_PARK_STATES = ["suspended"], RUNNING_STATES = ["running"], CLAIM_RELEASED_STATES = ["completed", "failed", "blocked", "timeout"], CLAIM_HELD_STATES = ["running", "suspended", "needs_review"];
60243
- CANCEL_RELEASE_WAIT_MS = 1e4, CANCEL_POLL_START_MS = 200, CANCEL_POLL_MAX_MS = 2e3;
60244
- DEFAULT_WAY_OUT = "run /clear to keep working in a fresh session", DEFAULT_FRESH_SESSION = "start a new session (drop --resume/--continue)";
60273
+ CANCEL_RELEASE_WAIT_MS = 1e4, OWNED_PENDING_RECHECK_TIMEOUT_MS = 4e3, CANCEL_POLL_START_MS = 200, CANCEL_POLL_MAX_MS = 2e3;
60274
+ INTERACTIVE_WAY_OUT = "run /clear to keep working in a fresh session", DEFAULT_WAY_OUT = INTERACTIVE_WAY_OUT, DEFAULT_FRESH_SESSION = "start a new session (drop --resume/--continue)";
60245
60275
  }
60246
60276
  });
60247
60277
 
@@ -60300,7 +60330,7 @@ function buildTaskRequest(input, lane) {
60300
60330
  }
60301
60331
  function applyLiveRequestDefaults(req, host) {
60302
60332
  let out6 = { ...req };
60303
- if (out6.cwd == null && host.cwd !== void 0 && (out6.cwd = host.cwd), out6.additionalDirectories === void 0 && (host.additionalDirectories?.length ?? 0) > 0 && (out6.additionalDirectories = [...host.additionalDirectories ?? []]), out6.forwardSubagentEvents === void 0 && (out6.forwardSubagentEvents = !0), out6.retainSubagentSessions === void 0 && (out6.retainSubagentSessions = !0), out6.agents === void 0 && host.agents !== void 0 && (out6.agents = host.agents), typeof out6.scenario == "string" && host.mockScenarioKeys?.has(out6.scenario) && delete out6.scenario, host.selfKnowledge !== void 0)
60333
+ if (out6.cwd == null && host.cwd !== void 0 && (out6.cwd = host.cwd), out6.additionalDirectories === void 0 && (host.additionalDirectories?.length ?? 0) > 0 && (out6.additionalDirectories = [...host.additionalDirectories ?? []]), out6.additionalReadDirectories === void 0 && (host.additionalReadDirectories?.length ?? 0) > 0 && (out6.additionalReadDirectories = [...host.additionalReadDirectories ?? []]), out6.forwardSubagentEvents === void 0 && (out6.forwardSubagentEvents = !0), out6.retainSubagentSessions === void 0 && (out6.retainSubagentSessions = !0), out6.agents === void 0 && host.agents !== void 0 && (out6.agents = host.agents), typeof out6.scenario == "string" && host.mockScenarioKeys?.has(out6.scenario) && delete out6.scenario, host.selfKnowledge !== void 0)
60304
60334
  if (host.appendSystemPromptCapable)
60305
60335
  out6.appendSystemPrompt = host.selfKnowledge.forAppend;
60306
60336
  else {
@@ -60387,6 +60417,7 @@ var REQUEST_FIELD_MATRIX, LIVE_DEFAULT_FIELDS, laneHas, init_taskRequest = __esm
60387
60417
  ], LIVE_DEFAULT_FIELDS = [
60388
60418
  "cwd",
60389
60419
  "additionalDirectories",
60420
+ "additionalReadDirectories",
60390
60421
  "forwardSubagentEvents",
60391
60422
  "retainSubagentSessions",
60392
60423
  "agents",
@@ -61009,17 +61040,21 @@ function engineWireTarget() {
61009
61040
  }
61010
61041
  function engineWireTargetFor(sessionKey) {
61011
61042
  let installed3 = installedByKey.get(sessionKey) ?? null;
61012
- if (installed3 !== null)
61013
- return installed3;
61043
+ if (installed3 !== null) {
61044
+ if (normalizeWirePrincipal(installed3.principal) === installed3.principal)
61045
+ return installed3;
61046
+ let { principal: _dropped, ...rest } = installed3;
61047
+ return rest;
61048
+ }
61014
61049
  let env5 = hostEnv(), baseUrl = env5.SEMA_LIVE_BASEURL;
61015
- return baseUrl ? {
61050
+ if (!baseUrl)
61051
+ return null;
61052
+ let envPrincipal = normalizeWirePrincipal(env5.SEMA_LIVE_PRINCIPAL);
61053
+ return {
61016
61054
  baseUrl,
61017
- // principal must match the run's owner (stamped by the live stream) — the owner-gated routes answer
61018
- // 404 for non-owners (no existence oracle). F-011 停发([3279]):缺席=不发头,owner-null 两侧
61019
- // 对齐(server 7.8.1 读写面窄互认盖存量);显式 SEMA_LIVE_PRINCIPAL 恒赢,绝不铸哨兵值。
61020
61055
  ...env5.SEMA_LIVE_TOKEN ? { token: env5.SEMA_LIVE_TOKEN } : {},
61021
- ...env5.SEMA_LIVE_PRINCIPAL ? { principal: env5.SEMA_LIVE_PRINCIPAL } : {}
61022
- } : null;
61056
+ ...envPrincipal !== void 0 ? { principal: envPrincipal } : {}
61057
+ };
61023
61058
  }
61024
61059
  function engineWireDebugEnabled() {
61025
61060
  return !!hostEnv().SEMA_DEBUG;
@@ -61028,6 +61063,7 @@ var installedByKey, init_engineWireTarget = __esm({
61028
61063
  "node_modules/@sema-agent/client-core/dist/engineWireTarget.js"() {
61029
61064
  init_hostEnv();
61030
61065
  init_sessionSlot();
61066
+ init_principalWire();
61031
61067
  installedByKey = createSessionSlot();
61032
61068
  }
61033
61069
  });
@@ -61861,6 +61897,92 @@ var capByBase2, CAP_FALSE_RETRY_TTL_MS2, activeTails, activitySink, init_engineS
61861
61897
  }
61862
61898
  });
61863
61899
 
61900
+ // node_modules/@sema-agent/client-core/dist/wireErrorTriage.js
61901
+ function wireErrorDetail(err8) {
61902
+ let e = err8, cause = e?.cause;
61903
+ return typeof cause?.message == "string" && cause.message.length > 0 && cause.message || typeof e?.message == "string" && e.message.length > 0 && e.message || String(err8);
61904
+ }
61905
+ function classifyTurnWireError(err8) {
61906
+ let e = err8;
61907
+ if (typeof e?.status == "number") {
61908
+ let errorCode = typeof e.errorCode == "string" && e.errorCode.length > 0 ? e.errorCode : void 0, message = typeof e.message == "string" && e.message.length > 0 ? e.message : String(err8);
61909
+ return { kind: "http", status: e.status, ...errorCode !== void 0 ? { errorCode } : {}, message };
61910
+ }
61911
+ if ((typeof err8 == "object" && err8 !== null && typeof err8.name == "string" ? err8.name : void 0) === "StreamEndedWithoutTerminalError")
61912
+ return { kind: "stream-ended-without-terminal" };
61913
+ let detail = wireErrorDetail(err8);
61914
+ return e?.cause !== void 0 || WIRE_NETWORK_ERROR_PATTERN.test(detail) ? { kind: "transport", detail } : { kind: "internal", name: err8 instanceof Error ? err8.name : typeof err8, detail };
61915
+ }
61916
+ function isWireTransportError(err8) {
61917
+ let e = err8;
61918
+ return typeof e?.status == "number" ? !1 : e?.cause !== void 0 || WIRE_NETWORK_ERROR_PATTERN.test(wireErrorDetail(err8));
61919
+ }
61920
+ function isPreStreamDrainingReject(err8) {
61921
+ let e = err8;
61922
+ return typeof e?.status == "number" && e.status === 503 && e.errorCode === DRAINING_ERROR_CODE;
61923
+ }
61924
+ function isResumeAtRejection(err8) {
61925
+ let e = err8;
61926
+ return typeof e?.errorCode == "string" && e.errorCode.startsWith(RESUME_AT_ERROR_CODE_PREFIX);
61927
+ }
61928
+ function drainingRetryDelayMs(err8, attempt, opts) {
61929
+ let ra = err8?.retryAfterMs;
61930
+ if (typeof ra == "number" && Number.isFinite(ra) && ra >= 0)
61931
+ return Math.min(ra, opts?.retryAfterCapMs ?? 15e3);
61932
+ let ladder = opts?.ladder && opts.ladder.length > 0 ? opts.ladder : [1e3, 2e3, 4e3];
61933
+ return ladder[Math.min(attempt, ladder.length - 1)] ?? 1e3;
61934
+ }
61935
+ function scenarioDenyFromError(err8) {
61936
+ if (typeof err8 != "object" || err8 === null)
61937
+ return null;
61938
+ let e = err8;
61939
+ return e.status !== 400 || e.errorCode !== SCENARIO_NOT_ALLOWED_ERROR_CODE ? null : { allowlist: Array.isArray(e.allowlist) ? e.allowlist.filter((x3) => typeof x3 == "string" && x3.length > 0) : [] };
61940
+ }
61941
+ var WIRE_NETWORK_ERROR_PATTERN, init_wireErrorTriage = __esm({
61942
+ "node_modules/@sema-agent/client-core/dist/wireErrorTriage.js"() {
61943
+ init_engineErrorCodes();
61944
+ WIRE_NETWORK_ERROR_PATTERN = /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|EHOSTUNREACH|ENETUNREACH|EPIPE|socket hang up|UND_ERR|terminated|other side closed/i;
61945
+ }
61946
+ });
61947
+
61948
+ // node_modules/@sema-agent/client-core/dist/sessionMap.js
61949
+ function engineNamespaceKeyFor(baseUrl) {
61950
+ if (!baseUrl)
61951
+ return "local";
61952
+ try {
61953
+ return new URL(baseUrl).origin.toLowerCase();
61954
+ } catch {
61955
+ return baseUrl.toLowerCase();
61956
+ }
61957
+ }
61958
+ function mergeSessionMapRecord(prior, partial2, now2 = isoNow) {
61959
+ let shellSessionId = partial2.shellSessionId ?? prior?.shellSessionId;
61960
+ return shellSessionId ? { ok: !0, record: { ...prior, ...partial2, shellSessionId, updatedAt: now2() } } : { ok: !1, reason: "no-shell-session-id" };
61961
+ }
61962
+ function mergeEngineEntry(prior, key, partial2, shellSessionId, now2 = isoNow) {
61963
+ let priorEntry = prior?.engines?.[key], engineSessionId = partial2.engineSessionId ?? priorEntry?.engineSessionId;
61964
+ if (!engineSessionId)
61965
+ return { ok: !1, reason: "no-engine-session-id" };
61966
+ let sid = shellSessionId ?? prior?.shellSessionId;
61967
+ if (!sid)
61968
+ return { ok: !1, reason: "no-shell-session-id" };
61969
+ let entry = { ...priorEntry, ...partial2, engineSessionId, updatedAt: now2() };
61970
+ return {
61971
+ ok: !0,
61972
+ record: {
61973
+ ...prior,
61974
+ shellSessionId: sid,
61975
+ engines: { ...prior?.engines, [key]: entry },
61976
+ updatedAt: now2()
61977
+ }
61978
+ };
61979
+ }
61980
+ var isoNow, init_sessionMap = __esm({
61981
+ "node_modules/@sema-agent/client-core/dist/sessionMap.js"() {
61982
+ isoNow = () => (/* @__PURE__ */ new Date()).toISOString();
61983
+ }
61984
+ });
61985
+
61864
61986
  // node_modules/@sema-agent/client-core/dist/detachWire.js
61865
61987
  function headlessDetachDisabledByEnv(env5 = hostEnv()) {
61866
61988
  return envFlagOff(env5[HEADLESS_DETACH_ENV]);
@@ -64892,11 +65014,30 @@ function setFor(sessionKey) {
64892
65014
  let s = armedGatesByKey.get(sessionKey);
64893
65015
  return s || (s = /* @__PURE__ */ new Set(), armedGatesByKey.set(sessionKey, s)), s;
64894
65016
  }
65017
+ function listenersFor(sessionKey) {
65018
+ let s = armedListenersByKey.get(sessionKey);
65019
+ return s || (s = /* @__PURE__ */ new Set(), armedListenersByKey.set(sessionKey, s)), s;
65020
+ }
65021
+ function genMapFor(sessionKey) {
65022
+ let m2 = planReviewGenByKey.get(sessionKey);
65023
+ return m2 || (m2 = /* @__PURE__ */ new Map(), planReviewGenByKey.set(sessionKey, m2)), m2;
65024
+ }
65025
+ function notedIdsFor(sessionKey) {
65026
+ let s = notedPlanReviewIdsByKey.get(sessionKey);
65027
+ return s || (s = /* @__PURE__ */ new Set(), notedPlanReviewIdsByKey.set(sessionKey, s)), s;
65028
+ }
65029
+ function emitGateArmedEventFor(sessionKey, key) {
65030
+ for (let listener5 of [...listenersFor(sessionKey)])
65031
+ try {
65032
+ listener5(key);
65033
+ } catch {
65034
+ }
65035
+ }
64895
65036
  function registerArmedGate(key) {
64896
65037
  registerArmedGateFor(DEFAULT_SESSION_KEY, key);
64897
65038
  }
64898
65039
  function registerArmedGateFor(sessionKey, key) {
64899
- typeof key == "string" && key.length > 0 && setFor(sessionKey).add(key);
65040
+ typeof key != "string" || key.length === 0 || (setFor(sessionKey).add(key), emitGateArmedEventFor(sessionKey, key));
64900
65041
  }
64901
65042
  function wasGateArmed(key) {
64902
65043
  return wasGateArmedFor(DEFAULT_SESSION_KEY, key);
@@ -64910,20 +65051,86 @@ function clearArmedGate(key) {
64910
65051
  function clearArmedGateFor(sessionKey, key) {
64911
65052
  typeof key == "string" && key.length > 0 && armedGatesByKey.get(sessionKey)?.delete(key);
64912
65053
  }
65054
+ function onGateArmed(listener5) {
65055
+ return onGateArmedFor(DEFAULT_SESSION_KEY, listener5);
65056
+ }
65057
+ function onGateArmedFor(sessionKey, listener5) {
65058
+ let listeners10 = listenersFor(sessionKey);
65059
+ return listeners10.add(listener5), () => {
65060
+ listeners10.delete(listener5);
65061
+ };
65062
+ }
65063
+ function _setGateArmedWaitMsForTest(ms) {
65064
+ gateArmedWaitOverrideMs = ms;
65065
+ }
65066
+ function gateArmedWaitMs() {
65067
+ return gateArmedWaitOverrideMs ?? GATE_ARMED_WAIT_MS;
65068
+ }
65069
+ function waitForGateArmed(keys2, timeoutMs) {
65070
+ return waitForGateArmedFor(DEFAULT_SESSION_KEY, keys2, timeoutMs);
65071
+ }
65072
+ function waitForGateArmedFor(sessionKey, keys2, timeoutMs) {
65073
+ let wanted = new Set(keys2.filter((k2) => typeof k2 == "string" && k2.length > 0));
65074
+ if (wanted.size === 0)
65075
+ return Promise.resolve(!1);
65076
+ let listeners10 = listenersFor(sessionKey);
65077
+ return new Promise((resolve57) => {
65078
+ let listener5 = (key) => {
65079
+ wanted.has(key) && (listeners10.delete(listener5), clearTimeout(timer2), resolve57(!0));
65080
+ };
65081
+ listeners10.add(listener5);
65082
+ let timer2 = setTimeout(() => {
65083
+ listeners10.delete(listener5), resolve57(!1);
65084
+ }, timeoutMs);
65085
+ });
65086
+ }
65087
+ function armedKeyForQuestionIdFor(sessionKey, questionId) {
65088
+ let base = armedKeyFromQuestionId(questionId);
65089
+ return base.startsWith(PLAN_REVIEW_QUESTION_ID_PREFIX) ? planReviewArmedKeyFor(sessionKey, base.slice(PLAN_REVIEW_QUESTION_ID_PREFIX.length)) : base;
65090
+ }
64913
65091
  function registerArmedGateFromQuestionId(questionId) {
64914
65092
  registerArmedGateFromQuestionIdFor(DEFAULT_SESSION_KEY, questionId);
64915
65093
  }
64916
65094
  function registerArmedGateFromQuestionIdFor(sessionKey, questionId) {
64917
- typeof questionId != "string" || questionId.length === 0 || registerArmedGateFor(sessionKey, armedKeyFromQuestionId(questionId));
65095
+ if (typeof questionId != "string" || questionId.length === 0)
65096
+ return;
65097
+ questionId.startsWith(PLAN_REVIEW_QUESTION_ID_PREFIX) && !questionId.includes(REOPEN_ID_TAIL) && notedPlanReviewIdsByKey.get(sessionKey)?.delete(questionId);
65098
+ let normalized = armedKeyForQuestionIdFor(sessionKey, questionId);
65099
+ registerArmedGateFor(sessionKey, normalized), questionId !== normalized && emitGateArmedEventFor(sessionKey, questionId);
65100
+ }
65101
+ function planReviewArmedKey(taskId) {
65102
+ return planReviewArmedKeyFor(DEFAULT_SESSION_KEY, taskId);
65103
+ }
65104
+ function planReviewArmedKeyFor(sessionKey, taskId) {
65105
+ let gen = planReviewGenByKey.get(sessionKey)?.get(taskId) ?? 0, canonical2 = planReviewQuestionId(taskId);
65106
+ return gen > 0 ? `${canonical2}#g${String(gen)}` : canonical2;
65107
+ }
65108
+ function notePlanReviewAnswered(questionId) {
65109
+ notePlanReviewAnsweredFor(DEFAULT_SESSION_KEY, questionId);
65110
+ }
65111
+ function notePlanReviewAnsweredFor(sessionKey, questionId) {
65112
+ if (typeof questionId != "string" || !questionId.startsWith(PLAN_REVIEW_QUESTION_ID_PREFIX))
65113
+ return;
65114
+ let noted = notedIdsFor(sessionKey);
65115
+ if (noted.has(questionId))
65116
+ return;
65117
+ noted.add(questionId);
65118
+ let base = questionId.slice(PLAN_REVIEW_QUESTION_ID_PREFIX.length), cut = base.indexOf(REOPEN_ID_TAIL), taskId = cut >= 0 ? base.slice(0, cut) : base;
65119
+ if (taskId.length === 0)
65120
+ return;
65121
+ clearArmedGateFor(sessionKey, planReviewArmedKeyFor(sessionKey, taskId));
65122
+ let gens = genMapFor(sessionKey);
65123
+ gens.set(taskId, (gens.get(taskId) ?? 0) + 1);
64918
65124
  }
64919
65125
  function _resetArmedGateRegistryForTest() {
64920
- armedGatesByKey.clear();
65126
+ armedGatesByKey.clear(), armedListenersByKey.clear(), planReviewGenByKey.clear(), notedPlanReviewIdsByKey.clear();
64921
65127
  }
64922
- var armedGatesByKey, init_armedGateRegistry = __esm({
65128
+ var armedGatesByKey, armedListenersByKey, planReviewGenByKey, notedPlanReviewIdsByKey, GATE_ARMED_WAIT_MS, gateArmedWaitOverrideMs, init_armedGateRegistry = __esm({
64923
65129
  "node_modules/@sema-agent/client-core/dist/hitl/armedGateRegistry.js"() {
64924
65130
  init_sessionSlot();
64925
65131
  init_gateIdentity();
64926
- armedGatesByKey = createSessionSlot();
65132
+ armedGatesByKey = createSessionSlot(), armedListenersByKey = createSessionSlot(), planReviewGenByKey = createSessionSlot(), notedPlanReviewIdsByKey = createSessionSlot();
65133
+ GATE_ARMED_WAIT_MS = 5e3, gateArmedWaitOverrideMs = null;
64927
65134
  }
64928
65135
  });
64929
65136
 
@@ -64932,6 +65139,12 @@ function planReviewDecisionFromAnswer(answer) {
64932
65139
  let selected = answer?.answers?.[0]?.selected?.[0];
64933
65140
  return selected === APPROVE_LABEL ? "approve" : selected === REJECT_LABEL ? "reject" : "dismissed";
64934
65141
  }
65142
+ function notePlanReviewAnsweredIfDecisive(questionId, answer) {
65143
+ notePlanReviewAnsweredIfDecisiveFor(DEFAULT_SESSION_KEY, questionId, answer);
65144
+ }
65145
+ function notePlanReviewAnsweredIfDecisiveFor(sessionKey, questionId, answer) {
65146
+ planReviewDecisionFromAnswer(answer ?? { answers: [] }) !== "dismissed" && notePlanReviewAnsweredFor(sessionKey, questionId);
65147
+ }
64935
65148
  function isPlanReviewPark(result) {
64936
65149
  let r = result;
64937
65150
  return !!r && r.status === "needs_review" && r.checkpointGate?.kind === "plan_review" && typeof r.taskId == "string" && r.taskId.length > 0;
@@ -64974,7 +65187,7 @@ function armPlanReviewApproval(result) {
64974
65187
  let questionId = planReviewQuestionId(taskId), unregister = registerLocalQuestionResponder(questionId, async (_id, answer) => {
64975
65188
  unregister(), armedPlanReviewTaskIds.delete(taskId);
64976
65189
  let decided = planReviewDecisionFromAnswer(answer);
64977
- return decided === "dismissed" ? { ok: !0 } : (clearArmedGate(planReviewQuestionId(taskId)), decidePlanReview(taskId, decided), { ok: !0 });
65190
+ return decided === "dismissed" ? { ok: !0 } : (notePlanReviewAnswered(questionId), decidePlanReview(taskId, decided), { ok: !0 });
64978
65191
  });
64979
65192
  return publishPlanReviewCard(taskId), hostLog("debug", `planReviewWire: approval card armed for parked plan (task ${taskId})`), !0;
64980
65193
  } catch (e) {
@@ -65049,19 +65262,29 @@ function _resetActiveReopenRespondersForTest() {
65049
65262
  activeReopenResponders.clear();
65050
65263
  }
65051
65264
  function reopenPlanReviewCard(taskId, opts) {
65265
+ let receiptMs = opts?.presentationReceiptMs, settleOnReceipt = (receipt, firstSight) => receipt.then((presented) => presented ? { reopened: !0, firstSight } : { reopened: !1 }, () => ({ reopened: !1 }));
65052
65266
  try {
65053
65267
  if (typeof taskId != "string" || taskId.length === 0)
65054
- return { reopened: !1 };
65268
+ return receiptMs === void 0 ? { reopened: !1 } : Promise.resolve({ reopened: !1 });
65055
65269
  let sessionKey = opts?.sessionKey ?? DEFAULT_SESSION_KEY;
65056
65270
  if (!hasQuestionOverlayFor(sessionKey))
65057
- return { reopened: !1 };
65058
- let canonicalId = planReviewQuestionId(taskId), firstSight = !wasGateArmedFor(sessionKey, canonicalId);
65059
- if (!(opts?.mintFreshQuestionId !== !1) && hasLocalQuestionResponder(canonicalId))
65060
- return opts?.deliverDecision !== void 0 && hostLog("debug", `planReviewWire: reopen canonical-reuse branch for task ${taskId} ignores opts.deliverDecision (answers route through the existing arm responder \u2014 documented exception)`), retireActiveReopen(sessionKey, canonicalId), publishQuestionFrameFor(sessionKey, {
65271
+ return receiptMs === void 0 ? { reopened: !1 } : Promise.resolve({ reopened: !1 });
65272
+ let canonicalId = planReviewQuestionId(taskId), armedKey = planReviewArmedKeyFor(sessionKey, taskId), firstSight = !wasGateArmedFor(sessionKey, armedKey);
65273
+ if (!(opts?.mintFreshQuestionId !== !1) && hasLocalQuestionResponder(canonicalId)) {
65274
+ if (opts?.deliverDecision !== void 0 && hostLog("debug", `planReviewWire: reopen canonical-reuse branch for task ${taskId} ignores opts.deliverDecision (answers route through the existing arm responder \u2014 documented exception)`), retireActiveReopen(sessionKey, canonicalId), receiptMs !== void 0) {
65275
+ let receipt = waitForGateArmedFor(sessionKey, [canonicalId], receiptMs);
65276
+ return publishQuestionFrameFor(sessionKey, {
65277
+ type: "question",
65278
+ questionId: canonicalId,
65279
+ questions: planReviewQuestions(ARM_QUESTION)
65280
+ }), settleOnReceipt(receipt, firstSight);
65281
+ }
65282
+ return publishQuestionFrameFor(sessionKey, {
65061
65283
  type: "question",
65062
65284
  questionId: canonicalId,
65063
65285
  questions: planReviewQuestions(ARM_QUESTION)
65064
- }), registerArmedGateFor(sessionKey, canonicalId), { reopened: !0, firstSight };
65286
+ }), registerArmedGateFor(sessionKey, armedKey), { reopened: !0, firstSight };
65287
+ }
65065
65288
  retireActiveReopen(sessionKey, canonicalId), unregisterLocalQuestionResponder(canonicalId) && hostLog("debug", `planReviewWire: reopen retired the canonical responder for task ${taskId} (single-active discipline)`), publishQuestionFrameFor(sessionKey, { type: "question_complete", questionId: canonicalId });
65066
65289
  let questionId = `${canonicalId}${REOPEN_ID_TAIL}${reopenIdSuffix()}`, deliver = opts?.deliverDecision ?? ((tid, decision) => {
65067
65290
  decidePlanReview(tid, decision);
@@ -65070,7 +65293,7 @@ function reopenPlanReviewCard(taskId, opts) {
65070
65293
  let decided = planReviewDecisionFromAnswer(answer);
65071
65294
  if (decided === "dismissed")
65072
65295
  return { ok: !0 };
65073
- clearArmedGateFor(sessionKey, canonicalId);
65296
+ notePlanReviewAnsweredFor(sessionKey, questionId);
65074
65297
  try {
65075
65298
  await deliver(taskId, decided);
65076
65299
  } catch (e) {
@@ -65078,13 +65301,21 @@ function reopenPlanReviewCard(taskId, opts) {
65078
65301
  }
65079
65302
  return { ok: !0 };
65080
65303
  });
65081
- return activeReopenResponders.set(activeKey, { questionId, unregister }), registerArmedGateFor(sessionKey, canonicalId), publishQuestionFrameFor(sessionKey, {
65304
+ if (activeReopenResponders.set(activeKey, { questionId, unregister }), receiptMs !== void 0) {
65305
+ let receipt = waitForGateArmedFor(sessionKey, [questionId], receiptMs);
65306
+ return publishQuestionFrameFor(sessionKey, {
65307
+ type: "question",
65308
+ questionId,
65309
+ questions: planReviewQuestions(REOPEN_QUESTION)
65310
+ }), settleOnReceipt(receipt, firstSight);
65311
+ }
65312
+ return registerArmedGateFor(sessionKey, armedKey), publishQuestionFrameFor(sessionKey, {
65082
65313
  type: "question",
65083
65314
  questionId,
65084
65315
  questions: planReviewQuestions(REOPEN_QUESTION)
65085
65316
  }), { reopened: !0, firstSight };
65086
65317
  } catch {
65087
- return { reopened: !1 };
65318
+ return receiptMs === void 0 ? { reopened: !1 } : Promise.resolve({ reopened: !1 });
65088
65319
  }
65089
65320
  }
65090
65321
  var PLAN_REVIEW_RESUME_TIMEOUT_MS, PLAN_REVIEW_APPROVE_LABEL, PLAN_REVIEW_REJECT_LABEL, APPROVE_LABEL, REJECT_LABEL, armedPlanReviewTaskIds, ARM_QUESTION, REOPEN_QUESTION, activeReopenResponders, init_planReviewWire = __esm({
@@ -65106,9 +65337,12 @@ var PLAN_REVIEW_RESUME_TIMEOUT_MS, PLAN_REVIEW_APPROVE_LABEL, PLAN_REVIEW_REJECT
65106
65337
 
65107
65338
  // node_modules/@sema-agent/client-core/dist/hitl/parkOwnership.js
65108
65339
  function pendingRowIsOwnedByThisSession(row2, deps2) {
65109
- let sessionKey = deps2?.sessionKey ?? DEFAULT_SESSION_KEY, rowTaskId = typeof row2.taskId == "string" ? row2.taskId : "", ownRun = deps2?.isOwnRun ?? (sessionKey === DEFAULT_SESSION_KEY ? isOwnEngineRun : void 0);
65110
- if (ownRun !== void 0 && rowTaskId.length > 0 && ownRun(rowIdTail(rowTaskId)))
65111
- return !0;
65340
+ let sessionKey = deps2?.sessionKey ?? DEFAULT_SESSION_KEY, rowTaskId = typeof row2.taskId == "string" ? row2.taskId : "";
65341
+ if (rowTaskId.length > 0) {
65342
+ let tail = rowIdTail(rowTaskId);
65343
+ if (deps2?.isOwnRun !== void 0 && deps2.isOwnRun(tail) || sessionKey === DEFAULT_SESSION_KEY && isOwnEngineRun(tail))
65344
+ return !0;
65345
+ }
65112
65346
  let sessionId = (deps2?.currentSessionId ?? (() => hostSessionFor(sessionKey)?.currentSessionId()))(), rowSessionId = typeof row2.sessionId == "string" ? row2.sessionId : "";
65113
65347
  return typeof sessionId == "string" && sessionId.length > 0 && rowSessionId.length > 0 && rowSessionId === sessionId;
65114
65348
  }
@@ -65136,7 +65370,7 @@ function parkRowPollDelay(ms, signal) {
65136
65370
  return abortableSleep(ms, signal ?? new AbortController().signal);
65137
65371
  }
65138
65372
  async function waitForParkRowBirth(deps2) {
65139
- let now2 = typeof deps2.now == "function" ? deps2.now : () => Date.now(), sleep10 = typeof deps2.sleep == "function" ? deps2.sleep : parkRowPollDelay, budgetMs = Number.isFinite(deps2.budgetMs) && deps2.budgetMs > 0 ? deps2.budgetMs : 0, intervalMs = Number.isFinite(deps2.intervalMs) && deps2.intervalMs > 0 ? deps2.intervalMs : 1, startedAt = now2(), probes = 0, lastReason = "no decidable pending row for this park", aborted2 = () => deps2.signal?.aborted === !0, safeProbe = async (attempt, signal) => {
65373
+ let now2 = typeof deps2.now == "function" ? deps2.now : () => Date.now(), sleep9 = typeof deps2.sleep == "function" ? deps2.sleep : parkRowPollDelay, budgetMs = Number.isFinite(deps2.budgetMs) && deps2.budgetMs > 0 ? deps2.budgetMs : 0, intervalMs = Number.isFinite(deps2.intervalMs) && deps2.intervalMs > 0 ? deps2.intervalMs : 1, startedAt = now2(), probes = 0, lastReason = "no decidable pending row for this park", aborted2 = () => deps2.signal?.aborted === !0, safeProbe = async (attempt, signal) => {
65140
65374
  try {
65141
65375
  return await deps2.probe(attempt, signal);
65142
65376
  } catch (e) {
@@ -65203,7 +65437,7 @@ async function waitForParkRowBirth(deps2) {
65203
65437
  let remainingMs = budgetMs - (now2() - startedAt);
65204
65438
  if (remainingMs <= 0)
65205
65439
  return { kind: "unborn", reason: lastReason, waitedMs: now2() - startedAt, probes };
65206
- if (await sleep10(Math.min(intervalMs, remainingMs), deps2.signal), aborted2())
65440
+ if (await sleep9(Math.min(intervalMs, remainingMs), deps2.signal), aborted2())
65207
65441
  return { kind: "aborted", waitedMs: now2() - startedAt, probes };
65208
65442
  }
65209
65443
  }
@@ -65385,6 +65619,175 @@ var RESUME_CHOICE_ATTACH_LABEL, RESUME_CHOICE_CANCEL_LABEL, RESUME_CHOICE_BACKGR
65385
65619
  }
65386
65620
  });
65387
65621
 
65622
+ // node_modules/@sema-agent/client-core/dist/hitl/persistedRulesWire.js
65623
+ function persistedRulesLaneAvailable(baseUrl) {
65624
+ return engineCapTrue(baseUrl, "permissionRules");
65625
+ }
65626
+ function persistedRulesGovernanceAvailable(baseUrl) {
65627
+ return engineCapTrue(baseUrl, "permissionRulesRevoke") && engineCapTrue(baseUrl, "permissionRules");
65628
+ }
65629
+ function errShape(e) {
65630
+ let o = e ?? {};
65631
+ return {
65632
+ ...typeof o.status == "number" ? { status: o.status } : {},
65633
+ ...typeof o.errorCode == "string" ? { errorCode: o.errorCode } : {},
65634
+ message: typeof o.message == "string" && o.message !== "" ? o.message : String(e)
65635
+ };
65636
+ }
65637
+ function retryAfterSecOf(e) {
65638
+ let ms = e.retryAfterMs;
65639
+ if (!(typeof ms != "number" || !Number.isFinite(ms) || ms < 0))
65640
+ return Math.ceil(ms / 1e3);
65641
+ }
65642
+ function classifyRulesFailure(e) {
65643
+ let { status: status3, errorCode, message } = errShape(e);
65644
+ if (status3 === 501 || errorCode === "capability.rule_store_required")
65645
+ return { kind: "lane-unavailable", message };
65646
+ if (status3 === 404)
65647
+ return errorCode === "not_found.route" ? { kind: "route-missing", message } : errorCode === "not_found.rule_ticket" ? { kind: "ticket-dead", message } : { kind: "error", message };
65648
+ if (errorCode === "state.rule_import_retry") {
65649
+ let sec = retryAfterSecOf(e);
65650
+ return { kind: "retry-same-ticket", message, ...sec !== void 0 ? { retryAfterSec: sec } : {} };
65651
+ }
65652
+ return errorCode === "state.rule_remove_failed" ? { kind: "retryable", message } : status3 === 400 && errorCode === "request.query_invalid" ? { kind: "cursor-stale", message } : status3 === 413 ? { kind: "too-many-candidates", message } : status3 === 403 && errorCode === "auth.operator_only" ? { kind: "forbidden", message } : { kind: "error", message };
65653
+ }
65654
+ async function listAllPersistedRules(facade, params = {}, opts) {
65655
+ let { cursor: callerCursor, ...cleanParams3 } = params;
65656
+ callerCursor !== void 0 && hostLog("debug", "persistedRulesWire: caller-supplied cursor ignored by listAllPersistedRules \u2014 a drain that starts mid-keyset cannot prove completeness, so it always starts from the top");
65657
+ for (let attempt = 0; attempt < 2; attempt++) {
65658
+ let rules = [], cursor, rev2 = null, restart = !1;
65659
+ for (let page = 0; page < MAX_PAGES; page++) {
65660
+ let res;
65661
+ try {
65662
+ res = await facade.list({ limit: PAGE_LIMIT, ...cleanParams3, ...cursor !== void 0 ? { cursor } : {} }, opts);
65663
+ } catch (e) {
65664
+ let failure = classifyRulesFailure(e);
65665
+ if (failure.kind === "cursor-stale" && cursor !== void 0 && attempt === 0) {
65666
+ hostLog("debug", "persistedRulesWire: rule list cursor was minted on another rev/principal/scope \u2014 dropping it and re-listing from the top (never resuming a stale keyset)"), restart = !0;
65667
+ break;
65668
+ }
65669
+ return { ok: !1, failure };
65670
+ }
65671
+ if (typeof res != "object" || res === null || !Array.isArray(res.rules) || typeof res.rev != "number" || !Number.isFinite(res.rev))
65672
+ return {
65673
+ ok: !1,
65674
+ failure: {
65675
+ kind: "error",
65676
+ message: "rule list page was malformed (missing/ill-typed rules array or rev on a 2xx) \u2014 refusing to certify it as a complete governance list"
65677
+ }
65678
+ };
65679
+ if (rev2 !== null && res.rev !== rev2)
65680
+ return {
65681
+ ok: !1,
65682
+ failure: {
65683
+ kind: "error",
65684
+ message: `rule list rev changed mid-drain (page rev ${res.rev} \u2260 first page rev ${rev2}) on a 2xx \u2014 refusing to stitch a mixed snapshot into one governance list`
65685
+ }
65686
+ };
65687
+ for (let r of res.rules) {
65688
+ let rr = r;
65689
+ if (rr === null || typeof rr != "object" || typeof rr.rule != "string" || rr.rule === "" || typeof rr.scope != "string" || rr.scope === "")
65690
+ return {
65691
+ ok: !1,
65692
+ failure: {
65693
+ kind: "error",
65694
+ message: "rule list page carried a malformed rule row (missing/ill-typed rule or scope) \u2014 refusing to present a list that hides or garbles live rules"
65695
+ }
65696
+ };
65697
+ }
65698
+ rev2 = res.rev, rules.push(...res.rules);
65699
+ let next = res.nextCursor;
65700
+ if (next === void 0)
65701
+ return { ok: !0, rules, rev: rev2 };
65702
+ if (typeof next != "string" || next === "")
65703
+ return {
65704
+ ok: !1,
65705
+ failure: {
65706
+ kind: "error",
65707
+ message: "rule list page carried a malformed nextCursor (neither absent nor a non-empty string) \u2014 refusing to guess where the list ends"
65708
+ }
65709
+ };
65710
+ cursor = next;
65711
+ }
65712
+ if (!restart)
65713
+ return {
65714
+ ok: !1,
65715
+ failure: {
65716
+ kind: "error",
65717
+ message: `rule list did not terminate within ${MAX_PAGES} pages \u2014 refusing to present a partial governance list`
65718
+ }
65719
+ };
65720
+ }
65721
+ return { ok: !1, failure: { kind: "cursor-stale", message: "rule list kept changing under the cursor \u2014 try again" } };
65722
+ }
65723
+ function classifySkippedReason(reason) {
65724
+ let text2 = typeof reason == "string" ? reason : String(reason), idx = text2.indexOf(":");
65725
+ if (idx <= 0)
65726
+ return { text: text2 };
65727
+ let head = text2.slice(0, idx);
65728
+ return /^[a-z][a-z0-9_]*(\.[a-z0-9_]+)*$/.test(head) ? { code: head, text: text2 } : { text: text2 };
65729
+ }
65730
+ function readRulePersistOutcome(ack) {
65731
+ let parsed = readToolApprovalRespondAck(ack);
65732
+ return parsed === void 0 ? { state: "unknown" } : parsed.rulePersisted === !0 ? { state: "persisted" } : parsed.rulePersisted === !1 ? {
65733
+ state: "refused",
65734
+ ...typeof parsed.ruleRefusal == "string" ? { reason: parsed.ruleRefusal } : {}
65735
+ } : { state: "unknown" };
65736
+ }
65737
+ var PAGE_LIMIT, MAX_PAGES, init_persistedRulesWire = __esm({
65738
+ "node_modules/@sema-agent/client-core/dist/hitl/persistedRulesWire.js"() {
65739
+ init_engineCapsCache();
65740
+ init_host();
65741
+ init_toolApprovalWire();
65742
+ PAGE_LIMIT = 200, MAX_PAGES = 25;
65743
+ }
65744
+ });
65745
+
65746
+ // node_modules/@sema-agent/client-core/dist/hitl/localAllowRule.js
65747
+ function parseLocalAllowRule(rule, expectedToolName, deps2) {
65748
+ if (typeof rule != "string" || rule === "")
65749
+ return { ok: !1, error: "rule text is empty" };
65750
+ let value;
65751
+ try {
65752
+ value = deps2.parseRule(rule);
65753
+ } catch (e) {
65754
+ return { ok: !1, error: `rule text did not parse (${String(e)})` };
65755
+ }
65756
+ return typeof value.toolName != "string" || value.toolName === "" ? { ok: !1, error: "rule text carries no tool name" } : value.ruleContent === void 0 || value.ruleContent === "" ? {
65757
+ ok: !1,
65758
+ error: "candidate is a whole-tool allow rule (broader than this ask) \u2014 not offered locally"
65759
+ } : expectedToolName !== void 0 && value.toolName !== expectedToolName ? {
65760
+ ok: !1,
65761
+ error: `candidate names tool "${value.toolName}" but this ask is for "${expectedToolName}" \u2014 a rule for another tool would never match`
65762
+ } : hasLiteralAnchor(value.ruleContent) ? value.toolName === BASH_TOOL_NAME_FOR_RULES && deps2.bashRuleContentHasDangerousBarePrefix(value.ruleContent) ? {
65763
+ ok: !1,
65764
+ error: "candidate is a bare interpreter/wrapper prefix (bash/sh/env/sudo/\u2026) \u2014 persisting it would authorize arbitrary commands, not offered locally"
65765
+ } : deps2.isDangerousBashPermission(value.toolName, value.ruleContent) || deps2.isDangerousPowerShellPermission(value.toolName, value.ruleContent) ? {
65766
+ ok: !1,
65767
+ error: "candidate allow-rule matches a code-execution interpreter/wrapper pattern (python/node/eval/ssh/\u2026) \u2014 persisting it would authorize arbitrary code, not offered locally"
65768
+ } : { ok: !0, value, canonical: deps2.formatRule(value) } : {
65769
+ ok: !1,
65770
+ error: "candidate is all wildcard (matches every command for this tool) \u2014 equivalent to a whole-tool allow, not offered locally"
65771
+ };
65772
+ }
65773
+ function hasLiteralAnchor(ruleContent) {
65774
+ let out6 = "";
65775
+ for (let i = 0; i < ruleContent.length; i++) {
65776
+ let ch2 = ruleContent[i];
65777
+ if (ch2 === "\\" && i + 1 < ruleContent.length) {
65778
+ out6 += ruleContent[i + 1], i++;
65779
+ continue;
65780
+ }
65781
+ ch2 !== "*" && (out6 += ch2);
65782
+ }
65783
+ return out6.trim() !== "";
65784
+ }
65785
+ var BASH_TOOL_NAME_FOR_RULES, init_localAllowRule = __esm({
65786
+ "node_modules/@sema-agent/client-core/dist/hitl/localAllowRule.js"() {
65787
+ BASH_TOOL_NAME_FOR_RULES = "Bash";
65788
+ }
65789
+ });
65790
+
65388
65791
  // node_modules/@sema-agent/client-core/dist/hitl/approvalsFeed.js
65389
65792
  function digestOf(rows2) {
65390
65793
  return rows2.map((r) => [r.sessionId ?? "", r.taskId ?? "", r.toolCallId ?? "", r.boundCallId ?? "", r.boundInputHash ?? "", r.toolName ?? ""].join("")).sort().join("");
@@ -67067,6 +67470,7 @@ __export(dist_exports, {
67067
67470
  DEVICE_CODE_MAX_LIFETIME_MS: () => DEVICE_CODE_MAX_LIFETIME_MS,
67068
67471
  DEVICE_CODE_MIN_INTERVAL_MS: () => DEVICE_CODE_MIN_INTERVAL_MS,
67069
67472
  DIFF_TIMEOUT_MS: () => DIFF_TIMEOUT_MS,
67473
+ DRAINING_ERROR_CODE: () => DRAINING_ERROR_CODE,
67070
67474
  EDIT_NOT_FORWARDED_WARN_TEXT: () => EDIT_NOT_FORWARDED_WARN_TEXT,
67071
67475
  ENABLE_FORK_ENV: () => ENABLE_FORK_ENV,
67072
67476
  ENGINE_ABORT_TOOL_RESULT: () => ENGINE_ABORT_TOOL_RESULT,
@@ -67104,6 +67508,7 @@ __export(dist_exports, {
67104
67508
  HitlBridge: () => HitlBridge,
67105
67509
  HitlSafetyError: () => HitlSafetyError,
67106
67510
  IDLE_FLUSH_MS: () => IDLE_FLUSH_MS,
67511
+ INTERACTIVE_WAY_OUT: () => INTERACTIVE_WAY_OUT,
67107
67512
  INTERNAL_SDK_ARM_TYPES: () => INTERNAL_SDK_ARM_TYPES,
67108
67513
  LIMITS_MAX_COST_EXCEEDED: () => LIMITS_MAX_COST_EXCEEDED,
67109
67514
  LIMITS_MAX_TOKENS_EXCEEDED: () => LIMITS_MAX_TOKENS_EXCEEDED,
@@ -67152,6 +67557,7 @@ __export(dist_exports, {
67152
67557
  REMEMBER_NOT_APPLIED_WARN_TEXT: () => REMEMBER_NOT_APPLIED_WARN_TEXT,
67153
67558
  REOPEN_ID_TAIL: () => REOPEN_ID_TAIL,
67154
67559
  REQUEST_FIELD_MATRIX: () => REQUEST_FIELD_MATRIX,
67560
+ RESUME_AT_ERROR_CODE_PREFIX: () => RESUME_AT_ERROR_CODE_PREFIX,
67155
67561
  RESUME_CHOICE_ATTACH_LABEL: () => RESUME_CHOICE_ATTACH_LABEL,
67156
67562
  RESUME_CHOICE_BACKGROUND_LABEL: () => RESUME_CHOICE_BACKGROUND_LABEL,
67157
67563
  RESUME_CHOICE_CANCEL_LABEL: () => RESUME_CHOICE_CANCEL_LABEL,
@@ -67166,6 +67572,7 @@ __export(dist_exports, {
67166
67572
  SANDBOX_NO_IMAGE_INDEX_400_ANCHOR: () => SANDBOX_NO_IMAGE_INDEX_400_ANCHOR,
67167
67573
  SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR: () => SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR,
67168
67574
  SCENARIO_NAME_RE: () => SCENARIO_NAME_RE,
67575
+ SCENARIO_NOT_ALLOWED_ERROR_CODE: () => SCENARIO_NOT_ALLOWED_ERROR_CODE,
67169
67576
  SDK_DEFAULT_GRACE_MS: () => SDK_DEFAULT_GRACE_MS,
67170
67577
  SEARCH_PROVIDER_PRESETS: () => SEARCH_PROVIDER_PRESETS,
67171
67578
  SEAT_CHROME_ENVELOPE_KEYS: () => SEAT_CHROME_ENVELOPE_KEYS,
@@ -67213,6 +67620,7 @@ __export(dist_exports, {
67213
67620
  WEB_SEARCH_ENV_KEYS: () => WEB_SEARCH_ENV_KEYS,
67214
67621
  WEB_SEARCH_MAX_RESULTS_MAX: () => WEB_SEARCH_MAX_RESULTS_MAX,
67215
67622
  WEB_SEARCH_MAX_RESULTS_MIN: () => WEB_SEARCH_MAX_RESULTS_MIN,
67623
+ WIRE_NETWORK_ERROR_PATTERN: () => WIRE_NETWORK_ERROR_PATTERN,
67216
67624
  WORKFLOW_DEFER_ENV: () => WORKFLOW_DEFER_ENV,
67217
67625
  WORKFLOW_TOOL_NAMES: () => WORKFLOW_TOOL_NAMES,
67218
67626
  __activeTailCountForTests: () => __activeTailCountForTests,
@@ -67245,6 +67653,7 @@ __export(dist_exports, {
67245
67653
  _resetNotificationQueuePortForTest: () => _resetNotificationQueuePortForTest,
67246
67654
  _resetScratchpadEnsuredForTest: () => _resetScratchpadEnsuredForTest,
67247
67655
  _resetUltracodePreset: () => _resetUltracodePreset,
67656
+ _setGateArmedWaitMsForTest: () => _setGateArmedWaitMsForTest,
67248
67657
  _setWatcherTimingForTest: () => _setWatcherTimingForTest,
67249
67658
  _tickWatchOnceForTest: () => _tickWatchOnceForTest,
67250
67659
  activeEngineRunId: () => activeEngineRunId,
@@ -67290,7 +67699,10 @@ __export(dist_exports, {
67290
67699
  classifyAskParkChainFailure: () => classifyAskParkChainFailure,
67291
67700
  classifyAskParkRows: () => classifyAskParkRows,
67292
67701
  classifyHookNoticeFrame: () => classifyHookNoticeFrame,
67702
+ classifyRulesFailure: () => classifyRulesFailure,
67703
+ classifySkippedReason: () => classifySkippedReason,
67293
67704
  classifyTaskStopConflict: () => classifyTaskStopConflict,
67705
+ classifyTurnWireError: () => classifyTurnWireError,
67294
67706
  clearAllRetainedFleetRows: () => clearAllRetainedFleetRows,
67295
67707
  clearAllRetainedFleetRowsFor: () => clearAllRetainedFleetRowsFor,
67296
67708
  clearArmedGate: () => clearArmedGate,
@@ -67335,6 +67747,7 @@ __export(dist_exports, {
67335
67747
  deviceAuthProviderFor: () => deviceAuthProviderFor,
67336
67748
  diagnoseSseIdleTear: () => diagnoseSseIdleTear,
67337
67749
  doneToSdkResult: () => doneToSdkResult,
67750
+ drainingRetryDelayMs: () => drainingRetryDelayMs,
67338
67751
  dropQueuedNotificationsForRun: () => dropQueuedNotificationsForRun,
67339
67752
  effortToReasoningEffort: () => effortToReasoningEffort,
67340
67753
  enableForkFromEnv: () => enableForkFromEnv,
@@ -67345,6 +67758,7 @@ __export(dist_exports, {
67345
67758
  engineCapsSettled: () => engineCapsSettled,
67346
67759
  engineCcStopSemantics: () => engineCcStopSemantics,
67347
67760
  engineLimitsSupportWarning: () => engineLimitsSupportWarning,
67761
+ engineNamespaceKeyFor: () => engineNamespaceKeyFor,
67348
67762
  engineOwnedRowIds: () => engineOwnedRowIds,
67349
67763
  engineRowNeedsStopConfirm: () => engineRowNeedsStopConfirm,
67350
67764
  engineSessionParam: () => engineSessionParam,
@@ -67379,6 +67793,7 @@ __export(dist_exports, {
67379
67793
  fleetViewStubRowIds: () => fleetViewStubRowIds,
67380
67794
  fmtCtxOut: () => fmtCtxOut,
67381
67795
  fmtTokens: () => fmtTokens,
67796
+ gateArmedWaitMs: () => gateArmedWaitMs,
67382
67797
  gateKind: () => gateKind,
67383
67798
  getBgParentRun: () => getBgParentRun,
67384
67799
  getBgTerminalFacts: () => getBgTerminalFacts,
@@ -67462,6 +67877,8 @@ __export(dist_exports, {
67462
67877
  isOwnEngineRun: () => isOwnEngineRun,
67463
67878
  isOwnWorkflowRun: () => isOwnWorkflowRun,
67464
67879
  isPlanReviewPark: () => isPlanReviewPark,
67880
+ isPreStreamDrainingReject: () => isPreStreamDrainingReject,
67881
+ isResumeAtRejection: () => isResumeAtRejection,
67465
67882
  isRewindFamilyCode: () => isRewindFamilyCode,
67466
67883
  isRunStreamActive: () => isRunStreamActive,
67467
67884
  isSeatModelCatalog: () => isSeatModelCatalog,
@@ -67472,10 +67889,12 @@ __export(dist_exports, {
67472
67889
  isToolApprovalFrame: () => isToolApprovalFrame,
67473
67890
  isToolApprovalGate: () => isToolApprovalGate,
67474
67891
  isToolPermissionRequest: () => isToolPermissionRequest,
67892
+ isWireTransportError: () => isWireTransportError,
67475
67893
  isWorkflowAgentTaskId: () => isWorkflowAgentTaskId,
67476
67894
  isWorkflowCompletionCardEnqueued: () => isWorkflowCompletionCardEnqueued,
67477
67895
  kickEngineCapsProbe: () => kickEngineCapsProbe,
67478
67896
  limitsForPrint: () => limitsForPrint,
67897
+ listAllPersistedRules: () => listAllPersistedRules,
67479
67898
  listNotifiedRuns: () => listNotifiedRuns,
67480
67899
  listOwnWorkflowRuns: () => listOwnWorkflowRuns,
67481
67900
  listWorkflowCompletionCardsEnqueued: () => listWorkflowCompletionCardsEnqueued,
@@ -67492,7 +67911,9 @@ __export(dist_exports, {
67492
67911
  markUserModelPickThisSession: () => markUserModelPickThisSession,
67493
67912
  mcpConfigToSpec: () => mcpConfigToSpec,
67494
67913
  mcpConfigsToSpecs: () => mcpConfigsToSpecs,
67914
+ mergeEngineEntry: () => mergeEngineEntry,
67495
67915
  mergeProviderLayers: () => mergeProviderLayers,
67916
+ mergeSessionMapRecord: () => mergeSessionMapRecord,
67496
67917
  mergeTaskOutput: () => mergeTaskOutput,
67497
67918
  modelFacingParseCalls: () => modelFacingParseCalls,
67498
67919
  modelFromAppState: () => modelFromAppState,
@@ -67500,11 +67921,18 @@ __export(dist_exports, {
67500
67921
  normalizeLiveModelRef: () => normalizeLiveModelRef,
67501
67922
  normalizeShellPermissionModeForWire: () => normalizeShellPermissionModeForWire,
67502
67923
  normalizeTaskNotification: () => normalizeTaskNotification,
67924
+ normalizeWirePrincipal: () => normalizeWirePrincipal,
67925
+ notePlanReviewAnswered: () => notePlanReviewAnswered,
67926
+ notePlanReviewAnsweredFor: () => notePlanReviewAnsweredFor,
67927
+ notePlanReviewAnsweredIfDecisive: () => notePlanReviewAnsweredIfDecisive,
67928
+ notePlanReviewAnsweredIfDecisiveFor: () => notePlanReviewAnsweredIfDecisiveFor,
67503
67929
  noteWorkflowCompletionCardEnqueued: () => noteWorkflowCompletionCardEnqueued,
67504
67930
  notificationDropCounters: () => notificationDropCounters,
67505
67931
  notificationQueuePortMisses: () => notificationQueuePortMisses,
67506
67932
  observeCancelByDeny: () => observeCancelByDeny,
67507
67933
  onEngineTaskBound: () => onEngineTaskBound,
67934
+ onGateArmed: () => onGateArmed,
67935
+ onGateArmedFor: () => onGateArmedFor,
67508
67936
  onQuestionFrame: () => onQuestionFrame,
67509
67937
  onQuestionFrameFor: () => onQuestionFrameFor,
67510
67938
  oneShotFromEnv: () => oneShotFromEnv,
@@ -67518,6 +67946,7 @@ __export(dist_exports, {
67518
67946
  parseCatalogSources: () => parseCatalogSources,
67519
67947
  parseFinalVerifyArgv: () => parseFinalVerifyArgv,
67520
67948
  parseLimitsArgv: () => parseLimitsArgv,
67949
+ parseLocalAllowRule: () => parseLocalAllowRule,
67521
67950
  parseModelFacingBash: () => parseModelFacingBash,
67522
67951
  parseModelFacingTaskOutput: () => parseModelFacingTaskOutput,
67523
67952
  parseNoFinalVerifyArgv: () => parseNoFinalVerifyArgv,
@@ -67528,9 +67957,13 @@ __export(dist_exports, {
67528
67957
  pendingRowIsOwnedByThisSession: () => pendingRowIsOwnedByThisSession,
67529
67958
  permissionModeField: () => permissionModeField,
67530
67959
  permissionModeFromArgv: () => permissionModeFromArgv,
67960
+ persistedRulesGovernanceAvailable: () => persistedRulesGovernanceAvailable,
67961
+ persistedRulesLaneAvailable: () => persistedRulesLaneAvailable,
67531
67962
  pickCheapCandidate: () => pickCheapCandidate,
67532
67963
  pickDelegatedPrompt: () => pickDelegatedPrompt,
67533
67964
  planModeExplicitlyRequested: () => planModeExplicitlyRequested,
67965
+ planReviewArmedKey: () => planReviewArmedKey,
67966
+ planReviewArmedKeyFor: () => planReviewArmedKeyFor,
67534
67967
  planReviewDecisionFromAnswer: () => planReviewDecisionFromAnswer,
67535
67968
  planReviewQuestionId: () => planReviewQuestionId,
67536
67969
  planSubagentViewSlots: () => planSubagentViewSlots,
@@ -67562,6 +67995,7 @@ __export(dist_exports, {
67562
67995
  readDecisionNoteAudit: () => readDecisionNoteAudit,
67563
67996
  readEngineActiveBgTasks: () => readEngineActiveBgTasks,
67564
67997
  readEngineActiveBgTasksFor: () => readEngineActiveBgTasksFor,
67998
+ readRulePersistOutcome: () => readRulePersistOutcome,
67565
67999
  readSteerDelivery: () => readSteerDelivery,
67566
68000
  readSteerReceiptStatus: () => readSteerReceiptStatus,
67567
68001
  readToolApprovalRespondAck: () => readToolApprovalRespondAck,
@@ -67617,6 +68051,7 @@ __export(dist_exports, {
67617
68051
  sandboxDegradeHint: () => sandboxDegradeHint,
67618
68052
  sandboxRequestFields: () => sandboxRequestFields,
67619
68053
  sanitizeToolUseBlock: () => sanitizeToolUseBlock,
68054
+ scenarioDenyFromError: () => scenarioDenyFromError,
67620
68055
  scenarioForPrint: () => scenarioForPrint,
67621
68056
  scratchpadDirField: () => scratchpadDirField,
67622
68057
  searchPresetTableViolations: () => searchPresetTableViolations,
@@ -67690,6 +68125,8 @@ __export(dist_exports, {
67690
68125
  versionSupportsDetach: () => versionSupportsDetach,
67691
68126
  versionSupportsLimits: () => versionSupportsLimits,
67692
68127
  waitForClaimRelease: () => waitForClaimRelease,
68128
+ waitForGateArmed: () => waitForGateArmed,
68129
+ waitForGateArmedFor: () => waitForGateArmedFor,
67693
68130
  waitForParkRowBirth: () => waitForParkRowBirth,
67694
68131
  wasGateArmed: () => wasGateArmed,
67695
68132
  wasGateArmedFor: () => wasGateArmedFor,
@@ -67789,6 +68226,9 @@ var init_dist = __esm({
67789
68226
  init_engineSubagentTail();
67790
68227
  init_engineSessionParam();
67791
68228
  init_engineWireTarget();
68229
+ init_principalWire();
68230
+ init_wireErrorTriage();
68231
+ init_sessionMap();
67792
68232
  init_detachWire();
67793
68233
  init_workflowMonitor();
67794
68234
  init_workflowClient();
@@ -67809,6 +68249,8 @@ var init_dist = __esm({
67809
68249
  init_approvalDecisionNoteAudit();
67810
68250
  init_askParkRowRouting();
67811
68251
  init_resumeRunningCard();
68252
+ init_persistedRulesWire();
68253
+ init_localAllowRule();
67812
68254
  init_approvalsFeed();
67813
68255
  init_compensations();
67814
68256
  init_printNotification();
@@ -106717,11 +107159,11 @@ var require_valid = __commonJS({
106717
107159
  var require_clean = __commonJS({
106718
107160
  "node_modules/semver/functions/clean.js"(exports2, module2) {
106719
107161
  "use strict";
106720
- var parse12 = require_parse2(), clean5 = (version4, options) => {
107162
+ var parse12 = require_parse2(), clean6 = (version4, options) => {
106721
107163
  let s = parse12(version4.trim().replace(/^[=v]+/, ""), options);
106722
107164
  return s ? s.version : null;
106723
107165
  };
106724
- module2.exports = clean5;
107166
+ module2.exports = clean6;
106725
107167
  }
106726
107168
  });
106727
107169
 
@@ -107509,11 +107951,11 @@ var require_subset = __commonJS({
107509
107951
  var require_semver2 = __commonJS({
107510
107952
  "node_modules/semver/index.js"(exports2, module2) {
107511
107953
  "use strict";
107512
- var internalRe = require_re(), constants7 = require_constants2(), SemVer = require_semver(), identifiers = require_identifiers(), parse12 = require_parse2(), valid = require_valid(), clean5 = require_clean(), inc = require_inc(), diff2 = require_diff(), major2 = require_major(), minor2 = require_minor(), patch2 = require_patch(), prerelease = require_prerelease(), compare = require_compare(), rcompare = require_rcompare(), compareLoose = require_compare_loose(), compareBuild = require_compare_build(), sort = require_sort(), rsort = require_rsort(), gt2 = require_gt(), lt2 = require_lt(), eq2 = require_eq(), neq = require_neq(), gte2 = require_gte(), lte = require_lte(), cmp = require_cmp(), coerce5 = require_coerce(), truncate4 = require_truncate(), Comparator = require_comparator(), Range2 = require_range2(), satisfies2 = require_satisfies(), toComparators = require_to_comparators(), maxSatisfying = require_max_satisfying(), minSatisfying = require_min_satisfying(), minVersion = require_min_version(), validRange = require_valid2(), outside = require_outside(), gtr = require_gtr(), ltr = require_ltr(), intersects = require_intersects(), simplifyRange = require_simplify(), subset = require_subset();
107954
+ var internalRe = require_re(), constants7 = require_constants2(), SemVer = require_semver(), identifiers = require_identifiers(), parse12 = require_parse2(), valid = require_valid(), clean6 = require_clean(), inc = require_inc(), diff2 = require_diff(), major2 = require_major(), minor2 = require_minor(), patch2 = require_patch(), prerelease = require_prerelease(), compare = require_compare(), rcompare = require_rcompare(), compareLoose = require_compare_loose(), compareBuild = require_compare_build(), sort = require_sort(), rsort = require_rsort(), gt2 = require_gt(), lt2 = require_lt(), eq2 = require_eq(), neq = require_neq(), gte2 = require_gte(), lte = require_lte(), cmp = require_cmp(), coerce5 = require_coerce(), truncate4 = require_truncate(), Comparator = require_comparator(), Range2 = require_range2(), satisfies2 = require_satisfies(), toComparators = require_to_comparators(), maxSatisfying = require_max_satisfying(), minSatisfying = require_min_satisfying(), minVersion = require_min_version(), validRange = require_valid2(), outside = require_outside(), gtr = require_gtr(), ltr = require_ltr(), intersects = require_intersects(), simplifyRange = require_simplify(), subset = require_subset();
107513
107955
  module2.exports = {
107514
107956
  parse: parse12,
107515
107957
  valid,
107516
- clean: clean5,
107958
+ clean: clean6,
107517
107959
  inc,
107518
107960
  diff: diff2,
107519
107961
  major: major2,
@@ -114575,8 +115017,8 @@ function useTerminalTitle(title) {
114575
115017
  let writeRaw = (0, import_react23.useContext)(TerminalWriteContext);
114576
115018
  (0, import_react23.useEffect)(() => {
114577
115019
  if (title === null || !writeRaw) return;
114578
- let clean5 = stripAnsi(title);
114579
- process.platform === "win32" ? process.title = clean5 : writeRaw(osc(OSC.SET_TITLE_AND_ICON, clean5));
115020
+ let clean6 = stripAnsi(title);
115021
+ process.platform === "win32" ? process.title = clean6 : writeRaw(osc(OSC.SET_TITLE_AND_ICON, clean6));
114580
115022
  }, [title, writeRaw]);
114581
115023
  }
114582
115024
  var import_react23, init_use_terminal_title = __esm({
@@ -114701,265 +115143,15 @@ var init_types8 = __esm({
114701
115143
  });
114702
115144
 
114703
115145
  // build-src/src/sema/activeRunSelfHeal.ts
114704
- function activeRunBusySignal2(ev) {
114705
- if (typeof ev != "object" || ev === null || !("type" in ev)) return null;
114706
- let type = ev.type, carrier;
114707
- if (type === "done") {
114708
- if (!("result" in ev)) return null;
114709
- let result = ev.result;
114710
- if (typeof result != "object" || result === null || !("status" in result) || result.status !== "failed") return null;
114711
- carrier = result;
114712
- } else if (type === "failed")
114713
- carrier = ev;
114714
- else
114715
- return null;
114716
- let errorCode = "errorCode" in carrier ? carrier.errorCode : void 0, activeTaskId = "activeTaskId" in carrier ? carrier.activeTaskId : void 0, activeTaskStatus = "activeTaskStatus" in carrier ? carrier.activeTaskStatus : void 0, rawGate = "pendingGate" in carrier ? carrier.pendingGate : void 0, codeHit = errorCode === ACTIVE_RUN_BUSY_ERROR_CODE, handle2 = typeof activeTaskId == "string" && activeTaskId.length > 0 ? activeTaskId : null;
114717
- if (!codeHit && handle2 === null) return null;
114718
- let pendingGate = null;
114719
- if (typeof rawGate == "object" && rawGate !== null) {
114720
- let k2 = "kind" in rawGate ? rawGate.kind : void 0, p = "decidePath" in rawGate ? rawGate.decidePath : void 0, g6 = "governanceForced" in rawGate ? rawGate.governanceForced : void 0;
114721
- pendingGate = {
114722
- kind: typeof k2 == "string" && k2.length > 0 ? k2 : null,
114723
- decidePath: typeof p == "string" && p.length > 0 ? p : null,
114724
- ...g6 === !0 ? { governanceForced: !0 } : {}
114725
- };
114726
- }
114727
- return {
114728
- activeTaskId: handle2,
114729
- activeTaskStatus: typeof activeTaskStatus == "string" && activeTaskStatus.length > 0 ? activeTaskStatus : null,
114730
- pendingGate
114731
- };
115146
+ function attemptActiveRunSelfHeal2(signal, runs, deps2) {
115147
+ let override = cancelReleaseWaitOverrideMs, merged = override === null || deps2?.cancelReleaseWaitMs !== void 0 ? deps2 : { ...deps2 ?? {}, cancelReleaseWaitMs: override };
115148
+ return attemptActiveRunSelfHeal(signal, runs, merged);
114732
115149
  }
114733
- function describeFailure2(e) {
114734
- if (typeof e == "object" && e !== null && "message" in e) {
114735
- let m2 = e.message;
114736
- if (typeof m2 == "string" && m2.length > 0) return m2.length > 200 ? `${m2.slice(0, 200)}\u2026` : m2;
114737
- }
114738
- return "the engine gave no detail";
114739
- }
114740
- function readStatus2(record2) {
114741
- if (typeof record2 != "object" || record2 === null || !("status" in record2)) return null;
114742
- let st2 = record2.status;
114743
- return typeof st2 == "string" && st2.length > 0 ? st2 : null;
114744
- }
114745
- function steerFailureClass(e) {
114746
- let status3 = e?.status;
114747
- return typeof status3 == "number" && status3 >= 400 && status3 < 500 ? "rejected" : "unknown";
114748
- }
114749
- function readDelivery(receipt) {
114750
- if (typeof receipt != "object" || receipt === null || !("delivery" in receipt)) return null;
114751
- let d4 = receipt.delivery;
114752
- return typeof d4 == "string" && d4.length > 0 ? d4 : null;
114753
- }
114754
- function readReceiptStatus(receipt) {
114755
- if (typeof receipt != "object" || receipt === null || !("status" in receipt)) return null;
114756
- let s = receipt.status;
114757
- return typeof s == "string" && s.length > 0 ? s : null;
114758
- }
114759
- function cancelReleaseWaitMs() {
114760
- return cancelReleaseWaitOverrideMs ?? CANCEL_RELEASE_WAIT_MS2;
114761
- }
114762
- function sleep2(ms, signal) {
114763
- return signal?.aborted === !0 ? Promise.resolve() : new Promise((resolve57) => {
114764
- let timer2 = setTimeout(() => {
114765
- signal?.removeEventListener("abort", onAbort), resolve57();
114766
- }, ms), onAbort = () => {
114767
- clearTimeout(timer2), resolve57();
114768
- };
114769
- signal?.addEventListener("abort", onAbort, { once: !0 });
114770
- });
114771
- }
114772
- function claimProbeSignal(caller, deadline) {
114773
- let remaining = Math.max(1, deadline - Date.now()), budget = AbortSignal.timeout(remaining);
114774
- if (caller === void 0) return budget;
114775
- if (typeof AbortSignal.any == "function") return AbortSignal.any([caller, budget]);
114776
- let ac = new AbortController(), abort = (s) => ac.abort(s.reason);
114777
- return caller.aborted ? abort(caller) : caller.addEventListener("abort", () => abort(caller), { once: !0 }), budget.addEventListener("abort", () => abort(budget), { once: !0 }), ac.signal;
114778
- }
114779
- async function waitForClaimRelease2(taskId, get4, budgetMs, signal) {
114780
- let startedAt = Date.now(), deadline = startedAt + budgetMs, waited = () => Date.now() - startedAt, isAborted3 = () => signal?.aborted === !0, delay = CANCEL_POLL_START_MS2;
114781
- for (; ; ) {
114782
- if (isAborted3()) return { released: !1, waitedMs: waited(), aborted: !0 };
114783
- let remaining = deadline - Date.now();
114784
- if (remaining <= 0) return { released: !1, waitedMs: waited(), aborted: !1 };
114785
- if (await sleep2(Math.min(delay, remaining), signal), isAborted3()) return { released: !1, waitedMs: waited(), aborted: !0 };
114786
- delay = Math.min(Math.round(delay * 1.5), CANCEL_POLL_MAX_MS2);
114787
- let status3;
114788
- try {
114789
- status3 = readStatus2(await get4(taskId, { signal: claimProbeSignal(signal, deadline) }));
114790
- } catch (e) {
114791
- if (isAborted3()) return { released: !1, waitedMs: waited(), aborted: !0 };
114792
- if (e?.status === 404) return { released: !0, waitedMs: waited(), aborted: !1 };
114793
- continue;
114794
- }
114795
- if (status3 !== null && CLAIM_RELEASED_STATES2.includes(status3)) return { released: !0, waitedMs: waited(), aborted: !1 };
114796
- }
114797
- }
114798
- async function attemptActiveRunSelfHeal2(signal, runs, deps2) {
114799
- let pending2 = !1;
114800
- try {
114801
- pending2 = deps2?.hasPendingDecision?.() === !0;
114802
- } catch {
114803
- pending2 = !1;
114804
- }
114805
- if (pending2 && deps2?.listOwnedPendingApprovals !== void 0)
114806
- try {
114807
- await deps2.listOwnedPendingApprovals() === 0 && (pending2 = !1);
114808
- } catch {
114809
- }
114810
- if (pending2) return { kind: "decision-pending", taskId: signal.activeTaskId };
114811
- let taskId = signal.activeTaskId;
114812
- if (taskId === null)
114813
- return {
114814
- kind: "state-unknown",
114815
- taskId: null,
114816
- detail: "the engine did not name the run that holds this session"
114817
- };
114818
- let planVerdict2 = async () => {
114819
- try {
114820
- return await deps2?.reopenPlanReview?.(taskId) ?? { reopened: !1 };
114821
- } catch {
114822
- return { reopened: !1 };
114823
- }
114824
- }, askVerdict2 = async () => {
114825
- try {
114826
- return await deps2?.reopenAskPark?.(taskId) ?? { reopened: !1 };
114827
- } catch {
114828
- return { reopened: !1 };
114829
- }
114830
- }, reopenPlanArm = async () => {
114831
- let verdict = await planVerdict2();
114832
- return verdict.reopened === !0 ? { kind: "plan-review-reopened", taskId, firstSight: verdict.firstSight === !0 } : { kind: "plan-review-reopen-failed", taskId, decidePath: signal.pendingGate?.decidePath ?? null };
114833
- }, reopenAskArm = async () => {
114834
- let verdict = await askVerdict2();
114835
- return verdict.reopened === !0 ? { kind: "ask-reopened", taskId, firstSight: verdict.firstSight === !0 } : { kind: "ask-reopen-failed", taskId, decidePath: signal.pendingGate?.decidePath ?? null };
114836
- }, runningChoiceArm2 = async (status4) => {
114837
- let notParked = { kind: "not-parked", taskId, status: status4 }, offer = deps2?.offerRunningChoice;
114838
- if (typeof offer != "function") return notParked;
114839
- let text2 = typeof deps2?.deniedMessage == "string" ? deps2.deniedMessage : "", steer = typeof runs?.steer == "function" ? runs.steer.bind(runs) : void 0, cancel = typeof runs?.cancel == "function" ? runs.cancel.bind(runs) : void 0, get4 = typeof runs?.get == "function" ? runs.get.bind(runs) : void 0, canSteer = typeof steer == "function" && text2.length > 0, canCancel = typeof cancel == "function" && typeof get4 == "function";
114840
- if (!canSteer && !canCancel) return notParked;
114841
- let choice = "wait";
114842
- try {
114843
- choice = await offer({ taskId, status: status4, canSteer, canCancel }) ?? "wait";
114844
- } catch {
114845
- choice = "wait";
114846
- }
114847
- if (choice === "steer" && canSteer && steer !== void 0)
114848
- try {
114849
- let receipt = await steer(taskId, { text: text2 }), delivery = readDelivery(receipt), receiptStatus = readReceiptStatus(receipt);
114850
- if (delivery === "queued") {
114851
- let verdict = receiptStatus !== null && PLAN_REVIEW_STATES2.includes(receiptStatus) ? await planVerdict2() : receiptStatus !== null && ASK_PARK_STATES2.includes(receiptStatus) ? await askVerdict2() : null;
114852
- return { kind: "running-steered", taskId, delivery, status: receiptStatus, reopened: verdict };
114853
- }
114854
- return { kind: "running-steered", taskId, delivery, status: receiptStatus, reopened: null };
114855
- } catch (e) {
114856
- return { kind: "running-steer-failed", taskId, detail: describeFailure2(e), delivery: steerFailureClass(e) };
114857
- }
114858
- if (choice === "cancel" && canCancel && cancel !== void 0 && get4 !== void 0) {
114859
- try {
114860
- await cancel(taskId);
114861
- } catch (e) {
114862
- return { kind: "running-cancel-failed", taskId, detail: describeFailure2(e) };
114863
- }
114864
- let verdict = await waitForClaimRelease2(taskId, get4, cancelReleaseWaitMs(), deps2?.signal);
114865
- return verdict.released ? { kind: "running-cancelled", taskId } : { kind: "running-cancel-timeout", taskId, waitedMs: verdict.waitedMs, aborted: verdict.aborted };
114866
- }
114867
- return notParked;
114868
- }, gateKind2 = signal.pendingGate?.kind ?? null;
114869
- if (gateKind2 !== null && PLAN_REVIEW_GATE_KINDS2.includes(gateKind2)) return reopenPlanArm();
114870
- if (gateKind2 !== null && ASK_PARK_GATE_KINDS2.includes(gateKind2)) return reopenAskArm();
114871
- let status3 = signal.activeTaskStatus;
114872
- if (status3 === null) {
114873
- if (typeof runs?.get != "function")
114874
- return { kind: "state-unknown", taskId, detail: "this client exposes no durable run verbs" };
114875
- let record2;
114876
- try {
114877
- record2 = await runs.get(taskId);
114878
- } catch (e) {
114879
- return { kind: "state-unknown", taskId, detail: describeFailure2(e) };
114880
- }
114881
- status3 = readStatus2(record2);
114882
- }
114883
- return status3 === null ? { kind: "state-unknown", taskId, detail: "the engine reported no status for that run" } : gateKind2 !== null ? { kind: "not-parked", taskId, status: status3 } : PLAN_REVIEW_STATES2.includes(status3) ? reopenPlanArm() : ASK_PARK_STATES2.includes(status3) ? reopenAskArm() : RUNNING_STATES2.includes(status3) ? runningChoiceArm2(status3) : { kind: "not-parked", taskId, status: status3 };
114884
- }
114885
- function gateKindPhrase2(kind) {
114886
- return kind ? `a ${kind} decision` : "a decision";
114887
- }
114888
- function decidePathClause2(signal) {
114889
- let decidePath = signal?.pendingGate?.decidePath;
114890
- return decidePath ? ` The engine says that run is waiting on ${gateKindPhrase2(signal?.pendingGate?.kind)} and that it is decided at POST ${decidePath} \u2014 deciding it releases the session.` : "";
114891
- }
114892
- function activeRunSelfHealRow2(outcome, signal) {
114893
- let base = activeRunSelfHealBaseRow2(outcome, signal);
114894
- switch (outcome.kind) {
114895
- // 这两条是「用户此刻卡住了、而且没有别的把手」的结局 —— wire 给的 decide 入口在这里才有用。
114896
- case "not-parked":
114897
- case "state-unknown":
114898
- return base + decidePathClause2(signal) + governanceOriginClause2(signal);
114899
- // 其余结局手上都另有一张更好的把手(重开的卡 / 已开的卡 / 失败臂基句自己渲的 decidePath)
114900
- // (重开的卡 / 已开的卡 / 基句自己渲的 decidePath)—— 再叠一条引擎路由只会稀释那一个动作。
114901
- default:
114902
- return base + governanceOriginClause2(signal);
114903
- }
114904
- }
114905
- function governanceOriginClause2(signal) {
114906
- return signal?.pendingGate?.governanceForced === !0 ? " That gate is enforced by this deployment's governance policy, not by a permission rule you set." : "";
114907
- }
114908
- function activeRunSelfHealBaseRow2(outcome, signal) {
114909
- switch (outcome.kind) {
114910
- case "decision-pending":
114911
- return `This session is held by an earlier turn${outcome.taskId ? ` (run ${outcome.taskId})` : ""} that is waiting on a decision you have not made yet, and there is a decision card open for it. sema did NOT cancel it \u2014 answering that card is what releases the session, and cancelling would decide it for you. Your message was NOT sent; answer the open card and send it again.`;
114912
- case "ask-reopened":
114913
- return outcome.firstSight ? `The previous turn advanced to a decision it needs from you (run ${outcome.taskId}), which is why nothing new could start \u2014 sema has surfaced that decision card. Answer it and send your message again. (sema did NOT cancel the run: cancelling would have decided it for you.)` : `The previous turn is parked waiting for your decision (run ${outcome.taskId}), which is why nothing new could start \u2014 that card was closed without being answered, so sema reopened it. Answer it and send your message again. (sema did NOT cancel the run: cancelling would have decided it for you.)`;
114914
- case "plan-review-reopened":
114915
- return outcome.firstSight ? `The previous turn produced a plan that is waiting for your review (run ${outcome.taskId}), which is why nothing new could start \u2014 sema has surfaced the review card. Answer it and send your message again. (sema did NOT cancel the run: cancelling would have thrown the plan away on your behalf.)` : `The previous turn is parked waiting for you to review its plan (run ${outcome.taskId}), which is why nothing new could start \u2014 that approval card was closed without being answered, so sema reopened it. Answer it and send your message again. (sema did NOT cancel the run: cancelling would have thrown the plan away on your behalf.)`;
114916
- case "ask-reopen-failed": {
114917
- let viaEngine = outcome.decidePath ? ` You can also decide it on the engine directly: POST ${outcome.decidePath}.` : "";
114918
- return `The previous turn is parked waiting for your decision (run ${outcome.taskId}) and sema could not reopen that card here. It did NOT cancel the run \u2014 that would have decided it for you. Your message was NOT sent; ${INTERACTIVE_WAY_OUT} if you no longer want it.${viaEngine}`;
114919
- }
114920
- case "plan-review-reopen-failed": {
114921
- let viaEngine = outcome.decidePath ? ` You can also decide it on the engine directly: POST ${outcome.decidePath}.` : "";
114922
- return `The previous turn is parked waiting for a plan review (run ${outcome.taskId}) and sema could not reopen that approval card. It did NOT cancel the run \u2014 that would have discarded the plan for you. Your message was NOT sent; ${INTERACTIVE_WAY_OUT} if you no longer want that plan.${viaEngine}`;
114923
- }
114924
- // ── C3 三选卡的四种动作结局(选 ③/没答/没呈上都落 not-parked,见下)────────────────────
114925
- case "running-steered": {
114926
- let handle2 = `run ${outcome.taskId}`, textOnly = "Only the TEXT of your message was handed over \u2014 a steer carries no attachments, so any images in that submission were NOT sent.";
114927
- if (outcome.delivery === "applied")
114928
- return `sema handed your message to the run that is already working (${handle2}) \u2014 the engine applied it to that run, so it is picked up at that run's next step. ${textOnly} Nothing was cancelled, and your message did NOT start a new turn \u2014 watch that run for what it does with it.`;
114929
- if (outcome.delivery === "queued") {
114930
- let parked = outcome.status ? `parked (status ${outcome.status})` : "parked", next = outcome.reopened?.reopened === !0 ? "sema has surfaced that decision card \u2014 answering it is what lets that run resume and pick your message up." : `sema could not surface that decision card here, so nothing will resume that run until that decision is made; ${INTERACTIVE_WAY_OUT} if you no longer want it.`;
114931
- return `${handle2} is not actually working right now: the engine reports it ${parked} on a decision it needs from you, so it queued your message on that park instead of running it. ${next} ${textOnly} Nothing was cancelled, and your message did NOT start a new turn.`;
114932
- }
114933
- return outcome.delivery === "parked_for_wake" ? `${handle2} had already finished, so the engine parked your message on that finished run instead of running it \u2014 a parked message is delivered only if this session is woken on the engine (POST /v1/sessions/:id/wake), which sema does not do here. That run is no longer holding this session: send your message again to run it as a new turn. ${textOnly} Nothing was cancelled.` : `sema handed your message to ${handle2}, but the engine did not say how it will be delivered${outcome.status ? ` (it reported that run as ${outcome.status})` : ""}. ${textOnly} Nothing was cancelled, and your message did NOT start a new turn \u2014 watch that run before sending it again.`;
114934
- }
114935
- case "running-steer-failed":
114936
- return outcome.delivery === "rejected" ? `The engine rejected handing your message to the running run (run ${outcome.taskId}): ${outcome.detail}. sema did NOT retry it (a steer is not safe to send twice) and it did NOT cancel that run. Your message was NOT sent; send it again if you still want it.` : `sema sent your message to the running run (run ${outcome.taskId}) but could not confirm what happened to it (${outcome.detail}). A steer is not safe to send twice, so sema did NOT retry it, and it did NOT cancel that run. That run may or may not have received your message \u2014 watch what it does next before sending it again.`;
114937
- case "running-cancelled":
114938
- return `You chose to cancel run ${outcome.taskId}. The engine confirmed it is no longer holding this session, so sema is sending your message now.`;
114939
- case "running-cancel-timeout": {
114940
- let waited = `${String(Math.max(1, Math.round(outcome.waitedMs / 1e3)))}s`;
114941
- return outcome.aborted ? `sema asked the engine to cancel run ${outcome.taskId} and you interrupted while it was still confirming (${waited} in). Cancelling is asynchronous, so that run may still be winding down and may still hold this session. Your message was NOT sent; send it again in a moment, or ${INTERACTIVE_WAY_OUT}.` : `sema asked the engine to cancel run ${outcome.taskId}, but that run still held this session ${waited} later \u2014 cancelling is asynchronous and it may still be winding down. Your message was NOT sent; send it again in a moment, or ${INTERACTIVE_WAY_OUT}.`;
114942
- }
114943
- case "running-cancel-failed":
114944
- return `sema could not cancel run ${outcome.taskId} (${outcome.detail}), so that run is still holding this session and your message was NOT sent. Send it again to retry, or ${INTERACTIVE_WAY_OUT}.`;
114945
- case "not-parked":
114946
- return signal?.pendingGate ? `This session is held by an earlier run (run ${outcome.taskId}, status ${outcome.status}) that is waiting on ${gateKindPhrase2(signal.pendingGate.kind)} \u2014 it will not finish on its own. sema did NOT cancel it, because cancelling would decide that item for you. Your message was NOT sent; ${INTERACTIVE_WAY_OUT} if you no longer want it.` : `This session already has a run in flight (run ${outcome.taskId}, status ${outcome.status}) \u2014 most likely a turn you sent to the background. sema did NOT cancel it, because that would throw away work you asked for. Wait for it to finish, or ${INTERACTIVE_WAY_OUT}.`;
114947
- case "state-unknown":
114948
- return `This session is locked by an earlier run${outcome.taskId ? ` (run ${outcome.taskId})` : ""} and sema could not read that run's state, so it did not touch it (${outcome.detail}). Your message was NOT sent. This session cannot start a new turn until that run settles \u2014 ${INTERACTIVE_WAY_OUT}.`;
114949
- }
114950
- }
114951
- function activeRunBusyHeadlessRow2(signal) {
114952
- let activeTaskId = signal.activeTaskId, handle2 = activeTaskId ? ` (run ${activeTaskId})` : "", cancelPath = `POST /v1/runs/${activeTaskId ?? "<id>"}/cancel`, status3 = signal.activeTaskStatus, decidePath = signal.pendingGate?.decidePath ?? null, freshSession = "start a new session (drop --resume/--continue)";
114953
- return decidePath ? `This session is held by an earlier run${handle2}${status3 ? ` (status ${status3})` : ""} that is parked waiting on ${gateKindPhrase2(signal.pendingGate?.kind)}, so this message was NOT sent. Decide it and the session unlocks: POST ${decidePath}. Cancelling instead (${cancelPath}) also unlocks it, but it decides that item against you. Or ${freshSession}.` + // 出身归因同款(见 governanceOriginClause):这条车道更需要它 —— 没有卡可看,
114954
- // 用户唯一能读到的就是这一段话。
114955
- governanceOriginClause2(signal) : status3 ? `This session is held by an earlier run${handle2} with status ${status3}, so this message was NOT sent. The engine reported no decision pending on that run: if it is still working, wait for it to finish; if it will never settle, release it with ${cancelPath} (that discards whatever it was doing). Or ${freshSession}.` : `This session is locked by an earlier run${handle2} that was never released, so this message was NOT sent. Nothing here clears on its own. Start a new session (drop --resume/--continue), or release the run on the engine: ${cancelPath}`;
114956
- }
114957
- var PLAN_REVIEW_STATES2, ASK_PARK_STATES2, PLAN_REVIEW_GATE_KINDS2, ASK_PARK_GATE_KINDS2, RUNNING_STATES2, CLAIM_RELEASED_STATES2, CANCEL_RELEASE_WAIT_MS2, CANCEL_POLL_START_MS2, CANCEL_POLL_MAX_MS2, cancelReleaseWaitOverrideMs, INTERACTIVE_WAY_OUT, init_activeRunSelfHeal2 = __esm({
115150
+ var cancelReleaseWaitOverrideMs, init_activeRunSelfHeal2 = __esm({
114958
115151
  "build-src/src/sema/activeRunSelfHeal.ts"() {
114959
115152
  init_dist();
114960
- PLAN_REVIEW_STATES2 = ["needs_review"], ASK_PARK_STATES2 = ["suspended"], PLAN_REVIEW_GATE_KINDS2 = ["plan_review", "dry_run_review"], ASK_PARK_GATE_KINDS2 = ["human", "irreversible_ask", "policy_ask", "tool_approval"], RUNNING_STATES2 = ["running"], CLAIM_RELEASED_STATES2 = ["completed", "failed", "blocked", "timeout"];
114961
- CANCEL_RELEASE_WAIT_MS2 = 1e4, CANCEL_POLL_START_MS2 = 200, CANCEL_POLL_MAX_MS2 = 2e3, cancelReleaseWaitOverrideMs = null;
114962
- INTERACTIVE_WAY_OUT = "run /clear to keep working in a fresh session";
115153
+ init_dist();
115154
+ cancelReleaseWaitOverrideMs = null;
114963
115155
  }
114964
115156
  });
114965
115157
 
@@ -114977,7 +115169,7 @@ __export(runStream_exports, {
114977
115169
  function watchActiveRunBusy(events3, seen2) {
114978
115170
  return (async function* () {
114979
115171
  for await (let ev of events3) {
114980
- let busy = activeRunBusySignal2(ev);
115172
+ let busy = activeRunBusySignal(ev);
114981
115173
  busy && (seen2.busy = busy), yield ev;
114982
115174
  }
114983
115175
  })();
@@ -115025,7 +115217,7 @@ function rewriteActiveRunBusyRow(msgs, seen2) {
115025
115217
  ...m2,
115026
115218
  message: {
115027
115219
  ...envelope,
115028
- content: [{ type: "text", text: activeRunBusyHeadlessRow2(busy) }]
115220
+ content: [{ type: "text", text: activeRunBusyHeadlessRow(busy) }]
115029
115221
  }
115030
115222
  };
115031
115223
  continue;
@@ -115049,13 +115241,13 @@ function hostSink(e, billTurnCosts = !0) {
115049
115241
  return;
115050
115242
  }
115051
115243
  if (e.kind === "human_input") {
115052
- let clean5 = (v2) => (
115244
+ let clean6 = (v2) => (
115053
115245
  // eslint-disable-next-line no-control-regex
115054
115246
  String(v2 ?? "").replace(/[\x00-\x1f\x7f]/g, ".").slice(0, 120)
115055
- ), who = e.actor?.id ? `${clean5(e.actor.id)}${e.actor.hostAsserted === !0 ? "" : " (unverified)"}` : "unattributed";
115247
+ ), who = e.actor?.id ? `${clean6(e.actor.id)}${e.actor.hostAsserted === !0 ? "" : " (unverified)"}` : "unattributed";
115056
115248
  Promise.resolve().then(() => (init_debug(), debug_exports)).then(
115057
115249
  (m2) => m2.logForDebugging(
115058
- `[sema][wire] human_input ledger: carrier=${clean5(e.carrier)} source=${clean5(e.source)} delivery=${clean5(e.delivery)} actor=${who}${e.eventId ? ` eventId=${clean5(e.eventId)}` : ""}`
115250
+ `[sema][wire] human_input ledger: carrier=${clean6(e.carrier)} source=${clean6(e.source)} delivery=${clean6(e.delivery)} actor=${who}${e.eventId ? ` eventId=${clean6(e.eventId)}` : ""}`
115059
115251
  )
115060
115252
  ).catch(() => {
115061
115253
  });
@@ -115073,10 +115265,10 @@ function _resetHostDroppedFrameMemoForTest() {
115073
115265
  reportedDroppedTypes2.clear();
115074
115266
  }
115075
115267
  function hostDroppedFrameSink(info) {
115076
- let clean5 = (v2) => (
115268
+ let clean6 = (v2) => (
115077
115269
  // eslint-disable-next-line no-control-regex
115078
115270
  String(v2).replace(/[\x00-\x1f\x7f]/g, ".").slice(0, 120)
115079
- ), type = clean5(info.type), line = `[sema][wire] dropped engine frame: type=${type} why=${clean5(info.why)} \u2014 this build's projector has no arm for it (engine newer than the client, or a malformed frame). It renders NOWHERE.`;
115271
+ ), type = clean6(info.type), line = `[sema][wire] dropped engine frame: type=${type} why=${clean6(info.why)} \u2014 this build's projector has no arm for it (engine newer than the client, or a malformed frame). It renders NOWHERE.`;
115080
115272
  Promise.resolve().then(() => (init_debug(), debug_exports)).then((m2) => {
115081
115273
  m2.logForDebugging(line, { level: "warn" }), !m2.isDebugMode() && process.env.USER_TYPE !== "ant" && consoleLegForDroppedFrame(type, line);
115082
115274
  }).catch(() => consoleLegForDroppedFrame(type, line));
@@ -138794,7 +138986,7 @@ var KEYCHAIN_PREFETCH_TIMEOUT_MS, legacyApiKeyPrefetch, prefetchPromise, init_ke
138794
138986
  });
138795
138987
 
138796
138988
  // build-src/src/utils/sleep.ts
138797
- function sleep3(ms, signal, opts) {
138989
+ function sleep2(ms, signal, opts) {
138798
138990
  return new Promise((resolve57, reject3) => {
138799
138991
  if (signal?.aborted) {
138800
138992
  opts?.throwOnAbort || opts?.abortError ? reject3(opts.abortError?.() ?? new Error("aborted")) : resolve57();
@@ -139221,7 +139413,7 @@ async function checkGcpCredentialsValid() {
139221
139413
  scopes: ["https://www.googleapis.com/auth/cloud-platform"]
139222
139414
  }), probe3 = (async () => {
139223
139415
  await (await auth2.getClient()).getAccessToken();
139224
- })(), timeout3 = sleep3(GCP_CREDENTIALS_CHECK_TIMEOUT_MS).then(() => {
139416
+ })(), timeout3 = sleep2(GCP_CREDENTIALS_CHECK_TIMEOUT_MS).then(() => {
139225
139417
  throw new GcpCredentialsTimeoutError("GCP credentials check timed out");
139226
139418
  });
139227
139419
  return await Promise.race([probe3, timeout3]), !0;
@@ -139425,7 +139617,7 @@ async function checkAndRefreshOAuthTokenIfNeededImpl(retryCount, force) {
139425
139617
  try {
139426
139618
  release2 = await lock(claudeDir), noteStorageLockAcquired();
139427
139619
  } catch (err8) {
139428
- return err8.code === "ELOCKED" ? retryCount < 5 ? (retryCount + 1, await sleep3(1e3 + Math.random() * 1e3), checkAndRefreshOAuthTokenIfNeededImpl(retryCount + 1, force)) : !1 : (logError(err8), errorMessage(
139620
+ return err8.code === "ELOCKED" ? retryCount < 5 ? (retryCount + 1, await sleep2(1e3 + Math.random() * 1e3), checkAndRefreshOAuthTokenIfNeededImpl(retryCount + 1, force)) : !1 : (logError(err8), errorMessage(
139429
139621
  err8
139430
139622
  ), !1);
139431
139623
  }
@@ -143465,7 +143657,7 @@ async function cleanupWorktree() {
143465
143657
  ...current5,
143466
143658
  activeWorktreeSession: void 0
143467
143659
  })), !hookBased && worktreeBranch) {
143468
- await sleep3(100);
143660
+ await sleep2(100);
143469
143661
  let { code: deleteBranchCode, stderr: deleteBranchError } = await execFileNoThrowWithCwd(
143470
143662
  gitExe(),
143471
143663
  ["branch", "-D", worktreeBranch],
@@ -176808,19 +177000,17 @@ function acquireFileLockSyncRetrying(path28) {
176808
177000
  return;
176809
177001
  }
176810
177002
  }
176811
- function engineNamespaceKeyFor(baseUrl) {
176812
- if (!baseUrl) return "local";
176813
- try {
176814
- return new URL(baseUrl).origin.toLowerCase();
176815
- } catch {
176816
- return baseUrl.toLowerCase();
176817
- }
177003
+ function logMergeSkip(reason, key) {
177004
+ logForDebugging(
177005
+ reason === "no-engine-session-id" ? `sessionIdMapping: persistEngineEntry(${key}) skipped \u2014 no engineSessionId` : "sessionIdMapping: persist skipped \u2014 no shellSessionId"
177006
+ );
176818
177007
  }
176819
177008
  var LOCK_STALE_MS3, SessionIdMapping, init_sessionIdMapping = __esm({
176820
177009
  "build-src/src/sema/sessionIdMapping.ts"() {
176821
177010
  init_debug();
176822
177011
  init_lockfile();
176823
177012
  init_slowOperations();
177013
+ init_dist();
176824
177014
  LOCK_STALE_MS3 = 1e4;
176825
177015
  SessionIdMapping = class {
176826
177016
  path;
@@ -176856,21 +177046,21 @@ var LOCK_STALE_MS3, SessionIdMapping, init_sessionIdMapping = __esm({
176856
177046
  */
176857
177047
  persist(partial2) {
176858
177048
  if (!this.path || process.env.SEMA_NO_PERSIST_WIRE === "1") {
176859
- let prior = this.freshPrior(), shellSessionId = partial2.shellSessionId ?? prior?.shellSessionId;
176860
- if (!shellSessionId) {
176861
- logForDebugging("sessionIdMapping: persist skipped \u2014 no shellSessionId");
177049
+ let verdict = mergeSessionMapRecord(this.freshPrior(), partial2);
177050
+ if (!verdict.ok) {
177051
+ logMergeSkip(verdict.reason);
176862
177052
  return;
176863
177053
  }
176864
- this.cache = { ...prior, ...partial2, shellSessionId, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
177054
+ this.cache = verdict.record;
176865
177055
  return;
176866
177056
  }
176867
- let next = this.lockedReadMergeWrite(this.path, (prior) => {
176868
- let shellSessionId = partial2.shellSessionId ?? prior?.shellSessionId;
176869
- if (!shellSessionId) {
176870
- logForDebugging("sessionIdMapping: persist skipped \u2014 no shellSessionId");
177057
+ let next = this.storeFor(this.path).readMergeWrite((prior) => {
177058
+ let verdict = mergeSessionMapRecord(prior, partial2);
177059
+ if (!verdict.ok) {
177060
+ logMergeSkip(verdict.reason);
176871
177061
  return;
176872
177062
  }
176873
- return { ...prior, ...partial2, shellSessionId, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
177063
+ return verdict.record;
176874
177064
  });
176875
177065
  next && (this.cache = next);
176876
177066
  }
@@ -176893,43 +177083,21 @@ var LOCK_STALE_MS3, SessionIdMapping, init_sessionIdMapping = __esm({
176893
177083
  */
176894
177084
  persistEngineEntry(key, partial2, shellSessionId) {
176895
177085
  if (!this.path || process.env.SEMA_NO_PERSIST_WIRE === "1") {
176896
- let prior = this.freshPrior(), priorEntry = prior?.engines?.[key], engineSessionId = partial2.engineSessionId ?? priorEntry?.engineSessionId;
176897
- if (!engineSessionId) {
176898
- logForDebugging(`sessionIdMapping: persistEngineEntry(${key}) skipped \u2014 no engineSessionId`);
176899
- return;
176900
- }
176901
- let sid = shellSessionId ?? prior?.shellSessionId;
176902
- if (!sid) {
176903
- logForDebugging("sessionIdMapping: persist skipped \u2014 no shellSessionId");
177086
+ let verdict = mergeEngineEntry(this.freshPrior(), key, partial2, shellSessionId);
177087
+ if (!verdict.ok) {
177088
+ logMergeSkip(verdict.reason, key);
176904
177089
  return;
176905
177090
  }
176906
- let entry = { ...priorEntry, ...partial2, engineSessionId, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
176907
- this.cache = {
176908
- ...prior,
176909
- shellSessionId: sid,
176910
- engines: { ...prior?.engines, [key]: entry },
176911
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
176912
- };
177091
+ this.cache = verdict.record;
176913
177092
  return;
176914
177093
  }
176915
- let next = this.lockedReadMergeWrite(this.path, (prior) => {
176916
- let priorEntry = prior?.engines?.[key], engineSessionId = partial2.engineSessionId ?? priorEntry?.engineSessionId;
176917
- if (!engineSessionId) {
176918
- logForDebugging(`sessionIdMapping: persistEngineEntry(${key}) skipped \u2014 no engineSessionId`);
177094
+ let next = this.storeFor(this.path).readMergeWrite((prior) => {
177095
+ let verdict = mergeEngineEntry(prior, key, partial2, shellSessionId);
177096
+ if (!verdict.ok) {
177097
+ logMergeSkip(verdict.reason, key);
176919
177098
  return;
176920
177099
  }
176921
- let sid = shellSessionId ?? prior?.shellSessionId;
176922
- if (!sid) {
176923
- logForDebugging("sessionIdMapping: persist skipped \u2014 no shellSessionId");
176924
- return;
176925
- }
176926
- let entry = { ...priorEntry, ...partial2, engineSessionId, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
176927
- return {
176928
- ...prior,
176929
- shellSessionId: sid,
176930
- engines: { ...prior?.engines, [key]: entry },
176931
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
176932
- };
177100
+ return verdict.record;
176933
177101
  });
176934
177102
  next && (this.cache = next);
176935
177103
  }
@@ -176946,6 +177114,17 @@ var LOCK_STALE_MS3, SessionIdMapping, init_sessionIdMapping = __esm({
176946
177114
  _reset() {
176947
177115
  this.path = void 0, this.cache = void 0;
176948
177116
  }
177117
+ /**
177118
+ * A-028.12:包 `SessionMapStorePort` 的 cli 文件实现(read = 无副作用新鲜读盘;
177119
+ * readMergeWrite = 锁内读-合-写)。端口在这里**真被消费**(persist/persistEngineEntry 经它写),
177120
+ * 不是装饰性 satisfies —— web 半场用 localStorage 实现同一契约。
177121
+ */
177122
+ storeFor(path28) {
177123
+ return {
177124
+ read: () => this.readRecordFromDisk(path28),
177125
+ readMergeWrite: (build2) => this.lockedReadMergeWrite(path28, build2)
177126
+ };
177127
+ }
176949
177128
  /**
176950
177129
  * M1 修 core: lock `path`, read the FRESH on-disk record (not `this.cache` / not a pre-lock read),
176951
177130
  * let `build` compute the next record from that fresh prior, and atomically persist it — all inside
@@ -178203,15 +178382,7 @@ function validateEngineUrlTransport(url3) {
178203
178382
  );
178204
178383
  }
178205
178384
  function resolveLiveAuthToken(baseUrl, token = process.env.SEMA_LIVE_TOKEN) {
178206
- return token || (baseUrl && isLoopbackEngineUrl(baseUrl) ? { mode: "loopback-unauthed" } : "anon");
178207
- }
178208
- function isLoopbackEngineUrl(url3) {
178209
- try {
178210
- let h = new URL(url3).hostname;
178211
- return h === "127.0.0.1" || h === "localhost" || h === "::1" || h === "[::1]";
178212
- } catch {
178213
- return !1;
178214
- }
178385
+ return resolveWireAuth(baseUrl, token);
178215
178386
  }
178216
178387
  function configuredEngineUrl() {
178217
178388
  let v2 = settingsEnv()[ENGINE_URL_ENV] ?? process.env[ENGINE_URL_ENV];
@@ -178318,14 +178489,6 @@ function enginePinUnreachableHint(pin) {
178318
178489
  \xB7 Leftover from an older install, or want the shell-managed engine back? ${removal} \u2014 the next launch self-spawns a local engine.
178319
178490
  \xB7 Not sure? Run \`sema doctor\` to see the engine status.`;
178320
178491
  }
178321
- function isEngineTransportError(err8) {
178322
- let e = err8;
178323
- if (typeof e?.status == "number") return !1;
178324
- let cause = e?.cause, detail = typeof cause?.message == "string" && cause.message.length > 0 && cause.message || typeof e?.message == "string" && e.message.length > 0 && e.message || String(err8);
178325
- return e?.cause !== void 0 || /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|EHOSTUNREACH|ENETUNREACH|EPIPE|socket hang up|UND_ERR|terminated|other side closed/i.test(
178326
- detail
178327
- );
178328
- }
178329
178492
  function noteEnginePinUnreachable(pin) {
178330
178493
  enginePinUnreachable = pin;
178331
178494
  }
@@ -178451,7 +178614,7 @@ function noteRemoteResumeWarning() {
178451
178614
  function remoteResumeWarningActive() {
178452
178615
  return remoteResumeWarning;
178453
178616
  }
178454
- var ENGINE_URL_ENV, TRUSTED_ENGINE_HOSTS_KEY, enginePinUnreachable, SYNC_ENGINE_URL_ENV, AUTO_SYNC_SOURCE_LABEL, AUTO_SYNC_LOCKED_BY_POLICY_ERROR, DEFAULT_BIND_HOST, engineRoutingRefusal, remoteResumeWarning, init_engineTarget = __esm({
178617
+ var ENGINE_URL_ENV, TRUSTED_ENGINE_HOSTS_KEY, isLoopbackEngineUrl, isEngineTransportError, enginePinUnreachable, SYNC_ENGINE_URL_ENV, AUTO_SYNC_SOURCE_LABEL, AUTO_SYNC_LOCKED_BY_POLICY_ERROR, DEFAULT_BIND_HOST, engineRoutingRefusal, remoteResumeWarning, init_engineTarget = __esm({
178455
178618
  "build-src/src/sema/engineTarget.ts"() {
178456
178619
  init_concurrencyTestHooks();
178457
178620
  init_envUtils();
@@ -178460,8 +178623,10 @@ var ENGINE_URL_ENV, TRUSTED_ENGINE_HOSTS_KEY, enginePinUnreachable, SYNC_ENGINE_
178460
178623
  init_enginePortDerive();
178461
178624
  init_envKnobs();
178462
178625
  init_cloudExecutionPolicy();
178626
+ init_dist();
178463
178627
  ENGINE_URL_ENV = "SEMA_ENGINE_URL", TRUSTED_ENGINE_HOSTS_KEY = "trustedEngineHosts";
178464
- enginePinUnreachable = null;
178628
+ isLoopbackEngineUrl = isLoopbackWireUrl;
178629
+ isEngineTransportError = isWireTransportError, enginePinUnreachable = null;
178465
178630
  SYNC_ENGINE_URL_ENV = "SEMA_SYNC_ENGINE_URL", AUTO_SYNC_SOURCE_LABEL = {
178466
178631
  "sync-target": "sync target",
178467
178632
  "org-default": "org default",
@@ -178771,67 +178936,9 @@ var mockClientIds, init_mockClient = __esm({
178771
178936
  });
178772
178937
 
178773
178938
  // build-src/src/sema/armedGateRegistry.ts
178774
- function emitGateArmedEvent(key) {
178775
- for (let listener5 of [...armedListeners])
178776
- try {
178777
- listener5(key);
178778
- } catch {
178779
- }
178780
- }
178781
- function registerArmedGate2(key) {
178782
- typeof key != "string" || key.length === 0 || (armedKeys.add(key), emitGateArmedEvent(key));
178783
- }
178784
- function wasGateArmed2(key) {
178785
- return typeof key == "string" && key.length > 0 && armedKeys.has(key);
178786
- }
178787
- function onGateArmed(listener5) {
178788
- return armedListeners.add(listener5), () => {
178789
- armedListeners.delete(listener5);
178790
- };
178791
- }
178792
- function gateArmedWaitMs() {
178793
- return gateArmedWaitOverrideMs ?? GATE_ARMED_WAIT_MS;
178794
- }
178795
- function waitForGateArmed(keys2, timeoutMs) {
178796
- let wanted = new Set(keys2.filter((k2) => typeof k2 == "string" && k2.length > 0));
178797
- return wanted.size === 0 ? Promise.resolve(!1) : new Promise((resolve57) => {
178798
- let listener5 = (key) => {
178799
- wanted.has(key) && (armedListeners.delete(listener5), clearTimeout(timer2), resolve57(!0));
178800
- };
178801
- armedListeners.add(listener5);
178802
- let timer2 = setTimeout(() => {
178803
- armedListeners.delete(listener5), resolve57(!1);
178804
- }, timeoutMs);
178805
- });
178806
- }
178807
- function armedKeyFromQuestionId2(questionId) {
178808
- let trimmed2 = armedKeyFromQuestionId(questionId);
178809
- return trimmed2.startsWith(PLAN_REVIEW_QUESTION_ID_PREFIX) ? planReviewArmedKey(trimmed2.slice(PLAN_REVIEW_QUESTION_ID_PREFIX.length)) : trimmed2;
178810
- }
178811
- function registerArmedGateFromQuestionId2(questionId) {
178812
- if (typeof questionId != "string" || questionId.length === 0) return;
178813
- let normalized = armedKeyFromQuestionId2(questionId);
178814
- registerArmedGate2(normalized), questionId !== normalized && emitGateArmedEvent(questionId);
178815
- }
178816
- function planReviewArmedKey(taskId) {
178817
- let gen = planReviewGenByTask.get(taskId) ?? 0, canonical2 = planReviewQuestionId(taskId);
178818
- return gen > 0 ? `${canonical2}#g${String(gen)}` : canonical2;
178819
- }
178820
- function notePlanReviewAnswered(questionId) {
178821
- if (typeof questionId != "string" || !questionId.startsWith(PLAN_REVIEW_QUESTION_ID_PREFIX) || notedPlanReviewQuestionIds.has(questionId)) return;
178822
- notedPlanReviewQuestionIds.add(questionId);
178823
- let base = questionId.slice(PLAN_REVIEW_QUESTION_ID_PREFIX.length), cut = base.indexOf(REOPEN_ID_TAIL), taskId = cut >= 0 ? base.slice(0, cut) : base;
178824
- taskId.length !== 0 && planReviewGenByTask.set(taskId, (planReviewGenByTask.get(taskId) ?? 0) + 1);
178825
- }
178826
- function notePlanReviewAnsweredIfDecisive(questionId, answer) {
178827
- planReviewDecisionFromAnswer(answer ?? { answers: [] }) !== "dismissed" && notePlanReviewAnswered(questionId);
178828
- }
178829
- var armedKeys, armedListeners, GATE_ARMED_WAIT_MS, gateArmedWaitOverrideMs, planReviewGenByTask, notedPlanReviewQuestionIds, init_armedGateRegistry2 = __esm({
178939
+ var init_armedGateRegistry2 = __esm({
178830
178940
  "build-src/src/sema/armedGateRegistry.ts"() {
178831
178941
  init_dist();
178832
- armedKeys = /* @__PURE__ */ new Set(), armedListeners = /* @__PURE__ */ new Set();
178833
- GATE_ARMED_WAIT_MS = 5e3, gateArmedWaitOverrideMs = null;
178834
- planReviewGenByTask = /* @__PURE__ */ new Map(), notedPlanReviewQuestionIds = /* @__PURE__ */ new Set();
178835
178942
  }
178836
178943
  });
178837
178944
 
@@ -178878,81 +178985,33 @@ __export(planReviewReopen_exports, {
178878
178985
  _resetPlanReviewReopenSeqForTest: () => _resetPlanReviewReopenSeqForTest,
178879
178986
  reopenPlanReviewCard: () => reopenPlanReviewCard2
178880
178987
  });
178881
- function retireActiveReopen2(canonicalId) {
178882
- let prev = activeReopenByCanonical.get(canonicalId);
178883
- if (prev) {
178884
- activeReopenByCanonical.delete(canonicalId);
178988
+ function deliverPlanReviewDecision(taskId, decision) {
178989
+ decidePlanReview(taskId, decision).catch((e) => {
178885
178990
  try {
178886
- prev.unregister();
178991
+ let line = "sema: your plan review decision could not be delivered to the engine \u2014 the session may still be held; send your message again to retry";
178992
+ surfaceTranscriptSystemNotice(line) || process.stderr.write(`${line}
178993
+ `), process.env.SEMA_DEBUG && console.error(`[sema][planReviewReopen] decide (${decision}, run ${taskId}) threw unexpectedly: ${String(e)}`);
178887
178994
  } catch {
178888
178995
  }
178889
- publishQuestionFrame({ type: "question_complete", questionId: prev.questionId });
178890
- }
178996
+ });
178891
178997
  }
178892
178998
  function _resetPlanReviewReopenSeqForTest() {
178893
- reopenSeq = 0;
178894
- for (let [, entry] of activeReopenByCanonical)
178895
- try {
178896
- entry.unregister();
178897
- } catch (e) {
178898
- failOpen("plan-review-reopen-unregister", void 0, String(e));
178899
- }
178900
- activeReopenByCanonical.clear();
178999
+ _resetActiveReopenRespondersForTest();
178901
179000
  }
178902
179001
  async function reopenPlanReviewCard2(taskId) {
178903
- try {
178904
- if (typeof taskId != "string" || taskId.length === 0) return { reopened: !1 };
178905
- if (!hasQuestionOverlay()) return { reopened: !1 };
178906
- let armedKey = planReviewArmedKey(taskId), firstSight = !wasGateArmed2(armedKey), canonicalId = planReviewQuestionId(taskId);
178907
- retireActiveReopen2(canonicalId), reopenSeq += 1;
178908
- let questionId = `${canonicalId}${REOPEN_ID_TAIL}${String(reopenSeq)}`, unregister = registerLocalQuestionResponder(questionId, async (id, answer) => {
178909
- activeReopenByCanonical.get(canonicalId)?.questionId === questionId && activeReopenByCanonical.delete(canonicalId);
178910
- let decision = planReviewDecisionFromAnswer(answer);
178911
- return decision === "dismissed" ? { ok: !0 } : (notePlanReviewAnswered(id), decidePlanReview(taskId, decision).catch((e) => {
178912
- try {
178913
- let line = "sema: your plan review decision could not be delivered to the engine \u2014 the session may still be held; send your message again to retry";
178914
- surfaceTranscriptSystemNotice(line) || process.stderr.write(`${line}
178915
- `), process.env.SEMA_DEBUG && console.error(`[sema][planReviewReopen] decide (${decision}, run ${taskId}) threw unexpectedly: ${String(e)}`);
178916
- } catch {
178917
- }
178918
- }), { ok: !0 });
178919
- });
178920
- activeReopenByCanonical.set(canonicalId, { questionId, unregister });
178921
- let frame = {
178922
- type: "question",
178923
- questionId,
178924
- questions: [
178925
- {
178926
- header: "Plan review",
178927
- question: "This plan is still waiting for your review \u2014 it is what is holding this session. Approve it and start the implementation?",
178928
- options: [
178929
- {
178930
- label: APPROVE_LABEL2,
178931
- description: "Resume the task now and execute the plan (runs to completion engine-side)"
178932
- },
178933
- {
178934
- label: REJECT_LABEL2,
178935
- description: "Discard this plan and stay in plan mode to refine it"
178936
- }
178937
- ],
178938
- multiSelect: !1
178939
- }
178940
- ]
178941
- }, receipt = waitForGateArmed([questionId], gateArmedWaitMs());
178942
- return publishQuestionFrame(frame), await receipt ? { reopened: !0, firstSight } : (process.env.SEMA_DEBUG && console.error(
178943
- `[sema][planReviewReopen] question frame ${questionId} published but no presentation receipt arrived within ${String(gateArmedWaitMs())}ms \u2014 reporting reopened:false (the overlay did not enqueue the card)`
178944
- ), { reopened: !1 });
178945
- } catch {
178946
- return { reopened: !1 };
178947
- }
179002
+ let verdict = await reopenPlanReviewCard(taskId, {
179003
+ presentationReceiptMs: gateArmedWaitMs(),
179004
+ deliverDecision: deliverPlanReviewDecision
179005
+ });
179006
+ return verdict.reopened === !1 && process.env.SEMA_DEBUG && console.error(
179007
+ hasQuestionOverlay() ? `[sema][planReviewReopen] reopen for task ${taskId} got no presentation receipt within ${String(gateArmedWaitMs())}ms \u2014 reporting reopened:false (the overlay did not enqueue the card)` : `[sema][planReviewReopen] reopen for task ${taskId} has no overlay subscriber (headless / REPL not mounted) \u2014 reporting reopened:false`
179008
+ ), verdict;
178948
179009
  }
178949
- var APPROVE_LABEL2, REJECT_LABEL2, reopenSeq, activeReopenByCanonical, init_planReviewReopen = __esm({
179010
+ var init_planReviewReopen = __esm({
178950
179011
  "build-src/src/sema/planReviewReopen.ts"() {
178951
179012
  init_dist();
178952
179013
  init_armedGateRegistry2();
178953
179014
  init_transcriptSystemNotice();
178954
- init_failOpen();
178955
- APPROVE_LABEL2 = PLAN_REVIEW_APPROVE_LABEL, REJECT_LABEL2 = PLAN_REVIEW_REJECT_LABEL, reopenSeq = 0, activeReopenByCanonical = /* @__PURE__ */ new Map();
178956
179015
  }
178957
179016
  });
178958
179017
 
@@ -178960,7 +179019,7 @@ var APPROVE_LABEL2, REJECT_LABEL2, reopenSeq, activeReopenByCanonical, init_plan
178960
179019
  function retryDelayMs() {
178961
179020
  return delayOverrideMs ?? DECIDE_RETRY_DELAY_MS;
178962
179021
  }
178963
- function sleep4(ms) {
179022
+ function sleep3(ms) {
178964
179023
  return new Promise((resolve57) => {
178965
179024
  setTimeout(resolve57, ms);
178966
179025
  });
@@ -178986,7 +179045,7 @@ async function attemptDecideWithOneRetry(opts) {
178986
179045
  }
178987
179046
  process.env.SEMA_DEBUG && console.error(
178988
179047
  `[sema][decideRetry] ${opts.label} failed (${first.detail}) \u2014 retrying once in ${String(retryDelayMs())}ms`
178989
- ), await sleep4(retryDelayMs());
179048
+ ), await sleep3(retryDelayMs());
178990
179049
  let second = await opts.attempt();
178991
179050
  return second.ok ? !0 : (surface(second.detail), !1);
178992
179051
  } catch (e) {
@@ -179010,8 +179069,8 @@ __export(askParkReopen_exports, {
179010
179069
  countOwnedPendingApprovals: () => countOwnedPendingApprovals,
179011
179070
  reopenAskParkCard: () => reopenAskParkCard
179012
179071
  });
179013
- async function countOwnedPendingApprovals(client3) {
179014
- return ((await client3.approvals.list()).pending ?? []).filter((row2) => pendingRowIsOwnedByThisSession(row2, ownershipDeps)).length;
179072
+ async function countOwnedPendingApprovals(client3, signal) {
179073
+ return ((await client3.approvals.list(signal ? { signal } : void 0)).pending ?? []).filter((row2) => pendingRowIsOwnedByThisSession(row2, ownershipDeps)).length;
179015
179074
  }
179016
179075
  function reopenAskParkCard(taskId, client3, signal) {
179017
179076
  if (typeof taskId != "string" || taskId.length === 0) return Promise.resolve({ reopened: !1 });
@@ -179095,7 +179154,7 @@ function armPendingRowCoalesced(flight, taskId, pending2, client3) {
179095
179154
  }
179096
179155
  async function armPendingRow(taskId, pending2, client3, identity3) {
179097
179156
  try {
179098
- let { rowTaskId, gatedCallId, armedKey } = identity3, firstSight = !wasGateArmed2(armedKey), rowStillPending = async () => {
179157
+ let { rowTaskId, gatedCallId, armedKey } = identity3, firstSight = !wasGateArmed(armedKey), rowStillPending = async () => {
179099
179158
  try {
179100
179159
  return askParkRowStillPending((await client3.approvals.list()).pending, identity3);
179101
179160
  } catch {
@@ -179119,8 +179178,8 @@ async function armPendingRow(taskId, pending2, client3, identity3) {
179119
179178
  `[sema][askParkReopen] row (task ${rowTaskId}) routed to the question arm but carries no question payload \u2014 refusing to mint an empty card, reporting reopened:false`
179120
179179
  ), { kind: "verdict", verdict: { reopened: !1 } };
179121
179180
  let attributedQuestions = rowTaskId !== taskId ? questions.map((q2, i) => i === 0 ? { ...q2, question: `[pending on run ${rowTaskId}] ${q2.question}` } : q2) : questions;
179122
- reopenSeq2 += 1;
179123
- let questionId = `ask-park:${rowTaskId}${REOPEN_ID_TAIL}${String(reopenSeq2)}`, unregister = registerLocalQuestionResponder(questionId, async (_id, answer) => {
179181
+ reopenSeq += 1;
179182
+ let questionId = `ask-park:${rowTaskId}${REOPEN_ID_TAIL}${String(reopenSeq)}`, unregister = registerLocalQuestionResponder(questionId, async (_id, answer) => {
179124
179183
  try {
179125
179184
  unregister();
179126
179185
  } catch (e) {
@@ -179151,7 +179210,7 @@ async function armPendingRow(taskId, pending2, client3, identity3) {
179151
179210
  questionId,
179152
179211
  questions: attributedQuestions
179153
179212
  }, receipt2 = waitForGateArmed([questionId], gateArmedWaitMs());
179154
- return publishQuestionFrame(frame), await receipt2 ? (registerArmedGate2(armedKey), { kind: "verdict", verdict: { reopened: !0, firstSight } }) : (process.env.SEMA_DEBUG && console.error(
179213
+ return publishQuestionFrame(frame), await receipt2 ? (registerArmedGate(armedKey), { kind: "verdict", verdict: { reopened: !0, firstSight } }) : (process.env.SEMA_DEBUG && console.error(
179155
179214
  `[sema][askParkReopen] question frame ${questionId} published but no presentation receipt arrived within ${String(gateArmedWaitMs())}ms \u2014 reporting reopened:false (the overlay did not enqueue the card)`
179156
179215
  ), { kind: "verdict", verdict: { reopened: !1 } });
179157
179216
  }
@@ -179201,14 +179260,14 @@ async function armPendingRow(taskId, pending2, client3, identity3) {
179201
179260
  ), { kind: "verdict", verdict: { reopened: !1 } };
179202
179261
  }
179203
179262
  }
179204
- var reopenSeq2, ownershipDeps, inFlightReopenByTask, rowWaitOverrideMs, rowPollOverrideMs, rowArmFlightEpoch, rowArmFlight, init_askParkReopen = __esm({
179263
+ var reopenSeq, ownershipDeps, inFlightReopenByTask, rowWaitOverrideMs, rowPollOverrideMs, rowArmFlightEpoch, rowArmFlight, init_askParkReopen = __esm({
179205
179264
  "build-src/src/sema/askParkReopen.ts"() {
179206
179265
  init_dist();
179207
179266
  init_liveSessionStore();
179208
179267
  init_armedGateRegistry2();
179209
179268
  init_decideRetry();
179210
179269
  init_failOpen();
179211
- reopenSeq2 = 0, ownershipDeps = {
179270
+ reopenSeq = 0, ownershipDeps = {
179212
179271
  currentSessionId: getLiveSessionId,
179213
179272
  isOwnRun: (taskIdTail) => {
179214
179273
  if (isOwnEngineRun(taskIdTail)) return !0;
@@ -179528,7 +179587,7 @@ async function* withInteractiveReattach(live, o) {
179528
179587
  }
179529
179588
  }
179530
179589
  async function* reattachLoop(machine, taskId, deps2, readLastEventId, writeLastEventId, originalTear) {
179531
- let { windowMs } = tuning(), now2 = deps2.now ?? Date.now, sleep10 = deps2.sleep ?? abortAwareSleep, log2 = deps2.log ?? (() => {
179590
+ let { windowMs } = tuning(), now2 = deps2.now ?? Date.now, sleep9 = deps2.sleep ?? abortAwareSleep, log2 = deps2.log ?? (() => {
179532
179591
  }), deadline = now2() + windowMs, attempt = 0, lastState2 = null, serverRetryAfterMs;
179533
179592
  for (log2(`[sema][reattach] live stream tore mid-turn for run ${taskId} \u2014 entering the reattach window (${String(windowMs)}ms)`); !machine.stopped && now2() < deadline; ) {
179534
179593
  attempt += 1, machine.noteAttempt(attempt), machine.setPhase("probing");
@@ -179568,7 +179627,7 @@ async function* reattachLoop(machine, taskId, deps2, readLastEventId, writeLastE
179568
179627
  if (machine.stopped) break;
179569
179628
  let backoff3 = reattachBackoffMs(attempt), delay = serverRetryAfterMs !== void 0 ? Math.max(backoff3, serverRetryAfterMs) : backoff3;
179570
179629
  if (serverRetryAfterMs = void 0, now2() + delay >= deadline) break;
179571
- machine.setPhase("waiting"), await sleep10(delay, machine.signal);
179630
+ machine.setPhase("waiting"), await sleep9(delay, machine.signal);
179572
179631
  }
179573
179632
  if (machine.stopped) {
179574
179633
  log2(`[sema][reattach] reconnect stopped by the user after ${String(attempt)} attempt(s) \u2014 no further requests`);
@@ -180790,11 +180849,6 @@ var MONTH_ABBR, init_quotaExhaustedCopy = __esm({
180790
180849
  });
180791
180850
 
180792
180851
  // build-src/src/sema/scenarioNotAllowedCopy.ts
180793
- function scenarioDenyFromError(err8) {
180794
- if (typeof err8 != "object" || err8 === null) return null;
180795
- let e = err8;
180796
- return e.status !== 400 || e.errorCode !== "scenario_not_allowed" ? null : { allowlist: Array.isArray(e.allowlist) ? e.allowlist.filter((x3) => typeof x3 == "string" && x3.length > 0) : [] };
180797
- }
180798
180852
  function scenarioNotAllowedContent(detail, requestedScenario) {
180799
180853
  let parts = [];
180800
180854
  return parts.push(
@@ -180803,6 +180857,7 @@ function scenarioNotAllowedContent(detail, requestedScenario) {
180803
180857
  }
180804
180858
  var init_scenarioNotAllowedCopy = __esm({
180805
180859
  "build-src/src/sema/scenarioNotAllowedCopy.ts"() {
180860
+ init_dist();
180806
180861
  }
180807
180862
  });
180808
180863
 
@@ -182142,7 +182197,7 @@ async function killEngineChildWithAutopsyWindow(child, opts) {
182142
182197
  let t0 = Date.now();
182143
182198
  for (; Date.now() - t0 < windowMs; ) {
182144
182199
  if (child.exitCode !== null || child.signalCode !== null) return;
182145
- await sleep5(pollMs);
182200
+ await sleep4(pollMs);
182146
182201
  }
182147
182202
  if (child.exitCode === null && child.signalCode === null)
182148
182203
  try {
@@ -182480,18 +182535,18 @@ async function reapStaleEngine(portFile, opts) {
182480
182535
  };
182481
182536
  signal("SIGTERM");
182482
182537
  let t0 = Date.now();
182483
- for (; Date.now() - t0 < SHUTDOWN_GRACE_MS && isProcessAlive(portFile.pid); ) await sleep5(200);
182538
+ for (; Date.now() - t0 < SHUTDOWN_GRACE_MS && isProcessAlive(portFile.pid); ) await sleep4(200);
182484
182539
  if (isProcessAlive(portFile.pid)) {
182485
182540
  logForDebugging(
182486
182541
  `[engine-lifecycle] reap pid=${portFile.pid}: no exit in ${SHUTDOWN_GRACE_MS}ms \u2192 second SIGTERM (engine hardShutdown)`
182487
182542
  ), signal("SIGTERM");
182488
182543
  let t1 = Date.now();
182489
- for (; Date.now() - t1 < SHUTDOWN_SECOND_TERM_GRACE_MS && isProcessAlive(portFile.pid); ) await sleep5(200);
182544
+ for (; Date.now() - t1 < SHUTDOWN_SECOND_TERM_GRACE_MS && isProcessAlive(portFile.pid); ) await sleep4(200);
182490
182545
  }
182491
182546
  if (isProcessAlive(portFile.pid)) {
182492
182547
  logForDebugging(`[engine-lifecycle] reap pid=${portFile.pid}: still alive after second SIGTERM \u2192 SIGKILL`), signal("SIGKILL");
182493
182548
  let t2 = Date.now();
182494
- for (; Date.now() - t2 < 2e3 && isProcessAlive(portFile.pid); ) await sleep5(200);
182549
+ for (; Date.now() - t2 < 2e3 && isProcessAlive(portFile.pid); ) await sleep4(200);
182495
182550
  }
182496
182551
  }
182497
182552
  let portPath = getEnginePortFilePath();
@@ -182756,7 +182811,7 @@ async function waitForLockOrAttach(portFilePath, configHome) {
182756
182811
  let budget = engineLockWaitBudgetMs(), t0 = Date.now();
182757
182812
  for (; Date.now() - t0 < budget; ) {
182758
182813
  let remaining = budget - (Date.now() - t0);
182759
- await sleep5(Math.max(1, Math.min(ENGINE_LOCK_WAIT_POLL_MS, remaining)));
182814
+ await sleep4(Math.max(1, Math.min(ENGINE_LOCK_WAIT_POLL_MS, remaining)));
182760
182815
  try {
182761
182816
  let release2 = await lock(portFilePath, { stale: LOCK_OPTS2.stale });
182762
182817
  return logForDebugging(
@@ -182842,11 +182897,11 @@ async function waitForHealthy(port2, child) {
182842
182897
  if (delay === null) break;
182843
182898
  delay === HEALTH_POLL_EXTENDED_INTERVAL_MS && !extensionLogged && (extensionLogged = !0, logForDebugging(
182844
182899
  "[engine-lifecycle] engine is slow to start (possibly high load) \u2014 child is alive, extending health wait to 60s total"
182845
- )), await sleep5(delay);
182900
+ )), await sleep4(delay);
182846
182901
  }
182847
182902
  return await probeHealth(port2);
182848
182903
  }
182849
- function sleep5(ms) {
182904
+ function sleep4(ms) {
182850
182905
  return new Promise((resolve57) => setTimeout(resolve57, ms));
182851
182906
  }
182852
182907
  function startHealthCheckLoop(instance2, onDead) {
@@ -182967,7 +183022,7 @@ async function runEngineDeadRespawn(deps2) {
182967
183022
  "[engine-lifecycle] host terminal is gone \u2014 refusing engine respawn, shutting down the orphaned shell"
182968
183023
  ), teardownOwnedEngineSync("orphan-respawn-guard"), process.exit(129)), deadRespawnInFlight) return !1;
182969
183024
  deadRespawnInFlight = !0;
182970
- let now2 = deps2.now ?? Date.now, doSleep = deps2.sleep ?? sleep5, backoff3 = deps2.backoffMs ?? [1e3, 5e3, 15e3];
183025
+ let now2 = deps2.now ?? Date.now, doSleep = deps2.sleep ?? sleep4, backoff3 = deps2.backoffMs ?? [1e3, 5e3, 15e3];
182971
183026
  try {
182972
183027
  let t2 = now2();
182973
183028
  if (lastRespawnOkAt !== null && t2 - lastRespawnOkAt >= CRASH_LOOP_WINDOW_MS && (cooldownRetryLevel = 0, cooldownRetriesUsed = 0, cooldownSpentMs = 0), recentDeathTimestamps = recentDeathTimestamps.filter((d4) => t2 - d4 < CRASH_LOOP_WINDOW_MS), recentDeathTimestamps.push(t2), recentDeathTimestamps.length > CRASH_LOOP_MAX_DEATHS) {
@@ -183167,7 +183222,7 @@ async function waitForExit(pid, timeoutMs) {
183167
183222
  let deadline = Date.now() + timeoutMs;
183168
183223
  for (; Date.now() < deadline; ) {
183169
183224
  if (!isProcessAlive(pid)) return !0;
183170
- await sleep5(100);
183225
+ await sleep4(100);
183171
183226
  }
183172
183227
  return !isProcessAlive(pid);
183173
183228
  }
@@ -183910,7 +183965,7 @@ __export(seamQuery_exports, {
183910
183965
  SCENARIO_KEYS: () => SCENARIO_KEYS,
183911
183966
  canUseTool: () => canUseTool,
183912
183967
  cancelEngineRun: () => cancelEngineRun,
183913
- drainingRetryDelayMs: () => drainingRetryDelayMs,
183968
+ drainingRetryDelayMs: () => drainingRetryDelayMs2,
183914
183969
  getSeamHitlClient: () => getSeamHitlClient,
183915
183970
  getSeamMcp: () => getSeamMcp,
183916
183971
  getSeamSandbox: () => getSeamSandbox,
@@ -183945,22 +184000,10 @@ function hasHitlVerbs(c2) {
183945
184000
  return typeof o.approvals?.list == "function" && typeof o.approvals?.decide == "function" && typeof o.assistant?.planReview == "function" && typeof o.assistant?.resume == "function";
183946
184001
  }
183947
184002
  function setDrainingBackoffForTest(ms) {
183948
- drainingBackoffMs = ms && ms.length > 0 ? ms : DEFAULT_DRAINING_BACKOFF_MS;
184003
+ drainingBackoffMs = ms && ms.length > 0 ? ms : void 0;
183949
184004
  }
183950
- function isPreStreamDrainingReject(err8) {
183951
- let e = err8;
183952
- return typeof e?.status == "number" && e.status === 503 && e.errorCode === "draining";
183953
- }
183954
- function isResumeAtRejection(err8) {
183955
- let e = err8;
183956
- return typeof e?.errorCode == "string" && e.errorCode.startsWith("resume_at.");
183957
- }
183958
- function drainingRetryDelayMs(err8, attempt) {
183959
- let ra = err8?.retryAfterMs;
183960
- if (typeof ra == "number" && Number.isFinite(ra) && ra >= 0)
183961
- return Math.min(ra, DRAINING_RETRY_AFTER_CAP_MS);
183962
- let ladder = drainingBackoffMs;
183963
- return ladder[Math.min(attempt, ladder.length - 1)] ?? 1e3;
184005
+ function drainingRetryDelayMs2(err8, attempt) {
184006
+ return drainingRetryDelayMs(err8, attempt, drainingBackoffMs ? { ladder: drainingBackoffMs } : void 0);
183964
184007
  }
183965
184008
  function isBgHeadlessWorker() {
183966
184009
  return process.env.SEMA_CODE_SESSION_KIND === "bg" && !!process.env.SEMA_JOB_DIR && !!process.env.SEMA_LIVE_BASEURL;
@@ -184274,23 +184317,18 @@ ${objective}`, process.env.SEMA_DEBUG && console.error("[sema][seamQuery] interr
184274
184317
  );
184275
184318
  }
184276
184319
  function semaApiErrorContent(err8, requestedScenario) {
184277
- let e = err8;
184278
- if (typeof e?.status == "number") {
184279
- let code2 = typeof e.errorCode == "string" && e.errorCode.length > 0 ? ` ${e.errorCode}` : "", msg = typeof e.message == "string" && e.message.length > 0 ? e.message : String(err8), lines = [`${API_ERROR_PREFIX}: ${e.status}${code2} \xB7 ${msg}`], supplement = semaApiErrorSupplement(err8, requestedScenario);
184320
+ let verdict = classifyTurnWireError(err8);
184321
+ if (verdict.kind === "http") {
184322
+ let code2 = verdict.errorCode !== void 0 ? ` ${verdict.errorCode}` : "", lines = [`${API_ERROR_PREFIX}: ${verdict.status}${code2} \xB7 ${verdict.message}`], supplement = semaApiErrorSupplement(err8, requestedScenario);
184280
184323
  supplement && lines.push(supplement);
184281
184324
  let sandboxHint = sandboxDegradeHint(err8);
184282
184325
  return sandboxHint && lines.push(sandboxHint), lines.join(`
184283
184326
  `);
184284
184327
  }
184285
- let cause = e?.cause, detail = typeof cause?.message == "string" && cause.message.length > 0 && cause.message || typeof e?.message == "string" && e.message.length > 0 && e.message || String(err8), isNetworkError = e?.cause !== void 0 || /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|EHOSTUNREACH|ENETUNREACH|EPIPE|socket hang up|UND_ERR|terminated|other side closed/i.test(
184286
- detail
184287
- );
184288
- if (err8 instanceof Error && err8.name === "StreamEndedWithoutTerminalError")
184328
+ if (verdict.kind === "stream-ended-without-terminal")
184289
184329
  return `${API_ERROR_PREFIX}: the event stream ended while the run had not reached a terminal state \u2014 the run is likely parked waiting for an approval decision (suspended / needs_review), not crashed. Check /tasks for its real status and decide any pending approval; the turn did not complete on this screen.`;
184290
- if (!isNetworkError) {
184291
- let name = err8 instanceof Error ? err8.name : typeof err8;
184292
- return `${API_ERROR_PREFIX}: internal shell error (${name}: ${detail}) \u2014 this is a bug in the sema shell, not an engine outage; the turn did not complete. Re-run with SEMA_DEBUG=1 and report it.`;
184293
- }
184330
+ if (verdict.kind === "internal")
184331
+ return `${API_ERROR_PREFIX}: internal shell error (${verdict.name}: ${verdict.detail}) \u2014 this is a bug in the sema shell, not an engine outage; the turn did not complete. Re-run with SEMA_DEBUG=1 and report it.`;
184294
184332
  let pinHint = "";
184295
184333
  try {
184296
184334
  let pin = activeEnginePin();
@@ -184298,7 +184336,7 @@ function semaApiErrorContent(err8, requestedScenario) {
184298
184336
  ${enginePinUnreachableHint(pin)}`);
184299
184337
  } catch {
184300
184338
  }
184301
- return `${API_ERROR_PREFIX}: ${detail} \xB7 the engine is unreachable \u2014 your message did not run; check the engine is up, then send it again.${pinHint}`;
184339
+ return `${API_ERROR_PREFIX}: ${verdict.detail} \xB7 the engine is unreachable \u2014 your message did not run; check the engine is up, then send it again.${pinHint}`;
184302
184340
  }
184303
184341
  function apiErrorRow(content) {
184304
184342
  return createAssistantAPIErrorMessage({ content, error: "unknown" });
@@ -184445,7 +184483,7 @@ Fix: run \`sema doctor\` to diagnose, or restart sema to retry.`
184445
184483
  let notice = fileLinkNoticeText(ev);
184446
184484
  notice !== null && surfaceFileLinkNotice(notice);
184447
184485
  }
184448
- let busy = activeRunBusySignal2(ev);
184486
+ let busy = activeRunBusySignal(ev);
184449
184487
  if (busy) {
184450
184488
  busySignal = busy;
184451
184489
  return;
@@ -184501,7 +184539,9 @@ Fix: run \`sema doctor\` to diagnose, or restart sema to retry.`
184501
184539
  // **属主** pending 行数,恰 0 = 脏值正面证据 ⇒ 放行真分诊;归属过滤见
184502
184540
  // countOwnedPendingApprovals 头注(引擎全局队列有别家陈年行,裸计数恒非零
184503
184541
  // = 防御恒不触发)。mock 车道无 approvals 面 ⇒ 读口不装 = 旧行为(S-g)。
184504
- listOwnedPendingApprovals: () => countOwnedPendingApprovals(hitl)
184542
+ // 🔴 opts.signal = 包内复核竞速的合流截止口(4s 窗 × turn Esc),透传进
184543
+ // approvals.list —— 超时/中止掐的是底层请求,不是只掐 await(复审轮二)。
184544
+ listOwnedPendingApprovals: (opts) => countOwnedPendingApprovals(hitl, opts?.signal)
184505
184545
  } : {};
184506
184546
  })(),
184507
184547
  // C3([3777]/[3779])running 形的三选卡口。**一条用户消息至多一张**(runningChoiceOffered
@@ -184521,14 +184561,14 @@ Fix: run \`sema doctor\` to diagnose, or restart sema to retry.`
184521
184561
  // 车B 的消费面(deps.signal)逐字不变。
184522
184562
  ...signal ? { signal } : {}
184523
184563
  });
184524
- if (yield apiErrorRow(activeRunSelfHealRow2(outcome, detectedBusy)), outcome.kind === "running-cancelled" && !signal?.aborted) {
184564
+ if (yield apiErrorRow(activeRunSelfHealRow(outcome, detectedBusy)), outcome.kind === "running-cancelled" && !signal?.aborted) {
184525
184565
  retryStream = !0;
184526
184566
  continue;
184527
184567
  }
184528
184568
  }
184529
184569
  } catch (err8) {
184530
184570
  if (!signal?.aborted && !engineFrameSeen && isPreStreamDrainingReject(err8) && drainingRetries < DRAINING_MAX_RETRIES) {
184531
- let waitMs = drainingRetryDelayMs(err8, drainingRetries);
184571
+ let waitMs = drainingRetryDelayMs2(err8, drainingRetries);
184532
184572
  if (drainingRetries++, process.env.SEMA_DEBUG && console.error(
184533
184573
  `[sema][seamQuery] engine draining (pre-stream 503) \u2014 retrying submit ${drainingRetries}/${DRAINING_MAX_RETRIES} in ${waitMs}ms`
184534
184574
  ), await new Promise((res) => setTimeout(res, waitMs)), !signal?.aborted) {
@@ -184741,7 +184781,7 @@ function resumeRunningArmWiring() {
184741
184781
  shellSessionId: () => getSessionId()
184742
184782
  };
184743
184783
  }
184744
- var BG_TEAR_MAX_RESENDS, BG_RECOVERY_WAIT_MS, DRAINING_MAX_RETRIES, DEFAULT_DRAINING_BACKOFF_MS, DRAINING_RETRY_AFTER_CAP_MS, drainingBackoffMs, client, clientExplicitlySet, seamSettings, seamWebSearch, seamSkills, seamMcp, seamRewindCapture, seamPendingRewind, INTERRUPT_WIRE_MARKER, seamPendingInterrupt, seamHistorySeedPending, seamSandbox, seamAutoSandboxInjected, HISTORY_SEED_MAX_CHARS, SCENARIO_KEYS, API_ERROR_PREFIX, defaultGatePrompt, canUseTool, RUN_PROBE_TIMEOUT_MS, init_seamQuery = __esm({
184784
+ var BG_TEAR_MAX_RESENDS, BG_RECOVERY_WAIT_MS, DRAINING_MAX_RETRIES, drainingBackoffMs, client, clientExplicitlySet, seamSettings, seamWebSearch, seamSkills, seamMcp, seamRewindCapture, seamPendingRewind, INTERRUPT_WIRE_MARKER, seamPendingInterrupt, seamHistorySeedPending, seamSandbox, seamAutoSandboxInjected, HISTORY_SEED_MAX_CHARS, SCENARIO_KEYS, API_ERROR_PREFIX, defaultGatePrompt, canUseTool, RUN_PROBE_TIMEOUT_MS, init_seamQuery = __esm({
184745
184785
  "build-src/src/sema/seamQuery.ts"() {
184746
184786
  init_adapter();
184747
184787
  init_dist();
@@ -184763,6 +184803,7 @@ var BG_TEAR_MAX_RESENDS, BG_RECOVERY_WAIT_MS, DRAINING_MAX_RETRIES, DEFAULT_DRAI
184763
184803
  init_dist();
184764
184804
  init_dist();
184765
184805
  init_dist();
184806
+ init_dist();
184766
184807
  init_deferSessionExemption();
184767
184808
  init_debug();
184768
184809
  init_hooksWireCaps2();
@@ -184798,7 +184839,7 @@ var BG_TEAR_MAX_RESENDS, BG_RECOVERY_WAIT_MS, DRAINING_MAX_RETRIES, DEFAULT_DRAI
184798
184839
  init_log2();
184799
184840
  init_engineRuntimeStatus();
184800
184841
  init_activeRunSelfHeal2();
184801
- BG_TEAR_MAX_RESENDS = 2, BG_RECOVERY_WAIT_MS = 12e4, DRAINING_MAX_RETRIES = 3, DEFAULT_DRAINING_BACKOFF_MS = [1e3, 2e3, 4e3], DRAINING_RETRY_AFTER_CAP_MS = 15e3, drainingBackoffMs = DEFAULT_DRAINING_BACKOFF_MS;
184842
+ BG_TEAR_MAX_RESENDS = 2, BG_RECOVERY_WAIT_MS = 12e4, DRAINING_MAX_RETRIES = 3;
184802
184843
  client = makeMockClient(), clientExplicitlySet = !1;
184803
184844
  seamRewindCapture = !0;
184804
184845
  INTERRUPT_WIRE_MARKER = "[Request interrupted by user]", seamPendingInterrupt = !1;
@@ -201033,7 +201074,7 @@ var require_ceylon = __commonJS({
201033
201074
  // node_modules/highlight.js/lib/languages/clean.js
201034
201075
  var require_clean2 = __commonJS({
201035
201076
  "node_modules/highlight.js/lib/languages/clean.js"(exports2, module2) {
201036
- function clean5(hljs2) {
201077
+ function clean6(hljs2) {
201037
201078
  return {
201038
201079
  name: "Clean",
201039
201080
  aliases: [
@@ -201089,7 +201130,7 @@ var require_clean2 = __commonJS({
201089
201130
  ]
201090
201131
  };
201091
201132
  }
201092
- module2.exports = clean5;
201133
+ module2.exports = clean6;
201093
201134
  }
201094
201135
  });
201095
201136
 
@@ -257943,7 +257984,7 @@ function stripUnderlineAnsi(content) {
257943
257984
  }
257944
257985
  var import_compiler_runtime24, React16, import_jsx_runtime27, MAX_JSON_FORMAT_LENGTH, URL_IN_JSON, init_OutputLine = __esm({
257945
257986
  "build-src/src/components/shell/OutputLine.tsx"() {
257946
- import_compiler_runtime24 = __toESM(require_compiler_runtime(), 1), React16 = __toESM(require_react(), 1);
257987
+ import_compiler_runtime24 = __toESM(require_compiler_runtime()), React16 = __toESM(require_react());
257947
257988
  init_useTerminalSize();
257948
257989
  init_ink2();
257949
257990
  init_hyperlink();
@@ -257952,7 +257993,7 @@ var import_compiler_runtime24, React16, import_jsx_runtime27, MAX_JSON_FORMAT_LE
257952
257993
  init_MessageResponse();
257953
257994
  init_messageActions();
257954
257995
  init_ExpandShellOutputContext();
257955
- import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
257996
+ import_jsx_runtime27 = __toESM(require_jsx_runtime());
257956
257997
  MAX_JSON_FORMAT_LENGTH = 1e4;
257957
257998
  URL_IN_JSON = /https?:\/\/[^\s"'<>\\]+/g;
257958
257999
  }
@@ -262544,7 +262585,7 @@ var import_xss2, AUTH_REQUEST_TIMEOUT_MS, MAX_LOCK_RETRIES, SENSITIVE_OAUTH_PARA
262544
262585
  logMCPDebug(
262545
262586
  this.serverName,
262546
262587
  `Refresh lock held by another process, waiting (attempt ${retry + 1}/${MAX_LOCK_RETRIES})`
262547
- ), await sleep3(1e3 + Math.random() * 1e3);
262588
+ ), await sleep2(1e3 + Math.random() * 1e3);
262548
262589
  continue;
262549
262590
  }
262550
262591
  logMCPDebug(
@@ -262685,7 +262726,7 @@ var import_xss2, AUTH_REQUEST_TIMEOUT_MS, MAX_LOCK_RETRIES, SENSITIVE_OAUTH_PARA
262685
262726
  logMCPDebug(
262686
262727
  this.serverName,
262687
262728
  `Token refresh failed, retrying in ${delayMs}ms (attempt ${attempt}/3)`
262688
- ), await sleep3(delayMs);
262729
+ ), await sleep2(delayMs);
262689
262730
  }
262690
262731
  }
262691
262732
  };
@@ -263926,7 +263967,7 @@ async function findAvailableIDE() {
263926
263967
  let startTime = Date.now();
263927
263968
  for (; Date.now() - startTime < 3e4 && !signal.aborted; ) {
263928
263969
  if (getIsScrollDraining()) {
263929
- await sleep3(1e3, signal);
263970
+ await sleep2(1e3, signal);
263930
263971
  continue;
263931
263972
  }
263932
263973
  let ides = await detectIDEs(!1);
@@ -263934,7 +263975,7 @@ async function findAvailableIDE() {
263934
263975
  return null;
263935
263976
  if (ides.length === 1)
263936
263977
  return ides[0];
263937
- await sleep3(1e3, signal);
263978
+ await sleep2(1e3, signal);
263938
263979
  }
263939
263980
  return null;
263940
263981
  }
@@ -264038,7 +264079,7 @@ async function installIDEExtension(ideType) {
264038
264079
  return await installFromArtifactory(command8);
264039
264080
  let version4 = await getInstalledVSCodeExtensionVersion(command8);
264040
264081
  if (!version4 || lt(version4, getClaudeCodeVersion())) {
264041
- await sleep3(500);
264082
+ await sleep2(500);
264042
264083
  let result = await execFileNoThrowWithCwd(
264043
264084
  command8,
264044
264085
  ["--force", "--install-extension", "anthropic.claude-code"],
@@ -264306,7 +264347,7 @@ async function installFromArtifactory(command8) {
264306
264347
  }), writeStream = getFsImplementation().createWriteStream(tempVsixPath);
264307
264348
  await new Promise((resolve57, reject3) => {
264308
264349
  vsixResponse.data.pipe(writeStream), writeStream.on("finish", resolve57), writeStream.on("error", reject3);
264309
- }), await sleep3(500);
264350
+ }), await sleep2(500);
264310
264351
  let result = await execFileNoThrowWithCwd(
264311
264352
  command8,
264312
264353
  ["--force", "--install-extension", tempVsixPath],
@@ -268672,18 +268713,17 @@ var FINGERPRINT_SALT, init_fingerprint = __esm({
268672
268713
 
268673
268714
  // build-src/src/sema/livePrincipal.ts
268674
268715
  function resolveLivePrincipal() {
268675
- let v2 = process.env.SEMA_LIVE_PRINCIPAL;
268676
- return v2 && v2.trim() !== "" ? v2 : void 0;
268716
+ return normalizeWirePrincipal(process.env.SEMA_LIVE_PRINCIPAL);
268677
268717
  }
268678
268718
  function resolveFleetPrincipal() {
268679
- let v2 = process.env.SEMA_FLEET_PRINCIPAL;
268680
- return v2 && v2.trim() !== "" ? v2 : resolveLivePrincipal();
268719
+ return normalizeWirePrincipal(process.env.SEMA_FLEET_PRINCIPAL) ?? resolveLivePrincipal();
268681
268720
  }
268682
268721
  function describeLivePrincipal() {
268683
268722
  return resolveLivePrincipal() ?? "absent(owner-null)";
268684
268723
  }
268685
268724
  var init_livePrincipal = __esm({
268686
268725
  "build-src/src/sema/livePrincipal.ts"() {
268726
+ init_dist();
268687
268727
  }
268688
268728
  });
268689
268729
 
@@ -270679,7 +270719,7 @@ var McpAuthError, McpSessionExpiredError, McpToolCallError_I_VERIFIED_THIS_IS_NO
270679
270719
  ), resolve57());
270680
270720
  }, 600);
270681
270721
  try {
270682
- if (await sleep3(100), !resolved) {
270722
+ if (await sleep2(100), !resolved) {
270683
270723
  try {
270684
270724
  process.kill(childPid, 0), logMCPDebug(
270685
270725
  name,
@@ -270695,7 +270735,7 @@ var McpAuthError, McpSessionExpiredError, McpToolCallError_I_VERIFIED_THIS_IS_NO
270695
270735
  resolved = !0, clearInterval(checkInterval), clearTimeout(failsafeTimeout), resolve57();
270696
270736
  return;
270697
270737
  }
270698
- if (await sleep3(400), !resolved)
270738
+ if (await sleep2(400), !resolved)
270699
270739
  try {
270700
270740
  process.kill(childPid, 0), logMCPDebug(
270701
270741
  name,
@@ -274687,7 +274727,7 @@ function createLSPServerInstance(name, config4) {
274687
274727
  let delay = RETRY_BASE_DELAY_MS * Math.pow(2, attempt);
274688
274728
  logForDebugging(
274689
274729
  `LSP request '${method}' to '${name}' got ContentModified error, retrying in ${delay}ms (attempt ${attempt + 1}/${MAX_RETRIES_FOR_TRANSIENT_ERRORS})\u2026`
274690
- ), await sleep3(delay);
274730
+ ), await sleep2(delay);
274691
274731
  continue;
274692
274732
  }
274693
274733
  break;
@@ -281346,9 +281386,9 @@ function checkStartProcess(parsed) {
281346
281386
  }
281347
281387
  }
281348
281388
  if (cmd.args.some((a) => {
281349
- let clean5 = a.replace(/`/g, "");
281389
+ let clean6 = a.replace(/`/g, "");
281350
281390
  return /^[-\u2013\u2014\u2015/]v[a-z]*:['"` ]*runas['"` ]*$/i.test(
281351
- clean5
281391
+ clean6
281352
281392
  );
281353
281393
  }))
281354
281394
  return {
@@ -286127,7 +286167,7 @@ function FileEditToolUseRejectedMessage(t0) {
286127
286167
  }
286128
286168
  var import_compiler_runtime43, import_jsx_runtime52, MAX_LINES_TO_RENDER, init_FileEditToolUseRejectedMessage = __esm({
286129
286169
  "build-src/src/components/FileEditToolUseRejectedMessage.tsx"() {
286130
- import_compiler_runtime43 = __toESM(require_compiler_runtime());
286170
+ import_compiler_runtime43 = __toESM(require_compiler_runtime(), 1);
286131
286171
  init_useTerminalSize();
286132
286172
  init_cwd();
286133
286173
  init_ink2();
@@ -286135,7 +286175,7 @@ var import_compiler_runtime43, import_jsx_runtime52, MAX_LINES_TO_RENDER, init_F
286135
286175
  init_MessageResponse();
286136
286176
  init_StructuredDiffList();
286137
286177
  init_stringUtils();
286138
- import_jsx_runtime52 = __toESM(require_jsx_runtime()), MAX_LINES_TO_RENDER = 10;
286178
+ import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1), MAX_LINES_TO_RENDER = 10;
286139
286179
  }
286140
286180
  });
286141
286181
 
@@ -294728,7 +294768,7 @@ async function* withRetry(getClient, operation, options) {
294728
294768
  }
294729
294769
  let retryAfterMs = getRetryAfterMs(error51);
294730
294770
  if (retryAfterMs !== null && retryAfterMs < SHORT_RETRY_THRESHOLD_MS) {
294731
- await sleep3(retryAfterMs, options.signal, { abortError });
294771
+ await sleep2(retryAfterMs, options.signal, { abortError });
294732
294772
  continue;
294733
294773
  }
294734
294774
  let cooldownMs = Math.max(
@@ -294814,11 +294854,11 @@ async function* withRetry(getClient, operation, options) {
294814
294854
  maxRetries
294815
294855
  ));
294816
294856
  let chunk2 = Math.min(remaining, HEARTBEAT_INTERVAL_MS2);
294817
- await sleep3(chunk2, options.signal, { abortError }), remaining -= chunk2;
294857
+ await sleep2(chunk2, options.signal, { abortError }), remaining -= chunk2;
294818
294858
  }
294819
294859
  attempt >= maxRetries && (attempt = maxRetries);
294820
294860
  } else
294821
- error51 instanceof APIError && (yield createSystemAPIErrorMessage(error51, delayMs, attempt, maxRetries)), await sleep3(delayMs, options.signal, { abortError });
294861
+ error51 instanceof APIError && (yield createSystemAPIErrorMessage(error51, delayMs, attempt, maxRetries)), await sleep2(delayMs, options.signal, { abortError });
294822
294862
  }
294823
294863
  }
294824
294864
  throw new CannotRetryError(lastError, retryContext);
@@ -296573,7 +296613,7 @@ async function waitForSessionMemoryExtraction() {
296573
296613
  for (; extractionStartedAt; ) {
296574
296614
  if (Date.now() - extractionStartedAt > EXTRACTION_STALE_THRESHOLD_MS || Date.now() - startTime > EXTRACTION_WAIT_TIMEOUT_MS)
296575
296615
  return;
296576
- await sleep3(1e3);
296616
+ await sleep2(1e3);
296577
296617
  }
296578
296618
  }
296579
296619
  async function getSessionMemoryContent() {
@@ -299857,7 +299897,7 @@ async function streamCompactSummary({
299857
299897
  if (context3.abortController.signal.aborted)
299858
299898
  throw new Error(ERROR_MESSAGE_USER_ABORT);
299859
299899
  if (attempt < maxAttempts) {
299860
- await sleep3(getRetryDelay(attempt), context3.abortController.signal, {
299900
+ await sleep2(getRetryDelay(attempt), context3.abortController.signal, {
299861
299901
  abortError: () => new APIUserAbortError()
299862
299902
  });
299863
299903
  continue;
@@ -301111,7 +301151,7 @@ async function gracefulShutdown(exitCode = 0, reason = "other", options) {
301111
301151
  try {
301112
301152
  await Promise.race([
301113
301153
  Promise.all([shutdown1PEventLogging(), shutdownDatadog()]),
301114
- sleep3(500)
301154
+ sleep2(500)
301115
301155
  ]);
301116
301156
  } catch {
301117
301157
  }
@@ -301506,7 +301546,7 @@ async function fetchWithRetry(cachedChecksum) {
301506
301546
  let delayMs = getRetryDelay(attempt);
301507
301547
  logForDebugging(
301508
301548
  `Policy limits: Retry ${attempt}/${DEFAULT_MAX_RETRIES2} after ${delayMs}ms`
301509
- ), await sleep3(delayMs);
301549
+ ), await sleep2(delayMs);
301510
301550
  }
301511
301551
  return lastResult2;
301512
301552
  }
@@ -304001,7 +304041,7 @@ async function fetchWithRetry2(cachedChecksum) {
304001
304041
  let delayMs = getRetryDelay(attempt);
304002
304042
  logForDebugging(
304003
304043
  `Remote settings: Retry ${attempt}/${DEFAULT_MAX_RETRIES3} after ${delayMs}ms`
304004
- ), await sleep3(delayMs);
304044
+ ), await sleep2(delayMs);
304005
304045
  }
304006
304046
  return lastResult2;
304007
304047
  }
@@ -306333,7 +306373,7 @@ async function downloadAndVerifyBinary(binaryUrl, expectedChecksum, binaryPath,
306333
306373
  if (isStallTimeout ? lastError = new StallTimeoutError() : lastError = toError(error51), isStallTimeout && attempt < MAX_DOWNLOAD_RETRIES) {
306334
306374
  logForDebugging(
306335
306375
  `Download stalled on attempt ${attempt}/${MAX_DOWNLOAD_RETRIES}, retrying...`
306336
- ), await sleep3(1e3);
306376
+ ), await sleep2(1e3);
306337
306377
  continue;
306338
306378
  }
306339
306379
  throw lastError;
@@ -306687,7 +306727,7 @@ async function tryWithVersionLock(versionFilePath, callback, retries = 0) {
306687
306727
  minTimeout * Math.pow(2, attempts - 1),
306688
306728
  maxTimeout
306689
306729
  );
306690
- await sleep3(timeout3);
306730
+ await sleep2(timeout3);
306691
306731
  }
306692
306732
  }
306693
306733
  return logLockAcquisitionError(
@@ -312749,7 +312789,7 @@ async function waitForNextPromptOrShutdown(identity3, abortController, taskId, g
312749
312789
  from: "user"
312750
312790
  };
312751
312791
  }
312752
- if (pollCount > 0 && await sleep3(500), pollCount++, abortController.signal.aborted)
312792
+ if (pollCount > 0 && await sleep2(500), pollCount++, abortController.signal.aborted)
312753
312793
  return logForDebugging(
312754
312794
  `[inProcessRunner] ${identity3.agentName} aborted while waiting (poll #${pollCount})`
312755
312795
  ), { type: "aborted" };
@@ -313936,7 +313976,7 @@ __export(TmuxBackend_exports, {
313936
313976
  TmuxBackend: () => TmuxBackend
313937
313977
  });
313938
313978
  function waitForPaneShellReady() {
313939
- return sleep3(PANE_SHELL_INIT_DELAY_MS);
313979
+ return sleep2(PANE_SHELL_INIT_DELAY_MS);
313940
313980
  }
313941
313981
  function acquirePaneCreationLock() {
313942
313982
  let release2, newLock = new Promise((resolve57) => {
@@ -316475,7 +316515,7 @@ async function axiosGetWithRetry(url3, config4) {
316475
316515
  let delay = TELEPORT_RETRY_DELAYS[attempt] ?? 2e3;
316476
316516
  logForDebugging(
316477
316517
  `Teleport request failed (attempt ${attempt + 1}/${MAX_TELEPORT_RETRIES + 1}), retrying in ${delay}ms: ${errorMessage(error51)}`
316478
- ), await sleep3(delay);
316518
+ ), await sleep2(delay);
316479
316519
  }
316480
316520
  throw lastError;
316481
316521
  }
@@ -316972,7 +317012,7 @@ function useClaudeAiLimits() {
316972
317012
  }
316973
317013
  var import_react69, init_claudeAiLimitsHook = __esm({
316974
317014
  "build-src/src/services/claudeAiLimitsHook.ts"() {
316975
- import_react69 = __toESM(require_react(), 1);
317015
+ import_react69 = __toESM(require_react());
316976
317016
  init_claudeAiLimits();
316977
317017
  }
316978
317018
  });
@@ -323650,7 +323690,7 @@ async function appendSessionLogImpl(sessionId, entry, url3, headers) {
323650
323690
  let delayMs = Math.min(BASE_DELAY_MS2 * Math.pow(2, attempt - 1), 8e3);
323651
323691
  logForDebugging(
323652
323692
  `Remote persistence attempt ${attempt}/${MAX_RETRIES} failed, retrying in ${delayMs}ms\u2026`
323653
- ), await sleep3(delayMs);
323693
+ ), await sleep2(delayMs);
323654
323694
  }
323655
323695
  return !1;
323656
323696
  }
@@ -323887,7 +323927,7 @@ async function ensureDaemonRunning() {
323887
323927
  { detached: !0, stdio: "ignore", env: process.env, windowsHide: !0 }
323888
323928
  ).unref());
323889
323929
  for (let i = 0; i < 100; i++)
323890
- if (await sleep7(150), info = await readDaemonInfo(), info && isDaemonAlive(info) && await pingOk(info)) return info;
323930
+ if (await sleep6(150), info = await readDaemonInfo(), info && isDaemonAlive(info) && await pingOk(info)) return info;
323891
323931
  return null;
323892
323932
  }
323893
323933
  function daemonStartupFailureMessage(registeredLate) {
@@ -323923,7 +323963,7 @@ async function dispatchJob(job) {
323923
323963
  return { ok: !1, code: "daemon-unreachable" };
323924
323964
  }
323925
323965
  for (let i = 0; i < 40; i++) {
323926
- await sleep7(200);
323966
+ await sleep6(200);
323927
323967
  try {
323928
323968
  let r = await daemonRpc(info, { op: "await-ack", short: job.short }, 2e3), mapped = mapResponse(r);
323929
323969
  if (mapped) return mapped;
@@ -323951,11 +323991,11 @@ async function dispatchJob(job) {
323951
323991
  }
323952
323992
  return { ok: !1, code: "daemon-unreachable" };
323953
323993
  }
323954
- var MAX_RPC_BYTES, sleep7, init_client7 = __esm({
323994
+ var MAX_RPC_BYTES, sleep6, init_client7 = __esm({
323955
323995
  "build-src/src/daemon/client.ts"() {
323956
323996
  init_envUtils();
323957
323997
  init_state2();
323958
- MAX_RPC_BYTES = 1048576, sleep7 = (ms) => new Promise((r) => setTimeout(r, ms));
323998
+ MAX_RPC_BYTES = 1048576, sleep6 = (ms) => new Promise((r) => setTimeout(r, ms));
323959
323999
  }
323960
324000
  });
323961
324001
 
@@ -323969,7 +324009,7 @@ async function waitPidGone(pid, deadlineMs) {
323969
324009
  let until = Date.now() + deadlineMs;
323970
324010
  for (; Date.now() < until; ) {
323971
324011
  if (!isPidAlive(pid)) return !0;
323972
- await sleep8(100);
324012
+ await sleep7(100);
323973
324013
  }
323974
324014
  return !isPidAlive(pid);
323975
324015
  }
@@ -323979,7 +324019,7 @@ async function stopDaemonWorker(short) {
323979
324019
  try {
323980
324020
  let r = await daemonRpc(info, { op: "kill", short }, 1e4);
323981
324021
  for (let i = 0; !r.ok && r.code === "ESTARTING" && i < 10; i++)
323982
- await sleep8(200), r = await daemonRpc(info, { op: "kill", short }, 1e4);
324022
+ await sleep7(200), r = await daemonRpc(info, { op: "kill", short }, 1e4);
323983
324023
  if (r.ok) return { confirmed: !0 };
323984
324024
  if (r.code !== "ENOJOB")
323985
324025
  return { confirmed: !1, error: r.message ?? r.code };
@@ -324061,11 +324101,11 @@ async function respawnJob(short, opts = {}) {
324061
324101
  error: "Previous session is still shutting down \u2014 try again in a moment"
324062
324102
  } : { ok: !1, alive: !1, error: "Couldn't reach the daemon (not running)" };
324063
324103
  }
324064
- var sleep8, init_respawn = __esm({
324104
+ var sleep7, init_respawn = __esm({
324065
324105
  "build-src/src/daemon/respawn.ts"() {
324066
324106
  init_client7();
324067
324107
  init_state2();
324068
- sleep8 = (ms) => new Promise((r) => setTimeout(r, ms));
324108
+ sleep7 = (ms) => new Promise((r) => setTimeout(r, ms));
324069
324109
  }
324070
324110
  });
324071
324111
 
@@ -325319,7 +325359,7 @@ async function retryWithBackoff(operation, attemptFn) {
325319
325359
  `${operation} attempt ${attempt}/${MAX_RETRIES2} failed: ${lastError}`
325320
325360
  ), attempt < MAX_RETRIES2) {
325321
325361
  let delayMs = BASE_DELAY_MS3 * Math.pow(2, attempt - 1);
325322
- logDebug(`Retrying ${operation} in ${delayMs}ms...`), await sleep3(delayMs);
325362
+ logDebug(`Retrying ${operation} in ${delayMs}ms...`), await sleep2(delayMs);
325323
325363
  }
325324
325364
  }
325325
325365
  throw new Error(`${lastError} after ${MAX_RETRIES2} attempts`);
@@ -328602,7 +328642,7 @@ var import_jsx_runtime140, proactiveModule, PROGRESS_THRESHOLD_MS2, isBackground
328602
328642
  let hasPendingRequiredServers = appState.mcp.clients.some((c2) => c2.type === "pending" && requiredMcpServers.some((pattern) => c2.name.toLowerCase().includes(pattern.toLowerCase()))), currentAppState = appState;
328603
328643
  if (hasPendingRequiredServers) {
328604
328644
  let deadline = Date.now() + 3e4;
328605
- for (; Date.now() < deadline && (await sleep3(500), currentAppState = toolUseContext.getAppState(), !(currentAppState.mcp.clients.some((c2) => c2.type === "failed" && requiredMcpServers.some((pattern) => c2.name.toLowerCase().includes(pattern.toLowerCase()))) || !currentAppState.mcp.clients.some((c2) => c2.type === "pending" && requiredMcpServers.some((pattern) => c2.name.toLowerCase().includes(pattern.toLowerCase()))))); )
328645
+ for (; Date.now() < deadline && (await sleep2(500), currentAppState = toolUseContext.getAppState(), !(currentAppState.mcp.clients.some((c2) => c2.type === "failed" && requiredMcpServers.some((pattern) => c2.name.toLowerCase().includes(pattern.toLowerCase()))) || !currentAppState.mcp.clients.some((c2) => c2.type === "pending" && requiredMcpServers.some((pattern) => c2.name.toLowerCase().includes(pattern.toLowerCase()))))); )
328606
328646
  ;
328607
328647
  }
328608
328648
  let serversWithTools = [];
@@ -328859,7 +328899,7 @@ var import_jsx_runtime140, proactiveModule, PROGRESS_THRESHOLD_MS2, isBackground
328859
328899
  let stopBackgroundedSummarization;
328860
328900
  try {
328861
328901
  await Promise.race([agentIterator.return(void 0).catch(() => {
328862
- }), sleep3(1e3)]);
328902
+ }), sleep2(1e3)]);
328863
328903
  let tracker = createProgressTracker(), resolveActivity2 = createActivityDescriptionResolver(toolUseContext.options.tools);
328864
328904
  for (let existingMsg of agentMessages)
328865
328905
  updateProgressFromMessage(tracker, existingMsg, resolveActivity2, toolUseContext.options.tools);
@@ -345693,7 +345733,7 @@ async function waitForTaskCompletion(taskId, getAppState, timeoutMs, abortContro
345693
345733
  return null;
345694
345734
  if (task.status !== "running" && task.status !== "pending")
345695
345735
  return task;
345696
- await sleep3(100);
345736
+ await sleep2(100);
345697
345737
  }
345698
345738
  return getAppState().tasks?.[taskId] ?? null;
345699
345739
  }
@@ -373094,7 +373134,7 @@ async function flushPromptHistory(retries) {
373094
373134
  try {
373095
373135
  await immediateFlushHistory();
373096
373136
  } finally {
373097
- isWriting = !1, pendingEntries.length > 0 && (await sleep3(500), flushPromptHistory(retries + 1));
373137
+ isWriting = !1, pendingEntries.length > 0 && (await sleep2(500), flushPromptHistory(retries + 1));
373098
373138
  }
373099
373139
  }
373100
373140
  }
@@ -400115,20 +400155,18 @@ var sema_brand_default, init_sema_brand = __esm({
400115
400155
  _doc: "displayName/email \u7559 null = \u8FD0\u884C\u65F6\u56DE\u9000(\u540D\u5B57\u53D6\u672C\u673A OS \u7528\u6237\u540D,\u90AE\u7BB1\u4E0D\u663E\u793A)\u3002\u522B\u70E7\u4E2A\u4EBA\u4FE1\u606F\u8FDB\u54C1\u724C\u6587\u4EF6(F-S1-1:\u65B0\u7528\u6237\u66FE\u770B\u5230 Welcome back Clay!)\u3002"
400116
400156
  },
400117
400157
  whatsNew: {
400118
- version: "1.0.76",
400158
+ version: "1.0.77",
400119
400159
  notes: [
400120
- "The agents panel no longer opens mid-turn: while a turn is in flight, the left-arrow key stays with the composer, and the footer hint plus the background-agent placeholder only advertise \u2190 when the prompt is idle and empty \u2014 the panel can no longer yank the screen away from a streaming turn",
400121
- "ctrl+b (send the current work to the background) no longer takes the turn's already-backgrounded subagents down with it",
400122
- "Resuming a session with a parked approval no longer risks a false deadlock: the ownership recheck that guards card re-presentation now recognizes runs by their persisted task id as well as the in-process ledger, so a first-turn park \u2192 kill \u2192 resume re-presents exactly one live card",
400123
- `Approval-card rule suggestions got stricter and more honest: interpreter-style commands (python, node, npx, eval, exec, ssh and friends) are never offered as persistent allow rules in any spelling, and "won't ask again" is only claimed when the rule took effect live \u2014 otherwise the card says it fully applies after restart`,
400124
- "Background subagents stream their transcript into the viewing pane while they run (per-agent detail stream), and the idle placeholder points at the agents panel instead of a stale hint",
400125
- "Task list rendering no longer collapses rows in fullscreen (alt-screen) terminals",
400126
- "Durable run controls from a reconnected session no longer fail due to a lost client binding on the run verbs",
400127
- "Engine unchanged at 7.19.0 (same pin as 1.0.75); this release is a shell-side interaction-safety and correctness batch"
400160
+ "Engine upgraded to 7.22.0 (from 7.19.0): reversibility probes, memory-governance surfaces, and full status-frame disclosure land in the wire this shell speaks",
400161
+ "Approval cards now explain why a command tripped the reversibility probe: a one-line note names the probe cause (for example an unbounded recursive read) and the directories it rooted in, alongside the existing governance and wire notes",
400162
+ "ctrl+b (send to background) stays honest on remote-hosted turns: the shell records the engine's session-backgroundable capability during handshake and keeps the local backgrounding shortcut scoped to turns it actually owns \u2014 remote lanes get a structured verdict instead of a silent no-op",
400163
+ "The engine-fence suite gained a full 7.22.0 lane (41 live checks) and the 7.18 fence re-run stays green on the new engine, so wire regressions in approvals, session reads, and SSE cleanup surface before a release rather than after",
400164
+ "Two upstream default flips are now pinned by tests so they cannot silently drift: shell-history files are readable by built-in tools (deny still available via explicit configuration), and a throwing activity listener no longer fails the whole leg",
400165
+ "client-core 0.30.3: principal handling gained a single normalization primitive (an all-whitespace principal now means absent \u2014 no more blank identity headers), turn-error classification and session-id mapping moved to shared single sources, and approval-card rule suggestions share one persistence verdict across surfaces"
400128
400166
  ]
400129
400167
  },
400130
- productVersion: "1.0.76",
400131
- announcement: `sema 1.0.76 \u2014 Interaction-safety batch: the agents panel no longer opens mid-turn (\u2190 stays with the composer while a turn is in flight, and every hint that advertises it follows the same predicate), ctrl+b no longer takes backgrounded subagents down with it, and resume ownership rechecks recognize persisted task ids so parked approvals re-present exactly once instead of dead-locking. Approval-card rule suggestions refuse interpreter-family commands in every spelling and only claim "won't ask again" when the rule applied live. Background subagents stream their transcripts into the viewer, and fullscreen task lists render without row collapse. Engine unchanged at 7.19.0.`
400168
+ productVersion: "1.0.77",
400169
+ announcement: "sema 1.0.77 \u2014 Engine 7.22.0 pickup: approval cards now name the reversibility-probe cause and its root directories, the shell records the engine's session-backgroundable capability at handshake (ctrl+b stays scoped to turns the shell owns, with a structured verdict instead of a silent no-op on remote lanes), and a full 7.22.0 live fence (41 checks) plus the 7.18 fence re-run guard approvals, session reads, and SSE cleanup against wire regressions. Two upstream default flips are pinned by tests (shell-history readable by built-ins; a throwing activity listener no longer fails the leg). client-core 0.30.3: blank principals mean absent (no more blank identity headers), and turn-error classification, session-id mapping, and rule-persistence verdicts are single-sourced across surfaces."
400132
400170
  };
400133
400171
  }
400134
400172
  });
@@ -404175,7 +404213,7 @@ function VirtualMessageList({
404175
404213
  if (indexWarmed.current) return 0;
404176
404214
  let msgs = jumpState.current.messages, CHUNK = 500, workMs = 0, wallStart = performance.now();
404177
404215
  for (let i = 0; i < msgs.length; i += CHUNK) {
404178
- await sleep3(0);
404216
+ await sleep2(0);
404179
404217
  let t0 = performance.now(), end2 = Math.min(i + CHUNK, msgs.length);
404180
404218
  for (let j3 = i; j3 < end2; j3++)
404181
404219
  extractSearchText(msgs[j3]);
@@ -404331,20 +404369,18 @@ var require_sema_brand = __commonJS({
404331
404369
  _doc: "displayName/email \u7559 null = \u8FD0\u884C\u65F6\u56DE\u9000(\u540D\u5B57\u53D6\u672C\u673A OS \u7528\u6237\u540D,\u90AE\u7BB1\u4E0D\u663E\u793A)\u3002\u522B\u70E7\u4E2A\u4EBA\u4FE1\u606F\u8FDB\u54C1\u724C\u6587\u4EF6(F-S1-1:\u65B0\u7528\u6237\u66FE\u770B\u5230 Welcome back Clay!)\u3002"
404332
404370
  },
404333
404371
  whatsNew: {
404334
- version: "1.0.76",
404372
+ version: "1.0.77",
404335
404373
  notes: [
404336
- "The agents panel no longer opens mid-turn: while a turn is in flight, the left-arrow key stays with the composer, and the footer hint plus the background-agent placeholder only advertise \u2190 when the prompt is idle and empty \u2014 the panel can no longer yank the screen away from a streaming turn",
404337
- "ctrl+b (send the current work to the background) no longer takes the turn's already-backgrounded subagents down with it",
404338
- "Resuming a session with a parked approval no longer risks a false deadlock: the ownership recheck that guards card re-presentation now recognizes runs by their persisted task id as well as the in-process ledger, so a first-turn park \u2192 kill \u2192 resume re-presents exactly one live card",
404339
- `Approval-card rule suggestions got stricter and more honest: interpreter-style commands (python, node, npx, eval, exec, ssh and friends) are never offered as persistent allow rules in any spelling, and "won't ask again" is only claimed when the rule took effect live \u2014 otherwise the card says it fully applies after restart`,
404340
- "Background subagents stream their transcript into the viewing pane while they run (per-agent detail stream), and the idle placeholder points at the agents panel instead of a stale hint",
404341
- "Task list rendering no longer collapses rows in fullscreen (alt-screen) terminals",
404342
- "Durable run controls from a reconnected session no longer fail due to a lost client binding on the run verbs",
404343
- "Engine unchanged at 7.19.0 (same pin as 1.0.75); this release is a shell-side interaction-safety and correctness batch"
404374
+ "Engine upgraded to 7.22.0 (from 7.19.0): reversibility probes, memory-governance surfaces, and full status-frame disclosure land in the wire this shell speaks",
404375
+ "Approval cards now explain why a command tripped the reversibility probe: a one-line note names the probe cause (for example an unbounded recursive read) and the directories it rooted in, alongside the existing governance and wire notes",
404376
+ "ctrl+b (send to background) stays honest on remote-hosted turns: the shell records the engine's session-backgroundable capability during handshake and keeps the local backgrounding shortcut scoped to turns it actually owns \u2014 remote lanes get a structured verdict instead of a silent no-op",
404377
+ "The engine-fence suite gained a full 7.22.0 lane (41 live checks) and the 7.18 fence re-run stays green on the new engine, so wire regressions in approvals, session reads, and SSE cleanup surface before a release rather than after",
404378
+ "Two upstream default flips are now pinned by tests so they cannot silently drift: shell-history files are readable by built-in tools (deny still available via explicit configuration), and a throwing activity listener no longer fails the whole leg",
404379
+ "client-core 0.30.3: principal handling gained a single normalization primitive (an all-whitespace principal now means absent \u2014 no more blank identity headers), turn-error classification and session-id mapping moved to shared single sources, and approval-card rule suggestions share one persistence verdict across surfaces"
404344
404380
  ]
404345
404381
  },
404346
- productVersion: "1.0.76",
404347
- announcement: `sema 1.0.76 \u2014 Interaction-safety batch: the agents panel no longer opens mid-turn (\u2190 stays with the composer while a turn is in flight, and every hint that advertises it follows the same predicate), ctrl+b no longer takes backgrounded subagents down with it, and resume ownership rechecks recognize persisted task ids so parked approvals re-present exactly once instead of dead-locking. Approval-card rule suggestions refuse interpreter-family commands in every spelling and only claim "won't ask again" when the rule applied live. Background subagents stream their transcripts into the viewer, and fullscreen task lists render without row collapse. Engine unchanged at 7.19.0.`
404382
+ productVersion: "1.0.77",
404383
+ announcement: "sema 1.0.77 \u2014 Engine 7.22.0 pickup: approval cards now name the reversibility-probe cause and its root directories, the shell records the engine's session-backgroundable capability at handshake (ctrl+b stays scoped to turns the shell owns, with a structured verdict instead of a silent no-op on remote lanes), and a full 7.22.0 live fence (41 checks) plus the 7.18 fence re-run guard approvals, session reads, and SSE cleanup against wire regressions. Two upstream default flips are pinned by tests (shell-history readable by built-ins; a throwing activity listener no longer fails the leg). client-core 0.30.3: blank principals mean absent (no more blank identity headers), and turn-error classification, session-id mapping, and rule-persistence verdicts are single-sourced across surfaces."
404348
404384
  };
404349
404385
  }
404350
404386
  });
@@ -407531,7 +407567,7 @@ async function pollForApprovedExitPlanMode(sessionId, timeoutMs, onPhaseChange,
407531
407567
  scanner.rejectCount,
407532
407568
  { cause: e }
407533
407569
  );
407534
- await sleep3(POLL_INTERVAL_MS2);
407570
+ await sleep2(POLL_INTERVAL_MS2);
407535
407571
  continue;
407536
407572
  }
407537
407573
  let result;
@@ -407563,7 +407599,7 @@ async function pollForApprovedExitPlanMode(sessionId, timeoutMs, onPhaseChange,
407563
407599
  scanner.rejectCount
407564
407600
  );
407565
407601
  let quietIdle = (sessionStatus === "idle" || sessionStatus === "requires_action") && newEvents.length === 0, phase = scanner.hasPendingPlan ? "plan_ready" : quietIdle ? "needs_input" : "running";
407566
- phase !== lastPhase && (logForDebugging(`[ultraplan] phase ${lastPhase} \u2192 ${phase}`), lastPhase = phase, onPhaseChange?.(phase)), await sleep3(POLL_INTERVAL_MS2);
407602
+ phase !== lastPhase && (logForDebugging(`[ultraplan] phase ${lastPhase} \u2192 ${phase}`), lastPhase = phase, onPhaseChange?.(phase)), await sleep2(POLL_INTERVAL_MS2);
407567
407603
  }
407568
407604
  throw new UltraplanPollError(
407569
407605
  scanner.everSeenPending ? `no approval after ${timeoutMs / 1e3}s` : `ExitPlanMode never reached after ${timeoutMs / 1e3}s (the remote container failed to start, or session ID mismatch?)`,
@@ -412562,11 +412598,11 @@ function capsBaseUrl2() {
412562
412598
  let raw2 = process.env.SEMA_LIVE_BASEURL;
412563
412599
  return typeof raw2 == "string" && raw2.trim() !== "" ? raw2 : void 0;
412564
412600
  }
412565
- function persistedRulesLaneAvailable(baseUrl = capsBaseUrl2()) {
412566
- return engineCapTrue(baseUrl, "permissionRules");
412601
+ function persistedRulesLaneAvailable2(baseUrl = capsBaseUrl2()) {
412602
+ return persistedRulesLaneAvailable(baseUrl);
412567
412603
  }
412568
- function persistedRulesGovernanceAvailable(baseUrl = capsBaseUrl2()) {
412569
- return engineCapTrue(baseUrl, "permissionRulesRevoke") && engineCapTrue(baseUrl, "permissionRules");
412604
+ function persistedRulesGovernanceAvailable2(baseUrl = capsBaseUrl2()) {
412605
+ return persistedRulesGovernanceAvailable(baseUrl);
412570
412606
  }
412571
412607
  async function resolveRulesFacade() {
412572
412608
  if (facadeOverride) return facadeOverride;
@@ -412600,67 +412636,6 @@ async function kickRulesCapsProbe() {
412600
412636
  logForDebugging(`persistedRulesWire: capability re-probe failed (cache stays unresolved): ${String(e)}`);
412601
412637
  });
412602
412638
  }
412603
- function errShape(e) {
412604
- let o = e ?? {};
412605
- return {
412606
- ...typeof o.status == "number" ? { status: o.status } : {},
412607
- ...typeof o.errorCode == "string" ? { errorCode: o.errorCode } : {},
412608
- message: typeof o.message == "string" && o.message !== "" ? o.message : String(e)
412609
- };
412610
- }
412611
- function retryAfterSecOf(e) {
412612
- let ms = e.retryAfterMs;
412613
- if (!(typeof ms != "number" || !Number.isFinite(ms) || ms < 0))
412614
- return Math.ceil(ms / 1e3);
412615
- }
412616
- function classifyRulesFailure(e) {
412617
- let { status: status3, errorCode, message } = errShape(e);
412618
- if (status3 === 501 || errorCode === "capability.rule_store_required")
412619
- return { kind: "lane-unavailable", message };
412620
- if (status3 === 404)
412621
- return errorCode === "not_found.route" ? { kind: "route-missing", message } : errorCode === "not_found.rule_ticket" ? { kind: "ticket-dead", message } : { kind: "error", message };
412622
- if (errorCode === "state.rule_import_retry") {
412623
- let sec = retryAfterSecOf(e);
412624
- return { kind: "retry-same-ticket", message, ...sec !== void 0 ? { retryAfterSec: sec } : {} };
412625
- }
412626
- return errorCode === "state.rule_remove_failed" ? { kind: "retryable", message } : status3 === 400 && errorCode === "request.query_invalid" ? { kind: "cursor-stale", message } : status3 === 413 ? { kind: "too-many-candidates", message } : status3 === 403 && errorCode === "auth.operator_only" ? { kind: "forbidden", message } : { kind: "error", message };
412627
- }
412628
- async function listAllPersistedRules(facade, params = {}, opts) {
412629
- for (let attempt = 0; attempt < 2; attempt++) {
412630
- let rules = [], cursor, rev2 = 0, restart = !1;
412631
- for (let page = 0; page < MAX_PAGES; page++) {
412632
- let res;
412633
- try {
412634
- res = await facade.list(
412635
- { limit: PAGE_LIMIT, ...params, ...cursor !== void 0 ? { cursor } : {} },
412636
- opts
412637
- );
412638
- } catch (e) {
412639
- let failure = classifyRulesFailure(e);
412640
- if (failure.kind === "cursor-stale" && cursor !== void 0 && attempt === 0) {
412641
- logForDebugging(
412642
- "persistedRulesWire: rule list cursor was minted on another rev/principal/scope \u2014 dropping it and re-listing from the top (never resuming a stale keyset)"
412643
- ), restart = !0;
412644
- break;
412645
- }
412646
- return { ok: !1, failure };
412647
- }
412648
- rev2 = typeof res.rev == "number" ? res.rev : rev2, Array.isArray(res.rules) && rules.push(...res.rules);
412649
- let next = res.nextCursor;
412650
- if (typeof next != "string" || next === "") return { ok: !0, rules, rev: rev2 };
412651
- cursor = next;
412652
- }
412653
- if (!restart)
412654
- return {
412655
- ok: !1,
412656
- failure: {
412657
- kind: "error",
412658
- message: `rule list did not terminate within ${MAX_PAGES} pages \u2014 refusing to present a partial governance list`
412659
- }
412660
- };
412661
- }
412662
- return { ok: !1, failure: { kind: "cursor-stale", message: "rule list kept changing under the cursor \u2014 try again" } };
412663
- }
412664
412639
  async function revokePersistedRule(facade, input, opts) {
412665
412640
  try {
412666
412641
  return { ok: !0, result: await facade.revoke(input, opts) };
@@ -412682,12 +412657,6 @@ async function redeemCcRuleImport(facade, ticket, opts) {
412682
412657
  return { ok: !1, failure: classifyRulesFailure(e) };
412683
412658
  }
412684
412659
  }
412685
- function classifySkippedReason(reason) {
412686
- let text2 = typeof reason == "string" ? reason : String(reason), idx = text2.indexOf(":");
412687
- if (idx <= 0) return { text: text2 };
412688
- let head = text2.slice(0, idx);
412689
- return /^[a-z][a-z0-9_]*(\.[a-z0-9_]+)*$/.test(head) ? { code: head, text: text2 } : { text: text2 };
412690
- }
412691
412660
  function ccRoot() {
412692
412661
  return process.env.SEMA_CC_ROOT || join156(homedir41(), CC_DIR4);
412693
412662
  }
@@ -412791,13 +412760,6 @@ function buildToolApprovalRespondBody(input) {
412791
412760
  ...input.note !== void 0 ? { note: input.note } : {}
412792
412761
  };
412793
412762
  }
412794
- function readRulePersistOutcome(ack) {
412795
- let o = ack ?? {};
412796
- return o.rulePersisted === !0 ? { state: "persisted" } : o.rulePersisted === !1 ? {
412797
- state: "refused",
412798
- ...typeof o.ruleRefusal == "string" && o.ruleRefusal !== "" ? { reason: o.ruleRefusal } : {}
412799
- } : { state: "unknown" };
412800
- }
412801
412763
  function surfaceRulePersistOutcome(ack) {
412802
412764
  let outcome = readRulePersistOutcome(ack);
412803
412765
  if (outcome.state === "unknown") return;
@@ -412818,7 +412780,7 @@ function surfaceRulePersistOutcome(ack) {
412818
412780
  }
412819
412781
  }
412820
412782
  function surfaceLocalRulePersistOutcome(outcome) {
412821
- let text2 = outcome.ok ? outcome.appliedLive ? "Saved: won't ask again for this rule" : "Saved to settings \u2014 fully applies after restart (this session may ask once more)" : `"Don't ask again" was not saved (${outcome.error}) \u2014 the one-time approval is still being submitted`;
412783
+ let text2 = outcome.ok ? outcome.redemptionGated === "budget-disabled" ? "Saved to settings \u2014 but automatic approval is disabled (SEMA_GATE_SYNC_ALLOW_BUDGET=0), so this rule will not silence asks until that changes" : outcome.redemptionGated === "budget-exhausted" ? "Saved to settings \u2014 but this session's automatic-approval budget is used up, so it may keep asking (fully applies after restart)" : outcome.appliedLive ? "Saved: won't ask again for this rule" : "Saved to settings \u2014 fully applies after restart (this session may ask once more)" : `"Don't ask again" was not saved (${outcome.error}) \u2014 the one-time approval is still being submitted`;
412822
412784
  try {
412823
412785
  surfaceWireNotice(
412824
412786
  {
@@ -412834,15 +412796,15 @@ function surfaceLocalRulePersistOutcome(outcome) {
412834
412796
  logForDebugging(`persistedRulesWire: surfacing local rule-persist outcome failed (non-fatal): ${String(e)}`);
412835
412797
  }
412836
412798
  }
412837
- var facadeOverride, PAGE_LIMIT, MAX_PAGES, CC_DIR4, LAYER_BYTE_CAP, RULE_PERSIST_NOTICE_KEY, RULE_PERSIST_NOTICE_DEFAULT_MS, rulePersistNoticeMs, init_persistedRulesWire = __esm({
412799
+ var facadeOverride, CC_DIR4, LAYER_BYTE_CAP, RULE_PERSIST_NOTICE_KEY, RULE_PERSIST_NOTICE_DEFAULT_MS, rulePersistNoticeMs, init_persistedRulesWire2 = __esm({
412838
412800
  "build-src/src/sema/persistedRulesWire.ts"() {
412839
412801
  init_main2();
412840
412802
  init_dist();
412841
412803
  init_debug();
412842
412804
  init_wireNoticePort();
412843
412805
  init_livePrincipal();
412806
+ init_dist();
412844
412807
  facadeOverride = null;
412845
- PAGE_LIMIT = 200, MAX_PAGES = 25;
412846
412808
  CC_DIR4 = ".claude";
412847
412809
  LAYER_BYTE_CAP = 16 * 1024;
412848
412810
  RULE_PERSIST_NOTICE_KEY = "rule-persist-outcome", RULE_PERSIST_NOTICE_DEFAULT_MS = 8e3, rulePersistNoticeMs = RULE_PERSIST_NOTICE_DEFAULT_MS;
@@ -412851,7 +412813,7 @@ var facadeOverride, PAGE_LIMIT, MAX_PAGES, CC_DIR4, LAYER_BYTE_CAP, RULE_PERSIST
412851
412813
 
412852
412814
  // build-src/src/sema/onboard/ccRulesImport.ts
412853
412815
  function detectCcRulesImport(cwd5) {
412854
- if (!persistedRulesLaneAvailable()) return { offer: !1, layers: [], why: "lane-unavailable" };
412816
+ if (!persistedRulesLaneAvailable2()) return { offer: !1, layers: [], why: "lane-unavailable" };
412855
412817
  let { layers: layers2 } = collectCcSettingsLayers(cwd5);
412856
412818
  return layers2.length === 0 ? { offer: !1, layers: [], why: "no-cc-settings" } : { offer: !0, layers: layers2 };
412857
412819
  }
@@ -412887,7 +412849,7 @@ function makeSingleFlightGate() {
412887
412849
  }
412888
412850
  var init_ccRulesImport = __esm({
412889
412851
  "build-src/src/sema/onboard/ccRulesImport.ts"() {
412890
- init_persistedRulesWire();
412852
+ init_persistedRulesWire2();
412891
412853
  }
412892
412854
  });
412893
412855
 
@@ -412921,7 +412883,7 @@ function writeCcImportMarker(marker) {
412921
412883
  var init_ccImportMarker = __esm({
412922
412884
  "build-src/src/sema/rules/ccImportMarker.ts"() {
412923
412885
  init_envUtils();
412924
- init_persistedRulesWire();
412886
+ init_persistedRulesWire2();
412925
412887
  }
412926
412888
  });
412927
412889
 
@@ -413108,7 +413070,7 @@ var React104, import_jsx_runtime305, init_CcRulesImportFlow = __esm({
413108
413070
  init_select();
413109
413071
  init_ink2();
413110
413072
  init_debug();
413111
- init_persistedRulesWire();
413073
+ init_persistedRulesWire2();
413112
413074
  init_ccImportMarker();
413113
413075
  init_ccRulesImport();
413114
413076
  import_jsx_runtime305 = __toESM(require_jsx_runtime(), 1);
@@ -413130,14 +413092,14 @@ function originsLabel(rule) {
413130
413092
  return seen2.length === 0 ? "unknown origin" : seen2.map((o) => o === "user" ? "approved on a card" : o === "imported-cc" ? "imported" : o === "starter" ? "preset" : o).join(" + ");
413131
413093
  }
413132
413094
  function usePersistedRulesGovernanceVisible() {
413133
- let [visible, setVisible] = React105.useState(() => persistedRulesGovernanceAvailable());
413095
+ let [visible, setVisible] = React105.useState(() => persistedRulesGovernanceAvailable2());
413134
413096
  return React105.useEffect(() => {
413135
413097
  if (visible) return;
413136
413098
  let alive = !0, timer2 = setInterval(() => {
413137
- alive && persistedRulesGovernanceAvailable() && (setVisible(!0), clearInterval(timer2));
413099
+ alive && persistedRulesGovernanceAvailable2() && (setVisible(!0), clearInterval(timer2));
413138
413100
  }, CAPS_POLL_MS);
413139
413101
  return kickRulesCapsProbe().then(() => {
413140
- alive && persistedRulesGovernanceAvailable() && (setVisible(!0), clearInterval(timer2));
413102
+ alive && persistedRulesGovernanceAvailable2() && (setVisible(!0), clearInterval(timer2));
413141
413103
  }), () => {
413142
413104
  alive = !1, clearInterval(timer2);
413143
413105
  };
@@ -413279,7 +413241,7 @@ var React105, import_jsx_runtime306, CAPS_POLL_MS, init_PersistedRulesTab = __es
413279
413241
  init_ink2();
413280
413242
  init_select();
413281
413243
  init_Tabs();
413282
- init_persistedRulesWire();
413244
+ init_persistedRulesWire2();
413283
413245
  init_detectSources();
413284
413246
  init_ccRulesImport();
413285
413247
  init_CcRulesImportFlow();
@@ -432779,12 +432741,12 @@ async function* sdkMessagesToCcEvents(sdk, meta3) {
432779
432741
  // 绝不铸 transcript 行(帧不带正文,替引擎编话=谎),落 debug 审计留痕(「这条 run 被谁插过话」
432780
432742
  // 可查);wire 值 UNTRUSTED,白名单键+控制字符消毒。
432781
432743
  case "human_input": {
432782
- let clean5 = (v2) => (
432744
+ let clean6 = (v2) => (
432783
432745
  // eslint-disable-next-line no-control-regex
432784
432746
  String(v2 ?? "").replace(/[\x00-\x1f\x7f]/g, ".").slice(0, 120)
432785
- ), who = e.actor?.id ? `${clean5(e.actor.id)}${e.actor.hostAsserted === !0 ? "" : " (unverified)"}` : "unattributed";
432747
+ ), who = e.actor?.id ? `${clean6(e.actor.id)}${e.actor.hostAsserted === !0 ? "" : " (unverified)"}` : "unattributed";
432786
432748
  return logForDebugging(
432787
- `[sema][bridge] human_input ledger frame (audit): carrier=${clean5(e.carrier)} eventId=${clean5(e.eventId)} by=${who}`
432749
+ `[sema][bridge] human_input ledger frame (audit): carrier=${clean6(e.carrier)} eventId=${clean6(e.eventId)} by=${who}`
432788
432750
  ), [];
432789
432751
  }
432790
432752
  default:
@@ -432873,8 +432835,121 @@ var BRIDGE_PROBE_ENV, init_upstreamBridge = __esm({
432873
432835
  });
432874
432836
 
432875
432837
  // node_modules/@sema-agent/core/dist/tools/fs/read-deny.js
432876
- var init_read_deny = __esm({
432838
+ function resolveReadDenyBuiltins(config4) {
432839
+ let activeTiers;
432840
+ if (config4?.tiers === void 0)
432841
+ activeTiers = new Set(READ_DENY_DEFAULT_TIERS);
432842
+ else {
432843
+ if (!Array.isArray(config4.tiers))
432844
+ throw new Error(`readDenyBuiltinTiers: expected an array of tier names, got ${JSON.stringify(config4.tiers)}.`);
432845
+ for (let t2 of config4.tiers)
432846
+ if (typeof t2 != "string" || !READ_DENY_BUILTIN_TIERS.includes(t2))
432847
+ throw new Error(`readDenyBuiltinTiers: unknown tier ${JSON.stringify(t2)} \u2014 known tiers: ${READ_DENY_BUILTIN_TIERS.join(", ")}.`);
432848
+ activeTiers = new Set(config4.tiers);
432849
+ }
432850
+ let excluded;
432851
+ if (config4?.exclude === void 0)
432852
+ excluded = /* @__PURE__ */ new Set();
432853
+ else {
432854
+ if (!Array.isArray(config4.exclude))
432855
+ throw new Error(`readDenyBuiltinExclude: expected an array of built-in row names (canonical pattern texts), got ${JSON.stringify(config4.exclude)}.`);
432856
+ for (let name of config4.exclude)
432857
+ if (typeof name != "string" || !READ_FACE_BUILTIN_DENY_TABLE.some((r) => r.pattern === name))
432858
+ throw new Error(`readDenyBuiltinExclude: ${JSON.stringify(name)} names no built-in row \u2014 row names are the canonical pattern texts of READ_FACE_BUILTIN_DENY_TABLE (e.g. ".ssh", ".config/gcloud").`);
432859
+ excluded = new Set(config4.exclude);
432860
+ }
432861
+ return READ_FACE_BUILTIN_DENY_TABLE.filter((r) => activeTiers.has(r.tier) && !excluded.has(r.pattern));
432862
+ }
432863
+ var READ_DENY_BUILTIN_TIERS, READ_FACE_BUILTIN_DENY_TABLE, READ_DENY_DEFAULT_TIERS, READ_FACE_DEFAULT_DENY_ENTRIES, init_read_deny = __esm({
432877
432864
  "node_modules/@sema-agent/core/dist/tools/fs/read-deny.js"() {
432865
+ READ_DENY_BUILTIN_TIERS = ["credentials", "shell-history", "browser", "wallet"], READ_FACE_BUILTIN_DENY_TABLE = [
432866
+ { pattern: ".ssh", tier: "credentials" },
432867
+ { pattern: "id_rsa*", tier: "credentials" },
432868
+ { pattern: "id_ed25519*", tier: "credentials" },
432869
+ { pattern: "id_ecdsa*", tier: "credentials" },
432870
+ { pattern: ".gnupg", tier: "credentials" },
432871
+ { pattern: ".aws", tier: "credentials" },
432872
+ { pattern: ".config/gcloud", tier: "credentials" },
432873
+ { pattern: ".azure", tier: "credentials" },
432874
+ { pattern: ".kube", tier: "credentials" },
432875
+ { pattern: ".netrc", tier: "credentials" },
432876
+ { pattern: "_netrc", tier: "credentials" },
432877
+ { pattern: ".git-credentials", tier: "credentials" },
432878
+ { pattern: ".docker/config.json", tier: "credentials" },
432879
+ { pattern: ".config/gh", tier: "credentials" },
432880
+ { pattern: ".npmrc", tier: "credentials" },
432881
+ { pattern: ".pypirc", tier: "credentials" },
432882
+ { pattern: ".local/share/keyrings", tier: "credentials" },
432883
+ { pattern: "Library/Keychains", tier: "credentials" },
432884
+ { pattern: ".bash_history", tier: "shell-history" },
432885
+ { pattern: ".zsh_history", tier: "shell-history" },
432886
+ { pattern: "Library/Application Support/Google/Chrome", tier: "browser" },
432887
+ { pattern: "Library/Application Support/Firefox", tier: "browser" },
432888
+ { pattern: "Library/Safari", tier: "browser" },
432889
+ { pattern: ".config/google-chrome", tier: "browser" },
432890
+ { pattern: ".config/chromium", tier: "browser" },
432891
+ { pattern: ".mozilla/firefox", tier: "browser" },
432892
+ { pattern: "AppData/Local/Google/Chrome/User Data", tier: "browser" },
432893
+ { pattern: "AppData/Local/Microsoft/Edge/User Data", tier: "browser" },
432894
+ { pattern: "AppData/Roaming/Mozilla/Firefox", tier: "browser" },
432895
+ { pattern: ".bitcoin", tier: "wallet" },
432896
+ { pattern: ".ethereum", tier: "wallet" },
432897
+ { pattern: ".electrum", tier: "wallet" },
432898
+ { pattern: "Library/Application Support/Exodus", tier: "wallet" },
432899
+ { pattern: "Library/Application Support/Ledger Live", tier: "wallet" },
432900
+ { pattern: "wallet.dat", tier: "wallet" }
432901
+ ], READ_DENY_DEFAULT_TIERS = READ_DENY_BUILTIN_TIERS.filter((t2) => t2 !== "shell-history");
432902
+ READ_FACE_DEFAULT_DENY_ENTRIES = resolveReadDenyBuiltins().map((r) => r.pattern);
432903
+ }
432904
+ });
432905
+
432906
+ // node_modules/@sema-agent/core/dist/core/safe-notify.js
432907
+ function createSafeNotifier(opts) {
432908
+ let onError = opts?.onError, sites, total = 0, record2 = (site, thrown) => {
432909
+ let error51 = thrown instanceof Error ? thrown : new Error(String(thrown));
432910
+ total += 1, sites === void 0 && (sites = /* @__PURE__ */ new Map());
432911
+ let state4 = sites.get(site);
432912
+ if (state4 !== void 0) {
432913
+ state4.count += 1, state4.last = error51;
432914
+ return;
432915
+ }
432916
+ if (sites.set(site, { count: 1, last: error51 }), onError !== void 0)
432917
+ try {
432918
+ onError({ site, error: error51, failures: 1 });
432919
+ } catch {
432920
+ }
432921
+ };
432922
+ return {
432923
+ notify(run2, site) {
432924
+ try {
432925
+ return run2(), !0;
432926
+ } catch (e) {
432927
+ return record2(site, e), !1;
432928
+ }
432929
+ },
432930
+ async notifyAsync(run2, site) {
432931
+ try {
432932
+ return await run2(), !0;
432933
+ } catch (e) {
432934
+ return record2(site, e), !1;
432935
+ }
432936
+ },
432937
+ get failures() {
432938
+ return total;
432939
+ },
432940
+ failuresAt(site) {
432941
+ return sites?.get(site)?.count ?? 0;
432942
+ },
432943
+ lastErrorAt(site) {
432944
+ return sites?.get(site)?.last;
432945
+ },
432946
+ failedSites() {
432947
+ return sites === void 0 ? [] : [...sites.keys()];
432948
+ }
432949
+ };
432950
+ }
432951
+ var init_safe_notify = __esm({
432952
+ "node_modules/@sema-agent/core/dist/core/safe-notify.js"() {
432878
432953
  }
432879
432954
  });
432880
432955
 
@@ -442853,9 +442928,9 @@ var init_union_priority_sort = __esm({
442853
442928
  // node_modules/typebox/build/value/clean/from_union.mjs
442854
442929
  function FromUnion9(context3, type, value) {
442855
442930
  for (let schema of UnionPrioritySort(type.anyOf)) {
442856
- let clean5 = FromType19(context3, schema, Clone2(value));
442857
- if (Check2(context3, schema, clean5))
442858
- return clean5;
442931
+ let clean6 = FromType19(context3, schema, Clone2(value));
442932
+ if (Check2(context3, schema, clean6))
442933
+ return clean6;
442859
442934
  }
442860
442935
  return value;
442861
442936
  }
@@ -446130,56 +446205,6 @@ var REVIVED_ROW_CLEARED_FIELDS, BackgroundAgentStoreError, STALE_RUNNING_REAP_AT
446130
446205
  }
446131
446206
  });
446132
446207
 
446133
- // node_modules/@sema-agent/core/dist/core/safe-notify.js
446134
- function createSafeNotifier(opts) {
446135
- let onError = opts?.onError, sites, total = 0, record2 = (site, thrown) => {
446136
- let error51 = thrown instanceof Error ? thrown : new Error(String(thrown));
446137
- total += 1, sites === void 0 && (sites = /* @__PURE__ */ new Map());
446138
- let state4 = sites.get(site);
446139
- if (state4 !== void 0) {
446140
- state4.count += 1, state4.last = error51;
446141
- return;
446142
- }
446143
- if (sites.set(site, { count: 1, last: error51 }), onError !== void 0)
446144
- try {
446145
- onError({ site, error: error51, failures: 1 });
446146
- } catch {
446147
- }
446148
- };
446149
- return {
446150
- notify(run2, site) {
446151
- try {
446152
- return run2(), !0;
446153
- } catch (e) {
446154
- return record2(site, e), !1;
446155
- }
446156
- },
446157
- async notifyAsync(run2, site) {
446158
- try {
446159
- return await run2(), !0;
446160
- } catch (e) {
446161
- return record2(site, e), !1;
446162
- }
446163
- },
446164
- get failures() {
446165
- return total;
446166
- },
446167
- failuresAt(site) {
446168
- return sites?.get(site)?.count ?? 0;
446169
- },
446170
- lastErrorAt(site) {
446171
- return sites?.get(site)?.last;
446172
- },
446173
- failedSites() {
446174
- return sites === void 0 ? [] : [...sites.keys()];
446175
- }
446176
- };
446177
- }
446178
- var init_safe_notify = __esm({
446179
- "node_modules/@sema-agent/core/dist/core/safe-notify.js"() {
446180
- }
446181
- });
446182
-
446183
446208
  // node_modules/@sema-agent/core/dist/core/workflow-run-store.js
446184
446209
  function summarizeWorkflowRun(run2) {
446185
446210
  let latestPhase = run2.phases.at(-1);
@@ -448998,6 +449023,8 @@ var init_fs_bash = __esm({
448998
449023
  init_remote_env3();
448999
449024
  init_gh_rate_limit();
449000
449025
  init_fs_shared();
449026
+ init_checkpoint_store();
449027
+ init_untrusted_text();
449001
449028
  init_bash_readonly_classifier();
449002
449029
  }
449003
449030
  });
@@ -451022,6 +451049,7 @@ var objectPrototype, init_hooks7 = __esm({
451022
451049
  init_tool_policy();
451023
451050
  init_ask_class();
451024
451051
  init_untrusted_text();
451052
+ init_checkpoint_store();
451025
451053
  init_ask_question();
451026
451054
  init_safe_notify();
451027
451055
  init_permission_rule_org();
@@ -451029,12 +451057,6 @@ var objectPrototype, init_hooks7 = __esm({
451029
451057
  }
451030
451058
  });
451031
451059
 
451032
- // node_modules/@sema-agent/core/dist/core/session-reconcile.js
451033
- var init_session_reconcile = __esm({
451034
- "node_modules/@sema-agent/core/dist/core/session-reconcile.js"() {
451035
- }
451036
- });
451037
-
451038
451060
  // node_modules/@sema-agent/core/dist/core/cache-break-detector.js
451039
451061
  var SERVER_GAP_MS, init_cache_break_detector = __esm({
451040
451062
  "node_modules/@sema-agent/core/dist/core/cache-break-detector.js"() {
@@ -451262,24 +451284,12 @@ var MEMORY_INDEX_MAX_BYTES, init_engine4 = __esm({
451262
451284
  }
451263
451285
  });
451264
451286
 
451265
- // node_modules/@sema-agent/core/dist/core/locked-config.js
451266
- var init_locked_config = __esm({
451267
- "node_modules/@sema-agent/core/dist/core/locked-config.js"() {
451268
- }
451269
- });
451270
-
451271
451287
  // node_modules/@sema-agent/core/dist/core/compliance.js
451272
451288
  var init_compliance = __esm({
451273
451289
  "node_modules/@sema-agent/core/dist/core/compliance.js"() {
451274
451290
  }
451275
451291
  });
451276
451292
 
451277
- // node_modules/@sema-agent/core/dist/core/retention.js
451278
- var init_retention = __esm({
451279
- "node_modules/@sema-agent/core/dist/core/retention.js"() {
451280
- }
451281
- });
451282
-
451283
451293
  // node_modules/@sema-agent/core/dist/core/memory-engine/dual-root.js
451284
451294
  var init_dual_root = __esm({
451285
451295
  "node_modules/@sema-agent/core/dist/core/memory-engine/dual-root.js"() {
@@ -451302,6 +451312,101 @@ var init_prepare_memory = __esm({
451302
451312
  }
451303
451313
  });
451304
451314
 
451315
+ // node_modules/@sema-agent/core/dist/core/locked-config.js
451316
+ var init_locked_config = __esm({
451317
+ "node_modules/@sema-agent/core/dist/core/locked-config.js"() {
451318
+ }
451319
+ });
451320
+
451321
+ // node_modules/@sema-agent/core/dist/core/retention.js
451322
+ var init_retention = __esm({
451323
+ "node_modules/@sema-agent/core/dist/core/retention.js"() {
451324
+ }
451325
+ });
451326
+
451327
+ // node_modules/@sema-agent/core/dist/core/usage-window-store.js
451328
+ var EMPTY_USAGE_WINDOW_RECORD, init_usage_window_store = __esm({
451329
+ "node_modules/@sema-agent/core/dist/core/usage-window-store.js"() {
451330
+ EMPTY_USAGE_WINDOW_RECORD = Object.freeze({
451331
+ slots: Object.freeze([]),
451332
+ buckets: Object.freeze([])
451333
+ });
451334
+ }
451335
+ });
451336
+
451337
+ // node_modules/@sema-agent/core/dist/core/wiring-manifest.js
451338
+ var init_wiring_manifest = __esm({
451339
+ "node_modules/@sema-agent/core/dist/core/wiring-manifest.js"() {
451340
+ init_canonical_json();
451341
+ init_checkpoint_store();
451342
+ init_ask_question();
451343
+ }
451344
+ });
451345
+
451346
+ // node_modules/@sema-agent/core/dist/core/runner/prepare-config-doors.js
451347
+ var TASK_LIMIT_KEY_DICT, TASK_LIMIT_KEYS, init_prepare_config_doors = __esm({
451348
+ "node_modules/@sema-agent/core/dist/core/runner/prepare-config-doors.js"() {
451349
+ init_timeout();
451350
+ init_fs();
451351
+ init_checkpoint_store();
451352
+ init_locked_config();
451353
+ init_retention();
451354
+ init_roles();
451355
+ init_usage_window_store();
451356
+ init_wiring_manifest();
451357
+ TASK_LIMIT_KEY_DICT = {
451358
+ maxTokens: !0,
451359
+ maxCostUsd: !0,
451360
+ maxTurns: !0,
451361
+ maxWalltimeMs: !0,
451362
+ maxOutputTokens: !0,
451363
+ approachNotice: !0,
451364
+ budgetStreamCancel: !0,
451365
+ degrade: !0,
451366
+ brainCallGuardrailMs: !0
451367
+ }, TASK_LIMIT_KEYS = Object.keys(TASK_LIMIT_KEY_DICT);
451368
+ }
451369
+ });
451370
+
451371
+ // node_modules/@sema-agent/core/dist/core/runner/prepare-safety-scan.js
451372
+ var NAMESPACED_NAME_SHAPES, init_prepare_safety_scan = __esm({
451373
+ "node_modules/@sema-agent/core/dist/core/runner/prepare-safety-scan.js"() {
451374
+ init_protocol_table();
451375
+ init_fs();
451376
+ init_tool_result_store();
451377
+ init_present_plan_tool();
451378
+ NAMESPACED_NAME_SHAPES = PROTOCOL_TABLE.map((ns) => `${ns.prefix}<peer>__<tool>`).join(", ");
451379
+ }
451380
+ });
451381
+
451382
+ // node_modules/@sema-agent/core/dist/core/session-reconcile.js
451383
+ var init_session_reconcile = __esm({
451384
+ "node_modules/@sema-agent/core/dist/core/session-reconcile.js"() {
451385
+ }
451386
+ });
451387
+
451388
+ // node_modules/@sema-agent/core/dist/core/runner/prepare-acquire-reconcile.js
451389
+ var init_prepare_acquire_reconcile = __esm({
451390
+ "node_modules/@sema-agent/core/dist/core/runner/prepare-acquire-reconcile.js"() {
451391
+ init_session4();
451392
+ init_session_reconcile();
451393
+ }
451394
+ });
451395
+
451396
+ // node_modules/@sema-agent/core/dist/core/with-retry.js
451397
+ var init_with_retry = __esm({
451398
+ "node_modules/@sema-agent/core/dist/core/with-retry.js"() {
451399
+ }
451400
+ });
451401
+
451402
+ // node_modules/@sema-agent/core/dist/core/runner/prepare-workspace-restore.js
451403
+ var init_prepare_workspace_restore = __esm({
451404
+ "node_modules/@sema-agent/core/dist/core/runner/prepare-workspace-restore.js"() {
451405
+ init_remote_env3();
451406
+ init_with_retry();
451407
+ }
451408
+ });
451409
+
451305
451410
  // node_modules/@sema-agent/core/dist/prompt-assembly/composer.js
451306
451411
  var SINGLE_BLOCK_LAYOUT, init_composer = __esm({
451307
451412
  "node_modules/@sema-agent/core/dist/prompt-assembly/composer.js"() {
@@ -451361,12 +451466,6 @@ var init_stub_env = __esm({
451361
451466
  }
451362
451467
  });
451363
451468
 
451364
- // node_modules/@sema-agent/core/dist/core/with-retry.js
451365
- var init_with_retry = __esm({
451366
- "node_modules/@sema-agent/core/dist/core/with-retry.js"() {
451367
- }
451368
- });
451369
-
451370
451469
  // node_modules/@sema-agent/core/dist/core/runner/teardown-bounded.js
451371
451470
  var init_teardown_bounded = __esm({
451372
451471
  "node_modules/@sema-agent/core/dist/core/runner/teardown-bounded.js"() {
@@ -451489,28 +451588,9 @@ var init_session_file_state_replay = __esm({
451489
451588
  }
451490
451589
  });
451491
451590
 
451492
- // node_modules/@sema-agent/core/dist/core/wiring-manifest.js
451493
- var init_wiring_manifest = __esm({
451494
- "node_modules/@sema-agent/core/dist/core/wiring-manifest.js"() {
451495
- init_canonical_json();
451496
- init_checkpoint_store();
451497
- init_ask_question();
451498
- }
451499
- });
451500
-
451501
- // node_modules/@sema-agent/core/dist/core/usage-window-store.js
451502
- var EMPTY_USAGE_WINDOW_RECORD, init_usage_window_store = __esm({
451503
- "node_modules/@sema-agent/core/dist/core/usage-window-store.js"() {
451504
- EMPTY_USAGE_WINDOW_RECORD = Object.freeze({
451505
- slots: Object.freeze([]),
451506
- buckets: Object.freeze([])
451507
- });
451508
- }
451509
- });
451510
-
451511
451591
  // node_modules/@sema-agent/core/dist/core/runner/prepare-task.js
451512
451592
  import { createHash as createHash27, randomBytes as randomBytes27 } from "node:crypto";
451513
- var PROMPT_HASH_SALT, TASK_LIMIT_KEY_DICT, TASK_LIMIT_KEYS, DEFAULT_RESOURCE_TTL_MS, USAGE_WINDOW_REAP_MARGIN_MS, DEFAULT_UNATTENDED_APPROVAL_TTL_MS, NAMESPACED_NAME_SHAPES, init_prepare_task = __esm({
451593
+ var PROMPT_HASH_SALT, DEFAULT_RESOURCE_TTL_MS, USAGE_WINDOW_REAP_MARGIN_MS, DEFAULT_UNATTENDED_APPROVAL_TTL_MS, init_prepare_task = __esm({
451514
451594
  "node_modules/@sema-agent/core/dist/core/runner/prepare-task.js"() {
451515
451595
  init_harness();
451516
451596
  init_auto_compaction();
@@ -451540,7 +451620,6 @@ var PROMPT_HASH_SALT, TASK_LIMIT_KEY_DICT, TASK_LIMIT_KEYS, DEFAULT_RESOURCE_TTL
451540
451620
  init_session_rule_policy();
451541
451621
  init_hooks7();
451542
451622
  init_permission_rule_org();
451543
- init_session_reconcile();
451544
451623
  init_cache_break_detector();
451545
451624
  init_request_params();
451546
451625
  init_timeout();
@@ -451559,11 +451638,13 @@ var PROMPT_HASH_SALT, TASK_LIMIT_KEY_DICT, TASK_LIMIT_KEYS, DEFAULT_RESOURCE_TTL
451559
451638
  init_content_origin();
451560
451639
  init_delegation_provenance();
451561
451640
  init_memory4();
451562
- init_locked_config();
451563
451641
  init_compliance();
451564
- init_retention();
451565
451642
  init_memory_admission();
451566
451643
  init_prepare_memory();
451644
+ init_prepare_config_doors();
451645
+ init_prepare_safety_scan();
451646
+ init_prepare_acquire_reconcile();
451647
+ init_prepare_workspace_restore();
451567
451648
  init_default6();
451568
451649
  init_assemble();
451569
451650
  init_tool_catalog();
@@ -451577,7 +451658,6 @@ var PROMPT_HASH_SALT, TASK_LIMIT_KEY_DICT, TASK_LIMIT_KEYS, DEFAULT_RESOURCE_TTL
451577
451658
  init_context_guard();
451578
451659
  init_stub_env();
451579
451660
  init_remote_env3();
451580
- init_with_retry();
451581
451661
  init_teardown_bounded();
451582
451662
  init_background_shell();
451583
451663
  init_task_registry();
@@ -451600,17 +451680,9 @@ var PROMPT_HASH_SALT, TASK_LIMIT_KEY_DICT, TASK_LIMIT_KEYS, DEFAULT_RESOURCE_TTL
451600
451680
  init_usage_window_store();
451601
451681
  init_types26();
451602
451682
  init_checkpoint_store();
451603
- PROMPT_HASH_SALT = randomBytes27(16), TASK_LIMIT_KEY_DICT = {
451604
- maxTokens: !0,
451605
- maxCostUsd: !0,
451606
- maxTurns: !0,
451607
- maxWalltimeMs: !0,
451608
- maxOutputTokens: !0,
451609
- approachNotice: !0,
451610
- budgetStreamCancel: !0,
451611
- degrade: !0,
451612
- brainCallGuardrailMs: !0
451613
- }, TASK_LIMIT_KEYS = Object.keys(TASK_LIMIT_KEY_DICT), DEFAULT_RESOURCE_TTL_MS = 720 * 60 * 60 * 1e3, USAGE_WINDOW_REAP_MARGIN_MS = 3600 * 1e3, DEFAULT_UNATTENDED_APPROVAL_TTL_MS = 720 * 60 * 60 * 1e3, NAMESPACED_NAME_SHAPES = PROTOCOL_TABLE.map((ns) => `${ns.prefix}<peer>__<tool>`).join(", ");
451683
+ init_prepare_config_doors();
451684
+ init_prepare_workspace_restore();
451685
+ PROMPT_HASH_SALT = randomBytes27(16), DEFAULT_RESOURCE_TTL_MS = 720 * 60 * 60 * 1e3, USAGE_WINDOW_REAP_MARGIN_MS = 3600 * 1e3, DEFAULT_UNATTENDED_APPROVAL_TTL_MS = 720 * 60 * 60 * 1e3;
451614
451686
  }
451615
451687
  });
451616
451688
 
@@ -451675,6 +451747,7 @@ var init_tool_output_projection = __esm({
451675
451747
  var SNAPSHOT_TOO_LARGE_TTL_MS, init_runtask = __esm({
451676
451748
  "node_modules/@sema-agent/core/dist/core/runner/runtask.js"() {
451677
451749
  init_read_deny();
451750
+ init_safe_notify();
451678
451751
  init_harness();
451679
451752
  init_llm2();
451680
451753
  init_checkpoint_store();
@@ -462899,7 +462972,7 @@ var WorkerStateUploader, init_WorkerStateUploader = __esm({
462899
462972
  let current5 = payload2, failures = 0;
462900
462973
  for (; !this.closed; ) {
462901
462974
  if (await this.config.send(current5)) return;
462902
- failures++, await sleep3(this.retryDelay(failures)), this.pending && !this.closed && (current5 = coalescePatches(current5, this.pending), this.pending = null);
462975
+ failures++, await sleep2(this.retryDelay(failures)), this.pending && !this.closed && (current5 = coalescePatches(current5, this.pending), this.pending = null);
462903
462976
  }
462904
462977
  }
462905
462978
  retryDelay(failures) {
@@ -463463,7 +463536,7 @@ var DEFAULT_HEARTBEAT_INTERVAL_MS, STREAM_EVENT_FLUSH_INTERVAL_MS, CCRInitError,
463463
463536
  { level: "warn" }
463464
463537
  ), attempt < 10) {
463465
463538
  let delay = Math.min(500 * 2 ** (attempt - 1), 3e4) + Math.random() * 500;
463466
- await sleep3(delay);
463539
+ await sleep2(delay);
463467
463540
  }
463468
463541
  continue;
463469
463542
  }
@@ -463474,7 +463547,7 @@ var DEFAULT_HEARTBEAT_INTERVAL_MS, STREAM_EVENT_FLUSH_INTERVAL_MS, CCRInitError,
463474
463547
  { level: "warn" }
463475
463548
  ), attempt < 10) {
463476
463549
  let delay = Math.min(500 * 2 ** (attempt - 1), 3e4) + Math.random() * 500;
463477
- await sleep3(delay);
463550
+ await sleep2(delay);
463478
463551
  }
463479
463552
  }
463480
463553
  return logForDebugging("CCRClient: GET retries exhausted", { level: "error" }), logForDiagnosticsNoPII("error", "cli_worker_get_retries_exhausted", {
@@ -463855,7 +463928,7 @@ var RECONNECT_BASE_DELAY_MS, RECONNECT_MAX_DELAY_MS, RECONNECT_GIVE_UP_MS, LIVEN
463855
463928
  POST_BASE_DELAY_MS * Math.pow(2, attempt - 1),
463856
463929
  POST_MAX_DELAY_MS
463857
463930
  );
463858
- await sleep3(delayMs);
463931
+ await sleep2(delayMs);
463859
463932
  }
463860
463933
  }
463861
463934
  // -----------------------------------------------------------------------
@@ -464950,7 +465023,7 @@ async function startWorkPollLoop({
464950
465023
  break;
464951
465024
  }
464952
465025
  }
464953
- hbCycles++, await sleep3(
465026
+ hbCycles++, await sleep2(
464954
465027
  hbConfig.non_exclusive_heartbeat_interval_ms,
464955
465028
  cap2.signal
464956
465029
  ), cap2.cleanup();
@@ -464966,14 +465039,14 @@ async function startWorkPollLoop({
464966
465039
  let sleepMs2 = atCapMs > 0 ? atCapMs : pollConfig.non_exclusive_heartbeat_interval_ms;
464967
465040
  if (sleepMs2 > 0) {
464968
465041
  let cap2 = capacitySignal(), sleepStart = Date.now();
464969
- await sleep3(sleepMs2, cap2.signal), cap2.cleanup();
465042
+ await sleep2(sleepMs2, cap2.signal), cap2.cleanup();
464970
465043
  let overrun = Date.now() - sleepStart - sleepMs2;
464971
465044
  overrun > 6e4 && (logForDebugging(
464972
465045
  `[bridge:repl] At-capacity sleep overran by ${Math.round(overrun / 1e3)}s \u2014 process suspension detected, forcing one fast-poll cycle`
464973
465046
  ), suspensionDetected = !0);
464974
465047
  }
464975
465048
  } else
464976
- await sleep3(pollConfig.poll_interval_ms_not_at_capacity, signal);
465049
+ await sleep2(pollConfig.poll_interval_ms_not_at_capacity, signal);
464977
465050
  continue;
464978
465051
  }
464979
465052
  let secret;
@@ -465096,7 +465169,7 @@ async function startWorkPollLoop({
465096
465169
  } catch {
465097
465170
  }
465098
465171
  }
465099
- await sleep3(backoff3, signal);
465172
+ await sleep2(backoff3, signal);
465100
465173
  }
465101
465174
  }
465102
465175
  logForDebugging(
@@ -465639,7 +465712,7 @@ async function withRetry3(fn2, label, cfg) {
465639
465712
  let base = cfg.init_retry_base_delay_ms * 2 ** (attempt - 1), jitter2 = base * cfg.init_retry_jitter_fraction * (2 * Math.random() - 1), delay = Math.min(base + jitter2, cfg.init_retry_max_delay_ms);
465640
465713
  logForDebugging(
465641
465714
  `[remote-bridge] ${label} failed (attempt ${attempt}/${max2}), retrying in ${Math.round(delay)}ms`
465642
- ), await sleep3(delay);
465715
+ ), await sleep2(delay);
465643
465716
  }
465644
465717
  }
465645
465718
  return null;
@@ -465908,7 +465981,7 @@ async function initReplBridge(options) {
465908
465981
  });
465909
465982
  }
465910
465983
  function deriveTitle(raw2) {
465911
- let clean5 = stripDisplayTagsAllowEmpty(raw2), flat = (/^(.*?[.!?])\s/.exec(clean5)?.[1] ?? clean5).replace(/\s+/g, " ").trim();
465984
+ let clean6 = stripDisplayTagsAllowEmpty(raw2), flat = (/^(.*?[.!?])\s/.exec(clean6)?.[1] ?? clean6).replace(/\s+/g, " ").trim();
465912
465985
  if (flat)
465913
465986
  return flat.length > TITLE_MAX_LEN ? flat.slice(0, TITLE_MAX_LEN - 1) + "\u2026" : flat;
465914
465987
  }
@@ -467032,6 +467105,47 @@ var RENDERED_UUID_PREFIX_LEN, init_rewindArm = __esm({
467032
467105
  }
467033
467106
  });
467034
467107
 
467108
+ // build-src/src/sema/sessionBackgroundArm.ts
467109
+ function engineHostsTheTurn(env5 = process.env) {
467110
+ let live = env5.SEMA_LIVE_BASEURL;
467111
+ return typeof live == "string" && live.length > 0;
467112
+ }
467113
+ function remoteHostsTheTurn(readGlobal = getIsRemoteMode, readPosture = hasRemoteConnection) {
467114
+ try {
467115
+ return readGlobal() || readPosture();
467116
+ } catch {
467117
+ return !0;
467118
+ }
467119
+ }
467120
+ function noteEngineCapsForSessionBackground(baseUrl, caps) {
467121
+ try {
467122
+ if (typeof caps != "object" || caps === null) return;
467123
+ let v2 = caps.sessionBackgroundable;
467124
+ sessionBackgroundableByBase.set(baseUrl, v2 === !0 ? "advertised" : v2 === !1 ? "declined" : "unknown");
467125
+ } catch {
467126
+ }
467127
+ }
467128
+ function engineSessionBackgroundableCap(baseUrl) {
467129
+ return sessionBackgroundableByBase.get(baseUrl) ?? "unknown";
467130
+ }
467131
+ function noteRemoteLaneEngagement(engaged) {
467132
+ remoteLaneEngaged = engaged === !0;
467133
+ }
467134
+ function sessionBackgroundingVerdict(env5 = process.env) {
467135
+ let cap2 = engineSessionBackgroundableCap(env5.SEMA_LIVE_BASEURL ?? "");
467136
+ return remoteLaneEngaged ? { available: !1, lane: "remote-lane", sessionBackgroundable: cap2 } : engineHostsTheTurn(env5) ? { available: !1, lane: "engine", sessionBackgroundable: cap2 } : remoteHostsTheTurn() ? { available: !1, lane: "remote", sessionBackgroundable: cap2 } : { available: !0 };
467137
+ }
467138
+ function sessionBackgroundingAvailable(env5 = process.env) {
467139
+ return sessionBackgroundingVerdict(env5).available;
467140
+ }
467141
+ var sessionBackgroundableByBase, remoteLaneEngaged, init_sessionBackgroundArm = __esm({
467142
+ "build-src/src/sema/sessionBackgroundArm.ts"() {
467143
+ init_state();
467144
+ init_remoteWriteSeam();
467145
+ sessionBackgroundableByBase = /* @__PURE__ */ new Map(), remoteLaneEngaged = !1;
467146
+ }
467147
+ });
467148
+
467035
467149
  // build-src/src/sema/footerFleetRows.ts
467036
467150
  function sameShape(a, b3) {
467037
467151
  if (a.viewedRowPresent !== b3.viewedRowPresent || a.taskRowIds.length !== b3.taskRowIds.length || a.workflowIds.length !== b3.workflowIds.length) return !1;
@@ -469650,9 +469764,9 @@ var pyright_default, init_pyright = __esm({
469650
469764
  });
469651
469765
 
469652
469766
  // build-src/src/utils/bash/specs/sleep.ts
469653
- var sleep9, sleep_default, init_sleep3 = __esm({
469767
+ var sleep8, sleep_default, init_sleep3 = __esm({
469654
469768
  "build-src/src/utils/bash/specs/sleep.ts"() {
469655
- sleep9 = {
469769
+ sleep8 = {
469656
469770
  name: "sleep",
469657
469771
  description: "Delay for a specified amount of time",
469658
469772
  args: {
@@ -469660,7 +469774,7 @@ var sleep9, sleep_default, init_sleep3 = __esm({
469660
469774
  description: "Duration to sleep (seconds or with suffix like 5s, 2m, 1h)",
469661
469775
  isOptional: !1
469662
469776
  }
469663
- }, sleep_default = sleep9;
469777
+ }, sleep_default = sleep8;
469664
469778
  }
469665
469779
  });
469666
469780
 
@@ -469878,47 +469992,283 @@ var NUMERIC, ENV_VAR, WRAPPER_COMMANDS, toArray4, init_prefix2 = __esm({
469878
469992
  }
469879
469993
  });
469880
469994
 
469881
- // build-src/src/sema/localAllowRuleWrite.ts
469882
- function parseLocalAllowRule(rule, expectedToolName) {
469883
- if (typeof rule != "string" || rule === "")
469884
- return { ok: !1, error: "rule text is empty" };
469885
- let value;
469995
+ // build-src/src/sema/engineGateSyncAllow.ts
469996
+ function cap() {
469997
+ return budgetCap !== null || (budgetCap = loudEnvInt("SEMA_GATE_SYNC_ALLOW_BUDGET", { min: 0, fallback: DEFAULT_BUDGET })), budgetCap;
469998
+ }
469999
+ function engineGateSyncAllowBudget() {
470000
+ return { used: budgetUsed, cap: cap() };
470001
+ }
470002
+ function readPermissionContext() {
470003
+ try {
470004
+ return getAppStateStoreRef()?.getState?.()?.toolPermissionContext ?? null;
470005
+ } catch {
470006
+ return null;
470007
+ }
470008
+ }
470009
+ function canonicalToolName(name) {
470010
+ let n2 = name.replace(/[\s_-]+/g, "").toLowerCase();
470011
+ return n2 === "bash" ? { canonical: "Bash", family: "bash" } : n2 === "write" || n2 === "filewrite" ? { canonical: "Write", family: "fsWrite", pathKey: "file_path" } : n2 === "edit" || n2 === "fileedit" ? { canonical: "Edit", family: "fsWrite", pathKey: "file_path" } : n2 === "multiedit" ? { canonical: "MultiEdit", family: "fsWrite", pathKey: "file_path" } : n2 === "notebookedit" ? { canonical: "NotebookEdit", family: "fsWrite", pathKey: "notebook_path" } : n2 === "read" || n2 === "fileread" ? { canonical: "Read", family: "fsRead", pathKey: "file_path" } : n2 === "webfetch" ? { canonical: "WebFetch", family: "webFetch" } : n2 === "agent" ? { canonical: "Agent", family: "agent" } : n2 === "powershell" ? { canonical: "PowerShell", family: "powershell" } : { canonical: name, family: "other" };
470012
+ }
470013
+ function permissionsModule() {
470014
+ return init_permissions2(), __toCommonJS(permissions_exports2);
470015
+ }
470016
+ function filesystemModule() {
470017
+ return init_filesystem(), __toCommonJS(filesystem_exports);
470018
+ }
470019
+ function bashPermissionsModule() {
470020
+ return init_bashPermissions(), __toCommonJS(bashPermissions_exports);
470021
+ }
470022
+ function bashCommandsModule() {
470023
+ return init_commands(), __toCommonJS(commands_exports);
470024
+ }
470025
+ function powershellPermissionsModule() {
470026
+ return init_powershellPermissions(), __toCommonJS(powershellPermissions_exports);
470027
+ }
470028
+ function webFetchRuleContent(args) {
470029
+ let url3 = args.url;
470030
+ if (typeof url3 != "string" || url3 === "") return null;
470031
+ try {
470032
+ return `domain:${new URL(url3).hostname}`;
470033
+ } catch {
470034
+ return null;
470035
+ }
470036
+ }
470037
+ function ruleCoord(rule) {
470038
+ let v2 = rule.ruleValue, shape = v2.ruleContent !== void 0 ? `content-rule\xB7len${v2.ruleContent.length}` : "bare";
470039
+ return `${v2.toolName} (${shape}) [${rule.source}]`;
470040
+ }
470041
+ function hasContentDenyRules(ctx, canonical2) {
470042
+ try {
470043
+ return permissionsModule().getDenyRules(ctx).some((r) => r.ruleValue.toolName === canonical2 && r.ruleValue.ruleContent !== void 0);
470044
+ } catch {
470045
+ return !0;
470046
+ }
470047
+ }
470048
+ function familyIdentityPresent(family, pathKey2, args) {
470049
+ if (family === "bash" || family === "powershell")
470050
+ return typeof args.command == "string" && args.command.trim() !== "";
470051
+ if (family === "fsWrite" || family === "fsRead") {
470052
+ let p = args[pathKey2 ?? "file_path"];
470053
+ return typeof p == "string" && p !== "";
470054
+ }
470055
+ return family === "webFetch" ? webFetchRuleContent(args) !== null : family === "agent" ? typeof args.subagent_type == "string" && args.subagent_type !== "" : !1;
470056
+ }
470057
+ function denyVerdict(ctx, req) {
470058
+ let { canonical: canonical2, family, pathKey: pathKey2 } = canonicalToolName(req.toolName), perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 }, toolRule = perms.getDenyRuleForTool(ctx, tool);
470059
+ if (toolRule !== null) return { allow: !1, deny: !0, reason: `deny rule ${ruleCoord(toolRule)}` };
470060
+ if (typeof req.args != "object" || req.args === null) return null;
470061
+ let args = req.args, denyHit = (rule) => rule ? { allow: !1, deny: !0, reason: `deny rule ${ruleCoord(rule)}` } : null;
470062
+ if (family === "bash") {
470063
+ let command8 = args.command;
470064
+ if (typeof command8 == "string" && command8.trim() !== "") {
470065
+ let segments = bashCommandsModule().splitCommand_DEPRECATED(command8);
470066
+ if (segments.length > bashPermissionsModule().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK)
470067
+ throw new Error(
470068
+ `compound command has ${segments.length} subcommands (cap ${bashPermissionsModule().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK}) \u2014 fail-closed to card`
470069
+ );
470070
+ let candidates = segments.length > 1 ? [command8, ...segments] : [command8], candidateEvalFailed = null;
470071
+ for (let cand of candidates)
470072
+ if (!(typeof cand != "string" || cand.trim() === ""))
470073
+ try {
470074
+ let result = bashPermissionsModule().bashToolCheckPermission({ command: cand }, ctx);
470075
+ if (result.behavior === "deny" && result.decisionReason?.type === "rule") {
470076
+ let rule = result.decisionReason.rule;
470077
+ return {
470078
+ allow: !1,
470079
+ deny: !0,
470080
+ reason: `deny rule ${rule ? ruleCoord(rule) : "(bash content rule)"}`
470081
+ };
470082
+ }
470083
+ } catch (e) {
470084
+ candidateEvalFailed = e;
470085
+ }
470086
+ if (candidateEvalFailed !== null) throw candidateEvalFailed;
470087
+ }
470088
+ } else if (family === "powershell") {
470089
+ let command8 = args.command;
470090
+ if (typeof command8 == "string" && command8.trim() !== "") {
470091
+ let fragments = /[`'"]/.test(command8) ? [] : command8.split(/[;|\n\r{}()&]+/).filter((f) => f.trim() !== "");
470092
+ if (fragments.length > bashPermissionsModule().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK)
470093
+ throw new Error(
470094
+ `powershell command has ${fragments.length} fragments (cap ${bashPermissionsModule().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK}) \u2014 fail-closed to card`
470095
+ );
470096
+ let candidates = fragments.length > 1 ? [command8, ...fragments] : [command8], candidateEvalFailed = null;
470097
+ for (let cand of candidates)
470098
+ try {
470099
+ let result = powershellPermissionsModule().powershellToolCheckPermission(
470100
+ { command: cand },
470101
+ ctx
470102
+ );
470103
+ if (result.behavior === "deny" && result.decisionReason?.type === "rule") {
470104
+ let rule = result.decisionReason.rule;
470105
+ return {
470106
+ allow: !1,
470107
+ deny: !0,
470108
+ reason: `deny rule ${rule ? ruleCoord(rule) : "(powershell content rule)"}`
470109
+ };
470110
+ }
470111
+ } catch (e) {
470112
+ candidateEvalFailed = e;
470113
+ }
470114
+ if (candidateEvalFailed !== null) throw candidateEvalFailed;
470115
+ }
470116
+ } else if (family === "fsWrite" || family === "fsRead") {
470117
+ let path28 = args[pathKey2 ?? "file_path"];
470118
+ if (typeof path28 == "string" && path28 !== "") {
470119
+ let toolType = family === "fsWrite" ? "edit" : "read";
470120
+ return denyHit(filesystemModule().matchingRuleForInput(path28, ctx, toolType, "deny"));
470121
+ }
470122
+ } else if (family === "webFetch") {
470123
+ let content = webFetchRuleContent(args);
470124
+ if (content !== null)
470125
+ return denyHit(perms.getRuleByContentsForToolName(ctx, canonical2, "deny").get(content));
470126
+ } else if (family === "agent") {
470127
+ let agentType = args.subagent_type;
470128
+ if (typeof agentType == "string" && agentType !== "")
470129
+ return denyHit(perms.getDenyRuleForAgent(ctx, canonical2, agentType));
470130
+ }
470131
+ return null;
470132
+ }
470133
+ function bashVerdict(ctx, args) {
470134
+ let command8 = args.command;
470135
+ if (typeof command8 != "string" || command8.trim() === "")
470136
+ return { allow: !1, reason: "bash gate carries no command string" };
470137
+ let result = bashPermissionsModule().bashToolCheckPermission(
470138
+ { command: command8 },
470139
+ ctx
470140
+ );
470141
+ return result.behavior !== "allow" ? { allow: !1, reason: `bash rules say ${String(result.behavior)}` } : result.decisionReason?.type !== "rule" ? { allow: !1, reason: `bash allow came from ${String(result.decisionReason?.type)}, not a remembered rule` } : { allow: !0, reason: "remembered Bash allow rule" };
470142
+ }
470143
+ function fsWriteVerdict(ctx, canonical2, pathKey2, args) {
470144
+ let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
470145
+ if (perms.getDenyRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level deny rule" };
470146
+ if (perms.getAskRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level ask rule" };
470147
+ let path28 = args[pathKey2];
470148
+ if (typeof path28 != "string" || path28 === "")
470149
+ return { allow: !1, reason: "fs-write gate carries no path identity (scoped rules unverifiable)" };
470150
+ let fs15 = filesystemModule();
470151
+ return fs15.matchingRuleForInput(path28, ctx, "edit", "deny") !== null ? { allow: !1, reason: "path deny rule" } : fs15.matchingRuleForInput(path28, ctx, "edit", "ask") !== null ? { allow: !1, reason: "path ask rule" } : fs15.matchingRuleForInput(path28, ctx, "edit", "allow") !== null ? { allow: !0, reason: "remembered path allow rule" } : perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this write" };
470152
+ }
470153
+ function fsReadVerdict(ctx, canonical2, pathKey2, args) {
470154
+ let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
470155
+ if (perms.getDenyRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level deny rule" };
470156
+ if (perms.getAskRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level ask rule" };
470157
+ let path28 = args[pathKey2];
470158
+ if (typeof path28 == "string" && path28 !== "") {
470159
+ let fs15 = filesystemModule();
470160
+ if (fs15.matchingRuleForInput(path28, ctx, "read", "deny") !== null) return { allow: !1, reason: "path deny rule" };
470161
+ if (fs15.matchingRuleForInput(path28, ctx, "read", "ask") !== null) return { allow: !1, reason: "path ask rule" };
470162
+ if (fs15.matchingRuleForInput(path28, ctx, "read", "allow") !== null)
470163
+ return { allow: !0, reason: "remembered read-path allow rule" };
470164
+ }
470165
+ return perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this read" };
470166
+ }
470167
+ function webFetchVerdict(ctx, canonical2, args) {
470168
+ let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
470169
+ if (perms.getDenyRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level deny rule" };
470170
+ if (perms.getAskRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level ask rule" };
470171
+ let content = webFetchRuleContent(args);
470172
+ if (content !== null) {
470173
+ if (perms.getRuleByContentsForToolName(ctx, canonical2, "deny").get(content) !== void 0)
470174
+ return { allow: !1, reason: "domain deny rule" };
470175
+ if (perms.getRuleByContentsForToolName(ctx, canonical2, "ask").get(content) !== void 0)
470176
+ return { allow: !1, reason: "domain ask rule" };
470177
+ if (perms.getRuleByContentsForToolName(ctx, canonical2, "allow").get(content) !== void 0)
470178
+ return { allow: !0, reason: "remembered WebFetch domain allow rule" };
470179
+ }
470180
+ return perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this fetch" };
470181
+ }
470182
+ function agentVerdict(ctx, canonical2, args) {
470183
+ let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
470184
+ if (perms.getDenyRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level deny rule" };
470185
+ if (perms.getAskRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level ask rule" };
470186
+ let agentType = args.subagent_type;
470187
+ return typeof agentType == "string" && agentType !== "" && perms.getAskRules(ctx).some((r) => r.ruleValue.toolName === canonical2 && r.ruleValue.ruleContent === agentType) ? { allow: !1, reason: "agent-type ask rule" } : perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this agent spawn" };
470188
+ }
470189
+ function genericVerdict(ctx, canonical2) {
470190
+ let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
470191
+ return perms.getDenyRuleForTool(ctx, tool) !== null ? { allow: !1, reason: "tool-level deny rule" } : perms.getAskRuleForTool(ctx, tool) !== null ? { allow: !1, reason: "tool-level ask rule" } : perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this tool" };
470192
+ }
470193
+ function _evaluateWithContextForTest(ctx, req) {
470194
+ if (ctx === null) return { allow: !1, reason: "no toolPermissionContext on this lane" };
469886
470195
  try {
469887
- value = permissionRuleValueFromString(rule);
470196
+ let denied = denyVerdict(ctx, req);
470197
+ if (denied !== null) return denied;
469888
470198
  } catch (e) {
469889
- return { ok: !1, error: `rule text did not parse (${String(e)})` };
470199
+ return logForDebugging(`engineGateSyncAllow: deny-rule evaluation threw for "${req.toolName}": ${String(e)}`), { allow: !1, reason: "deny-rule evaluation failed" };
469890
470200
  }
469891
- if (typeof value.toolName != "string" || value.toolName === "")
469892
- return { ok: !1, error: "rule text carries no tool name" };
469893
- if (value.ruleContent === void 0 || value.ruleContent === "")
469894
- return {
469895
- ok: !1,
469896
- error: "candidate is a whole-tool allow rule (broader than this ask) \u2014 not offered locally"
469897
- };
469898
- if (expectedToolName !== void 0 && value.toolName !== expectedToolName)
469899
- return {
469900
- ok: !1,
469901
- error: `candidate names tool "${value.toolName}" but this ask is for "${expectedToolName}" \u2014 a rule for another tool would never match`
469902
- };
469903
- if (!hasLiteralAnchor(value.ruleContent))
470201
+ if (req.governanceForced === !0)
469904
470202
  return {
469905
- ok: !1,
469906
- error: "candidate is all wildcard (matches every command for this tool) \u2014 equivalent to a whole-tool allow, not offered locally"
470203
+ allow: !1,
470204
+ reason: "governance-forced gate: posture/saved-rule auto-allow suspended (deployment governance requires an explicit decision)"
469907
470205
  };
469908
- if (value.toolName === BASH_TOOL_NAME_FOR_RULES && bashPermissionsModule().bashRuleContentHasDangerousBarePrefix(value.ruleContent))
469909
- return {
469910
- ok: !1,
469911
- error: "candidate is a bare interpreter/wrapper prefix (bash/sh/env/sudo/\u2026) \u2014 persisting it would authorize arbitrary commands, not offered locally"
470206
+ if (ctx.mode === "bypassPermissions") {
470207
+ if (typeof req.args != "object" || req.args === null || Array.isArray(req.args))
470208
+ return { allow: !1, reason: "bypassPermissions posture withheld: gate carries no tool input record (argsOmitted?)" };
470209
+ let { canonical: canonical3, family: family2, pathKey: pathKey3 } = canonicalToolName(req.toolName);
470210
+ return hasContentDenyRules(ctx, canonical3) && !familyIdentityPresent(family2, pathKey3, req.args) ? {
470211
+ allow: !1,
470212
+ reason: "bypassPermissions posture withheld: content-scoped deny rules exist for this tool but the gate carries no verifiable identity (argsOmitted?)"
470213
+ } : {
470214
+ allow: !0,
470215
+ postureAllow: !0,
470216
+ reason: "bypassPermissions posture auto-approves the engine gate (deny rules evaluated first)"
469912
470217
  };
469913
- {
469914
- let setup2 = permissionSetupModule2();
469915
- if (setup2.isDangerousBashPermission(value.toolName, value.ruleContent) || setup2.isDangerousPowerShellPermission(value.toolName, value.ruleContent))
469916
- return {
469917
- ok: !1,
469918
- error: "candidate allow-rule matches a code-execution interpreter/wrapper pattern (python/node/eval/ssh/\u2026) \u2014 persisting it would authorize arbitrary code, not offered locally"
469919
- };
469920
470218
  }
469921
- return { ok: !0, value, canonical: permissionRuleValueToString(value) };
470219
+ if (!SYNC_ALLOW_MODES.has(ctx.mode)) return { allow: !1, reason: `mode ${ctx.mode} never auto-allows` };
470220
+ if (typeof req.args != "object" || req.args === null)
470221
+ return { allow: !1, reason: "gate carries no tool input (argsOmitted?)" };
470222
+ let args = req.args, { canonical: canonical2, family, pathKey: pathKey2 } = canonicalToolName(req.toolName);
470223
+ try {
470224
+ return family === "bash" ? bashVerdict(ctx, args) : family === "powershell" ? genericVerdict(ctx, canonical2) : family === "fsWrite" ? fsWriteVerdict(ctx, canonical2, pathKey2 ?? "file_path", args) : family === "fsRead" ? fsReadVerdict(ctx, canonical2, pathKey2 ?? "file_path", args) : family === "webFetch" ? webFetchVerdict(ctx, canonical2, args) : family === "agent" ? agentVerdict(ctx, canonical2, args) : genericVerdict(ctx, canonical2);
470225
+ } catch (e) {
470226
+ return logForDebugging(`engineGateSyncAllow: rule evaluation threw for "${req.toolName}": ${String(e)}`), { allow: !1, reason: "rule evaluation failed" };
470227
+ }
470228
+ }
470229
+ function evaluateEngineGateSyncAllow(req) {
470230
+ let ctx = readPermissionContext(), verdict = _evaluateWithContextForTest(ctx, req);
470231
+ if (verdict.allow === !1 && verdict.deny === !0)
470232
+ return logForDebugging(
470233
+ `engineGateSyncAllow: gate for "${req.toolName}" AUTO-DENIED by permission rule (${verdict.reason}; mode=${ctx?.mode ?? "none"})`
470234
+ ), verdict;
470235
+ if (!verdict.allow) {
470236
+ let allowRuleCount = -1;
470237
+ try {
470238
+ ctx && (allowRuleCount = permissionsModule().getAllowRules(ctx).length);
470239
+ } catch {
470240
+ }
470241
+ return logForDebugging(
470242
+ `engineGateSyncAllow: no sync allow for "${req.toolName}" (${verdict.reason}; mode=${ctx?.mode ?? "none"}, allowRules=${allowRuleCount})`
470243
+ ), verdict;
470244
+ }
470245
+ return verdict.postureAllow === !0 ? (logForDebugging(
470246
+ `engineGateSyncAllow: gate for "${req.toolName}" AUTO-ALLOWED by bypassPermissions posture (${verdict.reason})`
470247
+ ), verdict) : budgetUsed >= cap() ? (budgetExhaustedLogged || (budgetExhaustedLogged = !0, logForDebugging(
470248
+ `engineGateSyncAllow: programmatic-allow budget exhausted (${budgetUsed}/${cap()}) \u2014 every further gate goes back to the approval card`
470249
+ )), { allow: !1, reason: "programmatic-allow budget exhausted" }) : (budgetUsed++, verdict);
470250
+ }
470251
+ var SYNC_ALLOW_MODES, DEFAULT_BUDGET, budgetUsed, budgetCap, budgetExhaustedLogged, init_engineGateSyncAllow = __esm({
470252
+ "build-src/src/sema/engineGateSyncAllow.ts"() {
470253
+ init_appStateRef();
470254
+ init_envKnobs();
470255
+ init_debug();
470256
+ SYNC_ALLOW_MODES = /* @__PURE__ */ new Set(["default", "acceptEdits", "auto"]), DEFAULT_BUDGET = 100, budgetUsed = 0, budgetCap = null, budgetExhaustedLogged = !1;
470257
+ }
470258
+ });
470259
+
470260
+ // build-src/src/sema/localAllowRuleWrite.ts
470261
+ function localAllowRuleDeps() {
470262
+ return {
470263
+ parseRule: (rule) => permissionRuleValueFromString(rule),
470264
+ formatRule: (value) => permissionRuleValueToString(value),
470265
+ bashRuleContentHasDangerousBarePrefix: (ruleContent) => bashPermissionsModule2().bashRuleContentHasDangerousBarePrefix(ruleContent),
470266
+ isDangerousBashPermission: (toolName2, ruleContent) => permissionSetupModule2().isDangerousBashPermission(toolName2, ruleContent),
470267
+ isDangerousPowerShellPermission: (toolName2, ruleContent) => permissionSetupModule2().isDangerousPowerShellPermission(toolName2, ruleContent)
470268
+ };
470269
+ }
470270
+ function parseLocalAllowRule2(rule, expectedToolName) {
470271
+ return parseLocalAllowRule(rule, expectedToolName, localAllowRuleDeps());
469922
470272
  }
469923
470273
  function localAllowRulesPermittedByPolicy() {
469924
470274
  try {
@@ -469927,25 +470277,13 @@ function localAllowRulesPermittedByPolicy() {
469927
470277
  return !1;
469928
470278
  }
469929
470279
  }
469930
- function hasLiteralAnchor(ruleContent) {
469931
- let out6 = "";
469932
- for (let i = 0; i < ruleContent.length; i++) {
469933
- let ch2 = ruleContent[i];
469934
- if (ch2 === "\\" && i + 1 < ruleContent.length) {
469935
- out6 += ruleContent[i + 1], i++;
469936
- continue;
469937
- }
469938
- ch2 !== "*" && (out6 += ch2);
469939
- }
469940
- return out6.trim() !== "";
469941
- }
469942
470280
  function permissionUpdateModule() {
469943
470281
  return init_PermissionUpdate(), __toCommonJS(PermissionUpdate_exports);
469944
470282
  }
469945
470283
  function permissionsLoaderModule() {
469946
470284
  return init_permissionsLoader(), __toCommonJS(permissionsLoader_exports);
469947
470285
  }
469948
- function bashPermissionsModule() {
470286
+ function bashPermissionsModule2() {
469949
470287
  return init_bashPermissions(), __toCommonJS(bashPermissions_exports);
469950
470288
  }
469951
470289
  function permissionSetupModule2() {
@@ -469954,8 +470292,16 @@ function permissionSetupModule2() {
469954
470292
  function leaderBridgeModule() {
469955
470293
  return init_leaderPermissionBridge(), __toCommonJS(leaderPermissionBridge_exports);
469956
470294
  }
470295
+ function redemptionGate() {
470296
+ try {
470297
+ let { used, cap: cap2 } = engineGateSyncAllowBudget();
470298
+ if (cap2 === 0) return "budget-disabled";
470299
+ if (used >= cap2) return "budget-exhausted";
470300
+ } catch {
470301
+ }
470302
+ }
469957
470303
  function persistLocalAllowRule(rule) {
469958
- let parsed = parseLocalAllowRule(rule);
470304
+ let parsed = parseLocalAllowRule2(rule);
469959
470305
  if (!parsed.ok)
469960
470306
  return logForDebugging(`localAllowRuleWrite: refusing to persist a rule candidate \u2014 ${parsed.error}`), { ok: !1, error: parsed.error };
469961
470307
  let update2 = {
@@ -469985,7 +470331,7 @@ function persistLocalAllowRule(rule) {
469985
470331
  try {
469986
470332
  let setCtx = leaderBridgeModule().getLeaderSetToolPermissionContext(), state4 = getAppStateStoreRef()?.getState?.();
469987
470333
  if (setCtx && state4?.toolPermissionContext)
469988
- return setCtx(mod.applyPermissionUpdate(state4.toolPermissionContext, update2)), { ok: !0, appliedLive: !0 };
470334
+ return setCtx(mod.applyPermissionUpdate(state4.toolPermissionContext, update2)), { ok: !0, appliedLive: !0, ...gatedStamp() };
469989
470335
  logForDebugging(
469990
470336
  "localAllowRuleWrite: rule persisted to local settings, but this lane has no in-memory permission context to update (it will take effect on next start)"
469991
470337
  );
@@ -469994,14 +470340,19 @@ function persistLocalAllowRule(rule) {
469994
470340
  `localAllowRuleWrite: rule persisted, but applying it to the in-memory permission context failed (non-fatal): ${String(e)}`
469995
470341
  );
469996
470342
  }
469997
- return { ok: !0, appliedLive: !1 };
470343
+ return { ok: !0, appliedLive: !1, ...gatedStamp() };
469998
470344
  }
469999
- var BASH_TOOL_NAME_FOR_RULES, init_localAllowRuleWrite = __esm({
470345
+ function gatedStamp() {
470346
+ let gate = redemptionGate();
470347
+ return gate !== void 0 ? { redemptionGated: gate } : {};
470348
+ }
470349
+ var init_localAllowRuleWrite = __esm({
470000
470350
  "build-src/src/sema/localAllowRuleWrite.ts"() {
470001
470351
  init_permissionRuleParser();
470352
+ init_dist();
470002
470353
  init_debug();
470003
470354
  init_appStateRef();
470004
- BASH_TOOL_NAME_FOR_RULES = "Bash";
470355
+ init_engineGateSyncAllow();
470005
470356
  }
470006
470357
  });
470007
470358
 
@@ -470046,7 +470397,7 @@ function tryEngineRulePersistSelection(confirm2, value, onDone) {
470046
470397
  function readLocalRedeemable(confirm2) {
470047
470398
  let expected = typeof confirm2.tool?.name == "string" ? confirm2.tool.name : void 0, out6 = [];
470048
470399
  for (let s of readSuggestions(confirm2, "ruleSuggestionsReadOnly")) {
470049
- let parsed = parseLocalAllowRule(s.rule, expected);
470400
+ let parsed = parseLocalAllowRule2(s.rule, expected);
470050
470401
  parsed.ok && out6.push({ rule: s.rule, canonical: parsed.canonical });
470051
470402
  }
470052
470403
  return out6;
@@ -491796,7 +492147,7 @@ async function reconcileResumePendingApprovals(deps2) {
491796
492147
  debug3("an owned pending row carries no taskId handle \u2014 both reopen arms address by taskId, nothing to reopen"), verdict.skipped.push({ taskId: null, reason: "no-task-handle" });
491797
492148
  continue;
491798
492149
  }
491799
- let kind = gateKindOf(row2), arm = kind === null ? null : ASK_PARK_GATE_KINDS2.includes(kind) ? "ask" : PLAN_REVIEW_GATE_KINDS2.includes(kind) ? "plan" : null;
492150
+ let kind = gateKindOf(row2), arm = kind === null ? null : ASK_PARK_GATE_KINDS.includes(kind) ? "ask" : PLAN_REVIEW_GATE_KINDS.includes(kind) ? "plan" : null;
491800
492151
  if (arm === null) {
491801
492152
  debug3(
491802
492153
  `owned pending row (task ${taskId}) is parked on gate kind '${kind ?? "<absent>"}' \u2014 not in either triage table, refusing to route it into a known reopen arm`
@@ -492064,7 +492415,7 @@ function useLiveQuestionOverlay({
492064
492415
  }
492065
492416
  alive && (setToolUseConfirmQueue(
492066
492417
  (queue3) => queue3.some((e) => e.toolUseID === frame.questionId) ? queue3 : [...queue3, entry]
492067
- ), registerArmedGateFromQuestionId2(frame.questionId));
492418
+ ), registerArmedGateFromQuestionId(frame.questionId));
492068
492419
  }
492069
492420
  })();
492070
492421
  } else frame.type === "question_complete" && (completedBeforeDialog.add(frame.questionId), setToolUseConfirmQueue((queue3) => queue3.filter((e) => e.toolUseID !== frame.questionId)));
@@ -492129,28 +492480,6 @@ var import_compiler_runtime299, import_react298, init_useIDEIntegration = __esm(
492129
492480
  }
492130
492481
  });
492131
492482
 
492132
- // build-src/src/sema/sessionBackgroundArm.ts
492133
- function engineHostsTheTurn(env5 = process.env) {
492134
- let live = env5.SEMA_LIVE_BASEURL;
492135
- return typeof live == "string" && live.length > 0;
492136
- }
492137
- function remoteHostsTheTurn(readGlobal = getIsRemoteMode, readPosture = hasRemoteConnection) {
492138
- try {
492139
- return readGlobal() || readPosture();
492140
- } catch {
492141
- return !0;
492142
- }
492143
- }
492144
- function sessionBackgroundingAvailable(env5 = process.env) {
492145
- return !engineHostsTheTurn(env5) && !remoteHostsTheTurn();
492146
- }
492147
- var init_sessionBackgroundArm = __esm({
492148
- "build-src/src/sema/sessionBackgroundArm.ts"() {
492149
- init_state();
492150
- init_remoteWriteSeam();
492151
- }
492152
- });
492153
-
492154
492483
  // build-src/src/components/SessionBackgroundHint.tsx
492155
492484
  function SessionBackgroundHint(t0) {
492156
492485
  let $3 = (0, import_compiler_runtime300.c)(10), {
@@ -495342,7 +495671,7 @@ function _temp158() {
495342
495671
  }
495343
495672
  var import_compiler_runtime308, import_react313, SETTINGS_ERRORS_NOTIFICATION_KEY, init_useSettingsErrors = __esm({
495344
495673
  "build-src/src/hooks/notifs/useSettingsErrors.tsx"() {
495345
- import_compiler_runtime308 = __toESM(require_compiler_runtime(), 1), import_react313 = __toESM(require_react(), 1);
495674
+ import_compiler_runtime308 = __toESM(require_compiler_runtime()), import_react313 = __toESM(require_react());
495346
495675
  init_notifications2();
495347
495676
  init_state();
495348
495677
  init_allErrors();
@@ -498247,7 +498576,11 @@ function REPL({
498247
498576
  setIsLoading: setIsExternalLoading,
498248
498577
  setToolUseConfirmQueue,
498249
498578
  tools: combinedInitialTools
498250
- }), activeRemote = sshRemote.isRemoteMode ? sshRemote : directConnect.isRemoteMode ? directConnect : remoteSession, [pastedContents, setPastedContents] = (0, import_react332.useState)({}), [submitCount, setSubmitCount] = (0, import_react332.useState)(0), responseLengthRef = (0, import_react332.useRef)(0), apiMetricsRef2 = (0, import_react332.useRef)([]), setResponseLength = (0, import_react332.useCallback)((f) => {
498579
+ }), activeRemote = sshRemote.isRemoteMode ? sshRemote : directConnect.isRemoteMode ? directConnect : remoteSession;
498580
+ (0, import_react332.useLayoutEffect)(() => {
498581
+ noteRemoteLaneEngagement(activeRemote.isRemoteMode);
498582
+ }, [activeRemote.isRemoteMode]);
498583
+ let [pastedContents, setPastedContents] = (0, import_react332.useState)({}), [submitCount, setSubmitCount] = (0, import_react332.useState)(0), responseLengthRef = (0, import_react332.useRef)(0), apiMetricsRef2 = (0, import_react332.useRef)([]), setResponseLength = (0, import_react332.useCallback)((f) => {
498251
498584
  let prev = responseLengthRef.current;
498252
498585
  if (responseLengthRef.current = f(prev), responseLengthRef.current > prev) {
498253
498586
  let entries = apiMetricsRef2.current;
@@ -500120,6 +500453,7 @@ var import_compiler_runtime325, React175, import_react332, import_jsx_runtime477
500120
500453
  init_userMessageSelect();
500121
500454
  init_engineAgentView();
500122
500455
  init_appStateRef();
500456
+ init_sessionBackgroundArm();
500123
500457
  init_chrome_agentprogress();
500124
500458
  init_selectors();
500125
500459
  init_dist();
@@ -509532,265 +509866,41 @@ var NOTICE_KEY, NOTICE_TIMEOUT_MS, init_classifierVerdictWire2 = __esm({
509532
509866
  }
509533
509867
  });
509534
509868
 
509535
- // build-src/src/sema/engineGateSyncAllow.ts
509536
- function cap() {
509537
- return budgetCap !== null || (budgetCap = loudEnvInt("SEMA_GATE_SYNC_ALLOW_BUDGET", { min: 0, fallback: DEFAULT_BUDGET })), budgetCap;
509538
- }
509539
- function readPermissionContext() {
509540
- try {
509541
- return getAppStateStoreRef()?.getState?.()?.toolPermissionContext ?? null;
509542
- } catch {
509543
- return null;
509544
- }
509545
- }
509546
- function canonicalToolName(name) {
509547
- let n2 = name.replace(/[\s_-]+/g, "").toLowerCase();
509548
- return n2 === "bash" ? { canonical: "Bash", family: "bash" } : n2 === "write" || n2 === "filewrite" ? { canonical: "Write", family: "fsWrite", pathKey: "file_path" } : n2 === "edit" || n2 === "fileedit" ? { canonical: "Edit", family: "fsWrite", pathKey: "file_path" } : n2 === "multiedit" ? { canonical: "MultiEdit", family: "fsWrite", pathKey: "file_path" } : n2 === "notebookedit" ? { canonical: "NotebookEdit", family: "fsWrite", pathKey: "notebook_path" } : n2 === "read" || n2 === "fileread" ? { canonical: "Read", family: "fsRead", pathKey: "file_path" } : n2 === "webfetch" ? { canonical: "WebFetch", family: "webFetch" } : n2 === "agent" ? { canonical: "Agent", family: "agent" } : n2 === "powershell" ? { canonical: "PowerShell", family: "powershell" } : { canonical: name, family: "other" };
509549
- }
509550
- function permissionsModule() {
509551
- return init_permissions2(), __toCommonJS(permissions_exports2);
509552
- }
509553
- function filesystemModule() {
509554
- return init_filesystem(), __toCommonJS(filesystem_exports);
509555
- }
509556
- function bashPermissionsModule2() {
509557
- return init_bashPermissions(), __toCommonJS(bashPermissions_exports);
509558
- }
509559
- function bashCommandsModule() {
509560
- return init_commands(), __toCommonJS(commands_exports);
509561
- }
509562
- function powershellPermissionsModule() {
509563
- return init_powershellPermissions(), __toCommonJS(powershellPermissions_exports);
509564
- }
509565
- function webFetchRuleContent(args) {
509566
- let url3 = args.url;
509567
- if (typeof url3 != "string" || url3 === "") return null;
509568
- try {
509569
- return `domain:${new URL(url3).hostname}`;
509570
- } catch {
509571
- return null;
509572
- }
509573
- }
509574
- function ruleCoord(rule) {
509575
- let v2 = rule.ruleValue, shape = v2.ruleContent !== void 0 ? `content-rule\xB7len${v2.ruleContent.length}` : "bare";
509576
- return `${v2.toolName} (${shape}) [${rule.source}]`;
509577
- }
509578
- function hasContentDenyRules(ctx, canonical2) {
509579
- try {
509580
- return permissionsModule().getDenyRules(ctx).some((r) => r.ruleValue.toolName === canonical2 && r.ruleValue.ruleContent !== void 0);
509581
- } catch {
509582
- return !0;
509583
- }
509584
- }
509585
- function familyIdentityPresent(family, pathKey2, args) {
509586
- if (family === "bash" || family === "powershell")
509587
- return typeof args.command == "string" && args.command.trim() !== "";
509588
- if (family === "fsWrite" || family === "fsRead") {
509589
- let p = args[pathKey2 ?? "file_path"];
509590
- return typeof p == "string" && p !== "";
509591
- }
509592
- return family === "webFetch" ? webFetchRuleContent(args) !== null : family === "agent" ? typeof args.subagent_type == "string" && args.subagent_type !== "" : !1;
509869
+ // build-src/src/sema/probeCauseNote.ts
509870
+ function readOperands(v2) {
509871
+ if (typeof v2 != "object" || v2 === null) return;
509872
+ let o = v2;
509873
+ if (!(!Array.isArray(o.shown) || o.shown.some((s) => typeof s != "string")) && !(typeof o.total != "number" || !Number.isInteger(o.total) || o.total < 0) && !(o.total < o.shown.length))
509874
+ return { shown: o.shown, total: o.total };
509593
509875
  }
509594
- function denyVerdict(ctx, req) {
509595
- let { canonical: canonical2, family, pathKey: pathKey2 } = canonicalToolName(req.toolName), perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 }, toolRule = perms.getDenyRuleForTool(ctx, tool);
509596
- if (toolRule !== null) return { allow: !1, deny: !0, reason: `deny rule ${ruleCoord(toolRule)}` };
509597
- if (typeof req.args != "object" || req.args === null) return null;
509598
- let args = req.args, denyHit = (rule) => rule ? { allow: !1, deny: !0, reason: `deny rule ${ruleCoord(rule)}` } : null;
509599
- if (family === "bash") {
509600
- let command8 = args.command;
509601
- if (typeof command8 == "string" && command8.trim() !== "") {
509602
- let segments = bashCommandsModule().splitCommand_DEPRECATED(command8);
509603
- if (segments.length > bashPermissionsModule2().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK)
509604
- throw new Error(
509605
- `compound command has ${segments.length} subcommands (cap ${bashPermissionsModule2().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK}) \u2014 fail-closed to card`
509606
- );
509607
- let candidates = segments.length > 1 ? [command8, ...segments] : [command8], candidateEvalFailed = null;
509608
- for (let cand of candidates)
509609
- if (!(typeof cand != "string" || cand.trim() === ""))
509610
- try {
509611
- let result = bashPermissionsModule2().bashToolCheckPermission({ command: cand }, ctx);
509612
- if (result.behavior === "deny" && result.decisionReason?.type === "rule") {
509613
- let rule = result.decisionReason.rule;
509614
- return {
509615
- allow: !1,
509616
- deny: !0,
509617
- reason: `deny rule ${rule ? ruleCoord(rule) : "(bash content rule)"}`
509618
- };
509619
- }
509620
- } catch (e) {
509621
- candidateEvalFailed = e;
509622
- }
509623
- if (candidateEvalFailed !== null) throw candidateEvalFailed;
509624
- }
509625
- } else if (family === "powershell") {
509626
- let command8 = args.command;
509627
- if (typeof command8 == "string" && command8.trim() !== "") {
509628
- let fragments = /[`'"]/.test(command8) ? [] : command8.split(/[;|\n\r{}()&]+/).filter((f) => f.trim() !== "");
509629
- if (fragments.length > bashPermissionsModule2().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK)
509630
- throw new Error(
509631
- `powershell command has ${fragments.length} fragments (cap ${bashPermissionsModule2().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK}) \u2014 fail-closed to card`
509632
- );
509633
- let candidates = fragments.length > 1 ? [command8, ...fragments] : [command8], candidateEvalFailed = null;
509634
- for (let cand of candidates)
509635
- try {
509636
- let result = powershellPermissionsModule().powershellToolCheckPermission(
509637
- { command: cand },
509638
- ctx
509639
- );
509640
- if (result.behavior === "deny" && result.decisionReason?.type === "rule") {
509641
- let rule = result.decisionReason.rule;
509642
- return {
509643
- allow: !1,
509644
- deny: !0,
509645
- reason: `deny rule ${rule ? ruleCoord(rule) : "(powershell content rule)"}`
509646
- };
509647
- }
509648
- } catch (e) {
509649
- candidateEvalFailed = e;
509650
- }
509651
- if (candidateEvalFailed !== null) throw candidateEvalFailed;
509876
+ function readProbeCauseKey(source) {
509877
+ if (typeof source != "object" || source === null) return;
509878
+ let raw2 = source.probeCause;
509879
+ if (typeof raw2 != "object" || raw2 === null) return;
509880
+ let o = raw2;
509881
+ if (typeof o.code != "string" || o.code.length === 0) return;
509882
+ let roots = readOperands(o.roots);
509883
+ if (roots !== void 0) {
509884
+ if (o.further !== void 0) {
509885
+ let further = readOperands(o.further);
509886
+ return further === void 0 ? void 0 : { code: o.code, roots, further };
509652
509887
  }
509653
- } else if (family === "fsWrite" || family === "fsRead") {
509654
- let path28 = args[pathKey2 ?? "file_path"];
509655
- if (typeof path28 == "string" && path28 !== "") {
509656
- let toolType = family === "fsWrite" ? "edit" : "read";
509657
- return denyHit(filesystemModule().matchingRuleForInput(path28, ctx, toolType, "deny"));
509658
- }
509659
- } else if (family === "webFetch") {
509660
- let content = webFetchRuleContent(args);
509661
- if (content !== null)
509662
- return denyHit(perms.getRuleByContentsForToolName(ctx, canonical2, "deny").get(content));
509663
- } else if (family === "agent") {
509664
- let agentType = args.subagent_type;
509665
- if (typeof agentType == "string" && agentType !== "")
509666
- return denyHit(perms.getDenyRuleForAgent(ctx, canonical2, agentType));
509888
+ return { code: o.code, roots };
509667
509889
  }
509668
- return null;
509669
509890
  }
509670
- function bashVerdict(ctx, args) {
509671
- let command8 = args.command;
509672
- if (typeof command8 != "string" || command8.trim() === "")
509673
- return { allow: !1, reason: "bash gate carries no command string" };
509674
- let result = bashPermissionsModule2().bashToolCheckPermission(
509675
- { command: command8 },
509676
- ctx
509677
- );
509678
- return result.behavior !== "allow" ? { allow: !1, reason: `bash rules say ${String(result.behavior)}` } : result.decisionReason?.type !== "rule" ? { allow: !1, reason: `bash allow came from ${String(result.decisionReason?.type)}, not a remembered rule` } : { allow: !0, reason: "remembered Bash allow rule" };
509891
+ function clean5(v2, max2) {
509892
+ return v2.replace(/[\x00-\x1f\x7f]/g, ".").slice(0, max2);
509679
509893
  }
509680
- function fsWriteVerdict(ctx, canonical2, pathKey2, args) {
509681
- let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
509682
- if (perms.getDenyRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level deny rule" };
509683
- if (perms.getAskRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level ask rule" };
509684
- let path28 = args[pathKey2];
509685
- if (typeof path28 != "string" || path28 === "")
509686
- return { allow: !1, reason: "fs-write gate carries no path identity (scoped rules unverifiable)" };
509687
- let fs15 = filesystemModule();
509688
- return fs15.matchingRuleForInput(path28, ctx, "edit", "deny") !== null ? { allow: !1, reason: "path deny rule" } : fs15.matchingRuleForInput(path28, ctx, "edit", "ask") !== null ? { allow: !1, reason: "path ask rule" } : fs15.matchingRuleForInput(path28, ctx, "edit", "allow") !== null ? { allow: !0, reason: "remembered path allow rule" } : perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this write" };
509689
- }
509690
- function fsReadVerdict(ctx, canonical2, pathKey2, args) {
509691
- let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
509692
- if (perms.getDenyRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level deny rule" };
509693
- if (perms.getAskRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level ask rule" };
509694
- let path28 = args[pathKey2];
509695
- if (typeof path28 == "string" && path28 !== "") {
509696
- let fs15 = filesystemModule();
509697
- if (fs15.matchingRuleForInput(path28, ctx, "read", "deny") !== null) return { allow: !1, reason: "path deny rule" };
509698
- if (fs15.matchingRuleForInput(path28, ctx, "read", "ask") !== null) return { allow: !1, reason: "path ask rule" };
509699
- if (fs15.matchingRuleForInput(path28, ctx, "read", "allow") !== null)
509700
- return { allow: !0, reason: "remembered read-path allow rule" };
509701
- }
509702
- return perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this read" };
509703
- }
509704
- function webFetchVerdict(ctx, canonical2, args) {
509705
- let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
509706
- if (perms.getDenyRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level deny rule" };
509707
- if (perms.getAskRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level ask rule" };
509708
- let content = webFetchRuleContent(args);
509709
- if (content !== null) {
509710
- if (perms.getRuleByContentsForToolName(ctx, canonical2, "deny").get(content) !== void 0)
509711
- return { allow: !1, reason: "domain deny rule" };
509712
- if (perms.getRuleByContentsForToolName(ctx, canonical2, "ask").get(content) !== void 0)
509713
- return { allow: !1, reason: "domain ask rule" };
509714
- if (perms.getRuleByContentsForToolName(ctx, canonical2, "allow").get(content) !== void 0)
509715
- return { allow: !0, reason: "remembered WebFetch domain allow rule" };
509716
- }
509717
- return perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this fetch" };
509718
- }
509719
- function agentVerdict(ctx, canonical2, args) {
509720
- let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
509721
- if (perms.getDenyRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level deny rule" };
509722
- if (perms.getAskRuleForTool(ctx, tool) !== null) return { allow: !1, reason: "tool-level ask rule" };
509723
- let agentType = args.subagent_type;
509724
- return typeof agentType == "string" && agentType !== "" && perms.getAskRules(ctx).some((r) => r.ruleValue.toolName === canonical2 && r.ruleValue.ruleContent === agentType) ? { allow: !1, reason: "agent-type ask rule" } : perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this agent spawn" };
509725
- }
509726
- function genericVerdict(ctx, canonical2) {
509727
- let perms = permissionsModule(), tool = { name: canonical2, mcpInfo: void 0 };
509728
- return perms.getDenyRuleForTool(ctx, tool) !== null ? { allow: !1, reason: "tool-level deny rule" } : perms.getAskRuleForTool(ctx, tool) !== null ? { allow: !1, reason: "tool-level ask rule" } : perms.toolAlwaysAllowedRule(ctx, tool) !== null ? { allow: !0, reason: "remembered whole-tool allow rule" } : { allow: !1, reason: "no remembered allow rule for this tool" };
509729
- }
509730
- function _evaluateWithContextForTest(ctx, req) {
509731
- if (ctx === null) return { allow: !1, reason: "no toolPermissionContext on this lane" };
509732
- try {
509733
- let denied = denyVerdict(ctx, req);
509734
- if (denied !== null) return denied;
509735
- } catch (e) {
509736
- return logForDebugging(`engineGateSyncAllow: deny-rule evaluation threw for "${req.toolName}": ${String(e)}`), { allow: !1, reason: "deny-rule evaluation failed" };
509737
- }
509738
- if (req.governanceForced === !0)
509739
- return {
509740
- allow: !1,
509741
- reason: "governance-forced gate: posture/saved-rule auto-allow suspended (deployment governance requires an explicit decision)"
509742
- };
509743
- if (ctx.mode === "bypassPermissions") {
509744
- if (typeof req.args != "object" || req.args === null || Array.isArray(req.args))
509745
- return { allow: !1, reason: "bypassPermissions posture withheld: gate carries no tool input record (argsOmitted?)" };
509746
- let { canonical: canonical3, family: family2, pathKey: pathKey3 } = canonicalToolName(req.toolName);
509747
- return hasContentDenyRules(ctx, canonical3) && !familyIdentityPresent(family2, pathKey3, req.args) ? {
509748
- allow: !1,
509749
- reason: "bypassPermissions posture withheld: content-scoped deny rules exist for this tool but the gate carries no verifiable identity (argsOmitted?)"
509750
- } : {
509751
- allow: !0,
509752
- postureAllow: !0,
509753
- reason: "bypassPermissions posture auto-approves the engine gate (deny rules evaluated first)"
509754
- };
509755
- }
509756
- if (!SYNC_ALLOW_MODES.has(ctx.mode)) return { allow: !1, reason: `mode ${ctx.mode} never auto-allows` };
509757
- if (typeof req.args != "object" || req.args === null)
509758
- return { allow: !1, reason: "gate carries no tool input (argsOmitted?)" };
509759
- let args = req.args, { canonical: canonical2, family, pathKey: pathKey2 } = canonicalToolName(req.toolName);
509760
- try {
509761
- return family === "bash" ? bashVerdict(ctx, args) : family === "powershell" ? genericVerdict(ctx, canonical2) : family === "fsWrite" ? fsWriteVerdict(ctx, canonical2, pathKey2 ?? "file_path", args) : family === "fsRead" ? fsReadVerdict(ctx, canonical2, pathKey2 ?? "file_path", args) : family === "webFetch" ? webFetchVerdict(ctx, canonical2, args) : family === "agent" ? agentVerdict(ctx, canonical2, args) : genericVerdict(ctx, canonical2);
509762
- } catch (e) {
509763
- return logForDebugging(`engineGateSyncAllow: rule evaluation threw for "${req.toolName}": ${String(e)}`), { allow: !1, reason: "rule evaluation failed" };
509764
- }
509894
+ function operandsText(f) {
509895
+ let shown = f.shown.slice(0, 8).map((p) => clean5(p, 120)), more = Math.max(0, f.total - shown.length);
509896
+ return shown.length === 0 ? `${String(f.total)} total` : more > 0 ? `${shown.join(", ")} (+${String(more)} more)` : shown.join(", ");
509765
509897
  }
509766
- function evaluateEngineGateSyncAllow(req) {
509767
- let ctx = readPermissionContext(), verdict = _evaluateWithContextForTest(ctx, req);
509768
- if (verdict.allow === !1 && verdict.deny === !0)
509769
- return logForDebugging(
509770
- `engineGateSyncAllow: gate for "${req.toolName}" AUTO-DENIED by permission rule (${verdict.reason}; mode=${ctx?.mode ?? "none"})`
509771
- ), verdict;
509772
- if (!verdict.allow) {
509773
- let allowRuleCount = -1;
509774
- try {
509775
- ctx && (allowRuleCount = permissionsModule().getAllowRules(ctx).length);
509776
- } catch {
509777
- }
509778
- return logForDebugging(
509779
- `engineGateSyncAllow: no sync allow for "${req.toolName}" (${verdict.reason}; mode=${ctx?.mode ?? "none"}, allowRules=${allowRuleCount})`
509780
- ), verdict;
509781
- }
509782
- return verdict.postureAllow === !0 ? (logForDebugging(
509783
- `engineGateSyncAllow: gate for "${req.toolName}" AUTO-ALLOWED by bypassPermissions posture (${verdict.reason})`
509784
- ), verdict) : budgetUsed >= cap() ? (budgetExhaustedLogged || (budgetExhaustedLogged = !0, logForDebugging(
509785
- `engineGateSyncAllow: programmatic-allow budget exhausted (${budgetUsed}/${cap()}) \u2014 every further gate goes back to the approval card`
509786
- )), { allow: !1, reason: "programmatic-allow budget exhausted" }) : (budgetUsed++, verdict);
509898
+ function probeCauseNoteText(pc) {
509899
+ let parts = [`reversibility probe: ${clean5(pc.code, 200)} \u2014 roots: ${operandsText(pc.roots)}`];
509900
+ return pc.further !== void 0 && parts.push(`further: ${operandsText(pc.further)}`), parts.join(" \u2014 ");
509787
509901
  }
509788
- var SYNC_ALLOW_MODES, DEFAULT_BUDGET, budgetUsed, budgetCap, budgetExhaustedLogged, init_engineGateSyncAllow = __esm({
509789
- "build-src/src/sema/engineGateSyncAllow.ts"() {
509790
- init_appStateRef();
509791
- init_envKnobs();
509792
- init_debug();
509793
- SYNC_ALLOW_MODES = /* @__PURE__ */ new Set(["default", "acceptEdits", "auto"]), DEFAULT_BUDGET = 100, budgetUsed = 0, budgetCap = null, budgetExhaustedLogged = !1;
509902
+ var init_probeCauseNote = __esm({
509903
+ "build-src/src/sema/probeCauseNote.ts"() {
509794
509904
  }
509795
509905
  });
509796
509906
 
@@ -509838,6 +509948,14 @@ function stubToolUseContext() {
509838
509948
  options: {}
509839
509949
  };
509840
509950
  }
509951
+ function composeCardWireNote(req) {
509952
+ let probeCause = readProbeCauseKey(req), parts = [
509953
+ ...req.governanceForced === !0 ? ["Required by deployment governance \u2014 permission-mode overrides do not apply"] : [],
509954
+ ...req.wireNote !== void 0 ? [req.wireNote] : [],
509955
+ ...probeCause !== void 0 ? [probeCauseNoteText(probeCause)] : []
509956
+ ];
509957
+ return parts.length > 0 ? parts.join(" \xB7 ") : void 0;
509958
+ }
509841
509959
  function shellApprovalCardPort(req) {
509842
509960
  let setQueue = getLeaderToolUseConfirmQueue();
509843
509961
  if (!setQueue) {
@@ -509933,12 +510051,11 @@ function shellApprovalCardPort(req) {
509933
510051
  // (AUTONOMY/commandPolicy/MANUAL_MODE_SHELL_GATE/SENSITIVE_WRITE_PATTERNS),权限模式
509934
510052
  // 表态掀不掉——呈现走 wireNote 超集车道(dim 行,与 argsOmitted 提示同位,可叠加)。
509935
510053
  // 🔴 缺席 ≠ false:键只在为真时在场;缺席帧绝不合成治理句(缺席=无治理来源证据)。
509936
- ...req.governanceForced === !0 || req.wireNote !== void 0 ? {
509937
- wireNote: [
509938
- ...req.governanceForced === !0 ? ["Required by deployment governance \u2014 permission-mode overrides do not apply"] : [],
509939
- ...req.wireNote !== void 0 ? [req.wireNote] : []
509940
- ].join(" \xB7 ")
509941
- } : {},
510054
+ // #280 件4:probeCause 探针因由句并入同车道(组装单源 composeCardWireNote,见其顶注)。
510055
+ ...(() => {
510056
+ let wireNote = composeCardWireNote(req);
510057
+ return wireNote !== void 0 ? { wireNote } : {};
510058
+ })(),
509942
510059
  permissionPromptStartTimeMs: Date.now(),
509943
510060
  onUserInteraction() {
509944
510061
  },
@@ -509973,7 +510090,7 @@ function shellApprovalCardPort(req) {
509973
510090
  }
509974
510091
  };
509975
510092
  try {
509976
- setQueue((queue3) => [...queue3, confirm2]), registerArmedGate2(callKey);
510093
+ setQueue((queue3) => [...queue3, confirm2]), registerArmedGate(callKey);
509977
510094
  } catch (e) {
509978
510095
  settle2({ kind: "failed", reason: `enqueue ToolUseConfirm failed: ${String(e)}` });
509979
510096
  }
@@ -509991,7 +510108,8 @@ var asWireTool, forcedToolLoadFailureForTest, forcedToolNilExportForTest, loadFi
509991
510108
  init_debug();
509992
510109
  init_engineGateSyncAllow();
509993
510110
  init_localAllowRuleWrite();
509994
- init_persistedRulesWire();
510111
+ init_probeCauseNote();
510112
+ init_persistedRulesWire2();
509995
510113
  init_armedGateRegistry2();
509996
510114
  init_dist();
509997
510115
  asWireTool = (t2) => t2, forcedToolLoadFailureForTest = null, forcedToolNilExportForTest = null, loadFileWrite = () => (init_FileWriteTool(), __toCommonJS(FileWriteTool_exports)).FileWriteTool, loadFileEdit = () => (init_FileEditTool(), __toCommonJS(FileEditTool_exports)).FileEditTool, loadNotebookEdit = () => (init_NotebookEditTool(), __toCommonJS(NotebookEditTool_exports)).NotebookEditTool, loadBash = () => (init_BashTool(), __toCommonJS(BashTool_exports)).BashTool, loadEngineWorkflow = () => (init_EngineWorkflowTool(), __toCommonJS(EngineWorkflowTool_exports)).EngineWorkflowTool, KNOWN_TOOL_LOADERS = {
@@ -510124,6 +510242,8 @@ function askCallKey(askId) {
510124
510242
  function approvalCardRequestFrom(frame, opts) {
510125
510243
  let card = frame.card, notes = [riskNoteFor(card.risk)];
510126
510244
  card.argsOmitted === !0 && notes.push("arguments omitted by the engine (over the 16 KiB cap) \u2014 this does NOT mean the call has no arguments");
510245
+ let probeCause = readProbeCauseKey(card);
510246
+ probeCause !== void 0 && notes.push(probeCauseNoteText(probeCause));
510127
510247
  let args = card.argsOmitted === !0 || typeof card.args != "object" || card.args === null ? {} : card.args;
510128
510248
  return {
510129
510249
  toolName: card.toolName,
@@ -510410,6 +510530,7 @@ var STREAM_APPROVAL_CAP, ASK_DECISION_DISABLED_CODE, IDEMPOTENCY_KEY_MAX, PARKIN
510410
510530
  init_dist();
510411
510531
  init_debug();
510412
510532
  init_appStateRef();
510533
+ init_probeCauseNote();
510413
510534
  init_wireNoticePort();
510414
510535
  STREAM_APPROVAL_CAP = "streamApproval", ASK_DECISION_DISABLED_CODE = "feature.approval_ask_disabled", IDEMPOTENCY_KEY_MAX = 255, PARKING_POLL_MAX = 2, PARKING_POLL_DELAY_MS = 400, CAPS_SETTLE_BUDGET_MS = 1500, LEGACY_SETTLE_GRACE_MS = 750, MAX_DECISION_NOTE_CHARS = 2048, TEARDOWN_BUDGET_MS = 1e3;
510415
510536
  TYPED_NAME_TO_KIND = /* @__PURE__ */ new Map([
@@ -510848,7 +510969,7 @@ async function* withDurableSuggestionsTail(events3, taskId, runsGet, opts) {
510848
510969
  for await (let ev of events3)
510849
510970
  ev?.type === "suggestions" && (settledOnStream = !0), yield ev;
510850
510971
  if (settledOnStream || !promptSuggestionsOptIn() || opts?.signal?.aborted) return;
510851
- let sleep10 = opts?.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms))), now2 = opts?.now ?? Date.now, t0 = now2();
510972
+ let sleep9 = opts?.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms))), now2 = opts?.now ?? Date.now, t0 = now2();
510852
510973
  for (let attempt = 1; attempt <= SUGGESTIONS_TAIL_MAX_ATTEMPTS; attempt++) {
510853
510974
  let rec;
510854
510975
  try {
@@ -510865,7 +510986,7 @@ async function* withDurableSuggestionsTail(events3, taskId, runsGet, opts) {
510865
510986
  }
510866
510987
  if (attempt >= SUGGESTIONS_TAIL_MAX_ATTEMPTS) return;
510867
510988
  let wait = Math.min(SUGGESTIONS_TAIL_RETRY_MS * attempt, SUGGESTIONS_TAIL_RETRY_CAP_MS), left = SUGGESTIONS_TAIL_BUDGET_MS - (now2() - t0);
510868
- if (left <= 0 || opts?.signal?.aborted || (await sleep10(Math.min(wait, left)), opts?.signal?.aborted)) return;
510989
+ if (left <= 0 || opts?.signal?.aborted || (await sleep9(Math.min(wait, left)), opts?.signal?.aborted)) return;
510869
510990
  }
510870
510991
  }
510871
510992
  async function* normalizeToolNames(events3) {
@@ -510906,53 +511027,53 @@ function promptSuggestionsOptIn() {
510906
511027
  return v2 === "1" || v2 === "true" || v2 === "yes" || v2 === "on";
510907
511028
  }
510908
511029
  function toLiveRequest(req, capturedSessionId) {
510909
- let out6 = { ...req };
510910
- if (out6.cwd == null && (out6.cwd = process.cwd()), out6.additionalDirectories === void 0)
510911
- try {
510912
- let dirs = getAppStateStoreRef()?.getState().toolPermissionContext?.additionalWorkingDirectories;
510913
- if (dirs && dirs.size > 0)
510914
- out6.additionalDirectories = [...dirs.keys()];
510915
- else if (dirs === void 0) {
510916
- let boot = getBootAdditionalDirectories();
510917
- boot && boot.length > 0 && (out6.additionalDirectories = [...boot]);
510918
- }
510919
- } catch {
510920
- }
510921
- if (out6.additionalReadDirectories === void 0) {
510922
- let configHome;
510923
- try {
510924
- configHome = getClaudeConfigHomeDir();
510925
- } catch {
510926
- configHome = void 0;
511030
+ let additionalDirectories;
511031
+ try {
511032
+ let dirs = getAppStateStoreRef()?.getState().toolPermissionContext?.additionalWorkingDirectories;
511033
+ if (dirs && dirs.size > 0)
511034
+ additionalDirectories = [...dirs.keys()];
511035
+ else if (dirs === void 0) {
511036
+ let boot = getBootAdditionalDirectories();
511037
+ boot && boot.length > 0 && (additionalDirectories = [...boot]);
510927
511038
  }
510928
- let roots = hostDefaultReadRoots({
510929
- configHome,
510930
- tmpdir: osTmpdir2(),
510931
- tmpdirEnv: process.env.TMPDIR,
510932
- homeDir: safeHomedir(),
510933
- cwd: out6.cwd ?? process.cwd(),
510934
- // 符号链接解析器:词法闸挡不住 `TMPDIR=/looks/fine`→`/`(复审轮二 [high])。
510935
- // 只用于**判决**,上 wire 的仍是词法值 —— canonicalize 是 core 的活,壳不写第二份。
510936
- realpath: realpathSyncNative
510937
- });
510938
- roots.length > 0 && (out6.additionalReadDirectories = roots);
510939
- }
510940
- if (out6.forwardSubagentEvents === void 0 && (out6.forwardSubagentEvents = !0), out6.retainSubagentSessions === void 0 && (out6.retainSubagentSessions = !0), out6.agents === void 0) {
510941
- let agentsField = taskAgentsField();
510942
- agentsField.agents && (out6.agents = agentsField.agents);
510943
- }
510944
- if (typeof out6.scenario == "string" && SEMA_MOCK_SCENARIO_KEYS.has(out6.scenario) && delete out6.scenario, appendSystemPromptCapable(liveCapsBaseUrl)) {
510945
- let existing = out6.appendSystemPrompt;
510946
- out6.appendSystemPrompt = withSelfKnowledgeAppend(existing);
510947
- } else {
510948
- let settings2 = out6.settings ?? {};
510949
- out6.settings = { ...settings2, outputStyle: withSelfKnowledgeOutputStyle(settings2.outputStyle) };
510950
- }
510951
- if (out6.suggestNextPrompts === void 0 && out6.verify === void 0 && out6.cascade === void 0 && promptSuggestionsOptIn() && (out6.suggestNextPrompts = !0), out6.compactionModel === void 0) {
510952
- let cheap = process.env.MODEL_CHEAP_ID?.trim();
510953
- cheap && engineCapTrue(liveCapsBaseUrl, "compactionModel") && getLiveModelCatalog()?.models.some((m2) => m2.name === cheap || m2.id === cheap) === !0 && (out6.compactionModel = cheap);
511039
+ } catch {
510954
511040
  }
510955
- return capturedSessionId ? out6.sessionId = capturedSessionId : out6.sessionId === mockClientIds.sessionId && delete out6.sessionId, out6;
511041
+ let configHome;
511042
+ try {
511043
+ configHome = getClaudeConfigHomeDir();
511044
+ } catch {
511045
+ configHome = void 0;
511046
+ }
511047
+ let readRoots = hostDefaultReadRoots({
511048
+ configHome,
511049
+ tmpdir: osTmpdir2(),
511050
+ tmpdirEnv: process.env.TMPDIR,
511051
+ homeDir: safeHomedir(),
511052
+ cwd: req.cwd ?? process.cwd(),
511053
+ // 符号链接解析器只用于**判决**,上 wire 的仍是词法值(canonicalize 是 core 的活)。
511054
+ realpath: realpathSyncNative
511055
+ }), compactionModel, cheap = process.env.MODEL_CHEAP_ID?.trim();
511056
+ cheap && engineCapTrue(liveCapsBaseUrl, "compactionModel") && getLiveModelCatalog()?.models.some((m2) => m2.name === cheap || m2.id === cheap) === !0 && (compactionModel = cheap);
511057
+ let agentsField = taskAgentsField(), existingAppend = req.appendSystemPrompt, existingOutputStyle = (req.settings ?? {}).outputStyle, reqLike = { ...req };
511058
+ return applyLiveRequestDefaults(reqLike, {
511059
+ cwd: process.cwd(),
511060
+ ...additionalDirectories !== void 0 ? { additionalDirectories } : {},
511061
+ additionalReadDirectories: readRoots,
511062
+ ...agentsField.agents ? { agents: agentsField.agents } : {},
511063
+ mockScenarioKeys: SEMA_MOCK_SCENARIO_KEYS,
511064
+ appendSystemPromptCapable: appendSystemPromptCapable(liveCapsBaseUrl),
511065
+ selfKnowledge: {
511066
+ forAppend: withSelfKnowledgeAppend(existingAppend),
511067
+ forOutputStyle: withSelfKnowledgeOutputStyle(existingOutputStyle)
511068
+ },
511069
+ suggestNextPrompts: promptSuggestionsOptIn(),
511070
+ ...compactionModel !== void 0 ? { compactionModel } : {},
511071
+ ...capturedSessionId !== void 0 ? { capturedSessionId } : {},
511072
+ mockSessionIdConstant: mockClientIds.sessionId
511073
+ // 出参定向转换(type-hygiene 基线 7→8 随批抬,理由注释即此行):包按结构操作返回
511074
+ // TaskRequestLike(Record 宽形),真 wire 形仍是 TaskRequest —— seamQuery.toTaskRequest
511075
+ // 出口的同款收窄惯例(同一转换形)。
511076
+ });
510956
511077
  }
510957
511078
  async function* captureSessionId(events3, onSession, wasEarlyAcquired, getEarlyTaskId, isCurrentEpoch) {
510958
511079
  for await (let ev of events3) {
@@ -510995,7 +511116,7 @@ function createLiveConversationClient(config4) {
510995
511116
  () => client3.capabilities()
510996
511117
  ), kickEngineCapsProbe(
510997
511118
  config4.baseUrl,
510998
- () => client3.capabilities().then((caps) => (noteEngineCapsForMcpGate(config4.baseUrl, caps), caps))
511119
+ () => client3.capabilities().then((caps) => (noteEngineCapsForMcpGate(config4.baseUrl, caps), noteEngineCapsForSessionBackground(config4.baseUrl, caps), caps))
510999
511120
  ), prepareTaskAgentsWire({
511000
511121
  baseUrl: config4.baseUrl,
511001
511122
  // loopback-unauthed = 不传 token(agentsWireCaps 对缺省 token 自然零 Authorization 头)。
@@ -511274,7 +511395,7 @@ function createLiveConversationClient(config4) {
511274
511395
  }
511275
511396
  var ENGINE_TO_CC_TOOL, SUGGESTIONS_TAIL_MAX_ATTEMPTS, SUGGESTIONS_TAIL_RETRY_MS, SUGGESTIONS_TAIL_RETRY_CAP_MS, SUGGESTIONS_TAIL_BUDGET_MS, SEMA_MOCK_SCENARIO_KEYS, liveCapsBaseUrl, liveClient_default, init_liveClient = __esm({
511276
511397
  "build-src/src/sema/liveClient.ts"() {
511277
- init_persistedRulesWire();
511398
+ init_persistedRulesWire2();
511278
511399
  init_rewindAnchorStore();
511279
511400
  init_engineToolDetach();
511280
511401
  init_dist();
@@ -511296,11 +511417,13 @@ var ENGINE_TO_CC_TOOL, SUGGESTIONS_TAIL_MAX_ATTEMPTS, SUGGESTIONS_TAIL_RETRY_MS,
511296
511417
  init_dist();
511297
511418
  init_agentsWire();
511298
511419
  init_mcpInjectionGate();
511420
+ init_sessionBackgroundArm();
511299
511421
  init_detachWire2();
511300
511422
  init_dist();
511301
511423
  init_selfKnowledge();
511302
511424
  init_dist();
511303
511425
  init_dist();
511426
+ init_dist();
511304
511427
  init_mockClient();
511305
511428
  init_seamQuery();
511306
511429
  ENGINE_TO_CC_TOOL = {
@@ -511987,12 +512110,12 @@ async function* ask(params) {
511987
512110
  }
511988
512111
  if (!(t2 === "retry_status" || t2 === "turn_usage" || t2 === "task_progress" || t2 === "steering_injected")) {
511989
512112
  if (t2 === "human_input") {
511990
- let hi = msg, clean5 = (v2) => (
512113
+ let hi = msg, clean6 = (v2) => (
511991
512114
  // eslint-disable-next-line no-control-regex
511992
512115
  String(v2 ?? "").replace(/[\x00-\x1f\x7f]/g, ".").slice(0, 120)
511993
- ), who = hi.actor?.id ? `${clean5(hi.actor.id)}${hi.actor.hostAsserted === !0 ? "" : " (unverified)"}` : "unattributed";
512116
+ ), who = hi.actor?.id ? `${clean6(hi.actor.id)}${hi.actor.hostAsserted === !0 ? "" : " (unverified)"}` : "unattributed";
511994
512117
  logForDebugging(
511995
- `[sema][print] human_input ledger frame (audit): carrier=${clean5(hi.carrier)} eventId=${clean5(hi.eventId)} by=${who}`
512118
+ `[sema][print] human_input ledger frame (audit): carrier=${clean6(hi.carrier)} eventId=${clean6(hi.eventId)} by=${who}`
511996
512119
  );
511997
512120
  continue;
511998
512121
  }
@@ -513236,7 +513359,7 @@ function runHeadlessStreaming(structuredIO, mcpClients, commands, tools, initial
513236
513359
  10
513237
513360
  );
513238
513361
  if (timeoutMs > 0) {
513239
- let timeout3 = sleep3(timeoutMs).then(() => "timeout");
513362
+ let timeout3 = sleep2(timeoutMs).then(() => "timeout");
513240
513363
  await Promise.race([pluginInstallPromise, timeout3]) === "timeout" && (logError(
513241
513364
  new Error(
513242
513365
  `SEMA_CODE_SYNC_PLUGIN_INSTALL: plugin installation timed out after ${timeoutMs}ms`
@@ -513482,7 +513605,7 @@ function runHeadlessStreaming(structuredIO, mcpClients, commands, tools, initial
513482
513605
  let state4 = getAppState(), hasRunningBg = getRunningTasks(state4).some(
513483
513606
  (t2) => isBackgroundTask(t2) && t2.type !== "in_process_teammate"
513484
513607
  ), hasDeliverableEngineWork = outstandingDeliverableWorkflowCount() > 0, hasMainThreadQueued = peek(isMainThread) !== void 0;
513485
- (hasRunningBg || hasMainThreadQueued || hasDeliverableEngineWork) && (waitingForAgents = !0, hasMainThreadQueued || (runPhase = "waiting_for_agents", await sleep3(100)));
513608
+ (hasRunningBg || hasMainThreadQueued || hasDeliverableEngineWork) && (waitingForAgents = !0, hasMainThreadQueued || (runPhase = "waiting_for_agents", await sleep2(100)));
513486
513609
  }
513487
513610
  } while (waitingForAgents);
513488
513611
  heldBackResult && (output.enqueue(heldBackResult), heldBackResult = null, suggestionState.pendingSuggestion && (output.enqueue(suggestionState.pendingSuggestion), suggestionState.pendingLastEmittedEntry && (suggestionState.lastEmitted = {
@@ -513607,7 +513730,7 @@ ${m2.text}
513607
513730
  }), run2();
513608
513731
  return;
513609
513732
  }
513610
- await sleep3(500);
513733
+ await sleep2(500);
513611
513734
  }
513612
513735
  }
513613
513736
  }
@@ -513620,7 +513743,7 @@ ${m2.text}
513620
513743
  mode: "prompt",
513621
513744
  value: SHUTDOWN_TEAM_PROMPT,
513622
513745
  uuid: randomUUID57()
513623
- }), run2()) : (suggestionState.inflightPromise && await Promise.race([suggestionState.inflightPromise, sleep3(5e3)]), suggestionState.abortController?.abort(), suggestionState.abortController = null, await finalizePendingAsyncHooks(), unsubscribeSkillChanges(), unsubscribeAuthStatus?.(), statusListeners.delete(rateLimitListener), output.done()));
513746
+ }), run2()) : (suggestionState.inflightPromise && await Promise.race([suggestionState.inflightPromise, sleep2(5e3)]), suggestionState.abortController?.abort(), suggestionState.abortController = null, await finalizePendingAsyncHooks(), unsubscribeSkillChanges(), unsubscribeAuthStatus?.(), statusListeners.delete(rateLimitListener), output.done()));
513624
513747
  }, cronScheduler = null, sendControlResponseSuccess = function(message, response) {
513625
513748
  output.enqueue({
513626
513749
  type: "control_response",
@@ -514381,7 +514504,7 @@ ${m2.text}
514381
514504
  }), run2();
514382
514505
  }
514383
514506
  }
514384
- inputClosed = !0, cronScheduler?.stop(), running || (suggestionState.inflightPromise && await Promise.race([suggestionState.inflightPromise, sleep3(5e3)]), suggestionState.abortController?.abort(), suggestionState.abortController = null, await finalizePendingAsyncHooks(), unsubscribeSkillChanges(), unsubscribeAuthStatus?.(), statusListeners.delete(rateLimitListener), output.done());
514507
+ inputClosed = !0, cronScheduler?.stop(), running || (suggestionState.inflightPromise && await Promise.race([suggestionState.inflightPromise, sleep2(5e3)]), suggestionState.abortController?.abort(), suggestionState.abortController = null, await finalizePendingAsyncHooks(), unsubscribeSkillChanges(), unsubscribeAuthStatus?.(), statusListeners.delete(rateLimitListener), output.done());
514385
514508
  })(), output;
514386
514509
  }
514387
514510
  function createCanUseToolWithPermissionPrompt(permissionPromptTool) {
@@ -518761,8 +518884,8 @@ function buildModelsValue(currentValue, uploaded, localRoles) {
518761
518884
  return Object.keys(roles).length > 0 && (value.roles = roles), Array.isArray(cur?.atModelAllowlist) && (value.atModelAllowlist = cur.atModelAllowlist), value;
518762
518885
  }
518763
518886
  function headerRefEnvName(server, header) {
518764
- let clean5 = (s) => s.toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
518765
- return `SEMA_MCP_${clean5(server) || "SERVER"}_${clean5(header) || "HEADER"}`;
518887
+ let clean6 = (s) => s.toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
518888
+ return `SEMA_MCP_${clean6(server) || "SERVER"}_${clean6(header) || "HEADER"}`;
518766
518889
  }
518767
518890
  function prepareMcp(name, c2) {
518768
518891
  let kind = asStr4(c2.type) ?? "stdio", display2 = `${name} (${kind}${kind === "stdio" ? `: ${asStr4(c2.command) ?? "?"}` : `: ${asStr4(c2.url) ?? "?"}`})`;
@@ -521072,7 +521195,7 @@ async function runBridgeLoop(config4, environmentId, environmentSecret, api2, sp
521072
521195
  cap2.cleanup();
521073
521196
  break;
521074
521197
  }
521075
- hbCycles++, await sleep3(
521198
+ hbCycles++, await sleep2(
521076
521199
  hbConfig.non_exclusive_heartbeat_interval_ms,
521077
521200
  cap2.signal
521078
521201
  ), cap2.cleanup();
@@ -521082,18 +521205,18 @@ async function runBridgeLoop(config4, environmentId, environmentSecret, api2, sp
521082
521205
  `[bridge:poll] Heartbeat poll_due after ${hbCycles} cycles \u2014 falling through to pollForWork`
521083
521206
  ), hbResult === "auth_failed" || hbResult === "fatal") {
521084
521207
  let cap2 = capacityWake.signal();
521085
- await sleep3(
521208
+ await sleep2(
521086
521209
  atCapMs > 0 ? atCapMs : pollConfig.non_exclusive_heartbeat_interval_ms,
521087
521210
  cap2.signal
521088
521211
  ), cap2.cleanup();
521089
521212
  }
521090
521213
  } else if (atCapMs > 0) {
521091
521214
  let cap2 = capacityWake.signal();
521092
- await sleep3(atCapMs, cap2.signal), cap2.cleanup();
521215
+ await sleep2(atCapMs, cap2.signal), cap2.cleanup();
521093
521216
  }
521094
521217
  } else {
521095
521218
  let interval = activeSessions.size > 0 ? pollConfig.multisession_poll_interval_ms_partial_capacity : pollConfig.multisession_poll_interval_ms_not_at_capacity;
521096
- await sleep3(interval, loopSignal);
521219
+ await sleep2(interval, loopSignal);
521097
521220
  }
521098
521221
  continue;
521099
521222
  }
@@ -521103,15 +521226,15 @@ async function runBridgeLoop(config4, environmentId, environmentSecret, api2, sp
521103
521226
  `[bridge:work] Skipping already-completed workId=${work.id}`
521104
521227
  ), atCapacityBeforeSwitch) {
521105
521228
  let cap2 = capacityWake.signal();
521106
- pollConfig.non_exclusive_heartbeat_interval_ms > 0 ? (await heartbeatActiveWorkItems(), await sleep3(
521229
+ pollConfig.non_exclusive_heartbeat_interval_ms > 0 ? (await heartbeatActiveWorkItems(), await sleep2(
521107
521230
  pollConfig.non_exclusive_heartbeat_interval_ms,
521108
521231
  cap2.signal
521109
- )) : pollConfig.multisession_poll_interval_ms_at_capacity > 0 && await sleep3(
521232
+ )) : pollConfig.multisession_poll_interval_ms_at_capacity > 0 && await sleep2(
521110
521233
  pollConfig.multisession_poll_interval_ms_at_capacity,
521111
521234
  cap2.signal
521112
521235
  ), cap2.cleanup();
521113
521236
  } else
521114
- await sleep3(1e3, loopSignal);
521237
+ await sleep2(1e3, loopSignal);
521115
521238
  continue;
521116
521239
  }
521117
521240
  let secret;
@@ -521131,10 +521254,10 @@ async function runBridgeLoop(config4, environmentId, environmentSecret, api2, sp
521131
521254
  )
521132
521255
  ), atCapacityBeforeSwitch) {
521133
521256
  let cap2 = capacityWake.signal();
521134
- pollConfig.non_exclusive_heartbeat_interval_ms > 0 ? (await heartbeatActiveWorkItems(), await sleep3(
521257
+ pollConfig.non_exclusive_heartbeat_interval_ms > 0 ? (await heartbeatActiveWorkItems(), await sleep2(
521135
521258
  pollConfig.non_exclusive_heartbeat_interval_ms,
521136
521259
  cap2.signal
521137
- )) : pollConfig.multisession_poll_interval_ms_at_capacity > 0 && await sleep3(
521260
+ )) : pollConfig.multisession_poll_interval_ms_at_capacity > 0 && await sleep2(
521138
521261
  pollConfig.multisession_poll_interval_ms_at_capacity,
521139
521262
  cap2.signal
521140
521263
  ), cap2.cleanup();
@@ -521198,7 +521321,7 @@ async function runBridgeLoop(config4, environmentId, environmentSecret, api2, sp
521198
521321
  if (attempt < 2) {
521199
521322
  if (logForDebugging(
521200
521323
  `[bridge:session] CCR v2: registerWorker attempt ${attempt} failed, retrying: ${errMsg}`
521201
- ), await sleep3(2e3, loopSignal), loopSignal.aborted) break;
521324
+ ), await sleep2(2e3, loopSignal), loopSignal.aborted) break;
521202
521325
  continue;
521203
521326
  }
521204
521327
  logger.logError(
@@ -521360,10 +521483,10 @@ async function runBridgeLoop(config4, environmentId, environmentSecret, api2, sp
521360
521483
  }
521361
521484
  if (atCapacityBeforeSwitch) {
521362
521485
  let cap2 = capacityWake.signal();
521363
- pollConfig.non_exclusive_heartbeat_interval_ms > 0 ? (await heartbeatActiveWorkItems(), await sleep3(
521486
+ pollConfig.non_exclusive_heartbeat_interval_ms > 0 ? (await heartbeatActiveWorkItems(), await sleep2(
521364
521487
  pollConfig.non_exclusive_heartbeat_interval_ms,
521365
521488
  cap2.signal
521366
- )) : pollConfig.multisession_poll_interval_ms_at_capacity > 0 && await sleep3(
521489
+ )) : pollConfig.multisession_poll_interval_ms_at_capacity > 0 && await sleep2(
521367
521490
  pollConfig.multisession_poll_interval_ms_at_capacity,
521368
521491
  cap2.signal
521369
521492
  ), cap2.cleanup();
@@ -521404,7 +521527,7 @@ async function runBridgeLoop(config4, environmentId, environmentSecret, api2, sp
521404
521527
  ), logger.updateReconnectingStatus(
521405
521528
  formatDelay(delay),
521406
521529
  formatDuration(elapsed)
521407
- ), getPollIntervalConfig().non_exclusive_heartbeat_interval_ms > 0 && await heartbeatActiveWorkItems(), await sleep3(delay, loopSignal);
521530
+ ), getPollIntervalConfig().non_exclusive_heartbeat_interval_ms > 0 && await heartbeatActiveWorkItems(), await sleep2(delay, loopSignal);
521408
521531
  } else {
521409
521532
  let now2 = Date.now();
521410
521533
  lastPollErrorTime !== null && now2 - lastPollErrorTime > pollSleepDetectionThresholdMs(backoffConfig) && (logForDebugging(
@@ -521429,7 +521552,7 @@ async function runBridgeLoop(config4, environmentId, environmentSecret, api2, sp
521429
521552
  ), logger.updateReconnectingStatus(
521430
521553
  formatDelay(delay),
521431
521554
  formatDuration(elapsed)
521432
- ), getPollIntervalConfig().non_exclusive_heartbeat_interval_ms > 0 && await heartbeatActiveWorkItems(), await sleep3(delay, loopSignal);
521555
+ ), getPollIntervalConfig().non_exclusive_heartbeat_interval_ms > 0 && await heartbeatActiveWorkItems(), await sleep2(delay, loopSignal);
521433
521556
  }
521434
521557
  }
521435
521558
  }
@@ -521456,7 +521579,7 @@ async function runBridgeLoop(config4, environmentId, environmentSecret, api2, sp
521456
521579
  let timeout3 = new AbortController();
521457
521580
  await Promise.race([
521458
521581
  Promise.allSettled([...activeSessions.values()].map((h) => h.done)),
521459
- sleep3(backoffConfig.shutdownGraceMs ?? 3e4, timeout3.signal)
521582
+ sleep2(backoffConfig.shutdownGraceMs ?? 3e4, timeout3.signal)
521460
521583
  ]), timeout3.abort();
521461
521584
  for (let [sid, handle2] of activeSessions.entries())
521462
521585
  logForDebugging(`[bridge:shutdown] Force-killing stuck sessionId=${sid}`), handle2.forceKill();
@@ -521542,7 +521665,7 @@ async function stopWorkWithRetry(api2, environmentId, workId, logger, baseDelayM
521542
521665
  let delay = addJitter(baseDelayMs * Math.pow(2, attempt - 1));
521543
521666
  logger.logVerbose(
521544
521667
  `Failed to stop work ${workId} (attempt ${attempt}/3), retrying in ${formatDelay(delay)}: ${errMsg}`
521545
- ), await sleep3(delay);
521668
+ ), await sleep2(delay);
521546
521669
  } else
521547
521670
  logger.logError(
521548
521671
  `Failed to stop work ${workId} after 3 attempts: ${errMsg}`
@@ -521746,7 +521869,7 @@ async function bridgeMain(args) {
521746
521869
  used_create_session_in_dir: parsedCreateSessionInDir !== void 0
521747
521870
  }), await Promise.race([
521748
521871
  Promise.all([shutdown1PEventLogging(), shutdownDatadog()]),
521749
- sleep3(500, void 0, { unref: !0 })
521872
+ sleep2(500, void 0, { unref: !0 })
521750
521873
  ]).catch(() => {
521751
521874
  }), console.error(
521752
521875
  "Error: Multi-session Remote Control is not enabled for your account yet."
@@ -529396,7 +529519,7 @@ Usage: sema --remote "your task description"`, () => gracefulShutdown(1));
529396
529519
  pendingHookMessages
529397
529520
  }, renderAndRun);
529398
529521
  }
529399
- }).version("sema 1.0.76", "-v, --version", "Output the version number"), program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)"), program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux."), canUserConfigureAdvisor() && program2.addOption(new Option("--advisor <model>", "Enable the server-side advisor tool with the specified model (alias or full ID).").hideHelp()), program2.addOption(new Option("--bg, --background", "Start the session as a background agent and return immediately (manage with `sema agents`)")), program2.command("ps").description("List background sessions").action(async () => {
529522
+ }).version("sema 1.0.77", "-v, --version", "Output the version number"), program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)"), program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux."), canUserConfigureAdvisor() && program2.addOption(new Option("--advisor <model>", "Enable the server-side advisor tool with the specified model (alias or full ID).").hideHelp()), program2.addOption(new Option("--bg, --background", "Start the session as a background agent and return immediately (manage with `sema agents`)")), program2.command("ps").description("List background sessions").action(async () => {
529400
529523
  await (await Promise.resolve().then(() => (init_bg2(), bg_exports))).psHandler([]), process.exit(process.exitCode ?? 0);
529401
529524
  }), program2.command("logs [id]").description("Print a background session's recent terminal output").action(async (id) => {
529402
529525
  await (await Promise.resolve().then(() => (init_bg2(), bg_exports))).logsHandler(id, []), process.exit(process.exitCode ?? 0);
@@ -535522,10 +535645,10 @@ async function deleteJobFromView(short) {
535522
535645
  return `Worktree ${keptReason === "dirty" ? "has uncommitted changes" : "could not be removed"} \u2014 kept at ${keptWorktree}`;
535523
535646
  }
535524
535647
  async function renameJobFromView(short, name) {
535525
- let clean5 = cleanName(name);
535648
+ let clean6 = cleanName(name);
535526
535649
  await patchJobState(short, {
535527
- name: clean5,
535528
- nameSource: clean5 ? "user" : void 0
535650
+ name: clean6,
535651
+ nameSource: clean6 ? "user" : void 0
535529
535652
  });
535530
535653
  }
535531
535654
  function jobLabel(j3) {