@sema-agent/cli 1.0.100 → 1.0.101

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
@@ -49104,7 +49104,7 @@ function isRewindFamilyCode(code2) {
49104
49104
  function asModelFallbackReason(v2) {
49105
49105
  return v2 === MODEL_FALLBACK_INHERIT_NO_TIER_BINDING ? MODEL_FALLBACK_INHERIT_NO_TIER_BINDING : void 0;
49106
49106
  }
49107
- var LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, LIMITS_ERROR_CODE_PREFIX, USAGE_WINDOW_EXHAUSTED, ENV_LIFETIME_EXPIRED, CONFIG_LIMIT_INVALID, CONFIG_STRATEGY_FIND_LIMIT_INVALID, CONFIG_STRATEGY_MAX_SIZE_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_DELEGATION_ENTRY_CAPS, CONFIG_REFUSAL_CODES, DELEGATION_CONCURRENCY_CAP, DELEGATION_SESSION_CAP, DELEGATION_CAP_CODES, MCP_SERVER_REVOKED, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, TOOL_END_INTERRUPTED_CODES, CAPABILITY_SELF_ORCHESTRATION_REQUIRED, 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, RESUME_USAGE_WINDOW_EXHAUSTED, RESUME_PREFLIGHT_REJECTED, RESUME_RETRY_LATER_CODES, DRAINING_ERROR_CODE, SCENARIO_NOT_ALLOWED_ERROR_CODE, STREAM_MAX_DURATION, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, init_engineErrorCodes = __esm({
49107
+ var LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, LIMITS_ERROR_CODE_PREFIX, USAGE_WINDOW_EXHAUSTED, ENV_LIFETIME_EXPIRED, CONFIG_LIMIT_INVALID, CONFIG_STRATEGY_FIND_LIMIT_INVALID, CONFIG_STRATEGY_MAX_SIZE_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_DELEGATION_ENTRY_CAPS, CONFIG_REFUSAL_CODES, DELEGATION_CONCURRENCY_CAP, DELEGATION_SESSION_CAP, DELEGATION_CAP_CODES, MCP_SERVER_REVOKED, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, TOOL_END_INTERRUPTED_CODES, CAPABILITY_SELF_ORCHESTRATION_REQUIRED, 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, RESUME_USAGE_WINDOW_EXHAUSTED, RESUME_PREFLIGHT_REJECTED, RESUME_PLACEMENT_MISMATCH, RESUME_RETRY_LATER_CODES, DRAINING_ERROR_CODE, SCENARIO_NOT_ALLOWED_ERROR_CODE, STREAM_MAX_DURATION, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, init_engineErrorCodes = __esm({
49108
49108
  "node_modules/@sema-agent/client-core/dist/engineErrorCodes.js"() {
49109
49109
  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", LIMITS_ERROR_CODE_PREFIX = "limits.";
49110
49110
  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_DELEGATION_ENTRY_CAPS = "config.delegation_entry_caps", CONFIG_REFUSAL_CODES = /* @__PURE__ */ new Set([
@@ -49129,7 +49129,7 @@ var LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TURNS_EXCEE
49129
49129
  STOP_NOT_LOCAL,
49130
49130
  STOP_PARKED
49131
49131
  ], OUTPUT_INVALID = "output.invalid", RESUME_AT_ERROR_CODE_PREFIX = "resume_at.", REWIND_ERROR_CODE_PREFIXES = [RESUME_AT_ERROR_CODE_PREFIX, "rewind_snapshot."];
49132
- RESUME_USAGE_WINDOW_EXHAUSTED = "resume.usage_window_exhausted", RESUME_PREFLIGHT_REJECTED = "resume.preflight_rejected", RESUME_RETRY_LATER_CODES = Object.freeze([
49132
+ RESUME_USAGE_WINDOW_EXHAUSTED = "resume.usage_window_exhausted", RESUME_PREFLIGHT_REJECTED = "resume.preflight_rejected", RESUME_PLACEMENT_MISMATCH = "resume.placement_mismatch", RESUME_RETRY_LATER_CODES = Object.freeze([
49133
49133
  RESUME_USAGE_WINDOW_EXHAUSTED,
49134
49134
  RESUME_PREFLIGHT_REJECTED
49135
49135
  ]), 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";
@@ -53425,6 +53425,25 @@ function eventToSdkMessage(ev, ctx) {
53425
53425
  */
53426
53426
  case "approval_request":
53427
53427
  return dropped("unsupported_arm", "approval_request");
53428
+ /**
53429
+ * `approval_revoke`(design/172 撤卡帧;server ≥7.55.0 起也进重放,SDK 8.x 才把它写进
53430
+ * `AgentEvent` union —— 0.58.0 sdk 8.2.0 提货批**编译期逼进来**的臂,与 `engine_notice`
53431
+ * / `human_input` 走的是同一条路:臂一进 union,`default` 的 B5 穷举断言当场红)。
53432
+ *
53433
+ * 🔴 **与 `approval_request` 同源同处置,所以并**在它旁边而不是并进上面那两条 —— 它是
53434
+ * 同一条流内审批协议的**撤销**半场(载荷同是 `ApprovalFrameEnvelope`,`schemaVersion`
53435
+ * 未知的帧要按信封先读再窄化)。本包今天**零消费口**:`isToolApprovalFrame` 只认
53436
+ * legacy 的 `tool_approval` / `tool_approval_complete` 两词,新族两帧一个都不接。
53437
+ * 🔴 分类 = `dropped/unsupported_arm` 而**不是** `nothing/not_in_slice`(与
53438
+ * `approval_request` 同一条理由,逐字见上一臂):`none` 是静默的,只有 `dropped` 会经
53439
+ * `reportDroppedFrame` 走宿主 sink + console 留痕。撤卡帧带的是**用户可见的状态迁移**
53440
+ * (那张卡已经不该再被决断了),悄悄丢掉它比吼一行更坏。
53441
+ * 📋 缺口如实记账(**不**在本批修 —— 与 `approval_request` 是同一条新卡链,属功能不属修复):
53442
+ * 接法在上一臂的「接法」段里写着,撤卡半场按 `approvalId` 撤同一张卡;在那条链落地之前
53443
+ * **不许**由本切片顺手编一个假 transcript 形来假装接上了。
53444
+ */
53445
+ case "approval_revoke":
53446
+ return dropped("unsupported_arm", "approval_revoke");
53428
53447
  // ── `engine_notice`(#310 / #318 件①,server ≥7.36,契约 = ASSISTANT-WIRE-CONTRACT 附录 D)────
53429
53448
  // 🔴 **到期复核已兑现(sdk 7.4.0 提货,0.48.0)** —— 与 `human_input`(sdk 6.9.0)逐字同一条路。
53430
53449
  // 本臂此前是 switch **之前**的一条 raw 预分派,理由 = 它还没进已发布 SDK 的 `AgentEvent`
@@ -56641,6 +56660,37 @@ var capByBase2, CAP_FALSE_RETRY_TTL_MS2, activeTails, activitySink, tailMetaSink
56641
56660
  }
56642
56661
  });
56643
56662
 
56663
+ // node_modules/@sema-agent/client-core/dist/resumeRefusalCopy.js
56664
+ function resumeRefusalFromError(err8) {
56665
+ if (typeof err8 != "object" || err8 === null)
56666
+ return null;
56667
+ let code2 = err8.errorCode;
56668
+ if (typeof code2 != "string" || !RESUME_REFUSAL_CODES.includes(code2))
56669
+ return null;
56670
+ if (code2 === RESUME_PLACEMENT_MISMATCH)
56671
+ return { code: code2, waitable: !1 };
56672
+ let timed = resumeRetryLaterFromError(err8);
56673
+ return timed === null ? { code: code2, waitable: !1 } : {
56674
+ code: code2,
56675
+ waitable: timed.waitable,
56676
+ ...timed.retryAfterSec !== void 0 ? { retryAfterSec: timed.retryAfterSec } : {}
56677
+ };
56678
+ }
56679
+ function resumeRefusalContent(detail) {
56680
+ let parts = [];
56681
+ return detail.code === RESUME_PLACEMENT_MISMATCH ? (parts.push("This resume named a different placement root than the one recorded when the work was parked"), parts.push("The engine refused it before consuming anything \u2014 the parked work is untouched"), parts.push("Retry with the recorded root, or omit the placement root to inherit it"), parts.join(" \xB7 ")) : (parts.push("The deployment's resume preflight refused this attempt"), parts.push("The refusal happened before the commit \u2014 your decision was not consumed"), parts.push(detail.waitable ? "The engine supplied a wait, so this token stays redeemable once the obstacle clears" : "The engine line above says whether this token can still be redeemed"), parts.join(" \xB7 "));
56682
+ }
56683
+ var RESUME_REFUSAL_CODES, init_resumeRefusalCopy = __esm({
56684
+ "node_modules/@sema-agent/client-core/dist/resumeRefusalCopy.js"() {
56685
+ init_engineErrorCodes();
56686
+ init_wireErrorTriage();
56687
+ RESUME_REFUSAL_CODES = Object.freeze([
56688
+ RESUME_PLACEMENT_MISMATCH,
56689
+ RESUME_PREFLIGHT_REJECTED
56690
+ ]);
56691
+ }
56692
+ });
56693
+
56644
56694
  // node_modules/@sema-agent/client-core/dist/sessionMap.js
56645
56695
  function engineNamespaceKeyFor(baseUrl) {
56646
56696
  if (!baseUrl)
@@ -59420,6 +59470,7 @@ var HITL_ASK_QUESTION_ID_PREFIX, PLAN_REVIEW_QUESTION_ID_PREFIX, HITL_FRAME_CALL
59420
59470
  });
59421
59471
 
59422
59472
  // node_modules/@sema-agent/client-core/dist/hitl/toolApprovalWire.js
59473
+ import { RULE_OFFER_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_UNCOVERED_REASONS } from "@sema-agent/sdk";
59423
59474
  function isFsApprovalGate(gate) {
59424
59475
  return gate ? gate.kind === "tool_approval" ? !0 : typeof gate.toolName == "string" && toolNameIsFsWrite(gate.toolName) : !1;
59425
59476
  }
@@ -59684,13 +59735,46 @@ function isNonNegativeFinite(v2) {
59684
59735
  function isWireRecordCarrier(v2) {
59685
59736
  return typeof v2 == "object" && v2 !== null && !Array.isArray(v2);
59686
59737
  }
59738
+ function isRuleOfferMatch(v2) {
59739
+ return typeof v2 == "string" && RULE_OFFER_MATCHES.includes(v2);
59740
+ }
59687
59741
  function readRuleTriple(v2) {
59688
59742
  if (v2 === null || typeof v2 != "object")
59689
59743
  return;
59690
59744
  let o = v2;
59691
- if (!(typeof o.rule != "string" || o.rule === "") && !(o.match !== "exact" && o.match !== "prefix") && !(typeof o.command != "string" || o.command === ""))
59745
+ if (!(typeof o.rule != "string" || o.rule === "") && isRuleOfferMatch(o.match) && !(typeof o.command != "string" || o.command === ""))
59692
59746
  return { rule: o.rule, match: o.match, command: o.command };
59693
59747
  }
59748
+ function readRuleOfferBatchMember(v2) {
59749
+ if (v2 === null || typeof v2 != "object")
59750
+ return;
59751
+ let o = v2, seg = o.segment;
59752
+ if (typeof seg != "string" || seg === "")
59753
+ return;
59754
+ let kind = o.kind === void 0 ? "command" : o.kind;
59755
+ if (typeof kind == "string" && RULE_OFFER_BATCH_MEMBER_KINDS.includes(kind)) {
59756
+ if (kind === "directoryRead") {
59757
+ let rule = o.rule, dir = o.directory;
59758
+ return typeof rule != "string" || rule === "" || typeof dir != "string" || dir === "" ? void 0 : { kind: "directoryRead", rule, directory: dir, segment: seg };
59759
+ }
59760
+ if (kind === "command") {
59761
+ let triple = readRuleTriple(v2);
59762
+ return triple === void 0 ? void 0 : { kind: "command", ...triple, segment: seg };
59763
+ }
59764
+ }
59765
+ }
59766
+ function readUncoveredDetail(v2) {
59767
+ if (!Array.isArray(v2) || v2.length === 0 || v2.length > MAX_RULE_OFFER_UNCOVERED_DETAIL_TOLERATED)
59768
+ return;
59769
+ let out6 = [];
59770
+ for (let raw2 of v2) {
59771
+ if (raw2 === null || typeof raw2 != "object")
59772
+ continue;
59773
+ let o = raw2;
59774
+ typeof o.segment != "string" || o.segment === "" || typeof o.reason == "string" && RULE_OFFER_UNCOVERED_REASONS.includes(o.reason) && out6.push({ segment: o.segment, reason: o.reason });
59775
+ }
59776
+ return out6.length > 0 ? out6 : void 0;
59777
+ }
59694
59778
  function readRuleOffers(v2) {
59695
59779
  if (!Array.isArray(v2) || v2.length === 0 || v2.length > MAX_RULE_OFFERS_TOLERATED)
59696
59780
  return;
@@ -59715,16 +59799,23 @@ function readRuleOffers(v2) {
59715
59799
  continue;
59716
59800
  let members = [], memberShapeOk = !0;
59717
59801
  for (let raw2 of o.rules) {
59718
- let triple = readRuleTriple(raw2), seg = raw2?.segment;
59719
- if (triple === void 0 || typeof seg != "string" || seg === "") {
59802
+ let member = readRuleOfferBatchMember(raw2);
59803
+ if (member === void 0) {
59720
59804
  memberShapeOk = !1;
59721
59805
  break;
59722
59806
  }
59723
- members.push({ ...triple, segment: seg });
59807
+ members.push(member);
59724
59808
  }
59725
59809
  if (!memberShapeOk)
59726
59810
  continue;
59727
- out6.push({ kind: "batch", offerIndex: i, rules: members, uncoveredSegments: uncovered });
59811
+ let detail = readUncoveredDetail(item.uncoveredDetail);
59812
+ out6.push({
59813
+ kind: "batch",
59814
+ offerIndex: i,
59815
+ rules: members,
59816
+ uncoveredSegments: uncovered,
59817
+ ...detail !== void 0 ? { uncoveredDetail: detail } : {}
59818
+ });
59728
59819
  continue;
59729
59820
  }
59730
59821
  }
@@ -59863,7 +59954,7 @@ async function surfaceToolApprovalFrameAndRespond(frame, respond, streamArgs, si
59863
59954
  return hostLog("debug", `liveToolApprovalWire: respond(${decision}) failed for ${frame.approvalId} (status=${respondRefusal?.status ?? "none"} errorCode=${logSafeErrorCode(respondRefusal?.errorCode)} messageLen=${respondRefusal?.message?.length ?? 0}) \u2014 engine self-settles (TTL/abort); the refusal text is handed back on outcome.respondRefusal for the host to surface`), respondRefusal !== void 0 ? { decision: "unresolved", respondRefusal } : { decision: "unresolved" };
59864
59955
  }
59865
59956
  }
59866
- var cardPortByKey, cardPortMissesByKey, TOOL_APPROVAL_FRAME_KEYS_MIRROR, RESPOND_DECISIONS, USELESS_REFUSAL_TEXTS, MACHINE_CODE_SHAPE, FS_WRITE_GATE_ASK_PATTERN, MAX_RULE_OFFERS_TOLERATED, MAX_RULE_OFFER_BATCH_MEMBERS_TOLERATED, MAX_RESPOND_NOTE_CHARS, init_toolApprovalWire = __esm({
59957
+ var cardPortByKey, cardPortMissesByKey, TOOL_APPROVAL_FRAME_KEYS_MIRROR, RESPOND_DECISIONS, USELESS_REFUSAL_TEXTS, MACHINE_CODE_SHAPE, FS_WRITE_GATE_ASK_PATTERN, MAX_RULE_OFFERS_TOLERATED, MAX_RULE_OFFER_BATCH_MEMBERS_TOLERATED, MAX_RULE_OFFER_UNCOVERED_DETAIL_TOLERATED, MAX_RESPOND_NOTE_CHARS, init_toolApprovalWire = __esm({
59867
59958
  "node_modules/@sema-agent/client-core/dist/hitl/toolApprovalWire.js"() {
59868
59959
  init_hitlBridge();
59869
59960
  init_host();
@@ -59890,16 +59981,16 @@ var cardPortByKey, cardPortMissesByKey, TOOL_APPROVAL_FRAME_KEYS_MIRROR, RESPOND
59890
59981
  "governanceForced",
59891
59982
  // sdk 6.14.0 追平(#225 件1,client-core 0.26.0):server 7.12.0 起真发规则候选 —— 门
59892
59983
  // (run-approval-frame-keys-test.mjs)在 bump SDK 当天恰红抓获本键缺席,本次补齐。
59893
- // ⚠️ **退役键**(server 7.46.0 起同文件 0 命中):留在镜像里是因为 sdk 7.2.0 的运行期锚仍含它,
59984
+ // ⚠️ **退役键**(server 7.46.0 起同文件 0 命中):留在镜像里是因为 sdk 8.2.0 的运行期锚仍含它,
59894
59985
  // 删了对账门的「SDK 锚的每个键本仓都有」当场红;本包对它只做归一读(见帧上同名键的 JSDoc)。
59895
59986
  "ruleSuggestions",
59896
59987
  // #334/[5223](client-core 0.43.0):server 7.46.0 起把规则候选整体换成判别联合 `ruleOffers`
59897
59988
  // (core 5.58.0 design/375;engine 7.46.0 fixture 的 `@sema-agent/server/dist/tool-approval.d.ts`
59898
- // 直证,同文件旧键 0 命中)sdk 7.2.0 锚**尚无**本键 `requiresRealApproval`/窗三键同形=
59899
- // **领先**,进对账门 AHEAD_OF_ANCHOR 带退出条件登记。
59989
+ // 直证,同文件旧键 0 命中)。✅ **sdk 8.2.0 锚已含本键**(S-134 锚②)0.58.0 提货批按退出
59990
+ // 条件删掉了对账门里那条 AHEAD_OF_ANCHOR 领先登记,本键回到「逐元素相等」的常态。
59900
59991
  "ruleOffers",
59901
59992
  // #341/[5214]③(client-core 0.43.0):server 7.46.0 起真发 `inputHasBidi`(E-14 Trojan Source 族;
59902
- // 7.44 fixture 同文件 0 命中)。同样**领先** sdk 7.2.0 锚 ⇒ AHEAD_OF_ANCHOR 登记。
59993
+ // 7.44 fixture 同文件 0 命中)。仍**领先** sdk 8.2.0 锚(node 直读 18 项无本键)⇒ AHEAD_OF_ANCHOR 登记。
59903
59994
  "inputHasBidi",
59904
59995
  // 🔴 **同形族扫的产物**(client-core 0.43.0,[same-shape-residue-constitution]):本批的病形是
59905
59996
  // 「镜像滞后于 server 实发键」。族扫 = 把 engine 7.46.0 fixture 的 `ToolApprovalFrame` 23 个声明键
@@ -59929,7 +60020,7 @@ var cardPortByKey, cardPortMissesByKey, TOOL_APPROVAL_FRAME_KEYS_MIRROR, RESPOND
59929
60020
  "requiresRealApproval",
59930
60021
  // [4851] 头号请托(client-core 0.38.2):server 7.34.0 起真发窗三键(#288/[4429]② cli 自己请托,
59931
60022
  // server src/tool-approval.ts 三键声明+条件 stamp)。⚠️ 与 requiresRealApproval 同形=**领先** SDK
59932
- // 运行期锚(sdk 7.2.0 锚 17 项,node 直读实证无三键)⇒ 进对账门 AHEAD_OF_ANCHOR 带退出条件登记
60023
+ // 运行期锚(sdk 8.2.0 锚 18 项,node 直读实证无三键)⇒ 进对账门 AHEAD_OF_ANCHOR 带退出条件登记
59933
60024
  // (SDK 追平当天登记自红逼删)。0.38.1 把三键丢在包边界外 = [4845]「卡到期屏幕零反应」的直接成因
59934
60025
  // (壳读器 readAskDeadlineMs 早已预埋,缺的一直是包边界这一格——#283 逐字同形第四例)。
59935
60026
  "expiresInMs",
@@ -59942,7 +60033,7 @@ var cardPortByKey, cardPortMissesByKey, TOOL_APPROVAL_FRAME_KEYS_MIRROR, RESPOND
59942
60033
  USELESS_REFUSAL_TEXTS = /* @__PURE__ */ new Set(["[object Object]", "null", "undefined", ""]);
59943
60034
  MACHINE_CODE_SHAPE = /^[A-Za-z0-9._:-]{1,64}$/;
59944
60035
  FS_WRITE_GATE_ASK_PATTERN = /^approve write to "([^"]+)"\?$/;
59945
- MAX_RULE_OFFERS_TOLERATED = 8, MAX_RULE_OFFER_BATCH_MEMBERS_TOLERATED = 8;
60036
+ MAX_RULE_OFFERS_TOLERATED = 8, MAX_RULE_OFFER_BATCH_MEMBERS_TOLERATED = 8, MAX_RULE_OFFER_UNCOVERED_DETAIL_TOLERATED = 32;
59946
60037
  MAX_RESPOND_NOTE_CHARS = 2048;
59947
60038
  }
59948
60039
  });
@@ -63548,7 +63639,9 @@ __export(dist_exports, {
63548
63639
  RESUME_CHOICE_BACKGROUND_LABEL: () => RESUME_CHOICE_BACKGROUND_LABEL,
63549
63640
  RESUME_CHOICE_CANCEL_LABEL: () => RESUME_CHOICE_CANCEL_LABEL,
63550
63641
  RESUME_CHOICE_HEADER: () => RESUME_CHOICE_HEADER,
63642
+ RESUME_PLACEMENT_MISMATCH: () => RESUME_PLACEMENT_MISMATCH,
63551
63643
  RESUME_PREFLIGHT_REJECTED: () => RESUME_PREFLIGHT_REJECTED,
63644
+ RESUME_REFUSAL_CODES: () => RESUME_REFUSAL_CODES,
63552
63645
  RESUME_RETRY_LATER_CODES: () => RESUME_RETRY_LATER_CODES,
63553
63646
  RESUME_RUNNING_GUIDANCE_TAG: () => RESUME_RUNNING_GUIDANCE_TAG,
63554
63647
  RESUME_RUNNING_NO_UI_EXIT_CODE: () => RESUME_RUNNING_NO_UI_EXIT_CODE,
@@ -63557,6 +63650,9 @@ __export(dist_exports, {
63557
63650
  REWIND_ERROR_CODE_PREFIXES: () => REWIND_ERROR_CODE_PREFIXES,
63558
63651
  RULE_NOT_SENT_REJECTED_WARN_TEXT: () => RULE_NOT_SENT_REJECTED_WARN_TEXT,
63559
63652
  RULE_NOT_SENT_WARN_TEXT: () => RULE_NOT_SENT_WARN_TEXT,
63653
+ RULE_OFFER_BATCH_MEMBER_KINDS: () => RULE_OFFER_BATCH_MEMBER_KINDS,
63654
+ RULE_OFFER_MATCHES: () => RULE_OFFER_MATCHES,
63655
+ RULE_OFFER_UNCOVERED_REASONS: () => RULE_OFFER_UNCOVERED_REASONS,
63560
63656
  RUNNING_STATES: () => RUNNING_STATES,
63561
63657
  RUN_BLOCKED_MESSAGE_PREFIX: () => RUN_BLOCKED_MESSAGE_PREFIX,
63562
63658
  RUN_LEVEL_STOP_ERROR_CODES: () => RUN_LEVEL_STOP_ERROR_CODES,
@@ -64114,6 +64210,8 @@ __export(dist_exports, {
64114
64210
  respondToQuestion: () => respondToQuestion,
64115
64211
  resumeAttachReplayDisclosure: () => resumeAttachReplayDisclosure,
64116
64212
  resumeChoiceFromLabels: () => resumeChoiceFromLabels,
64213
+ resumeRefusalContent: () => resumeRefusalContent,
64214
+ resumeRefusalFromError: () => resumeRefusalFromError,
64117
64215
  resumeRetryLaterFromError: () => resumeRetryLaterFromError,
64118
64216
  resumeRunningCancelUnconfirmedRow: () => resumeRunningCancelUnconfirmedRow,
64119
64217
  resumeRunningLivenessRow: () => resumeRunningLivenessRow,
@@ -64320,6 +64418,7 @@ var init_dist = __esm({
64320
64418
  init_engineWireTarget();
64321
64419
  init_principalWire();
64322
64420
  init_wireErrorTriage();
64421
+ init_resumeRefusalCopy();
64323
64422
  init_sessionMap();
64324
64423
  init_detachWire();
64325
64424
  init_workflowMonitor();
@@ -89000,38 +89099,87 @@ var consumedProbe, init_metaComboFallback = __esm({
89000
89099
  // build-src/src/utils/earlyInput.ts
89001
89100
  var earlyInput_exports = {};
89002
89101
  __export(earlyInput_exports, {
89102
+ __earlyInputStateForTests: () => __earlyInputStateForTests,
89103
+ __processChunkForTests: () => __processChunkForTests,
89104
+ __setEarlyInputStateForTests: () => __setEarlyInputStateForTests,
89003
89105
  consumeEarlyInput: () => consumeEarlyInput,
89004
89106
  flushPendingEscape: () => flushPendingEscape,
89005
89107
  foldEarlyInput: () => foldEarlyInput,
89006
89108
  hasEarlyInput: () => hasEarlyInput,
89007
89109
  isCapturingEarlyInput: () => isCapturingEarlyInput,
89008
89110
  releaseEarlyInputForNonReplLane: () => releaseEarlyInputForNonReplLane,
89111
+ replayHandover: () => replayHandover,
89009
89112
  seedEarlyInput: () => seedEarlyInput,
89010
89113
  startCapturingEarlyInput: () => startCapturingEarlyInput,
89011
89114
  stopCapturingEarlyInput: () => stopCapturingEarlyInput
89012
89115
  });
89116
+ function earlyInputTrace(line) {
89117
+ try {
89118
+ let argv = process.argv, path28;
89119
+ for (let i = 0; i < argv.length; i++) {
89120
+ let a = argv[i];
89121
+ if (a.startsWith("--debug-file=")) {
89122
+ path28 = a.slice(13);
89123
+ break;
89124
+ }
89125
+ if (a === "--debug-file" && typeof argv[i + 1] == "string") {
89126
+ path28 = argv[i + 1];
89127
+ break;
89128
+ }
89129
+ }
89130
+ if (!path28) return;
89131
+ __require("node:fs").appendFileSync(path28, `${(/* @__PURE__ */ new Date()).toISOString()} [DEBUG] [earlyInput] ${line}
89132
+ `);
89133
+ } catch {
89134
+ }
89135
+ }
89013
89136
  function startCapturingEarlyInput() {
89014
- if (!(!process.stdin.isTTY || isCapturing || process.argv.includes("-p") || process.argv.includes("--print"))) {
89015
- isCapturing = !0, captureArmedStdin = !0, earlyInputBuffer = "", flushPendingEscape();
89016
- try {
89017
- process.stdin.setEncoding("utf8"), process.stdin.setRawMode(!0), process.stdin.ref(), readableHandler = () => {
89018
- let chunk2 = process.stdin.read();
89019
- for (; chunk2 !== null; )
89020
- typeof chunk2 == "string" && processChunk(chunk2), chunk2 = process.stdin.read();
89021
- }, process.stdin.on("readable", readableHandler);
89022
- } catch {
89023
- isCapturing = !1;
89137
+ if (!process.stdin.isTTY || isCapturing || process.argv.includes("-p") || process.argv.includes("--print"))
89138
+ return;
89139
+ isCapturing = !0, captureArmedStdin = !0, earlyInputBuffer = "", flushPendingEscape();
89140
+ let handedOver = { chunks: [], stopped: !1 };
89141
+ try {
89142
+ let slot = globalThis[EARLY_INPUT_PRELUDE_SLOT];
89143
+ slot !== void 0 && typeof slot.detach == "function" && (handedOver = slot.detach(), delete globalThis[EARLY_INPUT_PRELUDE_SLOT]);
89144
+ } catch {
89145
+ handedOver = { chunks: [], stopped: !1 };
89146
+ }
89147
+ try {
89148
+ process.stdin.readableEncoding !== "utf8" && process.stdin.setEncoding("utf8"), process.stdin.setRawMode(!0), process.stdin.ref(), readableHandler = () => {
89149
+ let chunk2 = process.stdin.read();
89150
+ for (; chunk2 !== null; )
89151
+ typeof chunk2 == "string" && processChunk(chunk2), chunk2 = process.stdin.read();
89152
+ }, process.stdin.on("readable", readableHandler), replayHandover(handedOver, Date.now()), earlyInputTrace(`capture armed: handover chunks=${String(handedOver.chunks.length)} bytes=${String(handedOver.chunks.reduce((n2, c2) => n2 + c2.s.length, 0))} stopped=${String(handedOver.stopped)} buffer=${String(earlyInputBuffer.length)} capturing=${String(isCapturing)}`);
89153
+ } catch (e) {
89154
+ isCapturing = !1, earlyInputTrace(`capture FAILED: ${e instanceof Error ? e.stack ?? e.message : String(e)}`);
89155
+ }
89156
+ }
89157
+ function replayHandover(h, now2) {
89158
+ let list = h.chunks;
89159
+ for (let i = 0; i < list.length; i++) {
89160
+ let cur = list[i];
89161
+ if (processChunk(cur.s), !isCapturing) return;
89162
+ if (pendingEscape !== "\x1B") continue;
89163
+ if (i + 1 < list.length) {
89164
+ list[i + 1].t - cur.t > PENDING_ESCAPE_FLUSH_MS && flushPendingEscape();
89165
+ continue;
89024
89166
  }
89167
+ let waited = now2 - cur.t;
89168
+ waited > PENDING_ESCAPE_FLUSH_MS ? flushPendingEscape() : armPendingEscapeFlush(PENDING_ESCAPE_FLUSH_MS - waited);
89025
89169
  }
89026
89170
  }
89027
89171
  function clearPendingEscapeTimer() {
89028
89172
  pendingEscapeTimer !== null && (clearTimeout(pendingEscapeTimer), pendingEscapeTimer = null);
89029
89173
  }
89030
89174
  function flushPendingEscape() {
89031
- clearPendingEscapeTimer(), pendingEscape = "";
89175
+ clearPendingEscapeTimer(), pendingEscape = "", pendingEscapeDeadline = -1;
89032
89176
  }
89033
- function armPendingEscapeFlush() {
89034
- clearPendingEscapeTimer(), pendingEscape === "\x1B" && (pendingEscapeTimer = setTimeout(flushPendingEscape, PENDING_ESCAPE_FLUSH_MS), pendingEscapeTimer.unref?.());
89177
+ function armPendingEscapeFlush(remainingMs = PENDING_ESCAPE_FLUSH_MS) {
89178
+ if (clearPendingEscapeTimer(), pendingEscape !== "\x1B") {
89179
+ pendingEscapeDeadline = -1;
89180
+ return;
89181
+ }
89182
+ lastArmedEscapeMs = Math.max(0, remainingMs), pendingEscapeDeadline = Date.now() + lastArmedEscapeMs, pendingEscapeTimer = setTimeout(flushPendingEscape, lastArmedEscapeMs), pendingEscapeTimer.unref?.();
89035
89183
  }
89036
89184
  function foldEarlyInput(buffer5, pending4, str3) {
89037
89185
  let buf = buffer5, s = pending4 + str3, i = 0;
@@ -89086,7 +89234,7 @@ function processChunk(str3) {
89086
89234
  break;
89087
89235
  }
89088
89236
  }
89089
- clearPendingEscapeTimer();
89237
+ pendingEscape === "\x1B" && pendingEscapeDeadline >= 0 && Date.now() > pendingEscapeDeadline && flushPendingEscape(), clearPendingEscapeTimer();
89090
89238
  let folded = foldEarlyInput(earlyInputBuffer, pendingEscape, head);
89091
89239
  if (earlyInputBuffer = folded.buffer, pendingEscape = folded.pending, armPendingEscapeFlush(), tail === "ctrl-c") {
89092
89240
  stopCapturingEarlyInput(), process.exit(130);
@@ -89117,7 +89265,16 @@ function releaseEarlyInputForNonReplLane() {
89117
89265
  function consumeEarlyInput() {
89118
89266
  stopCapturingEarlyInput();
89119
89267
  let input = earlyInputBuffer.trim();
89120
- return earlyInputBuffer = "", input;
89268
+ return earlyInputTrace(`consume: buffer=${String(earlyInputBuffer.length)} trimmed=${String(input.length)}`), earlyInputBuffer = "", input;
89269
+ }
89270
+ function __earlyInputStateForTests() {
89271
+ return { buffer: earlyInputBuffer, pending: pendingEscape, capturing: isCapturing, armedMs: lastArmedEscapeMs };
89272
+ }
89273
+ function __processChunkForTests(str3) {
89274
+ processChunk(str3);
89275
+ }
89276
+ function __setEarlyInputStateForTests(o) {
89277
+ o.buffer !== void 0 && (earlyInputBuffer = o.buffer), o.pending !== void 0 && (pendingEscape = o.pending), o.capturing !== void 0 && (isCapturing = o.capturing), clearPendingEscapeTimer();
89121
89278
  }
89122
89279
  function hasEarlyInput() {
89123
89280
  return earlyInputBuffer.trim().length > 0;
@@ -89128,11 +89285,13 @@ function seedEarlyInput(text2) {
89128
89285
  function isCapturingEarlyInput() {
89129
89286
  return isCapturing;
89130
89287
  }
89131
- var earlyInputBuffer, isCapturing, captureArmedStdin, readableHandler, pendingEscape, PENDING_ESCAPE_FLUSH_MS, pendingEscapeTimer, init_earlyInput = __esm({
89288
+ var earlyInputBuffer, EARLY_INPUT_PRELUDE_SLOT, isCapturing, captureArmedStdin, readableHandler, pendingEscape, PENDING_ESCAPE_FLUSH_MS, pendingEscapeTimer, lastArmedEscapeMs, pendingEscapeDeadline, init_earlyInput = __esm({
89132
89289
  "build-src/src/utils/earlyInput.ts"() {
89133
89290
  init_intl();
89134
- earlyInputBuffer = "", isCapturing = !1, captureArmedStdin = !1, readableHandler = null;
89291
+ earlyInputBuffer = "";
89292
+ EARLY_INPUT_PRELUDE_SLOT = /* @__PURE__ */ Symbol.for("sema.earlyInputPrelude"), isCapturing = !1, captureArmedStdin = !1, readableHandler = null;
89135
89293
  pendingEscape = "", PENDING_ESCAPE_FLUSH_MS = 50, pendingEscapeTimer = null;
89294
+ lastArmedEscapeMs = -1, pendingEscapeDeadline = -1;
89136
89295
  }
89137
89296
  });
89138
89297
 
@@ -120569,7 +120728,8 @@ beta`,
120569
120728
  type: "engine_notice",
120570
120729
  code: "mcp_server_unavailable",
120571
120730
  message: "the MCP server is not reachable",
120572
- detail: { serverName: "nope", sessionId: scenarioIds.sessionId },
120731
+ // B-018 debug 不变量哨兵:未登记码的 detail **值**不许落任何日志(只落键名);无秘密纯哨兵串。
120732
+ detail: { serverName: "nope", sessionId: scenarioIds.sessionId, auditDetail: "B018_DETAIL_VALUE_MUST_NOT_BE_LOGGED" },
120573
120733
  sessionId: scenarioIds.sessionId,
120574
120734
  ts: 1700000000001
120575
120735
  };
@@ -175588,7 +175748,7 @@ How to use the statusLine command:
175588
175748
  To display both 5-hour and 7-day limits when available:
175589
175749
  - input=$(cat); five=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty'); week=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty'); out=""; [ -n "$five" ] && out="5h:$(printf '%.0f' "$five")%"; [ -n "$week" ] && out="$out 7d:$(printf '%.0f' "$week")%"; echo "$out"
175590
175750
 
175591
- 2. For longer commands, you can save a new file in the user's ~/.claude directory, e.g.:
175751
+ 2. For longer commands, you can save a new file in the user's ~/.sema directory, e.g.:
175592
175752
  - ~/.sema/statusline-command.sh and reference that file in the settings.
175593
175753
 
175594
175754
  3. Update the user's ~/.sema/settings.json with:
@@ -284568,7 +284728,7 @@ function FileEditToolUseRejectedMessage(t0) {
284568
284728
  }
284569
284729
  var import_compiler_runtime43, import_jsx_runtime53, MAX_LINES_TO_RENDER, init_FileEditToolUseRejectedMessage = __esm({
284570
284730
  "build-src/src/components/FileEditToolUseRejectedMessage.tsx"() {
284571
- import_compiler_runtime43 = __toESM(require_compiler_runtime());
284731
+ import_compiler_runtime43 = __toESM(require_compiler_runtime(), 1);
284572
284732
  init_useTerminalSize();
284573
284733
  init_cwd();
284574
284734
  init_ink2();
@@ -284576,7 +284736,7 @@ var import_compiler_runtime43, import_jsx_runtime53, MAX_LINES_TO_RENDER, init_F
284576
284736
  init_MessageResponse();
284577
284737
  init_StructuredDiffList();
284578
284738
  init_stringUtils();
284579
- import_jsx_runtime53 = __toESM(require_jsx_runtime()), MAX_LINES_TO_RENDER = 10;
284739
+ import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1), MAX_LINES_TO_RENDER = 10;
284580
284740
  }
284581
284741
  });
284582
284742
 
@@ -367524,27 +367684,6 @@ var arm, DEVICE_LANE_ABSENT_CODE, DEVICE_RUN_STORE_ABSENT_CODE, DEVICE_SERVICE_T
367524
367684
  }
367525
367685
  });
367526
367686
 
367527
- // build-src/src/sema/resumeRefusalCopy.ts
367528
- function resumeRefusalFromError(err8) {
367529
- if (typeof err8 != "object" || err8 === null) return null;
367530
- let e = err8, code2 = e.errorCode;
367531
- if (typeof code2 != "string" || !RESUME_REFUSAL_CODES.includes(code2)) return null;
367532
- let sec = e.retryAfterSec;
367533
- return {
367534
- code: code2,
367535
- ...typeof sec == "number" && Number.isFinite(sec) && sec >= 0 ? { retryAfterSec: sec } : {}
367536
- };
367537
- }
367538
- function resumeRefusalContent(detail) {
367539
- let parts = [];
367540
- return detail.code === "resume.placement_mismatch" ? (parts.push("This resume named a different placement root than the one recorded when the work was parked"), parts.push("The engine refused it before consuming anything \u2014 the parked work is untouched"), parts.push("Retry with the recorded root, or omit the placement root to inherit it")) : (parts.push("The deployment's resume preflight refused this attempt"), parts.push("The refusal happened before the commit \u2014 your decision was not consumed"), parts.push("The engine line above says whether this token can still be redeemed")), parts.join(" \xB7 ");
367541
- }
367542
- var RESUME_REFUSAL_CODES, init_resumeRefusalCopy = __esm({
367543
- "build-src/src/sema/resumeRefusalCopy.ts"() {
367544
- RESUME_REFUSAL_CODES = ["resume.placement_mismatch", "resume.preflight_rejected"];
367545
- }
367546
- });
367547
-
367548
367687
  // build-src/src/sema/scenarioNotAllowedCopy.ts
367549
367688
  function scenarioNotAllowedContent(detail, requestedScenario) {
367550
367689
  let parts = [];
@@ -367585,7 +367724,7 @@ var init_apiErrorSupplement = __esm({
367585
367724
  "build-src/src/sema/apiErrorSupplement.ts"() {
367586
367725
  init_devicesWire();
367587
367726
  init_quotaExhaustedCopy();
367588
- init_resumeRefusalCopy();
367727
+ init_dist();
367589
367728
  init_scenarioNotAllowedCopy();
367590
367729
  }
367591
367730
  });
@@ -401427,30 +401566,18 @@ var sema_brand_default, init_sema_brand = __esm({
401427
401566
  _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"
401428
401567
  },
401429
401568
  whatsNew: {
401430
- version: "1.0.100",
401569
+ version: "1.0.101",
401431
401570
  notes: [
401432
- 'If the local engine is older than this CLI build and nothing is running (no turn, no background tasks, no other sema session mid-turn), sema now switches to the newer engine on its own and says so in the transcript. When something is running, the footer banner now reads like "engine 7.55.0 running \xB7 7.57.0 installed (fixes not active) \xB7 ctrl+u to switch \u2014 interrupts N background tasks" instead of "engine update ready".',
401433
- "Approval cards whose window has closed no longer run on a single Yes: the first Yes shows a confirmation that says how long ago the window closed and what happens if you approve late; the second Yes approves. No still denies immediately, and cards inside their window are unchanged.",
401434
- "Permission rules such as Bash(touch:*) or Bash(npm run build:*) now auto-approve commands that create or write files inside the working directory (default mode). Previously those commands still prompted even with a matching allow rule; commands that write outside the working directory still prompt.",
401435
- `Choosing "Yes, and don't ask again for: <rule>" on an approval card now saves just that rule. It no longer silently allowed every call of that tool for the rest of the session.`,
401436
- "Turning file checkpointing off in /config now takes effect on the next turn instead of after a restart.",
401437
- "When you resume a session whose run is parked on an approval that no longer exists on the engine, sema now offers to cancel that run and send your message, or to leave it, instead of only suggesting /clear.",
401438
- "A sema started from inside an engine-run command (for example a hook or a Bash step) no longer writes a second state file under ~/.sema, so onboarding, directory trust, and marketplace state are not reset.",
401439
- "The bundled engine is 7.57.0: model request failures and retries are now written to the engine log, and secrets are scrubbed from stored run results.",
401440
- "The engine now refuses to let the model rewrite sema's own settings files (anything under ~/.sema and the other configuration roots), and the refusal is shown in the transcript instead of silently failing. Bundled engine is 7.59.0.",
401441
- "Switching models in /model no longer gets the whole model list rejected when an entry carries display-only keys; the switch takes effect without restarting the engine.",
401442
- "Typing while the prompt is still starting up no longer echoes raw characters or drops your Enter: keys are captured from the first millisecond and seeded into the input box once it is ready.",
401443
- "Control keys that arrive in the same burst as text (for example ctrl+U or a slash command typed quickly under load) are handled as keys again instead of landing in the input box as literal characters.",
401444
- "When the model has not sent its first token yet, the spinner line says so with the elapsed time instead of looking frozen; retry status shows what it is waiting on.",
401445
- 'Messages from sub-agents and from other sema sessions now appear as their own collapsed rows ("Message from @name: \u2026", ctrl+o to expand) instead of being folded into a generic background-task card.',
401446
- "Tools removed by a model gate are announced once in the transcript with the way to restore them, and /doctor now reports whether auto mode is actually armed on the engine.",
401447
- "Permission rules and settings descriptions now refer to ~/.sema instead of ~/.claude, so allow rules written for the real configuration directory match.",
401448
- "MCP server connection warnings are shown once per session instead of on every message, and agent definitions that reference an MCP tool the server does not offer now get a hint instead of silently losing the tool.",
401449
- "sema ps, sema logs and sema attach exit normally again after printing their result (they no longer hang in the terminal), and ctrl+C works in those commands."
401571
+ "Keys typed in the first second or two after launch \u2014 while the 25MB main bundle is still being parsed \u2014 are now captured by the tiny launcher and seeded into the input box once the prompt is ready, instead of being echoed raw by the terminal or lost. A lone Escape pressed during that window is still treated as Escape, and Ctrl+D still stops the capture.",
401572
+ "Approval cards now show rule offers whose match kind is wildcard or subpath, and batch offers that include a directory-read grant (for example the `cd /srv` segment of a compound command); previously those offers were silently dropped from the card.",
401573
+ "The wording shown when a resume is refused (placement root changed, or the deployment's preflight refused the token) now comes from the shared client library, so every sema client says the same thing; a retry-after window is only shown when the engine actually sent one.",
401574
+ '/doctor has a new "SQL engine" row: on a local single-machine engine it reports none (file stores); on a deployment with a SQL backend it reports the engine, isolation level and transaction mode, and it says "not observed" rather than inventing a value when no engine has answered yet.',
401575
+ "sema ps, sema logs and sema attach no longer hang after printing when Ctrl+D was pressed during startup.",
401576
+ "The bundled engine is 7.60.0 (core 7.5.0): rule stores are unified, the wiring manifest lists MCP servers, and classifier denial-limit fallbacks are marked on the wire."
401450
401577
  ]
401451
401578
  },
401452
- productVersion: "1.0.100",
401453
- announcement: `sema 1.0.100 \u2014 the engine now refuses to let the model rewrite sema's own settings file (and says so on screen), switching models in /model takes effect without restarting the engine, typing before the prompt is ready no longer loses your Enter or leaves control characters in the input box, a stall while waiting for the model's first token is shown on the spinner instead of looking frozen, messages from other sessions and sub-agents appear as their own rows, tools removed by a model gate are announced with how to restore them, /doctor reports whether auto mode is actually armed, and sema ps/logs/attach exit cleanly again. Everything listed for 1.0.99 (engine auto-switch, late-approval confirmation, allow rules for file-writing commands, per-rule "don't ask again") ships here too \u2014 1.0.99 was never published.`,
401579
+ productVersion: "1.0.101",
401580
+ announcement: 'sema 1.0.101 \u2014 keys typed in the first seconds after launch (before the main bundle has even loaded) are now captured instead of echoed raw or lost, approval cards show rule offers that use wildcard or subpath matching and directory-read grants, resume refusals share one wording with the other sema clients, /doctor has a new "SQL engine" row, and the bundled engine is 7.60.0.',
401454
401581
  version: "1.0.91"
401455
401582
  };
401456
401583
  }
@@ -405783,30 +405910,18 @@ var require_sema_brand = __commonJS({
405783
405910
  _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"
405784
405911
  },
405785
405912
  whatsNew: {
405786
- version: "1.0.100",
405913
+ version: "1.0.101",
405787
405914
  notes: [
405788
- 'If the local engine is older than this CLI build and nothing is running (no turn, no background tasks, no other sema session mid-turn), sema now switches to the newer engine on its own and says so in the transcript. When something is running, the footer banner now reads like "engine 7.55.0 running \xB7 7.57.0 installed (fixes not active) \xB7 ctrl+u to switch \u2014 interrupts N background tasks" instead of "engine update ready".',
405789
- "Approval cards whose window has closed no longer run on a single Yes: the first Yes shows a confirmation that says how long ago the window closed and what happens if you approve late; the second Yes approves. No still denies immediately, and cards inside their window are unchanged.",
405790
- "Permission rules such as Bash(touch:*) or Bash(npm run build:*) now auto-approve commands that create or write files inside the working directory (default mode). Previously those commands still prompted even with a matching allow rule; commands that write outside the working directory still prompt.",
405791
- `Choosing "Yes, and don't ask again for: <rule>" on an approval card now saves just that rule. It no longer silently allowed every call of that tool for the rest of the session.`,
405792
- "Turning file checkpointing off in /config now takes effect on the next turn instead of after a restart.",
405793
- "When you resume a session whose run is parked on an approval that no longer exists on the engine, sema now offers to cancel that run and send your message, or to leave it, instead of only suggesting /clear.",
405794
- "A sema started from inside an engine-run command (for example a hook or a Bash step) no longer writes a second state file under ~/.sema, so onboarding, directory trust, and marketplace state are not reset.",
405795
- "The bundled engine is 7.57.0: model request failures and retries are now written to the engine log, and secrets are scrubbed from stored run results.",
405796
- "The engine now refuses to let the model rewrite sema's own settings files (anything under ~/.sema and the other configuration roots), and the refusal is shown in the transcript instead of silently failing. Bundled engine is 7.59.0.",
405797
- "Switching models in /model no longer gets the whole model list rejected when an entry carries display-only keys; the switch takes effect without restarting the engine.",
405798
- "Typing while the prompt is still starting up no longer echoes raw characters or drops your Enter: keys are captured from the first millisecond and seeded into the input box once it is ready.",
405799
- "Control keys that arrive in the same burst as text (for example ctrl+U or a slash command typed quickly under load) are handled as keys again instead of landing in the input box as literal characters.",
405800
- "When the model has not sent its first token yet, the spinner line says so with the elapsed time instead of looking frozen; retry status shows what it is waiting on.",
405801
- 'Messages from sub-agents and from other sema sessions now appear as their own collapsed rows ("Message from @name: \u2026", ctrl+o to expand) instead of being folded into a generic background-task card.',
405802
- "Tools removed by a model gate are announced once in the transcript with the way to restore them, and /doctor now reports whether auto mode is actually armed on the engine.",
405803
- "Permission rules and settings descriptions now refer to ~/.sema instead of ~/.claude, so allow rules written for the real configuration directory match.",
405804
- "MCP server connection warnings are shown once per session instead of on every message, and agent definitions that reference an MCP tool the server does not offer now get a hint instead of silently losing the tool.",
405805
- "sema ps, sema logs and sema attach exit normally again after printing their result (they no longer hang in the terminal), and ctrl+C works in those commands."
405915
+ "Keys typed in the first second or two after launch \u2014 while the 25MB main bundle is still being parsed \u2014 are now captured by the tiny launcher and seeded into the input box once the prompt is ready, instead of being echoed raw by the terminal or lost. A lone Escape pressed during that window is still treated as Escape, and Ctrl+D still stops the capture.",
405916
+ "Approval cards now show rule offers whose match kind is wildcard or subpath, and batch offers that include a directory-read grant (for example the `cd /srv` segment of a compound command); previously those offers were silently dropped from the card.",
405917
+ "The wording shown when a resume is refused (placement root changed, or the deployment's preflight refused the token) now comes from the shared client library, so every sema client says the same thing; a retry-after window is only shown when the engine actually sent one.",
405918
+ '/doctor has a new "SQL engine" row: on a local single-machine engine it reports none (file stores); on a deployment with a SQL backend it reports the engine, isolation level and transaction mode, and it says "not observed" rather than inventing a value when no engine has answered yet.',
405919
+ "sema ps, sema logs and sema attach no longer hang after printing when Ctrl+D was pressed during startup.",
405920
+ "The bundled engine is 7.60.0 (core 7.5.0): rule stores are unified, the wiring manifest lists MCP servers, and classifier denial-limit fallbacks are marked on the wire."
405806
405921
  ]
405807
405922
  },
405808
- productVersion: "1.0.100",
405809
- announcement: `sema 1.0.100 \u2014 the engine now refuses to let the model rewrite sema's own settings file (and says so on screen), switching models in /model takes effect without restarting the engine, typing before the prompt is ready no longer loses your Enter or leaves control characters in the input box, a stall while waiting for the model's first token is shown on the spinner instead of looking frozen, messages from other sessions and sub-agents appear as their own rows, tools removed by a model gate are announced with how to restore them, /doctor reports whether auto mode is actually armed, and sema ps/logs/attach exit cleanly again. Everything listed for 1.0.99 (engine auto-switch, late-approval confirmation, allow rules for file-writing commands, per-rule "don't ask again") ships here too \u2014 1.0.99 was never published.`,
405923
+ productVersion: "1.0.101",
405924
+ announcement: 'sema 1.0.101 \u2014 keys typed in the first seconds after launch (before the main bundle has even loaded) are now captured instead of echoed raw or lost, approval cards show rule offers that use wildcard or subpath matching and directory-read grants, resume refusals share one wording with the other sema clients, /doctor has a new "SQL engine" row, and the bundled engine is 7.60.0.',
405810
405925
  version: "1.0.91"
405811
405926
  };
405812
405927
  }
@@ -426866,9 +426981,10 @@ var AUTO_MODE_DENIAL_LIMIT_DEFAULTS, init_auto_mode_defaults = __esm({
426866
426981
  });
426867
426982
 
426868
426983
  // node_modules/@sema-agent/core/dist/core/auto-mode-arming.js
426869
- var init_auto_mode_arming = __esm({
426984
+ var NO_BOUND_CEILING, init_auto_mode_arming = __esm({
426870
426985
  "node_modules/@sema-agent/core/dist/core/auto-mode-arming.js"() {
426871
426986
  init_auto_mode_defaults();
426987
+ NO_BOUND_CEILING = Number.POSITIVE_INFINITY;
426872
426988
  }
426873
426989
  });
426874
426990
 
@@ -430108,6 +430224,7 @@ import { tmpdir as tmpdir12 } from "node:os";
430108
430224
  import { join as join153 } from "node:path";
430109
430225
  var MCP_PREFIX, MCP_IDLE_TIMEOUT_STDIO_DEFAULT_MS, MCP_IDLE_TIMEOUT_HTTP_DEFAULT_MS, MCP_BLOB_DIR, MCP_SCHEMA_CHILD_SEAT, LIST_ENTRY_FINGERPRINT_MAX_CHARS, LOOP_REWIND_FINGERPRINT_MAX_CHARS, init_mcp4 = __esm({
430110
430226
  "node_modules/@sema-agent/core/dist/core/mcp.js"() {
430227
+ init_untrusted_egress();
430111
430228
  init_protocol_table();
430112
430229
  init_protocol_naming();
430113
430230
  init_client5();
@@ -430690,6 +430807,9 @@ function refuseOutOfContractDecision(d4, opts) {
430690
430807
  return d4;
430691
430808
  if (Object.prototype.hasOwnProperty.call(d4, RETIRED_TEXT_FIELD))
430692
430809
  return { action: "deny", message: RETIRED_TEXT_FIELD_DENY_MESSAGE, decisionReason: "rule" };
430810
+ let fb = d4.denialLimitFallback;
430811
+ if (typeof fb == "object" && fb !== null && fb.autoDenyAfterMs !== void 0)
430812
+ return { action: "deny", message: RETIRED_WINDOW_MEMBER_DENY_MESSAGE, decisionReason: "rule" };
430693
430813
  if (opts?.reasonIsNonInput === !0)
430694
430814
  return d4;
430695
430815
  let dr = d4.decisionReason;
@@ -430819,7 +430939,7 @@ function combinePolicies(...policies) {
430819
430939
  }
430820
430940
  };
430821
430941
  }
430822
- var DECISION_REASONS, DECISION_REASON_SET, ALLOW, RETIRED_TEXT_FIELD, RETIRED_TEXT_FIELD_DENY_MESSAGE, COARSE_SHELL_TOOLS, CASE_INSENSITIVE_FS, ASK_DENY_RESOLUTION_VALUES, ASK_DENY_RESOLUTION_SET, coreMintedResolutions, init_tool_policy = __esm({
430942
+ var DECISION_REASONS, DECISION_REASON_SET, ALLOW, RETIRED_TEXT_FIELD, RETIRED_WINDOW_MEMBER, RETIRED_WINDOW_MEMBER_DENY_MESSAGE, RETIRED_TEXT_FIELD_DENY_MESSAGE, COARSE_SHELL_TOOLS, CASE_INSENSITIVE_FS, ASK_DENY_RESOLUTION_VALUES, ASK_DENY_RESOLUTION_SET, coreMintedResolutions, init_tool_policy = __esm({
430823
430943
  "node_modules/@sema-agent/core/dist/core/tool-policy.js"() {
430824
430944
  init_ask_class();
430825
430945
  init_auto_mode_arming();
@@ -430830,7 +430950,7 @@ var DECISION_REASONS, DECISION_REASON_SET, ALLOW, RETIRED_TEXT_FIELD, RETIRED_TE
430830
430950
  init_protocol_table();
430831
430951
  init_safety();
430832
430952
  DECISION_REASONS = ["rule", "mode", "hook", "safety", "classifier", "persisted_rule", "sandbox", "org_rule", "org_unavailable"], DECISION_REASON_SET = new Set(DECISION_REASONS);
430833
- ALLOW = { action: "allow" }, RETIRED_TEXT_FIELD = "reason", RETIRED_TEXT_FIELD_DENY_MESSAGE = `a permission decision carries the retired "${RETIRED_TEXT_FIELD}" field \u2014 rename it to "message" (the one text field a decision carries); denied fail-closed rather than executing a decision whose text this layer cannot read`;
430953
+ ALLOW = { action: "allow" }, RETIRED_TEXT_FIELD = "reason", RETIRED_WINDOW_MEMBER = "autoDenyAfterMs", RETIRED_WINDOW_MEMBER_DENY_MESSAGE = `a permission decision's "denialLimitFallback" carries "${RETIRED_WINDOW_MEMBER}" \u2014 the decision names the counts only; the auto-deny window is decided by the ask's route (a live approver arms it, every other route runs none) and cannot be declared by a policy; denied fail-closed rather than silently replacing the declared number`, RETIRED_TEXT_FIELD_DENY_MESSAGE = `a permission decision carries the retired "${RETIRED_TEXT_FIELD}" field \u2014 rename it to "message" (the one text field a decision carries); denied fail-closed rather than executing a decision whose text this layer cannot read`;
430834
430954
  COARSE_SHELL_TOOLS = ["Bash", "Monitor"], CASE_INSENSITIVE_FS = process.platform === "darwin" || process.platform === "win32", ASK_DENY_RESOLUTION_VALUES = [
430835
430955
  "human_refused",
430836
430956
  "window_expired",
@@ -430845,6 +430965,13 @@ var DECISION_REASONS, DECISION_REASON_SET, ALLOW, RETIRED_TEXT_FIELD, RETIRED_TE
430845
430965
  }
430846
430966
  });
430847
430967
 
430968
+ // node_modules/@sema-agent/core/dist/core/ask-origin.js
430969
+ var ASK_ORIGINS, ASK_ORIGIN_SET, init_ask_origin = __esm({
430970
+ "node_modules/@sema-agent/core/dist/core/ask-origin.js"() {
430971
+ ASK_ORIGINS = ["content_question", "unresolvable", "org_unavailable", "org_rule", "hook", "ask_rule", "denial_limit_fallback", "policy"], ASK_ORIGIN_SET = new Set(ASK_ORIGINS);
430972
+ }
430973
+ });
430974
+
430848
430975
  // node_modules/@sema-agent/core/dist/core/permission-rule-model.js
430849
430976
  function foldSpacing(s) {
430850
430977
  let out6 = "", quote2, pendingGap = !1;
@@ -431203,6 +431330,7 @@ var MAX_PENDING_STEER_CHARS, PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES, MAX_PENDING_
431203
431330
  init_harness();
431204
431331
  init_untrusted_text();
431205
431332
  init_tool_policy();
431333
+ init_ask_origin();
431206
431334
  init_permission_rule_model();
431207
431335
  init_untrusted_egress();
431208
431336
  init_ask_question();
@@ -432807,13 +432935,13 @@ function assertRedemptionNotQuarantined(quarantined, delta) {
432807
432935
  if (hit !== void 0)
432808
432936
  throw new Error(`this approval's add (dot ${delta.add.dot.actor}#${delta.add.dot.counter}) was quarantined (${hit.reason}) \u2014 replaying the old record cannot revive it; a new consent (a new ask, a new record, a new dot) is required`);
432809
432937
  }
432810
- var PERMISSION_RULE_WRITER, ADD_ONLY_KEYS, InMemoryPermissionRuleStore, init_permission_rule_store = __esm({
432938
+ var PERMISSION_RULE_WRITER, ADD_ONLY_KEYS, InMemoryDurableRulePartition, init_permission_rule_store = __esm({
432811
432939
  "node_modules/@sema-agent/core/dist/core/permission-rule-store.js"() {
432812
432940
  init_canonical_json();
432813
432941
  init_permission_rule_model();
432814
432942
  PERMISSION_RULE_WRITER = "__semaPermissionRuleWriter";
432815
432943
  ADD_ONLY_KEYS = ["add", "redemption", "rule", "command", "match", "tool"];
432816
- InMemoryPermissionRuleStore = class {
432944
+ InMemoryDurableRulePartition = class {
432817
432945
  actor;
432818
432946
  now;
432819
432947
  durability = "process-local";
@@ -432874,11 +433002,11 @@ var PERMISSION_RULE_WRITER, ADD_ONLY_KEYS, InMemoryPermissionRuleStore, init_per
432874
433002
  });
432875
433003
 
432876
433004
  // node_modules/@sema-agent/core/dist/core/permission-rule-org.js
432877
- var ORG_FETCHED_AT_SKEW_ALLOWANCE_MS, init_permission_rule_org = __esm({
433005
+ var ORG_FETCHED_AT_SKEW_ALLOWANCE_MS, UNGOVERNED_ORG_RESOLUTION, init_permission_rule_org = __esm({
432878
433006
  "node_modules/@sema-agent/core/dist/core/permission-rule-org.js"() {
432879
433007
  init_permission_rule_model();
432880
433008
  init_permission_rule_store();
432881
- ORG_FETCHED_AT_SKEW_ALLOWANCE_MS = 5 * 6e4;
433009
+ ORG_FETCHED_AT_SKEW_ALLOWANCE_MS = 5 * 6e4, UNGOVERNED_ORG_RESOLUTION = Object.freeze({ source: "org", status: "ungoverned", rules: [], disclosures: [] });
432882
433010
  }
432883
433011
  });
432884
433012
 
@@ -433056,8 +433184,10 @@ var init_auto_mode = __esm({
433056
433184
  var init_denial_limit_arms = __esm({
433057
433185
  "node_modules/@sema-agent/core/dist/core/runner/denial-limit-arms.js"() {
433058
433186
  init_auto_mode();
433187
+ init_auto_mode_arming();
433059
433188
  init_types21();
433060
433189
  init_untrusted_text();
433190
+ init_ask_origin();
433061
433191
  }
433062
433192
  });
433063
433193
 
@@ -433228,6 +433358,14 @@ var uplinkSeqGlobal, REVIVE_LEASE_TTL_MS, init_send_message_tool = __esm({
433228
433358
  }
433229
433359
  });
433230
433360
 
433361
+ // node_modules/@sema-agent/core/dist/core/runner/prepare-permission-rules.js
433362
+ var init_prepare_permission_rules = __esm({
433363
+ "node_modules/@sema-agent/core/dist/core/runner/prepare-permission-rules.js"() {
433364
+ init_permission_rule_model();
433365
+ init_permission_rule_org();
433366
+ }
433367
+ });
433368
+
433231
433369
  // node_modules/@sema-agent/core/dist/core/runner/session-rule-policy.js
433232
433370
  var PATH_WRITE_TOOLS, PATH_CONFINABLE_WRITE_TOOLS, init_session_rule_policy = __esm({
433233
433371
  "node_modules/@sema-agent/core/dist/core/runner/session-rule-policy.js"() {
@@ -433257,11 +433395,20 @@ var init_active_skill_scope = __esm({
433257
433395
  }
433258
433396
  });
433259
433397
 
433398
+ // node_modules/@sema-agent/core/dist/core/runner/prepare-announce-once.js
433399
+ var init_prepare_announce_once = __esm({
433400
+ "node_modules/@sema-agent/core/dist/core/runner/prepare-announce-once.js"() {
433401
+ init_untrusted_egress();
433402
+ init_untrusted_text();
433403
+ }
433404
+ });
433405
+
433260
433406
  // node_modules/@sema-agent/core/dist/core/hooks.js
433261
433407
  var objectPrototype, init_hooks3 = __esm({
433262
433408
  "node_modules/@sema-agent/core/dist/core/hooks.js"() {
433263
433409
  init_tool_policy();
433264
433410
  init_ask_class();
433411
+ init_ask_origin();
433265
433412
  init_auto_mode();
433266
433413
  init_untrusted_text();
433267
433414
  init_reminder_mint();
@@ -433273,11 +433420,21 @@ var objectPrototype, init_hooks3 = __esm({
433273
433420
  }
433274
433421
  });
433275
433422
 
433423
+ // node_modules/@sema-agent/core/dist/core/sensitive-path-policy.js
433424
+ var CASE_INSENSITIVE_FS3, init_sensitive_path_policy = __esm({
433425
+ "node_modules/@sema-agent/core/dist/core/sensitive-path-policy.js"() {
433426
+ init_safety();
433427
+ init_read_deny();
433428
+ CASE_INSENSITIVE_FS3 = process.platform === "darwin" || process.platform === "win32";
433429
+ }
433430
+ });
433431
+
433276
433432
  // node_modules/@sema-agent/core/dist/core/write-protect.js
433277
433433
  var freezeTable, WRITE_PROTECTED_DEFAULT_TABLE, init_write_protect = __esm({
433278
433434
  "node_modules/@sema-agent/core/dist/core/write-protect.js"() {
433279
433435
  init_safety();
433280
433436
  init_session_rule_policy();
433437
+ init_sensitive_path_policy();
433281
433438
  freezeTable = (rows2) => Object.freeze(rows2.map((r) => Object.freeze(r))), WRITE_PROTECTED_DEFAULT_TABLE = freezeTable([
433282
433439
  { name: ".gitconfig", kind: "basename" },
433283
433440
  { name: ".gitmodules", kind: "basename" },
@@ -433327,7 +433484,9 @@ var freezeTable, WRITE_PROTECTED_DEFAULT_TABLE, init_write_protect = __esm({
433327
433484
  { name: ".mvn", kind: "segment" },
433328
433485
  { name: ".config/git", kind: "segment-run" },
433329
433486
  { name: ".ssh", kind: "segment" },
433330
- { name: ".gnupg", kind: "segment" }
433487
+ { name: ".gnupg", kind: "segment" },
433488
+ { name: ".sema.json", kind: "basename" },
433489
+ { name: ".sema", kind: "segment" }
433331
433490
  ]);
433332
433491
  }
433333
433492
  });
@@ -434100,17 +434259,17 @@ var PROMPT_HASH_SALT, DEFAULT_RESOURCE_TTL_MS, USAGE_WINDOW_REAP_MARGIN_MS, DEFA
434100
434259
  init_retain_ledger();
434101
434260
  init_tool_policy();
434102
434261
  init_permission_rule_model();
434103
- init_permission_rule_store();
434262
+ init_prepare_permission_rules();
434104
434263
  init_active_skill_scope();
434105
434264
  init_turn_attachments();
434106
434265
  init_untrusted_text();
434266
+ init_prepare_announce_once();
434107
434267
  init_reminder_mint();
434108
434268
  init_ask_class();
434109
434269
  init_trace();
434110
434270
  init_session_rule_policy();
434111
434271
  init_hooks3();
434112
434272
  init_write_protect();
434113
- init_permission_rule_org();
434114
434273
  init_cache_break_detector();
434115
434274
  init_request_params();
434116
434275
  init_route_adjudicator();
@@ -434290,6 +434449,7 @@ var init_runtask = __esm({
434290
434449
  init_hooks3();
434291
434450
  init_human_input_projection();
434292
434451
  init_untrusted_text();
434452
+ init_prepare_announce_once();
434293
434453
  init_session_reconcile();
434294
434454
  init_tool_result_store();
434295
434455
  init_lsp_diagnostics();
@@ -435079,6 +435239,15 @@ var WINDOWS_DEVICE_NAMES, STALE_JOURNAL_MS, init_file_history_store2 = __esm({
435079
435239
  }
435080
435240
  });
435081
435241
 
435242
+ // node_modules/@sema-agent/core/dist/core/permission-rule-provider.js
435243
+ var init_permission_rule_provider = __esm({
435244
+ "node_modules/@sema-agent/core/dist/core/permission-rule-provider.js"() {
435245
+ init_permission_rule_model();
435246
+ init_permission_rule_store();
435247
+ init_permission_rule_org();
435248
+ }
435249
+ });
435250
+
435082
435251
  // node_modules/@sema-agent/core/dist/core/permission-rule-sync.js
435083
435252
  var init_permission_rule_sync = __esm({
435084
435253
  "node_modules/@sema-agent/core/dist/core/permission-rule-sync.js"() {
@@ -435089,9 +435258,16 @@ var init_permission_rule_sync = __esm({
435089
435258
  });
435090
435259
 
435091
435260
  // node_modules/@sema-agent/core/dist/stores/file/permission-rule-store.js
435092
- import { closeSync as closeSync14, constants as FS2, existsSync as existsSync29, fsyncSync as fsyncSync11, lstatSync as lstatSync5, mkdirSync as mkdirSync24, openSync as openSync15, readFileSync as readFileSync42, renameSync as renameSync16, unlinkSync as unlinkSync15, writeFileSync as writeFileSync22 } from "node:fs";
435261
+ import { closeSync as closeSync14, constants as FS2, existsSync as existsSync29, fsyncSync as fsyncSync11, lstatSync as lstatSync5, mkdirSync as mkdirSync24, openSync as openSync15, readFileSync as readFileSync42, readdirSync as readdirSync13, renameSync as renameSync16, unlinkSync as unlinkSync15, writeFileSync as writeFileSync22 } from "node:fs";
435093
435262
  import { join as join157 } from "node:path";
435094
435263
  import { createHash as createHash28, randomBytes as randomBytes26 } from "node:crypto";
435264
+ function isRuleFile(v2) {
435265
+ let p = v2;
435266
+ return typeof p == "object" && p !== null && p.schemaVersion === 3 && Array.isArray(p.rules) && Array.isArray(p.tombstones) && typeof p.rev == "number" && (p.quarantined === void 0 || Array.isArray(p.quarantined));
435267
+ }
435268
+ function schemaVersionWord(v2) {
435269
+ return typeof v2 == "object" && v2 !== null ? v2.schemaVersion : void 0;
435270
+ }
435095
435271
  function atomicPublish(dir, file2, payload2) {
435096
435272
  let tmp = join157(dir, `.${randomBytes26(8).toString("hex")}.tmp`), fd2;
435097
435273
  try {
@@ -435129,14 +435305,14 @@ function assertSafeDir(dir) {
435129
435305
  if ((st2.mode & 18) !== 0)
435130
435306
  throw new Error(`permission-rule store directory ${dir} is writable by group or others (mode ${(st2.mode & 511).toString(8)}); refusing to use it \u2014 anyone who can write here can grant themselves permissions`);
435131
435307
  }
435132
- var EMPTY_READ, FilePermissionRuleStore, init_permission_rule_store2 = __esm({
435308
+ var EMPTY_READ, FileDurableRulePartition, init_permission_rule_store2 = __esm({
435133
435309
  "node_modules/@sema-agent/core/dist/stores/file/permission-rule-store.js"() {
435134
435310
  init_permission_rule_store();
435135
435311
  init_canonical_json();
435136
435312
  init_fs_atomic();
435137
435313
  init_marker();
435138
435314
  EMPTY_READ = { rules: [], tombstones: [], rev: 0 };
435139
- FilePermissionRuleStore = class {
435315
+ FileDurableRulePartition = class {
435140
435316
  dir;
435141
435317
  file;
435142
435318
  acquireWriteLock;
@@ -435170,8 +435346,8 @@ var EMPTY_READ, FilePermissionRuleStore, init_permission_rule_store2 = __esm({
435170
435346
  let why = `${this.file} is not valid JSON (${err8.message}); refusing the whole file and loading zero rules`;
435171
435347
  return this.disclose(why), { unreadable: why };
435172
435348
  }
435173
- if (parsed?.schemaVersion !== 1 && parsed?.schemaVersion !== 2 || !Array.isArray(parsed.rules) || !Array.isArray(parsed.tombstones) || typeof parsed.rev != "number" || parsed.quarantined !== void 0 && !Array.isArray(parsed.quarantined)) {
435174
- let why = `${this.file} does not carry a readable rule-file shape; refusing the whole file and loading zero rules`;
435349
+ if (!isRuleFile(parsed)) {
435350
+ let sv = schemaVersionWord(parsed), why = sv === 1 || sv === 2 ? `${this.file} is a schema ${String(sv)} bucket that was not migrated to schema 3 (written by an older engine after this directory was migrated?); refusing the whole file and loading zero rules` : `${this.file} does not carry a readable rule-file shape; refusing the whole file and loading zero rules`;
435175
435351
  return this.disclose(why), { unreadable: why };
435176
435352
  }
435177
435353
  let { checksum, ...body } = parsed;
@@ -435196,6 +435372,8 @@ var EMPTY_READ, FilePermissionRuleStore, init_permission_rule_store2 = __esm({
435196
435372
  }
435197
435373
  async list() {
435198
435374
  let r = this.read();
435375
+ if ("unreadable" in r)
435376
+ throw new Error(r.unreadable);
435199
435377
  if (!("file" in r))
435200
435378
  return { ...EMPTY_READ };
435201
435379
  let screened = this.screenDurableRows(r.file);
@@ -435210,26 +435388,11 @@ var EMPTY_READ, FilePermissionRuleStore, init_permission_rule_store2 = __esm({
435210
435388
  let r = this.read();
435211
435389
  return "file" in r ? this.screenDurableRows(r.file).quarantined : [];
435212
435390
  }
435213
- async readOrgState() {
435214
- let r = this.read();
435215
- return "file" in r ? r.file.org : void 0;
435216
- }
435217
- async installOrgState(state5) {
435218
- this.acquireWriteLock(), await this.serialize(() => {
435219
- let cur = this.current();
435220
- if (cur.org !== void 0 && state5.revisionHighWater < cur.org.revisionHighWater)
435221
- throw new Error(`refusing to lower the org revision high-water mark (${cur.org.revisionHighWater} \u2192 ${state5.revisionHighWater}) \u2014 an interleaved install must re-read and re-compare`);
435222
- if (cur.org !== void 0 && state5.snapshot.revision === cur.org.snapshot.revision && canonicalize3(state5.snapshot.rules) !== canonicalize3(cur.org.snapshot.rules))
435223
- throw new Error(`refusing to replace org revision ${state5.snapshot.revision} with DIFFERENT policy content under the same revision \u2014 content changes must bump the revision`);
435224
- if (!this.writeAndVerify({ ...cur, schemaVersion: 2, org: state5 }))
435225
- throw new Error("the permission-rule store did not survive its own write; the org snapshot was not installed");
435226
- });
435227
- }
435228
435391
  current() {
435229
435392
  let r = this.read();
435230
435393
  if ("unreadable" in r)
435231
435394
  throw new Error(`refusing to write the permission-rule store while it cannot be read: ${r.unreadable}`);
435232
- return "absent" in r ? { schemaVersion: 1, actor: `file-${randomBytes26(6).toString("hex")}`, counter: 0, rev: 0, rules: [], tombstones: [] } : {
435395
+ return "absent" in r ? { schemaVersion: 3, actor: `file-${randomBytes26(6).toString("hex")}`, counter: 0, rev: 0, rules: [], tombstones: [] } : {
435233
435396
  schemaVersion: r.file.schemaVersion,
435234
435397
  actor: r.file.actor,
435235
435398
  counter: r.file.counter,
@@ -435237,7 +435400,6 @@ var EMPTY_READ, FilePermissionRuleStore, init_permission_rule_store2 = __esm({
435237
435400
  rules: r.file.rules,
435238
435401
  tombstones: r.file.tombstones,
435239
435402
  ...r.file.sync !== void 0 ? { sync: r.file.sync } : {},
435240
- ...r.file.org !== void 0 ? { org: r.file.org } : {},
435241
435403
  ...r.file.quarantined !== void 0 ? { quarantined: r.file.quarantined } : {}
435242
435404
  };
435243
435405
  }
@@ -435291,7 +435453,6 @@ var EMPTY_READ, FilePermissionRuleStore, init_permission_rule_store2 = __esm({
435291
435453
  ...cur.sync?.observedVector !== void 0 ? { observedVector: cur.sync.observedVector } : {}
435292
435454
  }, delta, Date.now()), landed = {
435293
435455
  ...cur,
435294
- schemaVersion: 2,
435295
435456
  rev: cur.rev + 1,
435296
435457
  rules: next2.rules,
435297
435458
  tombstones: next2.tombstones,
@@ -435319,6 +435480,7 @@ var EMPTY_READ, FilePermissionRuleStore, init_permission_rule_store2 = __esm({
435319
435480
  var init_permission_rule_adopt = __esm({
435320
435481
  "node_modules/@sema-agent/core/dist/stores/file/permission-rule-adopt.js"() {
435321
435482
  init_permission_rule_store();
435483
+ init_permission_rule_provider();
435322
435484
  init_permission_rule_sync();
435323
435485
  init_permission_rule_store2();
435324
435486
  }
@@ -435369,15 +435531,6 @@ var init_file2 = __esm({
435369
435531
  }
435370
435532
  });
435371
435533
 
435372
- // node_modules/@sema-agent/core/dist/core/sensitive-path-policy.js
435373
- var CASE_INSENSITIVE_FS3, init_sensitive_path_policy = __esm({
435374
- "node_modules/@sema-agent/core/dist/core/sensitive-path-policy.js"() {
435375
- init_safety();
435376
- init_read_deny();
435377
- CASE_INSENSITIVE_FS3 = process.platform === "darwin" || process.platform === "win32";
435378
- }
435379
- });
435380
-
435381
435534
  // node_modules/@sema-agent/core/dist/core/fs-write-gate-policy.js
435382
435535
  var init_fs_write_gate_policy = __esm({
435383
435536
  "node_modules/@sema-agent/core/dist/core/fs-write-gate-policy.js"() {
@@ -435576,6 +435729,7 @@ function precheckEditedRuleText2(text2, command8) {
435576
435729
  var init_permission_rule_consent = __esm({
435577
435730
  "node_modules/@sema-agent/core/dist/core/permission-rule-consent.js"() {
435578
435731
  init_permission_rule_model();
435732
+ init_permission_rule_provider();
435579
435733
  init_permission_rule_store();
435580
435734
  }
435581
435735
  });
@@ -436232,6 +436386,7 @@ var init_dist10 = __esm({
436232
436386
  init_cascade();
436233
436387
  init_sql_adapters();
436234
436388
  init_mcp4();
436389
+ init_mcp4();
436235
436390
  init_a2a();
436236
436391
  init_protocol_table();
436237
436392
  init_session_policy_store();
@@ -436314,6 +436469,8 @@ var init_dist10 = __esm({
436314
436469
  init_loop_tick();
436315
436470
  init_tighten_task_spec();
436316
436471
  init_tool_policy();
436472
+ init_ask_origin();
436473
+ init_hooks3();
436317
436474
  init_auto_mode();
436318
436475
  init_auto_mode_defaults();
436319
436476
  init_auto_mode_prompt();
@@ -436324,6 +436481,7 @@ var init_dist10 = __esm({
436324
436481
  init_permission_rule_model();
436325
436482
  init_permission_rule_store();
436326
436483
  init_permission_rule_sync();
436484
+ init_permission_rule_provider();
436327
436485
  init_permission_rule_session();
436328
436486
  init_permission_rule_org();
436329
436487
  init_governance_codes();
@@ -470130,7 +470288,9 @@ __export(agentsWire_exports, {
470130
470288
  RESUME_CHOICE_BACKGROUND_LABEL: () => RESUME_CHOICE_BACKGROUND_LABEL,
470131
470289
  RESUME_CHOICE_CANCEL_LABEL: () => RESUME_CHOICE_CANCEL_LABEL,
470132
470290
  RESUME_CHOICE_HEADER: () => RESUME_CHOICE_HEADER,
470291
+ RESUME_PLACEMENT_MISMATCH: () => RESUME_PLACEMENT_MISMATCH,
470133
470292
  RESUME_PREFLIGHT_REJECTED: () => RESUME_PREFLIGHT_REJECTED,
470293
+ RESUME_REFUSAL_CODES: () => RESUME_REFUSAL_CODES,
470134
470294
  RESUME_RETRY_LATER_CODES: () => RESUME_RETRY_LATER_CODES,
470135
470295
  RESUME_RUNNING_GUIDANCE_TAG: () => RESUME_RUNNING_GUIDANCE_TAG,
470136
470296
  RESUME_RUNNING_NO_UI_EXIT_CODE: () => RESUME_RUNNING_NO_UI_EXIT_CODE,
@@ -470139,6 +470299,9 @@ __export(agentsWire_exports, {
470139
470299
  REWIND_ERROR_CODE_PREFIXES: () => REWIND_ERROR_CODE_PREFIXES,
470140
470300
  RULE_NOT_SENT_REJECTED_WARN_TEXT: () => RULE_NOT_SENT_REJECTED_WARN_TEXT,
470141
470301
  RULE_NOT_SENT_WARN_TEXT: () => RULE_NOT_SENT_WARN_TEXT,
470302
+ RULE_OFFER_BATCH_MEMBER_KINDS: () => RULE_OFFER_BATCH_MEMBER_KINDS,
470303
+ RULE_OFFER_MATCHES: () => RULE_OFFER_MATCHES,
470304
+ RULE_OFFER_UNCOVERED_REASONS: () => RULE_OFFER_UNCOVERED_REASONS,
470142
470305
  RUNNING_STATES: () => RUNNING_STATES,
470143
470306
  RUN_BLOCKED_MESSAGE_PREFIX: () => RUN_BLOCKED_MESSAGE_PREFIX,
470144
470307
  RUN_LEVEL_STOP_ERROR_CODES: () => RUN_LEVEL_STOP_ERROR_CODES,
@@ -470698,6 +470861,8 @@ __export(agentsWire_exports, {
470698
470861
  respondToQuestion: () => respondToQuestion,
470699
470862
  resumeAttachReplayDisclosure: () => resumeAttachReplayDisclosure,
470700
470863
  resumeChoiceFromLabels: () => resumeChoiceFromLabels,
470864
+ resumeRefusalContent: () => resumeRefusalContent,
470865
+ resumeRefusalFromError: () => resumeRefusalFromError,
470701
470866
  resumeRetryLaterFromError: () => resumeRetryLaterFromError,
470702
470867
  resumeRunningCancelUnconfirmedRow: () => resumeRunningCancelUnconfirmedRow,
470703
470868
  resumeRunningLivenessRow: () => resumeRunningLivenessRow,
@@ -470982,6 +471147,72 @@ var init_detachWire2 = __esm({
470982
471147
  }
470983
471148
  });
470984
471149
 
471150
+ // build-src/src/sema/sqlEngineCapability.ts
471151
+ var sqlEngineCapability_exports = {};
471152
+ __export(sqlEngineCapability_exports, {
471153
+ __resetSqlEngineReadingsForTests: () => __resetSqlEngineReadingsForTests,
471154
+ forgetSqlEngineReading: () => forgetSqlEngineReading,
471155
+ noteEngineCapsForSqlEngine: () => noteEngineCapsForSqlEngine,
471156
+ observedSqlEngine: () => observedSqlEngine,
471157
+ projectSqlEngineCapability: () => projectSqlEngineCapability,
471158
+ sqlEngineDoctorDetail: () => sqlEngineDoctorDetail
471159
+ });
471160
+ function projectSqlEngineCapability(caps) {
471161
+ if (caps === null || typeof caps != "object") return;
471162
+ if (!("sql" in caps)) return { kind: "not_reported" };
471163
+ let sql = caps.sql;
471164
+ if (sql === null) return { kind: "none" };
471165
+ if (sql === void 0) return { kind: "not_reported" };
471166
+ if (typeof sql != "object") return;
471167
+ let s = sql;
471168
+ if (!(typeof s.engine != "string" || s.engine === "") && !(typeof s.isolation != "string" || s.isolation === "") && !(s.txnMode !== null && (typeof s.txnMode != "string" || s.txnMode === "")))
471169
+ return { kind: "present", view: { engine: s.engine, isolation: s.isolation, txnMode: s.txnMode } };
471170
+ }
471171
+ function noteEngineCapsForSqlEngine(baseUrl, caps) {
471172
+ try {
471173
+ let reading = projectSqlEngineCapability(caps);
471174
+ if (reading === void 0) {
471175
+ readingByBase.delete(baseUrl);
471176
+ return;
471177
+ }
471178
+ readingByBase.set(baseUrl, reading);
471179
+ } catch {
471180
+ }
471181
+ }
471182
+ function capsBaseUrl5() {
471183
+ let raw2 = process.env.SEMA_LIVE_BASEURL;
471184
+ return typeof raw2 == "string" && raw2.trim() !== "" ? raw2 : void 0;
471185
+ }
471186
+ function observedSqlEngine(baseUrl = capsBaseUrl5()) {
471187
+ return typeof baseUrl != "string" || baseUrl === "" ? { kind: "unobserved" } : readingByBase.get(baseUrl) ?? { kind: "unobserved" };
471188
+ }
471189
+ function sqlEngineDoctorDetail(reading) {
471190
+ switch (reading.kind) {
471191
+ case "unobserved":
471192
+ return "not observed \u2014 the engine reports it on /v1/capabilities; this one-shot process has no engine response (run /doctor inside the REPL after a turn)";
471193
+ case "not_reported":
471194
+ return "not reported by this engine \u2014 the capability position needs a newer engine";
471195
+ case "none":
471196
+ return "none \u2014 the engine reports no SQL backend on this deployment (local file stores)";
471197
+ case "present": {
471198
+ let e = cleanUntrustedForDisplay(reading.view.engine, 40), i = cleanUntrustedForDisplay(reading.view.isolation, 40), t2 = reading.view.txnMode === null ? "no txn-mode indicator on this engine" : cleanUntrustedForDisplay(reading.view.txnMode, 40);
471199
+ return `${e} \xB7 isolation ${i} \xB7 txn ${t2}`;
471200
+ }
471201
+ }
471202
+ }
471203
+ function forgetSqlEngineReading(baseUrl) {
471204
+ typeof baseUrl != "string" || baseUrl === "" || readingByBase.delete(baseUrl);
471205
+ }
471206
+ function __resetSqlEngineReadingsForTests() {
471207
+ readingByBase.clear();
471208
+ }
471209
+ var readingByBase, init_sqlEngineCapability = __esm({
471210
+ "build-src/src/sema/sqlEngineCapability.ts"() {
471211
+ init_untrustedDisplayText();
471212
+ readingByBase = /* @__PURE__ */ new Map();
471213
+ }
471214
+ });
471215
+
470985
471216
  // build-src/src/sema/engineCapsArm.ts
470986
471217
  function beginCapsTeeEpoch(baseUrl) {
470987
471218
  let next = (capsTeeEpochByBase.get(baseUrl) ?? 0) + 1;
@@ -471006,7 +471237,7 @@ function armEngineCapsProbes(input) {
471006
471237
  return caps;
471007
471238
  }) : capsProbe;
471008
471239
  if (afterEngineRespawn) {
471009
- resetCapsDiscoveryState(baseUrl), invalidateSelfKnowledgeCap(baseUrl), kickAppendSystemPromptCapProbe(baseUrl, appendCapProbe), invalidateEngineCaps(baseUrl, guardedCapsProbe);
471240
+ resetCapsDiscoveryState(baseUrl), invalidateSelfKnowledgeCap(baseUrl), forgetSqlEngineReading(baseUrl), kickAppendSystemPromptCapProbe(baseUrl, appendCapProbe), invalidateEngineCaps(baseUrl, guardedCapsProbe);
471010
471241
  return;
471011
471242
  }
471012
471243
  kickAppendSystemPromptCapProbe(baseUrl, appendCapProbe), kickEngineCapsProbe(baseUrl, guardedCapsProbe);
@@ -471018,6 +471249,7 @@ var capsTeeEpochByBase, init_engineCapsArm = __esm({
471018
471249
  init_dist();
471019
471250
  init_projectContextCapGate();
471020
471251
  init_selfKnowledge();
471252
+ init_sqlEngineCapability();
471021
471253
  capsTeeEpochByBase = /* @__PURE__ */ new Map();
471022
471254
  }
471023
471255
  });
@@ -471447,7 +471679,7 @@ function createLiveConversationClient(config4) {
471447
471679
  capsTee: (caps) => {
471448
471680
  noteEngineCapsForMcpGate(config4.baseUrl, caps), noteEngineCapsForSessionBackground(config4.baseUrl, caps), noteEngineCapsForProjectContext(config4.baseUrl, caps), readCrashConvergedOnce(client3, config4.baseUrl, { principal: config4.principal }), noteEngineCapsForWorkflowsGate(config4.baseUrl, caps, {
471449
471681
  ...typeof config4.principal == "string" ? { principal: config4.principal } : {}
471450
- });
471682
+ }), noteEngineCapsForSqlEngine(config4.baseUrl, caps);
471451
471683
  },
471452
471684
  afterEngineRespawn: config4.afterEngineRespawn === !0
471453
471685
  }), prepareTaskAgentsWire({
@@ -471824,6 +472056,7 @@ var ENGINE_TO_CC_TOOL, SUGGESTIONS_TAIL_MAX_ATTEMPTS, SUGGESTIONS_TAIL_RETRY_MS,
471824
472056
  init_engineCapsArm();
471825
472057
  init_crashConvergedNotice();
471826
472058
  init_selfOrchestrationDenial2();
472059
+ init_sqlEngineCapability();
471827
472060
  init_projectContextCapGate();
471828
472061
  init_dist();
471829
472062
  init_dist();
@@ -472521,11 +472754,11 @@ var powerupUnlocked, powerupState_default, init_powerupState = __esm({
472521
472754
  });
472522
472755
 
472523
472756
  // build-src/src/sema/workflowJournalWire.ts
472524
- function capsBaseUrl5() {
472757
+ function capsBaseUrl6() {
472525
472758
  let raw2 = process.env.SEMA_LIVE_BASEURL;
472526
472759
  return typeof raw2 == "string" && raw2.trim() !== "" ? raw2 : void 0;
472527
472760
  }
472528
- function workflowJournalAvailable(baseUrl = capsBaseUrl5()) {
472761
+ function workflowJournalAvailable(baseUrl = capsBaseUrl6()) {
472529
472762
  return engineCapTrue(baseUrl, WORKFLOW_JOURNAL_CAP);
472530
472763
  }
472531
472764
  function resolveJournalFacade() {
@@ -487837,12 +488070,12 @@ function readOffers(confirm2, key = "ruleOffers") {
487837
488070
  if (!Array.isArray(o.rules) || o.rules.length === 0 || !Number.isSafeInteger(o.uncoveredSegments) || o.uncoveredSegments < 0) continue;
487838
488071
  let members = [], memberShapeOk = !0;
487839
488072
  for (let m2 of o.rules) {
487840
- let triple = readRuleTriple2(m2), segment2 = m2?.segment;
487841
- if (triple === void 0 || typeof segment2 != "string" || segment2 === "") {
488073
+ let member = readBatchMember(m2);
488074
+ if (member === void 0) {
487842
488075
  memberShapeOk = !1;
487843
488076
  break;
487844
488077
  }
487845
- members.push({ ...triple, segment: segment2 });
488078
+ members.push(member);
487846
488079
  }
487847
488080
  if (!memberShapeOk) continue;
487848
488081
  out6.push({ kind: "batch", offerIndex, rules: members, uncoveredSegments: o.uncoveredSegments });
@@ -487851,12 +488084,27 @@ function readOffers(confirm2, key = "ruleOffers") {
487851
488084
  }
487852
488085
  return out6;
487853
488086
  }
488087
+ function isRuleOfferMatch2(v2) {
488088
+ return RULE_OFFER_MATCHES.some((m2) => m2 === v2);
488089
+ }
487854
488090
  function readRuleTriple2(v2) {
487855
488091
  if (v2 === null || typeof v2 != "object") return;
487856
488092
  let s = v2;
487857
- if (!(typeof s.rule != "string" || s.rule === "") && !(s.match !== "exact" && s.match !== "prefix"))
488093
+ if (!(typeof s.rule != "string" || s.rule === "") && isRuleOfferMatch2(s.match))
487858
488094
  return { rule: s.rule, match: s.match, command: typeof s.command == "string" ? s.command : "" };
487859
488095
  }
488096
+ function readBatchMember(v2) {
488097
+ if (v2 === null || typeof v2 != "object") return;
488098
+ let m2 = v2;
488099
+ if (typeof m2.segment != "string" || m2.segment === "") return;
488100
+ let segment2 = m2.segment, kind = m2.kind === void 0 ? "command" : m2.kind;
488101
+ if (kind === "command") {
488102
+ let triple = readRuleTriple2(v2);
488103
+ return triple === void 0 ? void 0 : { kind: "command", ...triple, segment: segment2 };
488104
+ }
488105
+ if (kind === "directoryRead")
488106
+ return typeof m2.rule != "string" || m2.rule === "" || typeof m2.directory != "string" || m2.directory === "" ? void 0 : { kind: "directoryRead", rule: m2.rule, directory: m2.directory, segment: segment2 };
488107
+ }
487860
488108
  function engineRuleSuggestionOptions(confirm2) {
487861
488109
  let offers = readOffers(confirm2);
487862
488110
  if (offers.length === 0) return [];
@@ -512371,7 +512619,7 @@ function _temp158() {
512371
512619
  }
512372
512620
  var import_compiler_runtime307, import_react317, SETTINGS_ERRORS_NOTIFICATION_KEY, init_useSettingsErrors = __esm({
512373
512621
  "build-src/src/hooks/notifs/useSettingsErrors.tsx"() {
512374
- import_compiler_runtime307 = __toESM(require_compiler_runtime(), 1), import_react317 = __toESM(require_react(), 1);
512622
+ import_compiler_runtime307 = __toESM(require_compiler_runtime()), import_react317 = __toESM(require_react());
512375
512623
  init_notifications2();
512376
512624
  init_state();
512377
512625
  init_allErrors();
@@ -521907,6 +522155,12 @@ async function collectAxesRows(opts, deps2) {
521907
522155
  } catch {
521908
522156
  rows2.push({ label: "Auto mode", status: "warn", detail: "reading unavailable" });
521909
522157
  }
522158
+ try {
522159
+ let { sqlEngineDoctorDetail: sqlEngineDoctorDetail2, observedSqlEngine: observedSqlEngine2 } = await Promise.resolve().then(() => (init_sqlEngineCapability(), sqlEngineCapability_exports)), reading = deps2?.readSqlEngine !== void 0 ? deps2.readSqlEngine() : observedSqlEngine2();
522160
+ rows2.push({ label: "SQL engine", status: "info", detail: sqlEngineDoctorDetail2(reading) });
522161
+ } catch {
522162
+ rows2.push({ label: "SQL engine", status: "warn", detail: "reading unavailable" });
522163
+ }
521910
522164
  let remote = (() => {
521911
522165
  try {
521912
522166
  return engineTarget.configuredEngineUrl();
@@ -525252,7 +525506,7 @@ var CC_DIR5, CC_GLOBAL_FILE2, MCP_SCOPE_LABELS, init_mcpChannels = __esm({
525252
525506
  });
525253
525507
 
525254
525508
  // build-src/src/sema/importSources.ts
525255
- import { existsSync as existsSync34, mkdirSync as mkdirSync27, readdirSync as readdirSync13, readFileSync as readFileSync52, writeFileSync as writeFileSync27 } from "node:fs";
525509
+ import { existsSync as existsSync34, mkdirSync as mkdirSync27, readdirSync as readdirSync14, readFileSync as readFileSync52, writeFileSync as writeFileSync27 } from "node:fs";
525256
525510
  import { createHash as createHash31 } from "node:crypto";
525257
525511
  import { homedir as homedir48 } from "node:os";
525258
525512
  import { dirname as dirname89, join as join195, resolve as resolve50, sep as sep43 } from "node:path";
@@ -525261,14 +525515,14 @@ function toSafeName(raw2) {
525261
525515
  }
525262
525516
  function safeReaddirFiles(dir, ext) {
525263
525517
  try {
525264
- return readdirSync13(dir, { withFileTypes: !0 }).filter((e) => e.isFile() && e.name.endsWith(ext)).map((e) => e.name);
525518
+ return readdirSync14(dir, { withFileTypes: !0 }).filter((e) => e.isFile() && e.name.endsWith(ext)).map((e) => e.name);
525265
525519
  } catch {
525266
525520
  return [];
525267
525521
  }
525268
525522
  }
525269
525523
  function hasNamespacedSubdirs(dir) {
525270
525524
  try {
525271
- return readdirSync13(dir, { withFileTypes: !0 }).filter((e) => e.isDirectory()).map((e) => e.name);
525525
+ return readdirSync14(dir, { withFileTypes: !0 }).filter((e) => e.isDirectory()).map((e) => e.name);
525272
525526
  } catch {
525273
525527
  return [];
525274
525528
  }
@@ -526605,14 +526859,15 @@ async function* ask(params) {
526605
526859
  continue;
526606
526860
  }
526607
526861
  if (t2 === "engine_notice") {
526608
- let en2 = msg, clean9 = (v2) => cleanUntrustedForDisplay(v2, 160), detailText = "";
526862
+ let en2 = msg, clean9 = (v2) => cleanUntrustedForDisplay(v2, 160), detailKeys = "";
526609
526863
  try {
526610
- detailText = en2.detail === void 0 ? "" : cleanUntrustedForDisplay(JSON.stringify(en2.detail), 400);
526864
+ detailKeys = en2.detail !== null && typeof en2.detail == "object" && !Array.isArray(en2.detail) ? Object.keys(en2.detail).map((k2) => clean9(k2)).join(",") : en2.detail === void 0 ? "" : `<${typeof en2.detail}>`;
526611
526865
  } catch {
526612
- detailText = "(unserializable)";
526866
+ detailKeys = "(unreadable)";
526613
526867
  }
526868
+ let messageLen = typeof en2.message == "string" ? en2.message.length : 0;
526614
526869
  logForDebugging(
526615
- `[sema][print] engine_notice swallowed (audit; no stdout parity frame \u2014 see [4429]/#302): code=${clean9(en2.code)} eventId=${clean9(en2.eventId)} eventSeq=${clean9(en2.eventSeq)} ts=${clean9(en2.ts)} sessionId=${clean9(en2.sessionId)} message=${clean9(en2.message)} detail=${detailText}`
526870
+ `[sema][print] engine_notice swallowed (audit; no stdout parity frame \u2014 see [4429]/#302): code=${clean9(en2.code)} eventId=${clean9(en2.eventId)} eventSeq=${clean9(en2.eventSeq)} ts=${clean9(en2.ts)} sessionId=${clean9(en2.sessionId)} messageLen=${String(messageLen)} detailKeys=[${detailKeys}]`
526616
526871
  );
526617
526872
  let noticeKey = `${clean9(en2.eventId)}|${clean9(en2.eventSeq)}|${clean9(en2.code)}`;
526618
526873
  if (!emittedNoticeKeys.has(noticeKey) && isSurfaceableEngineNoticeCode(en2.code)) {
@@ -531150,18 +531405,18 @@ __export(adoptionGuard_exports, {
531150
531405
  countLocalSessionArtifacts: () => countLocalSessionArtifacts,
531151
531406
  remoteSwitchSessionNotice: () => remoteSwitchSessionNotice
531152
531407
  });
531153
- import { readdirSync as readdirSync14, existsSync as existsSync35 } from "node:fs";
531408
+ import { readdirSync as readdirSync15, existsSync as existsSync35 } from "node:fs";
531154
531409
  import { join as join198 } from "node:path";
531155
531410
  function countLocalSessionArtifacts() {
531156
531411
  let census = { projects: 0, sessions: 0 };
531157
531412
  try {
531158
531413
  let root2 = getProjectsDir();
531159
531414
  if (!existsSync35(root2)) return census;
531160
- for (let entry of readdirSync14(root2, { withFileTypes: !0 })) {
531415
+ for (let entry of readdirSync15(root2, { withFileTypes: !0 })) {
531161
531416
  if (!entry.isDirectory()) continue;
531162
531417
  let n2 = 0;
531163
531418
  try {
531164
- n2 = readdirSync14(join198(root2, entry.name)).filter((f) => f.endsWith(".jsonl")).length;
531419
+ n2 = readdirSync15(join198(root2, entry.name)).filter((f) => f.endsWith(".jsonl")).length;
531165
531420
  } catch {
531166
531421
  continue;
531167
531422
  }
@@ -533086,7 +533341,7 @@ __export(cloudResources_exports, {
533086
533341
  cloudResourceSync: () => cloudResourceSync
533087
533342
  });
533088
533343
  import { createHash as createHash32 } from "node:crypto";
533089
- import { existsSync as existsSync37, readdirSync as readdirSync15, readFileSync as readFileSync56, statSync as statSync17 } from "node:fs";
533344
+ import { existsSync as existsSync37, readdirSync as readdirSync16, readFileSync as readFileSync56, statSync as statSync17 } from "node:fs";
533090
533345
  import { basename as basename69, dirname as dirname91, isAbsolute as isAbsolute34, join as join201, resolve as resolve51 } from "node:path";
533091
533346
  import { getEffective as getEffective2, getMeConfig, getScopeConfigDraft as getScopeConfigDraft2, OAuthFlowError as OAuthFlowError3, RegistryApiError as RegistryApiError3 } from "@sema-agent/sdk/registry";
533092
533347
  function fail4(e) {
@@ -533585,7 +533840,7 @@ async function loadLocalSkillEntries() {
533585
533840
  for (let root2 of roots) {
533586
533841
  let dirs = [];
533587
533842
  try {
533588
- dirs = readdirSync15(root2).filter((d4) => {
533843
+ dirs = readdirSync16(root2).filter((d4) => {
533589
533844
  try {
533590
533845
  return statSync17(join201(root2, d4)).isDirectory() && existsSync37(join201(root2, d4, "SKILL.md"));
533591
533846
  } catch {
@@ -538731,7 +538986,7 @@ import {
538731
538986
  copyFileSync as copyFileSync8,
538732
538987
  existsSync as existsSync39,
538733
538988
  mkdirSync as mkdirSync29,
538734
- readdirSync as readdirSync16,
538989
+ readdirSync as readdirSync17,
538735
538990
  readFileSync as readFileSync57,
538736
538991
  statSync as statSync19
538737
538992
  } from "node:fs";
@@ -538852,7 +539107,7 @@ function syncTree(srcDir, destDir, labelBase, opts, report) {
538852
539107
  syncPlainFile(srcDir, destDir, labelBase, opts, report);
538853
539108
  return;
538854
539109
  }
538855
- for (let name of readdirSync16(srcDir)) {
539110
+ for (let name of readdirSync17(srcDir)) {
538856
539111
  let srcChild = join206(srcDir, name), destChild = join206(destDir, name), childStat;
538857
539112
  try {
538858
539113
  childStat = statSync19(srcChild);
@@ -541881,7 +542136,7 @@ var React202, import_jsx_runtime518, lastTierEditError, init_TiersHub = __esm({
541881
542136
  });
541882
542137
 
541883
542138
  // build-src/src/sema/config/skillsChannels.ts
541884
- import { existsSync as existsSync40, mkdirSync as mkdirSync30, readdirSync as readdirSync17, readFileSync as readFileSync60, realpathSync as realpathSync17, renameSync as renameSync18, statSync as statSync20 } from "node:fs";
542139
+ import { existsSync as existsSync40, mkdirSync as mkdirSync30, readdirSync as readdirSync18, readFileSync as readFileSync60, realpathSync as realpathSync17, renameSync as renameSync18, statSync as statSync20 } from "node:fs";
541885
542140
  import { basename as basename72, dirname as dirname96, join as join209 } from "node:path";
541886
542141
  function skillsDirFor(source) {
541887
542142
  return source === "user" ? join209(resolveConfigHome(), "skills") : join209(getCwd(), ".sema", "skills");
@@ -541928,7 +542183,7 @@ function listInstalledSkills() {
541928
542183
  for (let source of sources) {
541929
542184
  let dir = skillsDirFor(source), entries;
541930
542185
  try {
541931
- entries = readdirSync17(dir).filter((n2) => !n2.startsWith("."));
542186
+ entries = readdirSync18(dir).filter((n2) => !n2.startsWith("."));
541932
542187
  } catch {
541933
542188
  continue;
541934
542189
  }
@@ -544208,7 +544463,7 @@ Usage: sema --remote "your task description"`, () => gracefulShutdown(1));
544208
544463
  pendingHookMessages
544209
544464
  }, renderAndRun);
544210
544465
  }
544211
- }).version("sema 1.0.100", "-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 () => {
544466
+ }).version("sema 1.0.101", "-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 () => {
544212
544467
  await (await Promise.resolve().then(() => (init_bg2(), bg_exports))).psHandler([]), process.exit(process.exitCode ?? 0);
544213
544468
  }), program2.command("logs [id]").description("Print a background session's recent terminal output").action(async (id) => {
544214
544469
  await (await Promise.resolve().then(() => (init_bg2(), bg_exports))).logsHandler(id, []), process.exit(process.exitCode ?? 0);
@@ -546428,7 +546683,7 @@ var init_schedulerDaemonWire = __esm({
546428
546683
  });
546429
546684
 
546430
546685
  // build-src/src/sema/scheduler/sessionReap.ts
546431
- import { mkdirSync as mkdirSync33, readdirSync as readdirSync18, readFileSync as readFileSync65, unlinkSync as unlinkSync17, writeFileSync as writeFileSync31 } from "node:fs";
546686
+ import { mkdirSync as mkdirSync33, readdirSync as readdirSync19, readFileSync as readFileSync65, unlinkSync as unlinkSync17, writeFileSync as writeFileSync31 } from "node:fs";
546432
546687
  import { dirname as dirname99, join as join214 } from "node:path";
546433
546688
  function isSessionLifetimeRecord(r) {
546434
546689
  return r.lifetime === "session";
@@ -546482,7 +546737,7 @@ function removeSchedulerClaim(storePath, pid = process.pid) {
546482
546737
  function readAliveClaimedSessionIds(storePath, opts = {}) {
546483
546738
  let alive = opts.isPidAlive ?? pidAlive3, dir = schedulerClaimsDir(storePath), out6 = /* @__PURE__ */ new Set(), files2;
546484
546739
  try {
546485
- files2 = readdirSync18(dir);
546740
+ files2 = readdirSync19(dir);
546486
546741
  } catch {
546487
546742
  return out6;
546488
546743
  }
@@ -547240,11 +547495,11 @@ var init_skillsFill = __esm({
547240
547495
  });
547241
547496
 
547242
547497
  // build-src/src/sema/teamOnboarding.ts
547243
- import { existsSync as existsSync43, readdirSync as readdirSync19 } from "fs";
547498
+ import { existsSync as existsSync43, readdirSync as readdirSync20 } from "fs";
547244
547499
  function hasWorkspaceData() {
547245
547500
  try {
547246
547501
  let dir = getProjectsDir2();
547247
- return existsSync43(dir) ? readdirSync19(dir).length > 0 : !1;
547502
+ return existsSync43(dir) ? readdirSync20(dir).length > 0 : !1;
547248
547503
  } catch {
547249
547504
  return !1;
547250
547505
  }