oasis_test_v2 2.2.70 → 2.2.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1143 -640
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1706,6 +1706,7 @@ function delegationEnding(record9, evidence) {
1706
1706
  return hasDelegationDelivery(evidence) ? "timeout-delivered" : "timeout-empty";
1707
1707
  }
1708
1708
  function delegationEndingOfRecord(record9, artifacts = []) {
1709
+ if (record9.state === "running") return void 0;
1709
1710
  const last = record9.roundSummaries[record9.roundSummaries.length - 1];
1710
1711
  const lastRound = last?.round;
1711
1712
  return delegationEnding(record9, {
@@ -2083,6 +2084,13 @@ var init_chunked_message = __esm({
2083
2084
  });
2084
2085
 
2085
2086
  // ../contract/src/command-card-copy.ts
2087
+ function containsInternalId(text7) {
2088
+ for (const re of [PREFIXED_ID_RE, UUID_RE, SHORT_ID_RE]) {
2089
+ re.lastIndex = 0;
2090
+ if (re.test(text7)) return true;
2091
+ }
2092
+ return false;
2093
+ }
2086
2094
  function stripInternalIds(text7, placeholder = "\u2026") {
2087
2095
  if (!text7) return text7;
2088
2096
  let out = text7;
@@ -2152,7 +2160,55 @@ function commandCardDisplayLabel(command2, args, storedLabel, refs = {}) {
2152
2160
  const described = command2 ? describeCommandForHuman(command2, args ?? {}, refs) : void 0;
2153
2161
  return described ?? stripInternalIds(storedLabel ?? "");
2154
2162
  }
2155
- var PREFIXED_ID_RE, UUID_RE, SHORT_ID_RE, CARD_SUMMARY_MAX, NEUTRAL_NODE, NEUTRAL_ESCALATION, NEUTRAL_GAP, argStr;
2163
+ function nodeRefPhrase(ref2, refs, neutral = NEUTRAL_NODE) {
2164
+ const raw = (ref2 ?? "").trim();
2165
+ if (!raw) return neutral;
2166
+ const title = refs.nodeTitle?.(raw)?.trim();
2167
+ if (title) return `\u300A${title}\u300B`;
2168
+ if (!containsInternalId(raw)) {
2169
+ const tail = raw.includes(":") ? raw.slice(raw.indexOf(":") + 1).trim() : raw;
2170
+ if (tail && !containsInternalId(tail)) return `\u300A${tail}\u300B`;
2171
+ }
2172
+ return neutral;
2173
+ }
2174
+ function actorNamePhrase(actorId, refs) {
2175
+ const raw = (actorId ?? "").trim();
2176
+ if (!raw) return NEUTRAL_APPROVER;
2177
+ const name = refs.actorName?.(raw)?.trim();
2178
+ if (name) return name;
2179
+ return containsInternalId(raw) ? NEUTRAL_APPROVER : raw;
2180
+ }
2181
+ function graphEditOpDisplayLabel(op, refs = {}) {
2182
+ const node2 = nodeRefPhrase(op?.artifactId, refs);
2183
+ const to = nodeRefPhrase(op?.to, refs, NEUTRAL_NODE_OTHER);
2184
+ switch (op?.action) {
2185
+ case "spawn":
2186
+ return `\u65B0\u5EFA ${op.type || "\u4EA7\u7269"}${op.title ? `\u300C${op.title}\u300D` : ""}`;
2187
+ case "seal":
2188
+ return `${op.reason === "accepted" ? "\u9A8C\u6536" : op.reason === "cancelled" ? "\u5E9F\u5F03" : "\u51BB\u7ED3"}${node2}`;
2189
+ case "reopen":
2190
+ return `\u91CD\u5F00${node2}`;
2191
+ case "link":
2192
+ return `\u63A5\u4F9D\u8D56${node2} \u2192 ${to}`;
2193
+ case "unlink":
2194
+ return `\u65AD\u4F9D\u8D56${node2} \u2715 ${to}`;
2195
+ case "pin":
2196
+ return `\u56FA\u5B9A${node2} \u2192 ${to}`;
2197
+ case "assign":
2198
+ return `\u6539\u6D3E${node2} \u2192 ${actorNamePhrase(op.owner, refs)}`;
2199
+ case "edit":
2200
+ return `\u7F16\u8F91${node2}`;
2201
+ case "annotate":
2202
+ return `\u7ED9${node2}\u7559\u8A00`;
2203
+ case "cancelPart":
2204
+ return `\u64A4\u90E8\u4EF6${node2}`;
2205
+ case "resolveEscalation":
2206
+ return node2 === NEUTRAL_NODE ? "\u5173\u95ED\u8FD9\u4E00\u6B65\u7684\u6C42\u52A9" : `\u5173\u95ED${node2}\u7684\u6C42\u52A9`;
2207
+ default:
2208
+ return op?.action ? stripInternalIds(op.action) : "\u53D8\u66F4";
2209
+ }
2210
+ }
2211
+ var PREFIXED_ID_RE, UUID_RE, SHORT_ID_RE, CARD_SUMMARY_MAX, NEUTRAL_NODE, NEUTRAL_NODE_OTHER, NEUTRAL_ESCALATION, NEUTRAL_GAP, NEUTRAL_APPROVER, argStr;
2156
2212
  var init_command_card_copy = __esm({
2157
2213
  "../contract/src/command-card-copy.ts"() {
2158
2214
  "use strict";
@@ -2161,8 +2217,10 @@ var init_command_card_copy = __esm({
2161
2217
  SHORT_ID_RE = /\b(?=[0-9a-f-]*[0-9])(?=[0-9a-f-]*[a-f])[0-9a-f]{8,}(?:-[0-9a-f]{4,})*\b/giu;
2162
2218
  CARD_SUMMARY_MAX = 48;
2163
2219
  NEUTRAL_NODE = "\u8FD9\u4E00\u6B65";
2220
+ NEUTRAL_NODE_OTHER = "\u53E6\u4E00\u6B65";
2164
2221
  NEUTRAL_ESCALATION = "\u8FD9\u6761\u6C42\u52A9";
2165
2222
  NEUTRAL_GAP = "\u8FD9\u4E2A\u7F3A\u53E3";
2223
+ NEUTRAL_APPROVER = "\u8D1F\u8D23\u4EBA";
2166
2224
  argStr = (args, key2) => {
2167
2225
  const v2 = args[key2];
2168
2226
  return typeof v2 === "string" && v2.trim() ? v2.trim() : void 0;
@@ -6630,22 +6688,28 @@ function readCodexTokenCountLine(line2) {
6630
6688
  ...total ? { total } : {}
6631
6689
  };
6632
6690
  }
6691
+ function readCodexTurnContextModel(line2) {
6692
+ if (!line2 || line2.indexOf("turn_context") === -1) return void 0;
6693
+ let o;
6694
+ try {
6695
+ o = JSON.parse(line2);
6696
+ } catch {
6697
+ return void 0;
6698
+ }
6699
+ if (o?.type !== "turn_context") return void 0;
6700
+ return typeof o.payload?.model === "string" && o.payload.model ? o.payload.model : void 0;
6701
+ }
6633
6702
  function parseCodexModel(lines) {
6634
6703
  let model;
6635
- for (const line2 of lines) {
6636
- if (!line2 || line2.indexOf("turn_context") === -1) continue;
6637
- let o;
6638
- try {
6639
- o = JSON.parse(line2);
6640
- } catch {
6641
- continue;
6642
- }
6643
- if (o?.type === "turn_context" && typeof o.payload?.model === "string" && o.payload.model) {
6644
- model = o.payload.model;
6645
- }
6646
- }
6704
+ for (const line2 of lines) model = readCodexTurnContextModel(line2) ?? model;
6647
6705
  return model;
6648
6706
  }
6707
+ function pickCodexModel(sources) {
6708
+ for (const candidate of [sources.rollout, sources.thread, sources.requested]) {
6709
+ if (typeof candidate === "string" && candidate.trim().length > 0) return candidate;
6710
+ }
6711
+ return void 0;
6712
+ }
6649
6713
  function codexSessionsRoot() {
6650
6714
  const candidates = [];
6651
6715
  const ch = process.env["CODEX_HOME"];
@@ -6973,7 +7037,7 @@ function codexTurnErrorMessage(value2) {
6973
7037
  const detail = typeof error2?.additionalDetails === "string" ? error2.additionalDetails.trim() : "";
6974
7038
  return [summary, detail].filter(Boolean).join("\n").slice(0, 4e3);
6975
7039
  }
6976
- var import_node_child_process7, import_node_crypto9, fs8, os6, path10, readline2, CODEX_BLOCKED_FLAGS, CODEX_ARGV_PROMPT_MAX_BYTES, CodexRolloutUsageTail, CODEX_APP_SERVER_BLOCKED_FLAGS, CodexAdapter;
7040
+ var import_node_child_process7, import_node_crypto9, fs8, os6, path10, readline2, CODEX_BLOCKED_FLAGS, CODEX_ARGV_PROMPT_MAX_BYTES, CodexRolloutLineTail, CodexRolloutUsageTail, CodexRolloutModelTail, CODEX_APP_SERVER_BLOCKED_FLAGS, CodexAdapter;
6977
7041
  var init_codex = __esm({
6978
7042
  "../adapters/src/codex/index.ts"() {
6979
7043
  "use strict";
@@ -7011,25 +7075,21 @@ var init_codex = __esm({
7011
7075
  // Multica 实证:codex --listen stdio:// 是 daemon↔CLI 传输协议;改会断链
7012
7076
  ]);
7013
7077
  CODEX_ARGV_PROMPT_MAX_BYTES = 1e5;
7014
- CodexRolloutUsageTail = class {
7015
- constructor(file, sinceMs) {
7078
+ CodexRolloutLineTail = class {
7079
+ constructor(file) {
7016
7080
  this.file = file;
7017
- this.sinceMs = sinceMs;
7018
7081
  }
7019
7082
  offset = 0;
7020
7083
  rest = "";
7021
- acc = { input: 0, cacheRead: 0, cacheWrite: 0, output: 0 };
7022
- saw = false;
7023
- /** 读新追加的行,返回当前窗内累计;还没有任何窗内轮次返回 undefined。读失败抛给调用方(调用方吞)。 */
7024
- poll() {
7084
+ /** 读新追加的整行逐行回调;文件被截短时先回调 onReset 再从头读。读失败抛给调用方(调用方吞)。 */
7085
+ read(onLine, onReset) {
7025
7086
  const fd = fs8.openSync(this.file, "r");
7026
7087
  try {
7027
7088
  const size = fs8.fstatSync(fd).size;
7028
7089
  if (size < this.offset) {
7029
7090
  this.offset = 0;
7030
7091
  this.rest = "";
7031
- this.saw = false;
7032
- this.acc.input = this.acc.cacheRead = this.acc.cacheWrite = this.acc.output = 0;
7092
+ onReset?.();
7033
7093
  }
7034
7094
  if (size > this.offset) {
7035
7095
  const buf = Buffer.alloc(size - this.offset);
@@ -7038,19 +7098,62 @@ var init_codex = __esm({
7038
7098
  const text7 = this.rest + buf.subarray(0, n).toString("utf8");
7039
7099
  const lines = text7.split("\n");
7040
7100
  this.rest = lines.pop() ?? "";
7041
- for (const line2 of lines) {
7042
- const row = readCodexTokenCountLine(line2);
7043
- if (!row?.turn || !Number.isFinite(row.ts) || row.ts < this.sinceMs) continue;
7044
- addCodexBuckets(this.acc, row.turn);
7045
- this.saw = true;
7046
- }
7101
+ for (const line2 of lines) onLine(line2);
7047
7102
  }
7048
7103
  } finally {
7049
7104
  fs8.closeSync(fd);
7050
7105
  }
7106
+ }
7107
+ };
7108
+ CodexRolloutUsageTail = class {
7109
+ constructor(file, sinceMs) {
7110
+ this.file = file;
7111
+ this.sinceMs = sinceMs;
7112
+ this.tail = new CodexRolloutLineTail(file);
7113
+ }
7114
+ tail;
7115
+ acc = { input: 0, cacheRead: 0, cacheWrite: 0, output: 0 };
7116
+ saw = false;
7117
+ lastModel;
7118
+ /** 截至目前读到的**最后一条** `turn_context` 模型(与终值的 {@link parseCodexModel} 同判据)。 */
7119
+ get model() {
7120
+ return this.lastModel;
7121
+ }
7122
+ /** 读新追加的行,返回当前窗内累计;还没有任何窗内轮次返回 undefined。读失败抛给调用方(调用方吞)。 */
7123
+ poll() {
7124
+ this.tail.read((line2) => {
7125
+ const model = readCodexTurnContextModel(line2);
7126
+ if (model) this.lastModel = model;
7127
+ const row = readCodexTokenCountLine(line2);
7128
+ if (!row?.turn || !Number.isFinite(row.ts) || row.ts < this.sinceMs) return;
7129
+ addCodexBuckets(this.acc, row.turn);
7130
+ this.saw = true;
7131
+ }, () => {
7132
+ this.saw = false;
7133
+ this.lastModel = void 0;
7134
+ this.acc.input = this.acc.cacheRead = this.acc.cacheWrite = this.acc.output = 0;
7135
+ });
7051
7136
  return this.saw ? usageFromBuckets(this.acc) : void 0;
7052
7137
  }
7053
7138
  };
7139
+ CodexRolloutModelTail = class {
7140
+ constructor(file) {
7141
+ this.file = file;
7142
+ this.tail = new CodexRolloutLineTail(file);
7143
+ }
7144
+ tail;
7145
+ lastModel;
7146
+ /** 追读新行,返回截至目前**最后一条** `turn_context` 记的模型。读失败抛给调用方(调用方吞)。 */
7147
+ poll() {
7148
+ this.tail.read((line2) => {
7149
+ const model = readCodexTurnContextModel(line2);
7150
+ if (model) this.lastModel = model;
7151
+ }, () => {
7152
+ this.lastModel = void 0;
7153
+ });
7154
+ return this.lastModel;
7155
+ }
7156
+ };
7054
7157
  CODEX_APP_SERVER_BLOCKED_FLAGS = /* @__PURE__ */ new Map([
7055
7158
  ["app-server", "boolean"],
7056
7159
  ["--stdio", "boolean"],
@@ -7111,7 +7214,12 @@ var init_codex = __esm({
7111
7214
  // 只能从 resume 的响应里取(同上实测)。取不到它就读不到实际模型。
7112
7215
  rolloutPath: void 0,
7113
7216
  // thread/start / thread/resume 响应里 codex 报的线程模型:rollout 读不到时的兜底。
7114
- threadModel: void 0
7217
+ threadModel: void 0,
7218
+ // 运行中检查点的模型来源(Bug 0227):增量追读会话卷里逐轮记的实际模型。卷路径就位后才建。
7219
+ rolloutModelTail: void 0,
7220
+ rolloutModel: void 0,
7221
+ // 上一次报出去的用量指纹:只在用量真的变了的那一拍才去碰磁盘(runningUsage 每条协议消息都被调到)。
7222
+ lastUsageKey: ""
7115
7223
  }),
7116
7224
  initialCommand: () => ({
7117
7225
  jsonrpc: "2.0",
@@ -7253,14 +7361,14 @@ ${task}` : task;
7253
7361
  },
7254
7362
  runtimeSessionId: (state) => state.threadId,
7255
7363
  exitExtras: (state) => {
7256
- let model;
7364
+ let fromRollout;
7257
7365
  if (state.rolloutPath) {
7258
7366
  try {
7259
- model = parseCodexModel(fs8.readFileSync(state.rolloutPath, "utf8").split("\n"));
7367
+ fromRollout = parseCodexModel(fs8.readFileSync(state.rolloutPath, "utf8").split("\n"));
7260
7368
  } catch {
7261
7369
  }
7262
7370
  }
7263
- model ??= state.threadModel ?? resolvedModel2;
7371
+ const model = pickCodexModel({ rollout: fromRollout ?? state.rolloutModel, thread: state.threadModel, requested: resolvedModel2 });
7264
7372
  const usage = codexRunUsage(state.usageByTurn, state.runTurnIds);
7265
7373
  return {
7266
7374
  ...usage ? { usage } : {},
@@ -7273,7 +7381,18 @@ ${task}` : task;
7273
7381
  runningUsage: (state) => {
7274
7382
  const usage = codexRunUsage(state.usageByTurn, state.runTurnIds);
7275
7383
  if (!usage) return void 0;
7276
- const model = state.threadModel ?? resolvedModel2;
7384
+ const key2 = JSON.stringify(usage);
7385
+ if (key2 !== state.lastUsageKey) {
7386
+ state.lastUsageKey = key2;
7387
+ if (state.rolloutPath) {
7388
+ state.rolloutModelTail ??= new CodexRolloutModelTail(state.rolloutPath);
7389
+ try {
7390
+ state.rolloutModel = state.rolloutModelTail.poll() ?? state.rolloutModel;
7391
+ } catch {
7392
+ }
7393
+ }
7394
+ }
7395
+ const model = pickCodexModel({ rollout: state.rolloutModel, thread: state.threadModel, requested: resolvedModel2 });
7277
7396
  return { usage, ...model ? { model } : {} };
7278
7397
  },
7279
7398
  async append(input, state, send) {
@@ -7505,7 +7624,7 @@ ${task}` : task;
7505
7624
  const key2 = usage ? JSON.stringify(usage) : "";
7506
7625
  if (!usage || key2 === lastUsageKey) return;
7507
7626
  lastUsageKey = key2;
7508
- const model = job.model ?? this.opts.model;
7627
+ const model = pickCodexModel({ rollout: usageTail.model, requested: job.model ?? this.opts.model });
7509
7628
  for (const cb of usageCheckpointCbs) cb({ usage, ...model ? { model } : {} });
7510
7629
  } catch {
7511
7630
  }
@@ -7557,7 +7676,7 @@ ${task}` : task;
7557
7676
  clearTimeout(timer);
7558
7677
  const resumeSessionId = job.resumeRuntimeSession ? job.runtimeSessionId : void 0;
7559
7678
  const telemetry = scanCodexTelemetry(dir, startedAtMs, codexSessionsRoot(), job.runtimeSessionId);
7560
- const model = telemetry.model ?? job.model ?? this.opts.model;
7679
+ const model = pickCodexModel({ rollout: telemetry.model, requested: job.model ?? this.opts.model });
7561
7680
  const runtimeSessionId = telemetry.sessionId ?? resumeSessionId;
7562
7681
  const sawStreamError = streamErrorMessages.length > 0;
7563
7682
  const isError = !killReason && (code2 !== 0 || sawStreamError);
@@ -9144,14 +9263,14 @@ var init_reasonix = __esm({
9144
9263
  method: "_reasonix.io/session/status_update",
9145
9264
  pick(params) {
9146
9265
  const rec2 = (v2) => v2 && typeof v2 === "object" && !Array.isArray(v2) ? v2 : void 0;
9147
- const num4 = (v2) => typeof v2 === "number" && Number.isFinite(v2) && v2 >= 0 ? v2 : void 0;
9266
+ const num5 = (v2) => typeof v2 === "number" && Number.isFinite(v2) && v2 >= 0 ? v2 : void 0;
9148
9267
  const turn = rec2(rec2(rec2(rec2(params)?.["status"])?.["usage"])?.["turn"]);
9149
9268
  if (!turn) return void 0;
9150
- const promptTokens = num4(turn["promptTokens"]);
9151
- const cacheHit = num4(turn["cacheHitTokens"]);
9152
- const cacheMiss = num4(turn["cacheMissTokens"]);
9269
+ const promptTokens = num5(turn["promptTokens"]);
9270
+ const cacheHit = num5(turn["cacheHitTokens"]);
9271
+ const cacheMiss = num5(turn["cacheMissTokens"]);
9153
9272
  const inputTokens = cacheMiss ?? (promptTokens === void 0 ? void 0 : Math.max(0, promptTokens - (cacheHit ?? 0)));
9154
- const outputTokens = num4(turn["completionTokens"]);
9273
+ const outputTokens = num5(turn["completionTokens"]);
9155
9274
  if (inputTokens === void 0 && outputTokens === void 0 && cacheHit === void 0) return void 0;
9156
9275
  return {
9157
9276
  ...inputTokens !== void 0 ? { inputTokens } : {},
@@ -11529,11 +11648,11 @@ var init_chat_item_ledger = __esm({
11529
11648
  this.tick();
11530
11649
  const version2 = this.tick();
11531
11650
  if (!this.persistEnabled) return null;
11532
- const at = this.now();
11651
+ const at2 = this.now();
11533
11652
  return {
11534
11653
  id,
11535
11654
  payload: payload2,
11536
- at,
11655
+ at: at2,
11537
11656
  version: version2,
11538
11657
  create: {
11539
11658
  id,
@@ -11547,7 +11666,7 @@ var init_chat_item_ledger = __esm({
11547
11666
  payload: payload2,
11548
11667
  metadata: { [CHAT_ITEM_META_LEGACY_CONTENT]: false },
11549
11668
  providerItemKey: null,
11550
- createdAt: at,
11669
+ createdAt: at2,
11551
11670
  version: version2
11552
11671
  }
11553
11672
  };
@@ -12040,11 +12159,11 @@ var init_chat_item_ledger = __esm({
12040
12159
  persist(row, op, what) {
12041
12160
  const version2 = this.tick();
12042
12161
  row.wireVersion = version2;
12043
- const at = this.now();
12044
- if (op.op === "set_status" && op.status !== "streaming") row.completedAt = at;
12162
+ const at2 = this.now();
12163
+ if (op.op === "set_status" && op.status !== "streaming") row.completedAt = at2;
12045
12164
  if (!row.persist || !this.persistEnabled) return;
12046
12165
  this.enqueue(async () => {
12047
- await this.deps.items.applyOp(row.id, op, { at, version: version2 });
12166
+ await this.deps.items.applyOp(row.id, op, { at: at2, version: version2 });
12048
12167
  }, what);
12049
12168
  }
12050
12169
  /** 串行链 + 失败吞掉计数。**串行是必须的**:append_text 依赖建行已经落地。 */
@@ -12107,7 +12226,7 @@ var init_chat_item_ledger = __esm({
12107
12226
  async applyOp(itemId, op, opts) {
12108
12227
  const row = this.rows.find((r) => r.id === itemId);
12109
12228
  if (!row || opts?.sessionId !== void 0 && row.sessionId !== opts.sessionId) return null;
12110
- const at = opts?.at ?? (/* @__PURE__ */ new Date()).toISOString();
12229
+ const at2 = opts?.at ?? (/* @__PURE__ */ new Date()).toISOString();
12111
12230
  const payload2 = row.payload && typeof row.payload === "object" && !Array.isArray(row.payload) ? { ...row.payload } : {};
12112
12231
  if (op.op === "append_text") payload2.text = `${typeof payload2.text === "string" ? payload2.text : ""}${op.text}`;
12113
12232
  else if (op.op === "set_text") payload2.text = op.text;
@@ -12115,13 +12234,13 @@ var init_chat_item_ledger = __esm({
12115
12234
  else if (op.op === "set_payload") row.payload = op.payload;
12116
12235
  else if (op.op === "set_status") {
12117
12236
  row.status = op.status;
12118
- if (op.status !== "streaming") row.completedAt = at;
12237
+ if (op.status !== "streaming") row.completedAt = at2;
12119
12238
  }
12120
12239
  if (op.op !== "set_payload") row.payload = payload2;
12121
12240
  row.version = opts?.version === void 0 ? row.version + 1 : Math.max(row.version, opts.version);
12122
12241
  const scope2 = this.rows.filter((r) => r.sessionId === row.sessionId && r.turnId === row.turnId);
12123
12242
  row.turnVersion = scope2.reduce((n, r) => Math.max(n, r.turnVersion), 0) + 1;
12124
- row.updatedAt = at;
12243
+ row.updatedAt = at2;
12125
12244
  return row;
12126
12245
  }
12127
12246
  async bindMessage(sessionId, turnId, messageId, itemIds) {
@@ -12191,8 +12310,8 @@ function serveRestartCauseOfRun(run) {
12191
12310
  if (!run || run.exitReason !== "sweep-orphan") return void 0;
12192
12311
  const meta = run.metadata;
12193
12312
  if (!meta || typeof meta !== "object" || Array.isArray(meta)) return void 0;
12194
- const at = meta[SERVE_STOPPED_IN_FLIGHT_KEY];
12195
- return typeof at === "string" && at.length > 0 ? "system-restart" : void 0;
12313
+ const at2 = meta[SERVE_STOPPED_IN_FLIGHT_KEY];
12314
+ return typeof at2 === "string" && at2.length > 0 ? "system-restart" : void 0;
12196
12315
  }
12197
12316
  function attributeChatExit(text7, extra, cause) {
12198
12317
  if (extra.reason !== "cancelled") return { text: text7, extra };
@@ -12296,20 +12415,20 @@ async function openAssistantRunningRow(deps) {
12296
12415
  const now = deps.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
12297
12416
  if (typeof deps.chatStore.appendMessage !== "function") return void 0;
12298
12417
  const id = (0, import_node_crypto14.randomUUID)();
12299
- const at = now();
12418
+ const at2 = now();
12300
12419
  try {
12301
12420
  await deps.chatStore.appendMessage({
12302
12421
  id,
12303
12422
  sessionId: deps.chatSessionId,
12304
12423
  role: "assistant",
12305
12424
  content: "",
12306
- createdAt: at,
12425
+ createdAt: at2,
12307
12426
  status: "running",
12308
12427
  ...deps.runId ? { runId: deps.runId } : {},
12309
12428
  ...deps.turnId ? { turnId: deps.turnId } : {}
12310
12429
  });
12311
12430
  if (typeof deps.chatStore.updateSession === "function") {
12312
- await deps.chatStore.updateSession(deps.chatSessionId, { touchedAt: at }).catch(() => void 0);
12431
+ await deps.chatStore.updateSession(deps.chatSessionId, { touchedAt: at2 }).catch(() => void 0);
12313
12432
  }
12314
12433
  return id;
12315
12434
  } catch {
@@ -12358,14 +12477,14 @@ function beginInsertedAssistantSegment(deps) {
12358
12477
  const nextId = (deps.newId ?? import_node_crypto14.randomUUID)();
12359
12478
  const segment = deps.ledger.beginSegment();
12360
12479
  deps.live.setAssistantMessageId(nextId);
12361
- const at = (deps.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))();
12480
+ const at2 = (deps.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))();
12362
12481
  const { chatStore, closingId, segParts } = deps;
12363
12482
  const persist = async () => {
12364
12483
  if (closingId) {
12365
12484
  await chatStore.updateMessage(closingId, {
12366
12485
  content: segText,
12367
12486
  status: "done",
12368
- completedAt: at,
12487
+ completedAt: at2,
12369
12488
  ...segParts.length ? { parts: segParts } : {}
12370
12489
  }).catch(() => void 0);
12371
12490
  }
@@ -12374,7 +12493,7 @@ function beginInsertedAssistantSegment(deps) {
12374
12493
  sessionId: deps.chatSessionId,
12375
12494
  role: "user",
12376
12495
  content: deps.text,
12377
- createdAt: at,
12496
+ createdAt: at2,
12378
12497
  // ADR-0166 D9.1:插入带的附件也落在**这条 user 行**上(同 `/api/chat` 那侧只存引用)。
12379
12498
  ...deps.attachments?.length ? { attachments: deps.attachments } : {},
12380
12499
  ...deps.turnId ? { turnId: deps.turnId } : {}
@@ -12385,7 +12504,7 @@ function beginInsertedAssistantSegment(deps) {
12385
12504
  sessionId: deps.chatSessionId,
12386
12505
  role: "assistant",
12387
12506
  content: "",
12388
- createdAt: at,
12507
+ createdAt: at2,
12389
12508
  status: "running",
12390
12509
  ...deps.runId ? { runId: deps.runId } : {},
12391
12510
  ...deps.turnId ? { turnId: deps.turnId } : {}
@@ -12736,10 +12855,10 @@ async function recordChatTurnInterruption(deps) {
12736
12855
  const existing = rows.find((r) => r.id === noticeId);
12737
12856
  let version2 = await items.sessionVersionCursor(sessionId).catch(() => 0);
12738
12857
  const touched = [];
12739
- const at = now();
12858
+ const at2 = now();
12740
12859
  for (const row of rows) {
12741
12860
  if (row.status !== "streaming") continue;
12742
- const updated = await items.applyOp(row.id, { op: "set_status", status: "interrupted" }, { at, version: ++version2, sessionId });
12861
+ const updated = await items.applyOp(row.id, { op: "set_status", status: "interrupted" }, { at: at2, version: ++version2, sessionId });
12743
12862
  if (updated) touched.push(updated);
12744
12863
  }
12745
12864
  const payload2 = deps.cause === "sweep-orphan" ? {
@@ -12750,7 +12869,7 @@ async function recordChatTurnInterruption(deps) {
12750
12869
  ...deps.cancelledBy ? { cancelledBy: deps.cancelledBy } : {}
12751
12870
  } : { code: "error", note: CHAT_INTERRUPT_NOTICE[deps.cause], reason: deps.reason };
12752
12871
  if (existing) {
12753
- const updated = await items.applyOp(noticeId, { op: "set_payload", payload: payload2 }, { at, version: ++version2, sessionId });
12872
+ const updated = await items.applyOp(noticeId, { op: "set_payload", payload: payload2 }, { at: at2, version: ++version2, sessionId });
12754
12873
  if (updated) touched.push(updated);
12755
12874
  return touched;
12756
12875
  }
@@ -12766,7 +12885,7 @@ async function recordChatTurnInterruption(deps) {
12766
12885
  payload: payload2,
12767
12886
  // 这句话不进 `chat_messages.content`(那边由各自的收口路自己写),对账按这一位分流。
12768
12887
  metadata: { [CHAT_ITEM_META_LEGACY_CONTENT]: false },
12769
- createdAt: at,
12888
+ createdAt: at2,
12770
12889
  version: ++version2
12771
12890
  });
12772
12891
  touched.push(created);
@@ -29212,14 +29331,14 @@ var require_object_inspect = __commonJS({
29212
29331
  var gPO = (typeof Reflect === "function" ? Reflect.getPrototypeOf : Object.getPrototypeOf) || ([].__proto__ === Array.prototype ? function(O2) {
29213
29332
  return O2.__proto__;
29214
29333
  } : null);
29215
- function addNumericSeparator(num4, str5) {
29216
- if (num4 === Infinity || num4 === -Infinity || num4 !== num4 || num4 && num4 > -1e3 && num4 < 1e3 || $test.call(/e/, str5)) {
29334
+ function addNumericSeparator(num5, str5) {
29335
+ if (num5 === Infinity || num5 === -Infinity || num5 !== num5 || num5 && num5 > -1e3 && num5 < 1e3 || $test.call(/e/, str5)) {
29217
29336
  return str5;
29218
29337
  }
29219
29338
  var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;
29220
- if (typeof num4 === "number") {
29221
- var int2 = num4 < 0 ? -$floor(-num4) : $floor(num4);
29222
- if (int2 !== num4) {
29339
+ if (typeof num5 === "number") {
29340
+ var int2 = num5 < 0 ? -$floor(-num5) : $floor(num5);
29341
+ if (int2 !== num5) {
29223
29342
  var intStr = String(int2);
29224
29343
  var dec2 = $slice.call(str5, intStr.length + 1);
29225
29344
  return $replace.call(intStr, sepRegex, "$&_") + "." + $replace.call($replace.call(dec2, /([0-9]{3})/g, "$&_"), /_$/, "");
@@ -29289,7 +29408,7 @@ var require_object_inspect = __commonJS({
29289
29408
  if (depth >= maxDepth && maxDepth > 0 && typeof obj2 === "object") {
29290
29409
  return isArray(obj2) ? "[Array]" : "[Object]";
29291
29410
  }
29292
- var indent2 = getIndent(opts, depth);
29411
+ var indent3 = getIndent(opts, depth);
29293
29412
  if (typeof seen === "undefined") {
29294
29413
  seen = [];
29295
29414
  } else if (indexOf(seen, obj2) >= 0) {
@@ -29312,7 +29431,7 @@ var require_object_inspect = __commonJS({
29312
29431
  return inspect_(value2, opts, depth + 1, seen);
29313
29432
  }
29314
29433
  if (typeof obj2 === "function" && !isRegExp(obj2)) {
29315
- var name = nameOf(obj2);
29434
+ var name = nameOf2(obj2);
29316
29435
  var keys = arrObjKeys(obj2, inspect);
29317
29436
  return "[Function" + (name ? ": " + name : " (anonymous)") + "]" + (keys.length > 0 ? " { " + $join.call(keys, ", ") + " }" : "");
29318
29437
  }
@@ -29338,8 +29457,8 @@ var require_object_inspect = __commonJS({
29338
29457
  return "[]";
29339
29458
  }
29340
29459
  var xs = arrObjKeys(obj2, inspect);
29341
- if (indent2 && !singleLineValues(xs)) {
29342
- return "[" + indentedJoin(xs, indent2) + "]";
29460
+ if (indent3 && !singleLineValues(xs)) {
29461
+ return "[" + indentedJoin(xs, indent3) + "]";
29343
29462
  }
29344
29463
  return "[ " + $join.call(xs, ", ") + " ]";
29345
29464
  }
@@ -29367,7 +29486,7 @@ var require_object_inspect = __commonJS({
29367
29486
  mapParts.push(inspect(key2, obj2, true) + " => " + inspect(value2, obj2));
29368
29487
  });
29369
29488
  }
29370
- return collectionOf("Map", mapSize.call(obj2), mapParts, indent2);
29489
+ return collectionOf("Map", mapSize.call(obj2), mapParts, indent3);
29371
29490
  }
29372
29491
  if (isSet(obj2)) {
29373
29492
  var setParts = [];
@@ -29376,7 +29495,7 @@ var require_object_inspect = __commonJS({
29376
29495
  setParts.push(inspect(value2, obj2));
29377
29496
  });
29378
29497
  }
29379
- return collectionOf("Set", setSize.call(obj2), setParts, indent2);
29498
+ return collectionOf("Set", setSize.call(obj2), setParts, indent3);
29380
29499
  }
29381
29500
  if (isWeakMap(obj2)) {
29382
29501
  return weakCollectionOf("WeakMap");
@@ -29415,8 +29534,8 @@ var require_object_inspect = __commonJS({
29415
29534
  if (ys.length === 0) {
29416
29535
  return tag + "{}";
29417
29536
  }
29418
- if (indent2) {
29419
- return tag + "{" + indentedJoin(ys, indent2) + "}";
29537
+ if (indent3) {
29538
+ return tag + "{" + indentedJoin(ys, indent3) + "}";
29420
29539
  }
29421
29540
  return tag + "{ " + $join.call(ys, ", ") + " }";
29422
29541
  }
@@ -29491,7 +29610,7 @@ var require_object_inspect = __commonJS({
29491
29610
  function toStr(obj2) {
29492
29611
  return objectToString.call(obj2);
29493
29612
  }
29494
- function nameOf(f2) {
29613
+ function nameOf2(f2) {
29495
29614
  if (f2.name) {
29496
29615
  return f2.name;
29497
29616
  }
@@ -29627,8 +29746,8 @@ var require_object_inspect = __commonJS({
29627
29746
  function weakCollectionOf(type) {
29628
29747
  return type + " { ? }";
29629
29748
  }
29630
- function collectionOf(type, size, entries, indent2) {
29631
- var joinedEntries = indent2 ? indentedJoin(entries, indent2) : $join.call(entries, ", ");
29749
+ function collectionOf(type, size, entries, indent3) {
29750
+ var joinedEntries = indent3 ? indentedJoin(entries, indent3) : $join.call(entries, ", ");
29632
29751
  return type + " (" + size + ") {" + joinedEntries + "}";
29633
29752
  }
29634
29753
  function singleLineValues(xs) {
@@ -29653,12 +29772,12 @@ var require_object_inspect = __commonJS({
29653
29772
  prev: $join.call(Array(depth + 1), baseIndent)
29654
29773
  };
29655
29774
  }
29656
- function indentedJoin(xs, indent2) {
29775
+ function indentedJoin(xs, indent3) {
29657
29776
  if (xs.length === 0) {
29658
29777
  return "";
29659
29778
  }
29660
- var lineJoiner = "\n" + indent2.prev + indent2.base;
29661
- return lineJoiner + $join.call(xs, "," + lineJoiner) + "\n" + indent2.prev;
29779
+ var lineJoiner = "\n" + indent3.prev + indent3.base;
29780
+ return lineJoiner + $join.call(xs, "," + lineJoiner) + "\n" + indent3.prev;
29662
29781
  }
29663
29782
  function arrObjKeys(obj2, inspect) {
29664
29783
  var isArr = isArray(obj2);
@@ -32847,26 +32966,26 @@ var require_permessage_deflate = __commonJS({
32847
32966
  value2 = value2[0];
32848
32967
  if (key2 === "client_max_window_bits") {
32849
32968
  if (value2 !== true) {
32850
- const num4 = +value2;
32851
- if (!Number.isInteger(num4) || num4 < 8 || num4 > 15) {
32969
+ const num5 = +value2;
32970
+ if (!Number.isInteger(num5) || num5 < 8 || num5 > 15) {
32852
32971
  throw new TypeError(
32853
32972
  `Invalid value for parameter "${key2}": ${value2}`
32854
32973
  );
32855
32974
  }
32856
- value2 = num4;
32975
+ value2 = num5;
32857
32976
  } else if (!this._isServer) {
32858
32977
  throw new TypeError(
32859
32978
  `Invalid value for parameter "${key2}": ${value2}`
32860
32979
  );
32861
32980
  }
32862
32981
  } else if (key2 === "server_max_window_bits") {
32863
- const num4 = +value2;
32864
- if (!Number.isInteger(num4) || num4 < 8 || num4 > 15) {
32982
+ const num5 = +value2;
32983
+ if (!Number.isInteger(num5) || num5 < 8 || num5 > 15) {
32865
32984
  throw new TypeError(
32866
32985
  `Invalid value for parameter "${key2}": ${value2}`
32867
32986
  );
32868
32987
  }
32869
- value2 = num4;
32988
+ value2 = num5;
32870
32989
  } else if (key2 === "client_no_context_takeover" || key2 === "server_no_context_takeover") {
32871
32990
  if (value2 !== true) {
32872
32991
  throw new TypeError(
@@ -33579,8 +33698,8 @@ var require_receiver = __commonJS({
33579
33698
  return;
33580
33699
  }
33581
33700
  const buf = this.consume(8);
33582
- const num4 = buf.readUInt32BE(0);
33583
- if (num4 > Math.pow(2, 53 - 32) - 1) {
33701
+ const num5 = buf.readUInt32BE(0);
33702
+ if (num5 > Math.pow(2, 53 - 32) - 1) {
33584
33703
  const error2 = this.createError(
33585
33704
  RangeError,
33586
33705
  "Unsupported WebSocket frame: payload length > 2^53 - 1",
@@ -33591,7 +33710,7 @@ var require_receiver = __commonJS({
33591
33710
  cb(error2);
33592
33711
  return;
33593
33712
  }
33594
- this._payloadLength = num4 * Math.pow(2, 32) + buf.readUInt32BE(4);
33713
+ this._payloadLength = num5 * Math.pow(2, 32) + buf.readUInt32BE(4);
33595
33714
  this.haveLength(cb);
33596
33715
  }
33597
33716
  /**
@@ -124353,8 +124472,8 @@ ${block}
124353
124472
  const s2 = String(d.getUTCSeconds()).padStart(2, "0");
124354
124473
  return `${y}-${mo}-${day}T${h}:${mi}:${s2}+08:00`;
124355
124474
  }
124356
- function indentLines(text7, indent2) {
124357
- return text7.split("\n").map((line2) => `${indent2}${line2}`).join("\n");
124475
+ function indentLines(text7, indent3) {
124476
+ return text7.split("\n").map((line2) => `${indent3}${line2}`).join("\n");
124358
124477
  }
124359
124478
  function escapeAttr(s2) {
124360
124479
  return s2.replace(/"/g, "&quot;");
@@ -126570,62 +126689,62 @@ function isReviewKillable(r) {
126570
126689
  if (r.cancelledAt) return false;
126571
126690
  return true;
126572
126691
  }
126573
- function killWorkRow(state, w2, at) {
126692
+ function killWorkRow(state, w2, at2) {
126574
126693
  state.updateWork(w2.id, {
126575
- deadAt: w2.deadAt ?? at,
126576
- cancelledAt: w2.cancelledAt ?? at,
126694
+ deadAt: w2.deadAt ?? at2,
126695
+ cancelledAt: w2.cancelledAt ?? at2,
126577
126696
  status: "dead"
126578
126697
  });
126579
126698
  }
126580
- function killReviewRow(state, r, at) {
126581
- state.updateReview(r.id, { cancelledAt: r.cancelledAt ?? at, status: "dead" });
126699
+ function killReviewRow(state, r, at2) {
126700
+ state.updateReview(r.id, { cancelledAt: r.cancelledAt ?? at2, status: "dead" });
126582
126701
  }
126583
- function killLatestWork(state, nodeId, at) {
126702
+ function killLatestWork(state, nodeId, at2) {
126584
126703
  const node2 = state.node(nodeId);
126585
126704
  if (!node2) return;
126586
126705
  const lw = node2.latestWorkId ? state.work(node2.latestWorkId) : null;
126587
126706
  if (!lw) return;
126588
- if (isWorkKillable(lw)) killWorkRow(state, lw, at);
126707
+ if (isWorkKillable(lw)) killWorkRow(state, lw, at2);
126589
126708
  }
126590
- function supersedeLatestWork(state, nodeId, at) {
126709
+ function supersedeLatestWork(state, nodeId, at2) {
126591
126710
  const node2 = state.node(nodeId);
126592
126711
  if (!node2) return;
126593
126712
  const lw = node2.latestWorkId ? state.work(node2.latestWorkId) : null;
126594
126713
  if (!lw) return;
126595
126714
  if (isWorkFailed(lw)) return;
126596
- if (isWorkKillable(lw)) killWorkRow(state, lw, at);
126715
+ if (isWorkKillable(lw)) killWorkRow(state, lw, at2);
126597
126716
  }
126598
- function supersedeReview(state, reviewId, at) {
126717
+ function supersedeReview(state, reviewId, at2) {
126599
126718
  const r = state.review(reviewId);
126600
126719
  if (!r || !isReviewKillable(r)) return;
126601
126720
  const failed = r.status === "failed" || !r.status && r.endedAt && !r.verdict && !r.cancelledAt;
126602
126721
  if (failed) return;
126603
- killReviewRow(state, r, at);
126722
+ killReviewRow(state, r, at2);
126604
126723
  }
126605
- function killNodeReviews(state, nodeId, at) {
126724
+ function killNodeReviews(state, nodeId, at2) {
126606
126725
  for (const r of state.allReviews()) {
126607
126726
  if (r.nodeId === nodeId && isReviewKillable(r)) {
126608
- killReviewRow(state, r, at);
126727
+ killReviewRow(state, r, at2);
126609
126728
  }
126610
126729
  }
126611
126730
  }
126612
- function killReview(state, reviewId, at) {
126731
+ function killReview(state, reviewId, at2) {
126613
126732
  const r = state.review(reviewId);
126614
126733
  if (!r || !isReviewKillable(r)) return;
126615
- killReviewRow(state, r, at);
126734
+ killReviewRow(state, r, at2);
126616
126735
  }
126617
- function killAllWorks(state, at) {
126736
+ function killAllWorks(state, at2) {
126618
126737
  for (const w2 of state.allWorks()) {
126619
- if (!w2.endedAt && !w2.deadAt) killWorkRow(state, w2, at);
126738
+ if (!w2.endedAt && !w2.deadAt) killWorkRow(state, w2, at2);
126620
126739
  }
126621
126740
  for (const n of state.liveNodes()) {
126622
126741
  const lw = n.latestWorkId ? state.work(n.latestWorkId) : null;
126623
- if (lw && isWorkKillable(lw)) killWorkRow(state, lw, at);
126742
+ if (lw && isWorkKillable(lw)) killWorkRow(state, lw, at2);
126624
126743
  }
126625
126744
  }
126626
- function killAllReviews(state, at) {
126745
+ function killAllReviews(state, at2) {
126627
126746
  for (const r of state.allReviews()) {
126628
- if (isReviewKillable(r)) killReviewRow(state, r, at);
126747
+ if (isReviewKillable(r)) killReviewRow(state, r, at2);
126629
126748
  }
126630
126749
  }
126631
126750
  var init_kill = __esm({
@@ -127071,10 +127190,10 @@ function findHumanRecoveryPost(state, node2, deadAt) {
127071
127190
  const replies = state.repliesOf(issue2.id).sort((a, b2) => a.createdAt.localeCompare(b2.createdAt));
127072
127191
  const last = replies[replies.length - 1];
127073
127192
  const actorId = last?.authorActorId ?? issue2.authorActorId;
127074
- const at = last?.createdAt ?? issue2.createdAt;
127075
- const postMs = Date.parse(at);
127193
+ const at2 = last?.createdAt ?? issue2.createdAt;
127194
+ const postMs = Date.parse(at2);
127076
127195
  if (classify(actorId) === "human" && Number.isFinite(postMs) && postMs > deadMs) {
127077
- candidates.push({ actorId, at, issueId: issue2.id });
127196
+ candidates.push({ actorId, at: at2, issueId: issue2.id });
127078
127197
  }
127079
127198
  }
127080
127199
  candidates.sort((a, b2) => a.at.localeCompare(b2.at) || a.issueId.localeCompare(b2.issueId));
@@ -128635,8 +128754,8 @@ var require_postgres_date = __commonJS({
128635
128754
  function bcYearToNegativeYear(year) {
128636
128755
  return -(year - 1);
128637
128756
  }
128638
- function is0To99(num4) {
128639
- return num4 >= 0 && num4 < 100;
128757
+ function is0To99(num5) {
128758
+ return num5 >= 0 && num5 < 100;
128640
128759
  }
128641
128760
  }
128642
128761
  });
@@ -130776,18 +130895,18 @@ var require_buffer_writer = __commonJS({
130776
130895
  oldBuffer.copy(this.buffer);
130777
130896
  }
130778
130897
  }
130779
- addInt32(num4) {
130898
+ addInt32(num5) {
130780
130899
  this.ensure(4);
130781
- this.buffer[this.offset++] = num4 >>> 24 & 255;
130782
- this.buffer[this.offset++] = num4 >>> 16 & 255;
130783
- this.buffer[this.offset++] = num4 >>> 8 & 255;
130784
- this.buffer[this.offset++] = num4 >>> 0 & 255;
130900
+ this.buffer[this.offset++] = num5 >>> 24 & 255;
130901
+ this.buffer[this.offset++] = num5 >>> 16 & 255;
130902
+ this.buffer[this.offset++] = num5 >>> 8 & 255;
130903
+ this.buffer[this.offset++] = num5 >>> 0 & 255;
130785
130904
  return this;
130786
130905
  }
130787
- addInt16(num4) {
130906
+ addInt16(num5) {
130788
130907
  this.ensure(2);
130789
- this.buffer[this.offset++] = num4 >>> 8 & 255;
130790
- this.buffer[this.offset++] = num4 >>> 0 & 255;
130908
+ this.buffer[this.offset++] = num5 >>> 8 & 255;
130909
+ this.buffer[this.offset++] = num5 >>> 0 & 255;
130791
130910
  return this;
130792
130911
  }
130793
130912
  addCString(string7) {
@@ -134358,14 +134477,14 @@ var init_store_postgres = __esm({
134358
134477
  );
134359
134478
  return res.rows[0] ? toRecord(res.rows[0]) : null;
134360
134479
  }
134361
- async markEvent(seq, status, failedReason, at) {
134480
+ async markEvent(seq, status, failedReason, at2) {
134362
134481
  await this.c.query(
134363
134482
  `UPDATE ${this.s}.events
134364
134483
  SET status = $2, failed_reason = $3, available_at = NULL,
134365
134484
  applied_at = CASE WHEN $2 = 'applied' THEN $4::timestamptz ELSE applied_at END,
134366
134485
  done_at = CASE WHEN $2 = 'done' THEN $4::timestamptz ELSE done_at END
134367
134486
  WHERE seq = $1`,
134368
- [seq, status, failedReason, at]
134487
+ [seq, status, failedReason, at2]
134369
134488
  );
134370
134489
  }
134371
134490
  async getEvent(seq) {
@@ -134490,7 +134609,7 @@ var init_types = __esm({
134490
134609
  });
134491
134610
 
134492
134611
  // ../engine/src/handlers/plan.ts
134493
- function newNode(id, workorderId, at, version2) {
134612
+ function newNode(id, workorderId, at2, version2) {
134494
134613
  return {
134495
134614
  id,
134496
134615
  workorderId,
@@ -134504,27 +134623,27 @@ function newNode(id, workorderId, at, version2) {
134504
134623
  latestAcceptId: null,
134505
134624
  isFinalOutput: false,
134506
134625
  cancelledAt: null,
134507
- createdAt: at,
134508
- updatedAt: at
134626
+ createdAt: at2,
134627
+ updatedAt: at2
134509
134628
  };
134510
134629
  }
134511
- function markNodeForRetry(state, nodeId, at, resetRejectedBudget = false, resetCheckpointBudget = false) {
134630
+ function markNodeForRetry(state, nodeId, at2, resetRejectedBudget = false, resetCheckpointBudget = false) {
134512
134631
  const node2 = state.node(nodeId);
134513
134632
  if (!node2) return;
134514
134633
  const lw = node2.latestWorkId ? state.work(node2.latestWorkId) : null;
134515
134634
  if (lw && lw.deadAt && workState(lw, hasOutput(lw, state.artifactsOf(lw.id).length)) === "dead") {
134516
- state.updateWork(lw.id, { retryAt: at, status: "retry" });
134635
+ state.updateWork(lw.id, { retryAt: at2, status: "retry" });
134517
134636
  }
134518
134637
  if (lw && !lw.deadAt && workState(lw, hasOutput(lw, state.artifactsOf(lw.id).length)) === "success") {
134519
- if (resetRejectedBudget && lw.acceptanceState === "rejected") state.updateWork(lw.id, { retryAt: at });
134638
+ if (resetRejectedBudget && lw.acceptanceState === "rejected") state.updateWork(lw.id, { retryAt: at2 });
134520
134639
  if (resetCheckpointBudget && lw.conclusion == null && state.artifactsOf(lw.id).length > 0) {
134521
- state.updateWork(lw.id, { retryAt: at });
134640
+ state.updateWork(lw.id, { retryAt: at2 });
134522
134641
  }
134523
134642
  for (const req of state.requirementsOf(node2.id)) {
134524
134643
  if (!req.latestReviewId) continue;
134525
134644
  const r = state.review(req.latestReviewId);
134526
134645
  if (r && r.cancelledAt && reviewState(r) === "dead") {
134527
- state.updateReview(r.id, { retryAt: at, status: "retry" });
134646
+ state.updateReview(r.id, { retryAt: at2, status: "retry" });
134528
134647
  }
134529
134648
  }
134530
134649
  }
@@ -134535,7 +134654,7 @@ function markNodeForRetry(state, nodeId, at, resetRejectedBudget = false, resetC
134535
134654
  const replyWorks = state.replyWorksOf(nodeId).sort((a, b2) => a.createdAt.localeCompare(b2.createdAt));
134536
134655
  const latest = replyWorks[replyWorks.length - 1];
134537
134656
  if (latest && latest.deadAt && workState(latest, hasOutput(latest, 0)) === "dead") {
134538
- state.updateWork(latest.id, { retryAt: at, status: "retry" });
134657
+ state.updateWork(latest.id, { retryAt: at2, status: "retry" });
134539
134658
  }
134540
134659
  }
134541
134660
  }
@@ -143634,11 +143753,11 @@ function bridgeLoadReadModel(input) {
143634
143753
  for (let i = 1; i < workTimeRanks.length; i++) {
143635
143754
  workTimeRanks[i].rank = Math.max(workTimeRanks[i].rank, workTimeRanks[i - 1].rank);
143636
143755
  }
143637
- const seqBefore = (at) => {
143756
+ const seqBefore = (at2) => {
143638
143757
  let low = 0, high = workTimeRanks.length;
143639
143758
  while (low < high) {
143640
143759
  const mid = Math.floor((low + high) / 2);
143641
- if (workTimeRanks[mid].at < at) low = mid + 1;
143760
+ if (workTimeRanks[mid].at < at2) low = mid + 1;
143642
143761
  else high = mid;
143643
143762
  }
143644
143763
  return low === 0 ? 0 : workTimeRanks[low - 1].rank;
@@ -166407,7 +166526,7 @@ function kindOf(a, id) {
166407
166526
  }
166408
166527
  async function validateWorkorderPrincipals(plan, briefArtifactId, getActor) {
166409
166528
  const errors = [];
166410
- const nameOf = (a, id) => a?.name || String(id).split(":").pop() || id;
166529
+ const nameOf2 = (a, id) => a?.name || String(id).split(":").pop() || id;
166411
166530
  for (const op of plan.ops) {
166412
166531
  if (op.action !== "spawn") continue;
166413
166532
  const isBrief = op.id === briefArtifactId;
@@ -166415,16 +166534,16 @@ async function validateWorkorderPrincipals(plan, briefArtifactId, getActor) {
166415
166534
  if (op.owner) {
166416
166535
  const a = await getActor(op.owner);
166417
166536
  const k2 = kindOf(a, op.owner);
166418
- if (a && a.status !== "active") errors.push(`${label2}\u300C${nameOf(a, op.owner)}\u300D\u5DF2\u79BB\u5C97\uFF0C\u4E0D\u80FD\u62C5\u4EFB`);
166419
- else if (isBrief && k2 === "agent") errors.push(`\u5DE5\u5355\u8D1F\u8D23\u4EBA\u5FC5\u987B\u662F\u4EBA\u7C7B\u6210\u5458\uFF08\u300C${nameOf(a, op.owner)}\u300D\u662F AI \u5458\u5DE5\uFF09`);
166537
+ if (a && a.status !== "active") errors.push(`${label2}\u300C${nameOf2(a, op.owner)}\u300D\u5DF2\u79BB\u5C97\uFF0C\u4E0D\u80FD\u62C5\u4EFB`);
166538
+ else if (isBrief && k2 === "agent") errors.push(`\u5DE5\u5355\u8D1F\u8D23\u4EBA\u5FC5\u987B\u662F\u4EBA\u7C7B\u6210\u5458\uFF08\u300C${nameOf2(a, op.owner)}\u300D\u662F AI \u5458\u5DE5\uFF09`);
166420
166539
  }
166421
166540
  if (isBrief) {
166422
166541
  const manager = op.fields?.manager;
166423
166542
  if (typeof manager === "string" && manager) {
166424
166543
  const a = await getActor(manager);
166425
166544
  const k2 = kindOf(a, manager);
166426
- if (a && a.status !== "active") errors.push(`\u7BA1\u7406\u8005\u300C${nameOf(a, manager)}\u300D\u5DF2\u79BB\u5C97\uFF0C\u4E0D\u80FD\u62C5\u4EFB\u7BA1\u7406\u8005`);
166427
- else if (k2 === "human") errors.push(`\u5DE5\u5355\u7BA1\u7406\u8005\u5FC5\u987B\u662F AI \u5458\u5DE5\uFF08\u300C${nameOf(a, manager)}\u300D\u662F\u4EBA\u7C7B\uFF09`);
166545
+ if (a && a.status !== "active") errors.push(`\u7BA1\u7406\u8005\u300C${nameOf2(a, manager)}\u300D\u5DF2\u79BB\u5C97\uFF0C\u4E0D\u80FD\u62C5\u4EFB\u7BA1\u7406\u8005`);
166546
+ else if (k2 === "human") errors.push(`\u5DE5\u5355\u7BA1\u7406\u8005\u5FC5\u987B\u662F AI \u5458\u5DE5\uFF08\u300C${nameOf2(a, manager)}\u300D\u662F\u4EBA\u7C7B\uFF09`);
166428
166547
  }
166429
166548
  }
166430
166549
  }
@@ -166461,7 +166580,7 @@ function newHumanAssigneesOfPlan(plan, current) {
166461
166580
  }
166462
166581
  return out;
166463
166582
  }
166464
- async function assertCompanyMembers(listMembers, companyId, assignees, nameOf = async () => void 0) {
166583
+ async function assertCompanyMembers(listMembers, companyId, assignees, nameOf2 = async () => void 0) {
166465
166584
  if (!listMembers || assignees.length === 0) return;
166466
166585
  const members = await listMembers(companyId);
166467
166586
  const listed = /* @__PURE__ */ new Set();
@@ -166474,7 +166593,7 @@ async function assertCompanyMembers(listMembers, companyId, assignees, nameOf =
166474
166593
  if (rejected.length === 0) return;
166475
166594
  const parts = [];
166476
166595
  for (const a of rejected) {
166477
- const name = (await nameOf(a.actor).catch(() => void 0))?.trim() || a.actor;
166596
+ const name = (await nameOf2(a.actor).catch(() => void 0))?.trim() || a.actor;
166478
166597
  parts.push(`\u300C${name}\u300D\u4E0D\u662F\u672C\u516C\u53F8\u6210\u5458\uFF0C\u4E0D\u80FD\u62C5\u4EFB${a.role}`);
166479
166598
  }
166480
166599
  throw new NotCompanyMemberError(parts.join("\uFF1B"));
@@ -167781,7 +167900,7 @@ function buildWorkorderSummaries(model, resolveActor, resolveProject, dispatchPa
167781
167900
  }
167782
167901
  return out.sort((a, b2) => a.updatedAt < b2.updatedAt ? 1 : a.updatedAt > b2.updatedAt ? -1 : 0);
167783
167902
  }
167784
- function summaryOfWorkspace(model, workspace, arts, ref2, resolveProject, dispatchPausedOf, projectionOf, viewer, facts, resolveRoleExecutor, nodeStateOf) {
167903
+ function summaryOfWorkspace(model, workspace, arts, ref2, resolveProject, dispatchPausedOf, projectionOf, viewer, facts, resolveRoleExecutor, nodeStateOf2) {
167785
167904
  const members = arts.map((a) => nodeInfo(model, a));
167786
167905
  const seed = arts.find((a) => a.id === overviewRootIdOf(arts)) ?? arts[0];
167787
167906
  const spec = workorderSpecOf(model, arts);
@@ -167795,7 +167914,7 @@ function summaryOfWorkspace(model, workspace, arts, ref2, resolveProject, dispat
167795
167914
  const info = members[i];
167796
167915
  return {
167797
167916
  info,
167798
- state: nodeStateOf ? nodeStateOf(a.id, info) : evaluateNodeRunState(model, a, info, projectionOf?.(a.id, info)).state,
167917
+ state: nodeStateOf2 ? nodeStateOf2(a.id, info) : evaluateNodeRunState(model, a, info, projectionOf?.(a.id, info)).state,
167799
167918
  ...a.id === overviewRootId ? { overviewRoot: true } : {}
167800
167919
  };
167801
167920
  });
@@ -168569,9 +168688,9 @@ function buildCoordinatorActivityFromEvents(model, arts, events, ref2) {
168569
168688
  const issueKindById = /* @__PURE__ */ new Map();
168570
168689
  const issueTargetById = /* @__PURE__ */ new Map();
168571
168690
  const edits = [];
168572
- const push2 = (kind, artifactId, seq, at, actor, label2, detail) => {
168691
+ const push2 = (kind, artifactId, seq, at2, actor, label2, detail) => {
168573
168692
  if (!inWorkspace.has(artifactId)) return;
168574
- edits.push({ seq, at, actor: ref2(actor), kind, artifactId, label: label2, ...detail ? { detail } : {} });
168693
+ edits.push({ seq, at: at2, actor: ref2(actor), kind, artifactId, label: label2, ...detail ? { detail } : {} });
168575
168694
  };
168576
168695
  const str5 = (v2) => typeof v2 === "string" && v2.trim() ? v2 : void 0;
168577
168696
  for (const rec2 of events) {
@@ -168774,6 +168893,22 @@ var init_discuss = __esm({
168774
168893
  }
168775
168894
  });
168776
168895
 
168896
+ // ../server/src/domains/collab/escalation-kind.ts
168897
+ function escalationKindOf(issueId, authorActorId) {
168898
+ if (issueId.startsWith(RETRY_EXHAUSTED_ESC_PREFIX)) return "retry_exhausted";
168899
+ if (issueId.startsWith(REVIEW_EXHAUSTED_ESC_PREFIX2)) return "review_exhausted";
168900
+ return isSystemActorId(authorActorId) ? "output_stall" : "manual";
168901
+ }
168902
+ var RETRY_EXHAUSTED_ESC_PREFIX, REVIEW_EXHAUSTED_ESC_PREFIX2;
168903
+ var init_escalation_kind = __esm({
168904
+ "../server/src/domains/collab/escalation-kind.ts"() {
168905
+ "use strict";
168906
+ init_src();
168907
+ RETRY_EXHAUSTED_ESC_PREFIX = "esc:retry-exhausted:";
168908
+ REVIEW_EXHAUSTED_ESC_PREFIX2 = "esc:review-exhausted:";
168909
+ }
168910
+ });
168911
+
168777
168912
  // ../server/src/domains/collab/workorder-manager.ts
168778
168913
  function resolveWorkorderManager(snap) {
168779
168914
  const nodes = snap.nodes;
@@ -168812,16 +168947,111 @@ function escalationContextOf(snap, escalationId) {
168812
168947
  ownerActorId: snap.workorder.ownerActorId,
168813
168948
  managerActorId: managerId
168814
168949
  });
168815
- const agentId = issue2.authorActorId.startsWith("actor:agent:") ? issue2.authorActorId : issue2.handActorId?.startsWith("actor:agent:") ? issue2.handActorId : managerId;
168816
- return { issue: issue2, gap, recipientActorId, agentId };
168950
+ const agentId = managerId;
168951
+ return { issue: issue2, gap, node: node2 ?? null, kind: escalationKindOf(issue2.id, issue2.authorActorId), recipientActorId, agentId };
168817
168952
  }
168818
168953
  var init_escalation_recipient = __esm({
168819
168954
  "../server/src/domains/collab/escalation-recipient.ts"() {
168820
168955
  "use strict";
168956
+ init_escalation_kind();
168821
168957
  init_workorder_manager();
168822
168958
  }
168823
168959
  });
168824
168960
 
168961
+ // ../server/src/domains/collab/escalation-chat-context.ts
168962
+ function nodeStateOf(snap, node2) {
168963
+ if (node2.cancelledAt) {
168964
+ const reason = node2.sealReason;
168965
+ return reason === "accepted" ? "\u5DF2\u9A8C\u6536\u5F52\u6863\uFF08\u4E0D\u5728\u8BA1\u5212\u91CC\u4E86\uFF09" : reason === "frozen" ? "\u5DF2\u51BB\u7ED3\uFF08\u4E0D\u5728\u8BA1\u5212\u91CC\u4E86\uFF09" : "\u5DF2\u79FB\u51FA\u8BA1\u5212";
168966
+ }
168967
+ if (node2.latestAcceptId && node2.latestAcceptId === node2.latestProposedWorkId) return "\u5DF2\u9A8C\u6536";
168968
+ if (!node2.latestWorkId) return "\u8FD8\u6CA1\u5F00\u59CB\u6267\u884C";
168969
+ const work = snap.works.find((row) => row.id === node2.latestWorkId);
168970
+ switch (work?.status) {
168971
+ case "running":
168972
+ return "\u6B63\u5728\u6267\u884C";
168973
+ case "success":
168974
+ return "\u5DF2\u4EA4\u51FA\u8FD9\u4E00\u7248\uFF0C\u7B49\u9A8C\u6536 / \u8BC4\u5BA1";
168975
+ case "failed":
168976
+ return "\u4E0A\u4E00\u8F6E\u6267\u884C\u5931\u8D25";
168977
+ case "dead":
168978
+ return "\u4E0A\u4E00\u8F6E\u88AB\u4E2D\u65AD\uFF08kill / \u53D6\u4EE3 / \u53D6\u6D88\uFF09";
168979
+ case "retry":
168980
+ return "\u5DF2\u6392\u91CD\u8BD5\uFF0C\u7B49\u8C03\u5EA6";
168981
+ // 老快照的 works 行可能没有 status 列(那是存储态,桥接前的数据没有)——不猜,直说读不出来。
168982
+ default:
168983
+ return "\u8BFB\u4E0D\u51FA\u8FD9\u4E00\u6B65\u6700\u8FD1\u4E00\u8F6E\u7684\u72B6\u6001";
168984
+ }
168985
+ }
168986
+ function buildEscalationChatContext(input) {
168987
+ const escalationId = input.escalationId?.trim();
168988
+ if (!escalationId || !input.snap) return null;
168989
+ const snap = input.snap;
168990
+ const context2 = escalationContextOf(snap, escalationId);
168991
+ if (!context2) return null;
168992
+ const { issue: issue2, gap, node: node2, kind } = context2;
168993
+ const KIND_LABEL3 = {
168994
+ retry_exhausted: "\u8FDE\u8D25\u7194\u65AD\uFF08\u8FD9\u4E00\u6B65\u7684\u81EA\u52A8\u91CD\u8BD5\u5DF2\u7528\u5C3D\uFF0C\u5F15\u64CE\u4EE5\u5361\u4F4F\u7684\u6267\u884C\u4EBA\u8EAB\u4EFD\u4EE3\u5F00\uFF09",
168995
+ review_exhausted: "\u8BC4\u5BA1\u7194\u65AD\uFF08\u8FD9\u4E00\u8F6E\u8BC4\u5BA1\u8FDE\u7EED\u6536\u4E0D\u9F50\uFF0C\u5F15\u64CE\u4EE3\u5F00\uFF09",
168996
+ output_stall: "\u96F6\u4EA7\u51FA\u6B62\u635F\uFF08\u7CFB\u7EDF\u53D1\u73B0\u53CD\u590D\u7A7A\u8DD1\uFF0C\u5DF2\u6682\u505C\u6D3E\u53D1\u5E76\u4EE3\u5F00\uFF09",
168997
+ manual: "\u4EBA\u5DE5\u4E0A\u62A5\uFF08\u6709\u4EBA\u7528 oasis escalate \u63D0\u7684\uFF09"
168998
+ };
168999
+ const others = snap.issues.filter((row) => row.kind === "escalation" && !row.resolvedAt && row.id !== issue2.id).sort((a, b2) => String(a.createdAt).localeCompare(String(b2.createdAt)));
169000
+ const shown = others.slice(0, OTHER_OPEN_LIMIT);
169001
+ const lines = [
169002
+ "\u3010\u8FD9\u6761\u4F1A\u8BDD\u662F\u4EBA\u4ECE\u4E00\u6761\u4E0A\u62A5\uFF08\u5347\u7EA7\u5361\uFF09\u70B9\u8FDB\u6765\u7684\u2014\u2014\u4F60\u662F\u8FD9\u5F20\u4EFB\u52A1\u7684\u534F\u8C03\u8005\uFF0C\u4EBA\u662F\u6765\u627E\u4F60\u4E00\u8D77\u5904\u7F6E\u8FD9\u6761\u4E0A\u62A5\u7684\u3002",
169003
+ "\u4EE5\u4E0B\u662F\u8FD9\u6761\u4E0A\u62A5\u6B64\u523B\u7684\u4E8B\u5B9E\uFF0C\u4E0E\u4EBA\u5728\u754C\u9762\u4E0A\u770B\u5230\u7684\u90A3\u6BB5\u5F00\u573A\u767D\u540C\u6E90\u3002\u522B\u53CD\u95EE\u300C\u4F60\u8BF4\u7684\u662F\u54EA\u4EF6\u4E8B\u300D\uFF1B\u8981\u66F4\u7EC6\u7684\u73B0\u72B6\u81EA\u5DF1\u7528 `oasis status` / `oasis content <id>` \u73B0\u67E5\u56FE\u3002\u3011",
169004
+ "",
169005
+ `\u4EFB\u52A1\uFF1A${snap.workorder.title}\uFF08${snap.workorder.id}\uFF09\uFF0C\u8D1F\u8D23\u4EBA ${nameOf(input.ref, snap.workorder.ownerActorId)}`,
169006
+ `\u8FD9\u6761\u4E0A\u62A5\uFF1A${issue2.id}`,
169007
+ ` \u7C7B\u522B\uFF1A${KIND_LABEL3[kind]}`,
169008
+ ` \u63D0\u51FA\u65B9\uFF1A${nameOf(input.ref, issue2.authorActorId)}${issue2.handActorId ? `\uFF08\u7ECF\u624B ${nameOf(input.ref, issue2.handActorId)}\uFF09` : ""}\uFF0C\u65F6\u95F4 ${issue2.createdAt}`
169009
+ ];
169010
+ if (node2) {
169011
+ lines.push(
169012
+ ` \u6302\u5728\u8282\u70B9\uFF1A\u300A${node2.title || node2.id}\u300B\uFF08${node2.id}\uFF0C\u7C7B\u578B ${node2.type}\uFF09`,
169013
+ ` \u8282\u70B9\u5F53\u524D\u72B6\u6001\uFF1A${nodeStateOf(snap, node2)}\uFF1B\u8D1F\u8D23\u4EBA ${nameOf(input.ref, node2.assigneeActorId)}`
169014
+ );
169015
+ } else {
169016
+ lines.push(" \u6302\u5728\u8282\u70B9\uFF1A\u8FD9\u6761\u4E0A\u62A5\u6CA1\u6709\u8BB0\u8282\u70B9\uFF08aboutNodeId / raisedByNodeId \u90FD\u7A7A\uFF09");
169017
+ }
169018
+ lines.push(" \u4E0A\u62A5\u6B63\u6587\uFF08\u539F\u6587\u7167\u5F55\uFF09\uFF1A", indent(issue2.body));
169019
+ if (gap?.body.trim()) {
169020
+ lines.push(` \u5173\u8054\u7F3A\u53E3 ${gap.id}${gap.resolvedAt ? "\uFF08\u5DF2\u89E3\u51B3\uFF09" : "\uFF08\u672A\u89E3\u51B3\uFF09"}\uFF1A`, indent(gap.body));
169021
+ }
169022
+ lines.push(
169023
+ "",
169024
+ others.length ? `\u8FD9\u5F20\u4EFB\u52A1\u4E0A\u8FD8\u5F00\u7740\u53E6\u5916 ${others.length} \u6761\u4E0A\u62A5\uFF1A` : "\u8FD9\u5F20\u4EFB\u52A1\u4E0A\u6CA1\u6709\u522B\u7684\u672A\u5173\u4E0A\u62A5\u3002",
169025
+ ...shown.map((row) => ` \xB7 ${row.id}${row.aboutNodeId ? `\uFF08\u8282\u70B9 ${row.aboutNodeId}\uFF09` : ""}\uFF1A${oneLine(row.body)}`),
169026
+ ...others.length > shown.length ? [` \xB7 \uFF08\u53E6\u6709 ${others.length - shown.length} \u6761\u6CA1\u5217\u51FA\u6765\uFF0C\u7528 \`oasis status\` \u770B\u5168\uFF09`] : [],
169027
+ "",
169028
+ '\u5904\u7F6E\u5B8C\u8FD9\u6761\u4E0A\u62A5\uFF0C\u5728\u672C\u4F1A\u8BDD\u91CC\u8DD1 `oasis resolve-escalation --reason "<\u7ED3\u8BBA>"` \u5373\u53EF\u2014\u2014\u4F1A\u8BDD\u5DF2\u7ECF\u7ED1\u7740\u8FD9\u6761\u4E0A\u62A5\uFF0C\u4E0D\u7528\u5E26 id\uFF08\u5B83\u4F1A\u8F6C\u6210\u4E00\u5F20\u5F85\u4EBA\u786E\u8BA4\u7684\u5361\uFF0C\u4E0D\u662F\u7ACB\u523B\u751F\u6548\uFF09\u3002',
169029
+ ...kind === "output_stall" && node2 ? [`\u96F6\u4EA7\u51FA\u6B62\u635F\u540C\u65F6\u6682\u505C\u4E86\u6D3E\u53D1\uFF0C\u786E\u8BA4\u6839\u56E0\u5904\u7406\u6389\u4E4B\u540E\u8FD8\u8981 \`oasis release ${node2.id}\` \u624D\u4F1A\u91CD\u65B0\u6D3E\u3002`] : []
169030
+ );
169031
+ return lines.join("\n");
169032
+ }
169033
+ function indent(body2) {
169034
+ return body2.trim().split("\n").map((row) => ` ${row}`).join("\n");
169035
+ }
169036
+ var OTHER_OPEN_LIMIT, SUMMARY_LIMIT, nameOf, oneLine;
169037
+ var init_escalation_chat_context = __esm({
169038
+ "../server/src/domains/collab/escalation-chat-context.ts"() {
169039
+ "use strict";
169040
+ init_escalation_recipient();
169041
+ OTHER_OPEN_LIMIT = 5;
169042
+ SUMMARY_LIMIT = 60;
169043
+ nameOf = (ref2, id) => {
169044
+ if (typeof id !== "string" || !id) return "\u672A\u6307\u5B9A";
169045
+ const name = ref2(id).name?.trim();
169046
+ return name ? `${name}\uFF08${id}\uFF09` : id;
169047
+ };
169048
+ oneLine = (body2) => {
169049
+ const line2 = body2.trim().split("\n").find((row) => row.trim()) ?? "";
169050
+ return line2.length > SUMMARY_LIMIT ? `${line2.slice(0, SUMMARY_LIMIT)}\u2026` : line2;
169051
+ };
169052
+ }
169053
+ });
169054
+
168825
169055
  // ../server/src/domains/chat-sessions/injected-context.ts
168826
169056
  function matchingBlockEnd(text7, start) {
168827
169057
  let cursor = start;
@@ -168913,6 +169143,11 @@ ${prompt2}`;
168913
169143
  if (input.draftWorkspace) {
168914
169144
  prompt2 = `\u3010\u4F60\u5DF2\u4E3A workspace ${input.draftWorkspace} \u6682\u5B58\u4E86\u4E00\u5F20\u5DE5\u5355\u8349\u6848\uFF0C\u7528\u6237\u6B63\u5728\u7F16\u8F91\u5668\u91CC\u770B\u7740\u5B83\u3002\u82E5\u8FD9\u6761\u6D88\u606F\u8981\u6539\u5B83\uFF1A**\u5C0F\u6539**\uFF08\u52A0/\u5220/\u6539\u8282\u70B9\u3001\u8FDE\u8FB9\u3001\u8C03\u6807\u9898/\u76EE\u6807/\u89C4\u683C\uFF09\u2192 \u7528\u6539\u8349\u6848\u547D\u4EE4 \`oasis spawn/edit/link/cancel \u2026 --workspace ${input.draftWorkspace}\` **\u589E\u91CF\u6539**\uFF08\u9ED8\u8BA4\uFF0C\u522B\u91CD\u8DD1\u6574\u4EFD\uFF09\uFF1B**\u63A8\u5012\u91CD\u6765**\uFF08\u65B9\u6848\u6574\u4E2A\u6362\uFF09\u624D \`oasis create-workorder --workspace ${input.draftWorkspace} \u2026\` \u91CD\u65B0\u751F\u6210\u4E00\u7248\uFF1B\u53EA\u662F\u95F2\u804A/\u8FFD\u95EE\u5C31\u6B63\u5E38\u56DE\u590D\u3001\u522B\u52A8\u8349\u6848\u3002\u6539\u5B8C\u6211\u4F1A\u81EA\u52A8\u91CD\u8F7D\u7F16\u8F91\u5668\u3002\u3011
168915
169145
 
169146
+ ${prompt2}`;
169147
+ }
169148
+ if (input.escalationContext) {
169149
+ prompt2 = `${input.escalationContext}
169150
+
168916
169151
  ${prompt2}`;
168917
169152
  }
168918
169153
  if (input.pendingBroadcasts?.length) {
@@ -168944,8 +169179,8 @@ var init_injected_context = __esm({
168944
169179
 
168945
169180
  // ../contract/src/discussions.ts
168946
169181
  function isStaleProposal(r, now) {
168947
- const at = typeof now === "number" ? now : Date.parse(now);
168948
- return r.state === "proposed" && at - Date.parse(r.updated_at) > DECISION_STALE_DAYS * 864e5;
169182
+ const at2 = typeof now === "number" ? now : Date.parse(now);
169183
+ return r.state === "proposed" && at2 - Date.parse(r.updated_at) > DECISION_STALE_DAYS * 864e5;
168949
169184
  }
168950
169185
  var PROJECT_DISCUSSIONS_DIR, DECISION_STATES, DECISION_STALE_DAYS, DECISION_STATEMENT_MAX, DISCUSSION_SUMMARY_MAX;
168951
169186
  var init_discussions = __esm({
@@ -169402,6 +169637,8 @@ async function planChatContinuation(input) {
169402
169637
  ...history.length ? { history: history.map(({ role, content: content3 }) => ({ role, content: content3 })) } : {},
169403
169638
  ...hintFor(historyWindow),
169404
169639
  ...input.draftWorkspace ? { draftWorkspace: input.draftWorkspace } : {},
169640
+ // 冷起(首轮 / 换过节点 / 无 native 会话号)才带上报上下文,理由见入参注释。
169641
+ ...needsHistoryInjection && input.escalationContext ? { escalationContext: input.escalationContext } : {},
169405
169642
  ...pendingBroadcasts ? { pendingBroadcasts } : {},
169406
169643
  ...persistedSystemNotices ? { persistedSystemNotices } : {}
169407
169644
  });
@@ -169412,6 +169649,8 @@ async function planChatContinuation(input) {
169412
169649
  history: fallbackHistory.map(({ role, content: content3 }) => ({ role, content: content3 })),
169413
169650
  ...hintFor(fallbackWindow),
169414
169651
  ...input.draftWorkspace ? { draftWorkspace: input.draftWorkspace } : {},
169652
+ // 兜底正文的前提就是「resume 扑空、那边没有这段记忆」——上报上下文在这条路上无条件带。
169653
+ ...input.escalationContext ? { escalationContext: input.escalationContext } : {},
169415
169654
  // resume 扑空后的重派也要带上通告:那一轮才是真正送到 agent 的那一轮。
169416
169655
  ...pendingBroadcasts ? { pendingBroadcasts } : {},
169417
169656
  ...persistedSystemNotices ? { persistedSystemNotices } : {}
@@ -169533,9 +169772,9 @@ async function legacyVerdict(turns, chatStore, sid, message) {
169533
169772
  if (others.some((t) => t.status !== "reserved" && t.status !== "running" && !provablyNotDispatched(t))) return "unknown";
169534
169773
  if (others.some((t) => t.status === "reserved" || t.status === "running")) return "pending";
169535
169774
  const rows = await read("legacy", () => chatStore.listMessages(sid, LEGACY_LOOKBACK_MESSAGES));
169536
- const at = rows.findIndex((m2) => m2.id === message.id);
169537
- if (at < 0) return "unknown";
169538
- return rows.slice(at + 1).some((m2) => m2.role === "assistant") ? "unknown" : "retryable";
169775
+ const at2 = rows.findIndex((m2) => m2.id === message.id);
169776
+ if (at2 < 0) return "unknown";
169777
+ return rows.slice(at2 + 1).some((m2) => m2.role === "assistant") ? "unknown" : "retryable";
169539
169778
  }
169540
169779
  function provablyNotDispatched(t) {
169541
169780
  return (t.status === "failed" || t.status === "cancelled") && !t.startedAt && !t.assistantRunId && !t.dispatchId;
@@ -169693,9 +169932,9 @@ var init_chat_workorder_files = __esm({
169693
169932
  // ../server/src/chat-broadcast.ts
169694
169933
  function isFreshTerminal(terminalAt, nowMs, maxAgeMs) {
169695
169934
  if (!terminalAt) return true;
169696
- const at = Date.parse(terminalAt);
169697
- if (!Number.isFinite(at)) return true;
169698
- return nowMs - at <= maxAgeMs;
169935
+ const at2 = Date.parse(terminalAt);
169936
+ if (!Number.isFinite(at2)) return true;
169937
+ return nowMs - at2 <= maxAgeMs;
169699
169938
  }
169700
169939
  function broadcastMessageText(t) {
169701
169940
  const head = t.kind === "workorder-settled" ? "\u5DF2\u7ED3\u6848" : "\u5DF2\u53D6\u6D88";
@@ -181466,7 +181705,7 @@ function tokenizeDefinitionStart(effects2, ok3, nok) {
181466
181705
  }
181467
181706
  }
181468
181707
  function tokenizeDefinitionContinuation(effects2, ok3, nok) {
181469
- return effects2.check(blankLine, ok3, effects2.attempt(indent, ok3, nok));
181708
+ return effects2.check(blankLine, ok3, effects2.attempt(indent2, ok3, nok));
181470
181709
  }
181471
181710
  function gfmFootnoteDefinitionEnd(effects2) {
181472
181711
  effects2.exit("gfmFootnoteDefinition");
@@ -181479,14 +181718,14 @@ function tokenizeIndent2(effects2, ok3, nok) {
181479
181718
  return tail && tail[1].type === "gfmFootnoteDefinitionIndent" && tail[2].sliceSerialize(tail[1], true).length === 4 ? ok3(code2) : nok(code2);
181480
181719
  }
181481
181720
  }
181482
- var indent;
181721
+ var indent2;
181483
181722
  var init_syntax2 = __esm({
181484
181723
  "../../node_modules/.pnpm/micromark-extension-gfm-footnote@2.1.0/node_modules/micromark-extension-gfm-footnote/lib/syntax.js"() {
181485
181724
  init_micromark_core_commonmark();
181486
181725
  init_micromark_factory_space();
181487
181726
  init_micromark_util_character();
181488
181727
  init_micromark_util_normalize_identifier();
181489
- indent = {
181728
+ indent2 = {
181490
181729
  tokenize: tokenizeIndent2,
181491
181730
  partial: true
181492
181731
  };
@@ -181609,20 +181848,20 @@ var init_micromark_extension_gfm_strikethrough = __esm({
181609
181848
  });
181610
181849
 
181611
181850
  // ../../node_modules/.pnpm/micromark-extension-gfm-table@2.1.1/node_modules/micromark-extension-gfm-table/lib/edit-map.js
181612
- function addImplementation(editMap, at, remove, add) {
181851
+ function addImplementation(editMap, at2, remove, add) {
181613
181852
  let index2 = 0;
181614
181853
  if (remove === 0 && add.length === 0) {
181615
181854
  return;
181616
181855
  }
181617
181856
  while (index2 < editMap.map.length) {
181618
- if (editMap.map[index2][0] === at) {
181857
+ if (editMap.map[index2][0] === at2) {
181619
181858
  editMap.map[index2][1] += remove;
181620
181859
  editMap.map[index2][2].push(...add);
181621
181860
  return;
181622
181861
  }
181623
181862
  index2 += 1;
181624
181863
  }
181625
- editMap.map.push([at, remove, add]);
181864
+ editMap.map.push([at2, remove, add]);
181626
181865
  }
181627
181866
  var EditMap;
181628
181867
  var init_edit_map = __esm({
@@ -183482,12 +183721,12 @@ var require_stringifyComment = __commonJS({
183482
183721
  "../../node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/stringify/stringifyComment.js"(exports2) {
183483
183722
  "use strict";
183484
183723
  var stringifyComment = (str5) => str5.replace(/^(?!$)(?: $)?/gm, "#");
183485
- function indentComment(comment, indent2) {
183724
+ function indentComment(comment, indent3) {
183486
183725
  if (/^\n+$/.test(comment))
183487
183726
  return comment.substring(1);
183488
- return indent2 ? comment.replace(/^(?! *$)/gm, indent2) : comment;
183727
+ return indent3 ? comment.replace(/^(?! *$)/gm, indent3) : comment;
183489
183728
  }
183490
- var lineComment = (str5, indent2, comment) => str5.endsWith("\n") ? indentComment(comment, indent2) : comment.includes("\n") ? "\n" + indentComment(comment, indent2) : (str5.endsWith(" ") ? "" : " ") + comment;
183729
+ var lineComment = (str5, indent3, comment) => str5.endsWith("\n") ? indentComment(comment, indent3) : comment.includes("\n") ? "\n" + indentComment(comment, indent3) : (str5.endsWith(" ") ? "" : " ") + comment;
183491
183730
  exports2.indentComment = indentComment;
183492
183731
  exports2.lineComment = lineComment;
183493
183732
  exports2.stringifyComment = stringifyComment;
@@ -183501,17 +183740,17 @@ var require_foldFlowLines = __commonJS({
183501
183740
  var FOLD_FLOW = "flow";
183502
183741
  var FOLD_BLOCK = "block";
183503
183742
  var FOLD_QUOTED = "quoted";
183504
- function foldFlowLines(text7, indent2, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
183743
+ function foldFlowLines(text7, indent3, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
183505
183744
  if (!lineWidth || lineWidth < 0)
183506
183745
  return text7;
183507
183746
  if (lineWidth < minContentWidth)
183508
183747
  minContentWidth = 0;
183509
- const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent2.length);
183748
+ const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent3.length);
183510
183749
  if (text7.length <= endStep)
183511
183750
  return text7;
183512
183751
  const folds = [];
183513
183752
  const escapedFolds = {};
183514
- let end = lineWidth - indent2.length;
183753
+ let end = lineWidth - indent3.length;
183515
183754
  if (typeof indentAtStart === "number") {
183516
183755
  if (indentAtStart > lineWidth - Math.max(2, minContentWidth))
183517
183756
  folds.push(0);
@@ -183525,7 +183764,7 @@ var require_foldFlowLines = __commonJS({
183525
183764
  let escStart = -1;
183526
183765
  let escEnd = -1;
183527
183766
  if (mode === FOLD_BLOCK) {
183528
- i = consumeMoreIndentedLines(text7, i, indent2.length);
183767
+ i = consumeMoreIndentedLines(text7, i, indent3.length);
183529
183768
  if (i !== -1)
183530
183769
  end = i + endStep;
183531
183770
  }
@@ -183549,8 +183788,8 @@ var require_foldFlowLines = __commonJS({
183549
183788
  }
183550
183789
  if (ch === "\n") {
183551
183790
  if (mode === FOLD_BLOCK)
183552
- i = consumeMoreIndentedLines(text7, i, indent2.length);
183553
- end = i + indent2.length + endStep;
183791
+ i = consumeMoreIndentedLines(text7, i, indent3.length);
183792
+ end = i + indent3.length + endStep;
183554
183793
  split = void 0;
183555
183794
  } else {
183556
183795
  if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") {
@@ -183595,22 +183834,22 @@ var require_foldFlowLines = __commonJS({
183595
183834
  const end2 = folds[i2 + 1] || text7.length;
183596
183835
  if (fold2 === 0)
183597
183836
  res = `
183598
- ${indent2}${text7.slice(0, end2)}`;
183837
+ ${indent3}${text7.slice(0, end2)}`;
183599
183838
  else {
183600
183839
  if (mode === FOLD_QUOTED && escapedFolds[fold2])
183601
183840
  res += `${text7[fold2]}\\`;
183602
183841
  res += `
183603
- ${indent2}${text7.slice(fold2 + 1, end2)}`;
183842
+ ${indent3}${text7.slice(fold2 + 1, end2)}`;
183604
183843
  }
183605
183844
  }
183606
183845
  return res;
183607
183846
  }
183608
- function consumeMoreIndentedLines(text7, i, indent2) {
183847
+ function consumeMoreIndentedLines(text7, i, indent3) {
183609
183848
  let end = i;
183610
183849
  let start = i + 1;
183611
183850
  let ch = text7[start];
183612
183851
  while (ch === " " || ch === " ") {
183613
- if (i < start + indent2) {
183852
+ if (i < start + indent3) {
183614
183853
  ch = text7[++i];
183615
183854
  } else {
183616
183855
  do {
@@ -183666,7 +183905,7 @@ var require_stringifyString = __commonJS({
183666
183905
  return json;
183667
183906
  const { implicitKey } = ctx;
183668
183907
  const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;
183669
- const indent2 = ctx.indent || (containsDocumentMarker(value2) ? " " : "");
183908
+ const indent3 = ctx.indent || (containsDocumentMarker(value2) ? " " : "");
183670
183909
  let str5 = "";
183671
183910
  let start = 0;
183672
183911
  for (let i = 0, ch = json[i]; ch; ch = json[++i]) {
@@ -183726,7 +183965,7 @@ var require_stringifyString = __commonJS({
183726
183965
  str5 += "\n";
183727
183966
  i += 2;
183728
183967
  }
183729
- str5 += indent2;
183968
+ str5 += indent3;
183730
183969
  if (json[i + 2] === " ")
183731
183970
  str5 += "\\";
183732
183971
  i += 1;
@@ -183738,15 +183977,15 @@ var require_stringifyString = __commonJS({
183738
183977
  }
183739
183978
  }
183740
183979
  str5 = start ? str5 + json.slice(start) : json;
183741
- return implicitKey ? str5 : foldFlowLines.foldFlowLines(str5, indent2, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
183980
+ return implicitKey ? str5 : foldFlowLines.foldFlowLines(str5, indent3, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
183742
183981
  }
183743
183982
  function singleQuotedString(value2, ctx) {
183744
183983
  if (ctx.options.singleQuote === false || ctx.implicitKey && value2.includes("\n") || /[ \t]\n|\n[ \t]/.test(value2))
183745
183984
  return doubleQuotedString(value2, ctx);
183746
- const indent2 = ctx.indent || (containsDocumentMarker(value2) ? " " : "");
183985
+ const indent3 = ctx.indent || (containsDocumentMarker(value2) ? " " : "");
183747
183986
  const res = "'" + value2.replace(/'/g, "''").replace(/\n+/g, `$&
183748
- ${indent2}`) + "'";
183749
- return ctx.implicitKey ? res : foldFlowLines.foldFlowLines(res, indent2, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
183987
+ ${indent3}`) + "'";
183988
+ return ctx.implicitKey ? res : foldFlowLines.foldFlowLines(res, indent3, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
183750
183989
  }
183751
183990
  function quotedString(value2, ctx) {
183752
183991
  const { singleQuote } = ctx.options;
@@ -183776,8 +184015,8 @@ ${indent2}`) + "'";
183776
184015
  if (!blockQuote2 || /\n[\t ]+$/.test(value2)) {
183777
184016
  return quotedString(value2, ctx);
183778
184017
  }
183779
- const indent2 = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value2) ? " " : "");
183780
- const literal2 = blockQuote2 === "literal" ? true : blockQuote2 === "folded" || type === Scalar.Scalar.BLOCK_FOLDED ? false : type === Scalar.Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(value2, lineWidth, indent2.length);
184018
+ const indent3 = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value2) ? " " : "");
184019
+ const literal2 = blockQuote2 === "literal" ? true : blockQuote2 === "folded" || type === Scalar.Scalar.BLOCK_FOLDED ? false : type === Scalar.Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(value2, lineWidth, indent3.length);
183781
184020
  if (!value2)
183782
184021
  return literal2 ? "|\n" : ">\n";
183783
184022
  let chomp;
@@ -183802,7 +184041,7 @@ ${indent2}`) + "'";
183802
184041
  value2 = value2.slice(0, -end.length);
183803
184042
  if (end[end.length - 1] === "\n")
183804
184043
  end = end.slice(0, -1);
183805
- end = end.replace(blockEndNewlines, `$&${indent2}`);
184044
+ end = end.replace(blockEndNewlines, `$&${indent3}`);
183806
184045
  }
183807
184046
  let startWithSpace = false;
183808
184047
  let startEnd;
@@ -183819,9 +184058,9 @@ ${indent2}`) + "'";
183819
184058
  let start = value2.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);
183820
184059
  if (start) {
183821
184060
  value2 = value2.substring(start.length);
183822
- start = start.replace(/\n+/g, `$&${indent2}`);
184061
+ start = start.replace(/\n+/g, `$&${indent3}`);
183823
184062
  }
183824
- const indentSize = indent2 ? "2" : "1";
184063
+ const indentSize = indent3 ? "2" : "1";
183825
184064
  let header = (startWithSpace ? indentSize : "") + chomp;
183826
184065
  if (comment) {
183827
184066
  header += " " + commentString(comment.replace(/ ?[\r\n]+/g, " "));
@@ -183829,7 +184068,7 @@ ${indent2}`) + "'";
183829
184068
  onComment();
183830
184069
  }
183831
184070
  if (!literal2) {
183832
- const foldedValue = value2.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${indent2}`);
184071
+ const foldedValue = value2.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${indent3}`);
183833
184072
  let literalFallback = false;
183834
184073
  const foldOptions = getFoldOptions(ctx, true);
183835
184074
  if (blockQuote2 !== "folded" && type !== Scalar.Scalar.BLOCK_FOLDED) {
@@ -183837,18 +184076,18 @@ ${indent2}`) + "'";
183837
184076
  literalFallback = true;
183838
184077
  };
183839
184078
  }
183840
- const body2 = foldFlowLines.foldFlowLines(`${start}${foldedValue}${end}`, indent2, foldFlowLines.FOLD_BLOCK, foldOptions);
184079
+ const body2 = foldFlowLines.foldFlowLines(`${start}${foldedValue}${end}`, indent3, foldFlowLines.FOLD_BLOCK, foldOptions);
183841
184080
  if (!literalFallback)
183842
184081
  return `>${header}
183843
- ${indent2}${body2}`;
184082
+ ${indent3}${body2}`;
183844
184083
  }
183845
- value2 = value2.replace(/\n+/g, `$&${indent2}`);
184084
+ value2 = value2.replace(/\n+/g, `$&${indent3}`);
183846
184085
  return `|${header}
183847
- ${indent2}${start}${value2}${end}`;
184086
+ ${indent3}${start}${value2}${end}`;
183848
184087
  }
183849
184088
  function plainString(item, ctx, onComment, onChompKeep) {
183850
184089
  const { type, value: value2 } = item;
183851
- const { actualString, implicitKey, indent: indent2, indentStep, inFlow } = ctx;
184090
+ const { actualString, implicitKey, indent: indent3, indentStep, inFlow } = ctx;
183852
184091
  if (implicitKey && value2.includes("\n") || inFlow && /[[\]{},]/.test(value2)) {
183853
184092
  return quotedString(value2, ctx);
183854
184093
  }
@@ -183859,22 +184098,22 @@ ${indent2}${start}${value2}${end}`;
183859
184098
  return blockString(item, ctx, onComment, onChompKeep);
183860
184099
  }
183861
184100
  if (containsDocumentMarker(value2)) {
183862
- if (indent2 === "") {
184101
+ if (indent3 === "") {
183863
184102
  ctx.forceBlockIndent = true;
183864
184103
  return blockString(item, ctx, onComment, onChompKeep);
183865
- } else if (implicitKey && indent2 === indentStep) {
184104
+ } else if (implicitKey && indent3 === indentStep) {
183866
184105
  return quotedString(value2, ctx);
183867
184106
  }
183868
184107
  }
183869
184108
  const str5 = value2.replace(/\n+/g, `$&
183870
- ${indent2}`);
184109
+ ${indent3}`);
183871
184110
  if (actualString) {
183872
184111
  const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str5);
183873
184112
  const { compat, tags } = ctx.doc.schema;
183874
184113
  if (tags.some(test) || compat?.some(test))
183875
184114
  return quotedString(value2, ctx);
183876
184115
  }
183877
- return implicitKey ? str5 : foldFlowLines.foldFlowLines(str5, indent2, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
184116
+ return implicitKey ? str5 : foldFlowLines.foldFlowLines(str5, indent3, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
183878
184117
  }
183879
184118
  function stringifyString(item, ctx, onComment, onChompKeep) {
183880
184119
  const { implicitKey, inFlow } = ctx;
@@ -184046,7 +184285,7 @@ var require_stringifyPair = __commonJS({
184046
184285
  var stringify = require_stringify2();
184047
184286
  var stringifyComment = require_stringifyComment();
184048
184287
  function stringifyPair({ key: key2, value: value2 }, ctx, onComment, onChompKeep) {
184049
- const { allNullValues, doc, indent: indent2, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
184288
+ const { allNullValues, doc, indent: indent3, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
184050
184289
  let keyComment = identity.isNode(key2) && key2.comment || null;
184051
184290
  if (simpleKeys) {
184052
184291
  if (keyComment) {
@@ -184061,7 +184300,7 @@ var require_stringifyPair = __commonJS({
184061
184300
  ctx = Object.assign({}, ctx, {
184062
184301
  allNullValues: false,
184063
184302
  implicitKey: !explicitKey && (simpleKeys || !allNullValues),
184064
- indent: indent2 + indentStep
184303
+ indent: indent3 + indentStep
184065
184304
  });
184066
184305
  let keyCommentDone = false;
184067
184306
  let chompKeep = false;
@@ -184091,7 +184330,7 @@ var require_stringifyPair = __commonJS({
184091
184330
  if (keyComment)
184092
184331
  str5 += stringifyComment.lineComment(str5, ctx.indent, commentString(keyComment));
184093
184332
  str5 = `? ${str5}
184094
- ${indent2}:`;
184333
+ ${indent3}:`;
184095
184334
  } else {
184096
184335
  str5 = `${str5}:`;
184097
184336
  if (keyComment)
@@ -184369,7 +184608,7 @@ var require_stringifyCollection = __commonJS({
184369
184608
  return stringify2(collection, ctx, options);
184370
184609
  }
184371
184610
  function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {
184372
- const { indent: indent2, options: { commentString } } = ctx;
184611
+ const { indent: indent3, options: { commentString } } = ctx;
184373
184612
  const itemCtx = Object.assign({}, ctx, { indent: itemIndent, type: null });
184374
184613
  let chompKeep = false;
184375
184614
  const lines = [];
@@ -184406,11 +184645,11 @@ var require_stringifyCollection = __commonJS({
184406
184645
  for (let i = 1; i < lines.length; ++i) {
184407
184646
  const line2 = lines[i];
184408
184647
  str5 += line2 ? `
184409
- ${indent2}${line2}` : "\n";
184648
+ ${indent3}${line2}` : "\n";
184410
184649
  }
184411
184650
  }
184412
184651
  if (comment) {
184413
- str5 += "\n" + stringifyComment.indentComment(commentString(comment), indent2);
184652
+ str5 += "\n" + stringifyComment.indentComment(commentString(comment), indent3);
184414
184653
  if (onComment)
184415
184654
  onComment();
184416
184655
  } else if (chompKeep && onChompKeep)
@@ -184418,7 +184657,7 @@ ${indent2}${line2}` : "\n";
184418
184657
  return str5;
184419
184658
  }
184420
184659
  function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
184421
- const { indent: indent2, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
184660
+ const { indent: indent3, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
184422
184661
  itemIndent += indentStep;
184423
184662
  const itemCtx = Object.assign({}, ctx, {
184424
184663
  indent: itemIndent,
@@ -184487,19 +184726,19 @@ ${indent2}${line2}` : "\n";
184487
184726
  let str5 = start;
184488
184727
  for (const line2 of lines)
184489
184728
  str5 += line2 ? `
184490
- ${indentStep}${indent2}${line2}` : "\n";
184729
+ ${indentStep}${indent3}${line2}` : "\n";
184491
184730
  return `${str5}
184492
- ${indent2}${end}`;
184731
+ ${indent3}${end}`;
184493
184732
  } else {
184494
184733
  return `${start}${fcPadding}${lines.join(" ")}${fcPadding}${end}`;
184495
184734
  }
184496
184735
  }
184497
184736
  }
184498
- function addCommentBefore({ indent: indent2, options: { commentString } }, lines, comment, chompKeep) {
184737
+ function addCommentBefore({ indent: indent3, options: { commentString } }, lines, comment, chompKeep) {
184499
184738
  if (comment && chompKeep)
184500
184739
  comment = comment.replace(/^\n+/, "");
184501
184740
  if (comment) {
184502
- const ic = stringifyComment.indentComment(commentString(comment), indent2);
184741
+ const ic = stringifyComment.indentComment(commentString(comment), indent3);
184503
184742
  lines.push(ic.trimStart());
184504
184743
  }
184505
184744
  }
@@ -184879,9 +185118,9 @@ var require_stringifyNumber = __commonJS({
184879
185118
  function stringifyNumber({ format, minFractionDigits, tag, value: value2 }) {
184880
185119
  if (typeof value2 === "bigint")
184881
185120
  return String(value2);
184882
- const num4 = typeof value2 === "number" ? value2 : Number(value2);
184883
- if (!isFinite(num4))
184884
- return isNaN(num4) ? ".nan" : num4 < 0 ? "-.inf" : ".inf";
185121
+ const num5 = typeof value2 === "number" ? value2 : Number(value2);
185122
+ if (!isFinite(num5))
185123
+ return isNaN(num5) ? ".nan" : num5 < 0 ? "-.inf" : ".inf";
184885
185124
  let n = Object.is(value2, -0) ? "-0" : JSON.stringify(value2);
184886
185125
  if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
184887
185126
  let i = n.indexOf(".");
@@ -184921,8 +185160,8 @@ var require_float2 = __commonJS({
184921
185160
  test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,
184922
185161
  resolve: (str5) => parseFloat(str5),
184923
185162
  stringify(node2) {
184924
- const num4 = Number(node2.value);
184925
- return isFinite(num4) ? num4.toExponential() : stringifyNumber.stringifyNumber(node2);
185163
+ const num5 = Number(node2.value);
185164
+ return isFinite(num5) ? num5.toExponential() : stringifyNumber.stringifyNumber(node2);
184926
185165
  }
184927
185166
  };
184928
185167
  var float = {
@@ -185361,8 +185600,8 @@ var require_float3 = __commonJS({
185361
185600
  test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,
185362
185601
  resolve: (str5) => parseFloat(str5.replace(/_/g, "")),
185363
185602
  stringify(node2) {
185364
- const num4 = Number(node2.value);
185365
- return isFinite(num4) ? num4.toExponential() : stringifyNumber.stringifyNumber(node2);
185603
+ const num5 = Number(node2.value);
185604
+ return isFinite(num5) ? num5.toExponential() : stringifyNumber.stringifyNumber(node2);
185366
185605
  }
185367
185606
  };
185368
185607
  var float = {
@@ -185564,23 +185803,23 @@ var require_timestamp = __commonJS({
185564
185803
  function parseSexagesimal(str5, asBigInt) {
185565
185804
  const sign3 = str5[0];
185566
185805
  const parts = sign3 === "-" || sign3 === "+" ? str5.substring(1) : str5;
185567
- const num4 = (n) => asBigInt ? BigInt(n) : Number(n);
185568
- const res = parts.replace(/_/g, "").split(":").reduce((res2, p2) => res2 * num4(60) + num4(p2), num4(0));
185569
- return sign3 === "-" ? num4(-1) * res : res;
185806
+ const num5 = (n) => asBigInt ? BigInt(n) : Number(n);
185807
+ const res = parts.replace(/_/g, "").split(":").reduce((res2, p2) => res2 * num5(60) + num5(p2), num5(0));
185808
+ return sign3 === "-" ? num5(-1) * res : res;
185570
185809
  }
185571
185810
  function stringifySexagesimal(node2) {
185572
185811
  let { value: value2 } = node2;
185573
- let num4 = (n) => n;
185812
+ let num5 = (n) => n;
185574
185813
  if (typeof value2 === "bigint")
185575
- num4 = (n) => BigInt(n);
185814
+ num5 = (n) => BigInt(n);
185576
185815
  else if (isNaN(value2) || !isFinite(value2))
185577
185816
  return stringifyNumber.stringifyNumber(node2);
185578
185817
  let sign3 = "";
185579
185818
  if (value2 < 0) {
185580
185819
  sign3 = "-";
185581
- value2 *= num4(-1);
185820
+ value2 *= num5(-1);
185582
185821
  }
185583
- const _60 = num4(60);
185822
+ const _60 = num5(60);
185584
185823
  const parts = [value2 % _60];
185585
185824
  if (value2 < 60) {
185586
185825
  parts.unshift(0);
@@ -186449,10 +186688,10 @@ var require_util_flow_indent_check = __commonJS({
186449
186688
  "../../node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/compose/util-flow-indent-check.js"(exports2) {
186450
186689
  "use strict";
186451
186690
  var utilContainsNewline = require_util_contains_newline();
186452
- function flowIndentCheck(indent2, fc, onError) {
186691
+ function flowIndentCheck(indent3, fc, onError) {
186453
186692
  if (fc?.type === "flow-collection") {
186454
186693
  const end = fc.end[0];
186455
- if (end.indent === indent2 && (end.source === "]" || end.source === "}") && utilContainsNewline.containsNewline(fc)) {
186694
+ if (end.indent === indent3 && (end.source === "]" || end.source === "}") && utilContainsNewline.containsNewline(fc)) {
186456
186695
  const msg = "Flow end indicator should be more indented than parent";
186457
186696
  onError(end, "BAD_INDENT", msg, true);
186458
186697
  }
@@ -186970,17 +187209,17 @@ var require_resolve_block_scalar = __commonJS({
186970
187209
  let offset = scalar.offset + header.length;
186971
187210
  let contentStart = 0;
186972
187211
  for (let i = 0; i < chompStart; ++i) {
186973
- const [indent2, content3] = lines[i];
187212
+ const [indent3, content3] = lines[i];
186974
187213
  if (content3 === "" || content3 === "\r") {
186975
- if (header.indent === 0 && indent2.length > trimIndent)
186976
- trimIndent = indent2.length;
187214
+ if (header.indent === 0 && indent3.length > trimIndent)
187215
+ trimIndent = indent3.length;
186977
187216
  } else {
186978
- if (indent2.length < trimIndent) {
187217
+ if (indent3.length < trimIndent) {
186979
187218
  const message = "Block scalars with more-indented leading empty lines must use an explicit indentation indicator";
186980
- onError(offset + indent2.length, "MISSING_CHAR", message);
187219
+ onError(offset + indent3.length, "MISSING_CHAR", message);
186981
187220
  }
186982
187221
  if (header.indent === 0)
186983
- trimIndent = indent2.length;
187222
+ trimIndent = indent3.length;
186984
187223
  contentStart = i;
186985
187224
  if (trimIndent === 0 && !ctx.atRoot) {
186986
187225
  const message = "Block scalar values in collections must be indented";
@@ -186988,7 +187227,7 @@ var require_resolve_block_scalar = __commonJS({
186988
187227
  }
186989
187228
  break;
186990
187229
  }
186991
- offset += indent2.length + content3.length + 1;
187230
+ offset += indent3.length + content3.length + 1;
186992
187231
  }
186993
187232
  for (let i = lines.length - 1; i >= chompStart; --i) {
186994
187233
  if (lines[i][0].length > trimIndent)
@@ -187000,26 +187239,26 @@ var require_resolve_block_scalar = __commonJS({
187000
187239
  for (let i = 0; i < contentStart; ++i)
187001
187240
  value2 += lines[i][0].slice(trimIndent) + "\n";
187002
187241
  for (let i = contentStart; i < chompStart; ++i) {
187003
- let [indent2, content3] = lines[i];
187004
- offset += indent2.length + content3.length + 1;
187242
+ let [indent3, content3] = lines[i];
187243
+ offset += indent3.length + content3.length + 1;
187005
187244
  const crlf = content3[content3.length - 1] === "\r";
187006
187245
  if (crlf)
187007
187246
  content3 = content3.slice(0, -1);
187008
- if (content3 && indent2.length < trimIndent) {
187247
+ if (content3 && indent3.length < trimIndent) {
187009
187248
  const src = header.indent ? "explicit indentation indicator" : "first line";
187010
187249
  const message = `Block scalar lines must not be less indented than their ${src}`;
187011
187250
  onError(offset - content3.length - (crlf ? 2 : 1), "BAD_INDENT", message);
187012
- indent2 = "";
187251
+ indent3 = "";
187013
187252
  }
187014
187253
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
187015
- value2 += sep6 + indent2.slice(trimIndent) + content3;
187254
+ value2 += sep6 + indent3.slice(trimIndent) + content3;
187016
187255
  sep6 = "\n";
187017
- } else if (indent2.length > trimIndent || content3[0] === " ") {
187256
+ } else if (indent3.length > trimIndent || content3[0] === " ") {
187018
187257
  if (sep6 === " ")
187019
187258
  sep6 = "\n";
187020
187259
  else if (!prevMoreIndented && sep6 === "\n")
187021
187260
  sep6 = "\n\n";
187022
- value2 += sep6 + indent2.slice(trimIndent) + content3;
187261
+ value2 += sep6 + indent3.slice(trimIndent) + content3;
187023
187262
  sep6 = "\n";
187024
187263
  prevMoreIndented = true;
187025
187264
  } else if (content3 === "") {
@@ -187055,7 +187294,7 @@ var require_resolve_block_scalar = __commonJS({
187055
187294
  }
187056
187295
  const { source } = props[0];
187057
187296
  const mode = source[0];
187058
- let indent2 = 0;
187297
+ let indent3 = 0;
187059
187298
  let chomp = "";
187060
187299
  let error2 = -1;
187061
187300
  for (let i = 1; i < source.length; ++i) {
@@ -187064,8 +187303,8 @@ var require_resolve_block_scalar = __commonJS({
187064
187303
  chomp = ch;
187065
187304
  else {
187066
187305
  const n = Number(ch);
187067
- if (!indent2 && n)
187068
- indent2 = n;
187306
+ if (!indent3 && n)
187307
+ indent3 = n;
187069
187308
  else if (error2 === -1)
187070
187309
  error2 = offset + i;
187071
187310
  }
@@ -187106,7 +187345,7 @@ var require_resolve_block_scalar = __commonJS({
187106
187345
  }
187107
187346
  }
187108
187347
  }
187109
- return { mode, indent: indent2, chomp, comment, length };
187348
+ return { mode, indent: indent3, chomp, comment, length };
187110
187349
  }
187111
187350
  function splitLines(source) {
187112
187351
  const split = source.split(/\n( *)/);
@@ -187839,15 +188078,15 @@ var require_cst_scalar = __commonJS({
187839
188078
  return null;
187840
188079
  }
187841
188080
  function createScalarToken(value2, context2) {
187842
- const { implicitKey = false, indent: indent2, inFlow = false, offset = -1, type = "PLAIN" } = context2;
188081
+ const { implicitKey = false, indent: indent3, inFlow = false, offset = -1, type = "PLAIN" } = context2;
187843
188082
  const source = stringifyString.stringifyString({ type, value: value2 }, {
187844
188083
  implicitKey,
187845
- indent: indent2 > 0 ? " ".repeat(indent2) : "",
188084
+ indent: indent3 > 0 ? " ".repeat(indent3) : "",
187846
188085
  inFlow,
187847
188086
  options: { blockQuote: true, lineWidth: -1 }
187848
188087
  });
187849
188088
  const end = context2.end ?? [
187850
- { type: "newline", offset: -1, indent: indent2, source: "\n" }
188089
+ { type: "newline", offset: -1, indent: indent3, source: "\n" }
187851
188090
  ];
187852
188091
  switch (source[0]) {
187853
188092
  case "|":
@@ -187856,25 +188095,25 @@ var require_cst_scalar = __commonJS({
187856
188095
  const head = source.substring(0, he);
187857
188096
  const body2 = source.substring(he + 1) + "\n";
187858
188097
  const props = [
187859
- { type: "block-scalar-header", offset, indent: indent2, source: head }
188098
+ { type: "block-scalar-header", offset, indent: indent3, source: head }
187860
188099
  ];
187861
188100
  if (!addEndtoBlockProps(props, end))
187862
- props.push({ type: "newline", offset: -1, indent: indent2, source: "\n" });
187863
- return { type: "block-scalar", offset, indent: indent2, props, source: body2 };
188101
+ props.push({ type: "newline", offset: -1, indent: indent3, source: "\n" });
188102
+ return { type: "block-scalar", offset, indent: indent3, props, source: body2 };
187864
188103
  }
187865
188104
  case '"':
187866
- return { type: "double-quoted-scalar", offset, indent: indent2, source, end };
188105
+ return { type: "double-quoted-scalar", offset, indent: indent3, source, end };
187867
188106
  case "'":
187868
- return { type: "single-quoted-scalar", offset, indent: indent2, source, end };
188107
+ return { type: "single-quoted-scalar", offset, indent: indent3, source, end };
187869
188108
  default:
187870
- return { type: "scalar", offset, indent: indent2, source, end };
188109
+ return { type: "scalar", offset, indent: indent3, source, end };
187871
188110
  }
187872
188111
  }
187873
188112
  function setScalarValue(token, value2, context2 = {}) {
187874
188113
  let { afterKey = false, implicitKey = false, inFlow = false, type } = context2;
187875
- let indent2 = "indent" in token ? token.indent : null;
187876
- if (afterKey && typeof indent2 === "number")
187877
- indent2 += 2;
188114
+ let indent3 = "indent" in token ? token.indent : null;
188115
+ if (afterKey && typeof indent3 === "number")
188116
+ indent3 += 2;
187878
188117
  if (!type)
187879
188118
  switch (token.type) {
187880
188119
  case "single-quoted-scalar":
@@ -187894,8 +188133,8 @@ var require_cst_scalar = __commonJS({
187894
188133
  type = "PLAIN";
187895
188134
  }
187896
188135
  const source = stringifyString.stringifyString({ type, value: value2 }, {
187897
- implicitKey: implicitKey || indent2 === null,
187898
- indent: indent2 !== null && indent2 > 0 ? " ".repeat(indent2) : "",
188136
+ implicitKey: implicitKey || indent3 === null,
188137
+ indent: indent3 !== null && indent3 > 0 ? " ".repeat(indent3) : "",
187899
188138
  inFlow,
187900
188139
  options: { blockQuote: true, lineWidth: -1 }
187901
188140
  });
@@ -187926,16 +188165,16 @@ var require_cst_scalar = __commonJS({
187926
188165
  token.source = body2;
187927
188166
  } else {
187928
188167
  const { offset } = token;
187929
- const indent2 = "indent" in token ? token.indent : -1;
188168
+ const indent3 = "indent" in token ? token.indent : -1;
187930
188169
  const props = [
187931
- { type: "block-scalar-header", offset, indent: indent2, source: head }
188170
+ { type: "block-scalar-header", offset, indent: indent3, source: head }
187932
188171
  ];
187933
188172
  if (!addEndtoBlockProps(props, "end" in token ? token.end : void 0))
187934
- props.push({ type: "newline", offset: -1, indent: indent2, source: "\n" });
188173
+ props.push({ type: "newline", offset: -1, indent: indent3, source: "\n" });
187935
188174
  for (const key2 of Object.keys(token))
187936
188175
  if (key2 !== "type" && key2 !== "offset")
187937
188176
  delete token[key2];
187938
- Object.assign(token, { type: "block-scalar", indent: indent2, props, source: body2 });
188177
+ Object.assign(token, { type: "block-scalar", indent: indent3, props, source: body2 });
187939
188178
  }
187940
188179
  }
187941
188180
  function addEndtoBlockProps(props, end) {
@@ -187980,12 +188219,12 @@ var require_cst_scalar = __commonJS({
187980
188219
  break;
187981
188220
  }
187982
188221
  default: {
187983
- const indent2 = "indent" in token ? token.indent : -1;
188222
+ const indent3 = "indent" in token ? token.indent : -1;
187984
188223
  const end = "end" in token && Array.isArray(token.end) ? token.end.filter((st) => st.type === "space" || st.type === "comment" || st.type === "newline") : [];
187985
188224
  for (const key2 of Object.keys(token))
187986
188225
  if (key2 !== "type" && key2 !== "offset")
187987
188226
  delete token[key2];
187988
- Object.assign(token, { type, indent: indent2, source, end });
188227
+ Object.assign(token, { type, indent: indent3, source, end });
187989
188228
  }
187990
188229
  }
187991
188230
  }
@@ -188291,15 +188530,15 @@ var require_lexer = __commonJS({
188291
188530
  continueScalar(offset) {
188292
188531
  let ch = this.buffer[offset];
188293
188532
  if (this.indentNext > 0) {
188294
- let indent2 = 0;
188533
+ let indent3 = 0;
188295
188534
  while (ch === " ")
188296
- ch = this.buffer[++indent2 + offset];
188535
+ ch = this.buffer[++indent3 + offset];
188297
188536
  if (ch === "\r") {
188298
- const next = this.buffer[indent2 + offset + 1];
188537
+ const next = this.buffer[indent3 + offset + 1];
188299
188538
  if (next === "\n" || !next && !this.atEnd)
188300
- return offset + indent2 + 1;
188539
+ return offset + indent3 + 1;
188301
188540
  }
188302
- return ch === "\n" || indent2 >= this.indentNext || !ch && !this.atEnd ? offset + indent2 : -1;
188541
+ return ch === "\n" || indent3 >= this.indentNext || !ch && !this.atEnd ? offset + indent3 : -1;
188303
188542
  }
188304
188543
  if (ch === "-" || ch === ".") {
188305
188544
  const dt = this.buffer.substr(offset, 3);
@@ -188468,12 +188707,12 @@ var require_lexer = __commonJS({
188468
188707
  }
188469
188708
  *parseFlowCollection() {
188470
188709
  let nl, sp;
188471
- let indent2 = -1;
188710
+ let indent3 = -1;
188472
188711
  do {
188473
188712
  nl = yield* this.pushNewline();
188474
188713
  if (nl > 0) {
188475
188714
  sp = yield* this.pushSpaces(false);
188476
- this.indentValue = indent2 = sp;
188715
+ this.indentValue = indent3 = sp;
188477
188716
  } else {
188478
188717
  sp = 0;
188479
188718
  }
@@ -188482,8 +188721,8 @@ var require_lexer = __commonJS({
188482
188721
  const line2 = this.getLine();
188483
188722
  if (line2 === null)
188484
188723
  return this.setNext("flow");
188485
- if (indent2 !== -1 && indent2 < this.indentNext && line2[0] !== "#" || indent2 === 0 && (line2.startsWith("---") || line2.startsWith("...")) && isEmpty(line2[3])) {
188486
- const atFlowEndMarker = indent2 === this.indentNext - 1 && this.flowLevel === 1 && (line2[0] === "]" || line2[0] === "}");
188724
+ if (indent3 !== -1 && indent3 < this.indentNext && line2[0] !== "#" || indent3 === 0 && (line2.startsWith("---") || line2.startsWith("...")) && isEmpty(line2[3])) {
188725
+ const atFlowEndMarker = indent3 === this.indentNext - 1 && this.flowLevel === 1 && (line2[0] === "]" || line2[0] === "}");
188487
188726
  if (!atFlowEndMarker) {
188488
188727
  this.flowLevel = 0;
188489
188728
  yield cst.FLOW_END;
@@ -188591,16 +188830,16 @@ var require_lexer = __commonJS({
188591
188830
  }
188592
188831
  *parseBlockScalar() {
188593
188832
  let nl = this.pos - 1;
188594
- let indent2 = 0;
188833
+ let indent3 = 0;
188595
188834
  let ch;
188596
188835
  loop: for (let i2 = this.pos; ch = this.buffer[i2]; ++i2) {
188597
188836
  switch (ch) {
188598
188837
  case " ":
188599
- indent2 += 1;
188838
+ indent3 += 1;
188600
188839
  break;
188601
188840
  case "\n":
188602
188841
  nl = i2;
188603
- indent2 = 0;
188842
+ indent3 = 0;
188604
188843
  break;
188605
188844
  case "\r": {
188606
188845
  const next = this.buffer[i2 + 1];
@@ -188616,9 +188855,9 @@ var require_lexer = __commonJS({
188616
188855
  }
188617
188856
  if (!ch && !this.atEnd)
188618
188857
  return this.setNext("block-scalar");
188619
- if (indent2 >= this.indentNext) {
188858
+ if (indent3 >= this.indentNext) {
188620
188859
  if (this.blockScalarIndent === -1)
188621
- this.indentNext = indent2;
188860
+ this.indentNext = indent3;
188622
188861
  else {
188623
188862
  this.indentNext = this.blockScalarIndent + (this.indentNext === 0 ? 1 : this.indentNext);
188624
188863
  }
@@ -188651,7 +188890,7 @@ var require_lexer = __commonJS({
188651
188890
  const lastChar = i2;
188652
188891
  while (ch2 === " ")
188653
188892
  ch2 = this.buffer[--i2];
188654
- if (ch2 === "\n" && i2 >= this.pos && i2 + 1 + indent2 > lastChar)
188893
+ if (ch2 === "\n" && i2 >= this.pos && i2 + 1 + indent3 > lastChar)
188655
188894
  nl = i2;
188656
188895
  else
188657
188896
  break;
@@ -189667,10 +189906,10 @@ var require_parser2 = __commonJS({
189667
189906
  }
189668
189907
  return null;
189669
189908
  }
189670
- atIndentedComment(start, indent2) {
189909
+ atIndentedComment(start, indent3) {
189671
189910
  if (this.type !== "comment")
189672
189911
  return false;
189673
- if (this.indent <= indent2)
189912
+ if (this.indent <= indent3)
189674
189913
  return false;
189675
189914
  return start.every((st) => st.type === "newline" || st.type === "space");
189676
189915
  }
@@ -189792,8 +190031,8 @@ var require_public_api = __commonJS({
189792
190031
  if (typeof options === "string")
189793
190032
  options = options.length;
189794
190033
  if (typeof options === "number") {
189795
- const indent2 = Math.round(options);
189796
- options = indent2 < 1 ? void 0 : indent2 > 8 ? { indent: 8 } : { indent: indent2 };
190034
+ const indent3 = Math.round(options);
190035
+ options = indent3 < 1 ? void 0 : indent3 > 8 ? { indent: 8 } : { indent: indent3 };
189797
190036
  }
189798
190037
  if (value2 === void 0) {
189799
190038
  const { keepUndefined } = options ?? replacer ?? {};
@@ -201129,8 +201368,8 @@ function failureSummary(kind, ctx) {
201129
201368
  case "auth":
201130
201369
  return `\u5BF9\u8BDD\u5931\u8D25\uFF1A\u8FD0\u884C\u65F6\u7684\u767B\u5F55\u5DF2\u8FC7\u671F\u6216\u51ED\u8BC1\u65E0\u6548\uFF0C\u8C03\u7528\u4E0D\u4E86\u6A21\u578B\u3002\u8BF7\u8282\u70B9\u7BA1\u7406\u5458\u5728\u90A3\u53F0\u673A\u5668\u4E0A\u91CD\u65B0\u767B\u5F55\u8FD9\u4E2A\u8FD0\u884C\u65F6\uFF08\u6216\u66F4\u65B0 API Key\uFF09\u540E\u518D\u53D1\u4E00\u6B21\uFF1B\u7740\u6025\u7684\u8BDD\u4E5F\u53EF\u4EE5${chatRebindHint("\u6362\u4E00\u4E2A\u53EF\u7528\u7684\u8FD0\u884C\u65F6")}\u3002`;
201131
201370
  case "quota": {
201132
- const at = resetTime(ctx.line);
201133
- return `\u5BF9\u8BDD\u5931\u8D25\uFF1A\u6A21\u578B\u989D\u5EA6\u5DF2\u7528\u5B8C${at ? `\uFF0C\u9884\u8BA1 ${at} \u6062\u590D` : ""}\u3002\u8BF7\u7B49\u989D\u5EA6\u6062\u590D\u540E\u518D\u53D1\u4E00\u6B21\uFF1B\u7740\u6025\u7684\u8BDD\u53EF\u4EE5${chatRebindHint("\u6362\u4E00\u4E2A\u989D\u5EA6\u5145\u8DB3\u7684\u8FD0\u884C\u65F6")}\u3002`;
201371
+ const at2 = resetTime(ctx.line);
201372
+ return `\u5BF9\u8BDD\u5931\u8D25\uFF1A\u6A21\u578B\u989D\u5EA6\u5DF2\u7528\u5B8C${at2 ? `\uFF0C\u9884\u8BA1 ${at2} \u6062\u590D` : ""}\u3002\u8BF7\u7B49\u989D\u5EA6\u6062\u590D\u540E\u518D\u53D1\u4E00\u6B21\uFF1B\u7740\u6025\u7684\u8BDD\u53EF\u4EE5${chatRebindHint("\u6362\u4E00\u4E2A\u989D\u5EA6\u5145\u8DB3\u7684\u8FD0\u884C\u65F6")}\u3002`;
201134
201373
  }
201135
201374
  case "rate-limit":
201136
201375
  return "\u5BF9\u8BDD\u5931\u8D25\uFF1A\u6A21\u578B\u670D\u52A1\u6682\u65F6\u9650\u6D41\u6216\u7E41\u5FD9\u3002\u8BF7\u7B49\u4E00\u4E24\u5206\u949F\u518D\u53D1\u4E00\u6B21\u3002";
@@ -202369,10 +202608,10 @@ var init_service3 = __esm({
202369
202608
  failureKind2 = exitReasonOf(err) === "timeout" ? "timeout" : "interrupted";
202370
202609
  error2 = err instanceof Error ? err.message : String(err);
202371
202610
  }
202372
- const at = this.now();
202611
+ const at2 = this.now();
202373
202612
  await turns?.settleTurn(turnId, {
202374
202613
  status: failureKind2 ? "failed" : "succeeded",
202375
- completedAt: at,
202614
+ completedAt: at2,
202376
202615
  ...error2 ? { lastError: error2 } : {}
202377
202616
  }).catch(() => void 0);
202378
202617
  const store = await this.options.resolveStore(companyId).catch(() => null);
@@ -202388,7 +202627,7 @@ var init_service3 = __esm({
202388
202627
  合成的那句话仍写进下面子会话的占位行(用户在子会话里要看到一句交代),
202389
202628
  通告里空正文由 `delegationReturnText` 渲染成「(这一轮没有文本产出)」。 */
202390
202629
  text: text7 || (failureKind2 && failureKind2 !== "timeout" ? roundFailureText(failureKind2, error2) : ""),
202391
- at,
202630
+ at: at2,
202392
202631
  // 本轮的键 = 派发这一轮时的 dispatchSeq(`record` 就是派发时那一份,轮次账本业务键也由它算)。
202393
202632
  dispatchSeq: record9.dispatchSeq ?? 0
202394
202633
  };
@@ -202399,7 +202638,7 @@ var init_service3 = __esm({
202399
202638
  await chatStore?.updateMessage(childRoundMessageIds(fresh.childSessionId, round).placeholderId, {
202400
202639
  content: text7 || (failureKind2 ? roundFailureText(failureKind2, error2) : ""),
202401
202640
  status: failureKind2 ? "error" : "done",
202402
- completedAt: at
202641
+ completedAt: at2
202403
202642
  }).catch(() => void 0);
202404
202643
  if (pending > 0 && !stopLoss) {
202405
202644
  await store.appendRoundSummary(fresh.id, newSummary, { consecutiveFails }).catch(() => null);
@@ -202415,7 +202654,7 @@ var init_service3 = __esm({
202415
202654
  state: failureKind2 ? "failed" : "done",
202416
202655
  failureKind: failureKind2 ?? null,
202417
202656
  settledSeq: settledSeqAtRound,
202418
- settledAt: at
202657
+ settledAt: at2
202419
202658
  }).catch(() => null);
202420
202659
  if (settled) await this.notifySettled(settled, companyId);
202421
202660
  }
@@ -202468,14 +202707,14 @@ var init_service3 = __esm({
202468
202707
  const dispatchSeq = _DelegationService.dispatchSeqOfTurn(record9, opts?.turnId);
202469
202708
  if (roundRecorded(record9.roundSummaries, dispatchSeq)) return record9;
202470
202709
  if (opts?.outcome === "succeeded") return this.settleSucceededFromSweep(record9, dispatchSeq, companyId);
202471
- const at = this.now();
202710
+ const at2 = this.now();
202472
202711
  const settledSeqAtRound = record9.settledSeq + 1;
202473
202712
  const timedOut = opts?.exitReason === "timeout";
202474
202713
  const partialAnswer = timedOut ? await this.readChildRoundAnswer(record9, dispatchSeq + 1, companyId).catch(() => "") : "";
202475
202714
  const newSummary = {
202476
202715
  round: (record9.roundSummaries[record9.roundSummaries.length - 1]?.round ?? 0) + 1,
202477
202716
  text: timedOut ? partialAnswer : `\u8FD9\u4E00\u8F6E\u88AB\u65F6\u949F\u95ED\u5408\uFF1A${reason}`,
202478
- at,
202717
+ at: at2,
202479
202718
  settledSeq: settledSeqAtRound,
202480
202719
  dispatchSeq
202481
202720
  };
@@ -202486,7 +202725,7 @@ var init_service3 = __esm({
202486
202725
  failureKind: timedOut ? "timeout" : "interrupted",
202487
202726
  consecutiveFails: record9.consecutiveFails + 1,
202488
202727
  settledSeq: settledSeqAtRound,
202489
- settledAt: at
202728
+ settledAt: at2
202490
202729
  }).catch(() => null);
202491
202730
  if (settled) await this.notifySettled(settled, companyId);
202492
202731
  return settled;
@@ -202529,13 +202768,13 @@ var init_service3 = __esm({
202529
202768
  const store = await this.options.resolveStore(companyId).catch(() => null);
202530
202769
  if (!store) return record9;
202531
202770
  const thisRound = dispatchSeq + 1;
202532
- const at = this.now();
202771
+ const at2 = this.now();
202533
202772
  const text7 = await this.readChildRoundAnswer(record9, thisRound, companyId);
202534
202773
  const settledSeqAtRound = record9.settledSeq + 1;
202535
202774
  const newSummary = {
202536
202775
  round: (record9.roundSummaries[record9.roundSummaries.length - 1]?.round ?? 0) + 1,
202537
202776
  text: text7 || "\u8FD9\u4E00\u8F6E\u5DF2\u5B8C\u6210\uFF08\u6536\u5C3E\u65F6\u6B63\u6587\u6CA1\u8BFB\u5230\uFF0C\u4EA7\u7269\u4EE5\u5DE5\u4F5C\u533A\u91CC\u7684\u6587\u4EF6\u4E3A\u51C6\uFF09\u3002",
202538
- at,
202777
+ at: at2,
202539
202778
  settledSeq: settledSeqAtRound,
202540
202779
  dispatchSeq
202541
202780
  };
@@ -202543,7 +202782,7 @@ var init_service3 = __esm({
202543
202782
  state: "done",
202544
202783
  consecutiveFails: 0,
202545
202784
  settledSeq: settledSeqAtRound,
202546
- settledAt: at
202785
+ settledAt: at2
202547
202786
  }).catch(() => null);
202548
202787
  if (settled) await this.notifySettled(settled, companyId);
202549
202788
  return settled;
@@ -203152,14 +203391,14 @@ var init_store2 = __esm({
203152
203391
  this.rows.set(id, next);
203153
203392
  return this.clone(next);
203154
203393
  }
203155
- async claimDispatch(id, at, opts) {
203394
+ async claimDispatch(id, at2, opts) {
203156
203395
  const current = this.rows.get(id);
203157
203396
  if (!current) return null;
203158
203397
  if (current.dispatchedAt) {
203159
203398
  const reclaimable = !!opts?.reclaimBefore && current.state === "running" && !current.childRunId && current.dispatchedAt < opts.reclaimBefore;
203160
203399
  if (!reclaimable) return null;
203161
203400
  }
203162
- const next = { ...this.clone(current), dispatchedAt: at };
203401
+ const next = { ...this.clone(current), dispatchedAt: at2 };
203163
203402
  this.rows.set(id, next);
203164
203403
  return this.clone(next);
203165
203404
  }
@@ -203175,11 +203414,11 @@ var init_store2 = __esm({
203175
203414
  async countPendingTouches(delegationId) {
203176
203415
  return (await this.listTouches(delegationId, { pendingOnly: true })).length;
203177
203416
  }
203178
- async markTouchesConsumed(delegationId, messageIds, at) {
203417
+ async markTouchesConsumed(delegationId, messageIds, at2) {
203179
203418
  for (const messageId of messageIds) {
203180
203419
  const key2 = touchKey(delegationId, messageId);
203181
203420
  const t = this.touches.get(key2);
203182
- if (t && !t.consumedAt) this.touches.set(key2, { ...t, consumedAt: at });
203421
+ if (t && !t.consumedAt) this.touches.set(key2, { ...t, consumedAt: at2 });
203183
203422
  }
203184
203423
  }
203185
203424
  /**
@@ -203259,8 +203498,8 @@ var init_store2 = __esm({
203259
203498
  if (r) this.save();
203260
203499
  return r;
203261
203500
  }
203262
- async claimDispatch(id, at, opts) {
203263
- const r = await super.claimDispatch(id, at, opts);
203501
+ async claimDispatch(id, at2, opts) {
203502
+ const r = await super.claimDispatch(id, at2, opts);
203264
203503
  if (r) this.save();
203265
203504
  return r;
203266
203505
  }
@@ -203269,8 +203508,8 @@ var init_store2 = __esm({
203269
203508
  if (r.inserted) this.save();
203270
203509
  return r;
203271
203510
  }
203272
- async markTouchesConsumed(delegationId, messageIds, at) {
203273
- await super.markTouchesConsumed(delegationId, messageIds, at);
203511
+ async markTouchesConsumed(delegationId, messageIds, at2) {
203512
+ await super.markTouchesConsumed(delegationId, messageIds, at2);
203274
203513
  this.save();
203275
203514
  }
203276
203515
  async appendRoundFiles(id, round, files) {
@@ -205744,8 +205983,8 @@ function retryAfterMs(response, now) {
205744
205983
  if (!raw) return void 0;
205745
205984
  const seconds = Number(raw);
205746
205985
  if (Number.isFinite(seconds) && seconds >= 0) return Math.ceil(seconds * 1e3);
205747
- const at = Date.parse(raw);
205748
- return Number.isFinite(at) ? Math.max(0, at - now) : void 0;
205986
+ const at2 = Date.parse(raw);
205987
+ return Number.isFinite(at2) ? Math.max(0, at2 - now) : void 0;
205749
205988
  }
205750
205989
  async function enqueueWrite(key2, intervalMs, now, sleep6, signal, operation) {
205751
205990
  const coordinator = writeCoordinators.get(key2) ?? { tail: Promise.resolve(), nextAvailableAt: 0 };
@@ -208459,6 +208698,24 @@ async function loadWorkorderSnapshot(kernel, workorderId) {
208459
208698
  if (!store) return null;
208460
208699
  return store.transaction((tx) => tx.loadWorkorder(workorderId));
208461
208700
  }
208701
+ async function escalationChatContextFor(kernel, registry2, session) {
208702
+ const escalationId = session?.escalationId?.trim();
208703
+ const workspace = session?.workspace?.trim();
208704
+ if (!escalationId || !workspace) return void 0;
208705
+ try {
208706
+ const snap = await loadWorkorderSnapshot(kernel, workspace);
208707
+ if (!snap) return void 0;
208708
+ const resolve11 = await draftActorResolver(registry2);
208709
+ const ref2 = (id) => {
208710
+ const extra = resolve11?.(id);
208711
+ return { id, ...extra?.name ? { name: extra.name } : {}, ...extra?.role ? { role: extra.role } : {} };
208712
+ };
208713
+ return buildEscalationChatContext({ snap, escalationId, ref: ref2 }) ?? void 0;
208714
+ } catch (err) {
208715
+ console.warn(`[escalation-context] \u4E0A\u62A5\u4E0A\u4E0B\u6587\u672A\u751F\u6210 escalation=${escalationId}: ${String(err)}`);
208716
+ return void 0;
208717
+ }
208718
+ }
208462
208719
  function wantsChatParts(req) {
208463
208720
  const accept = req.headers.accept;
208464
208721
  return typeof accept === "string" && accept.includes("application/x-ndjson");
@@ -209741,11 +209998,11 @@ async function runView(kernel, oplog, engineStore, blobs, name, artifactId, para
209741
209998
  if (w2.rejectedReason) rejectionByRevision.set(w2.id, w2.rejectedReason);
209742
209999
  }
209743
210000
  for (const a of snap?.artifacts ?? []) {
209744
- const at = a.contentEditedAt;
209745
- if (!at) continue;
210001
+ const at2 = a.contentEditedAt;
210002
+ if (!at2) continue;
209746
210003
  const workId = a.workId;
209747
210004
  const prev = contentEditedByRevision.get(workId);
209748
- if (!prev || at > prev) contentEditedByRevision.set(workId, at);
210005
+ if (!prev || at2 > prev) contentEditedByRevision.set(workId, at2);
209749
210006
  }
209750
210007
  }
209751
210008
  const revisionViews = revisions.map((rev) => ({
@@ -209920,7 +210177,7 @@ async function runView(kernel, oplog, engineStore, blobs, name, artifactId, para
209920
210177
  if (isEmptyContent(headRev.contentKind)) {
209921
210178
  return { kind: "empty" };
209922
210179
  }
209923
- const at = {
210180
+ const at2 = {
209924
210181
  artifactId: artifactId2,
209925
210182
  revisionId: targetId,
209926
210183
  isCurrentHead: targetId === artifact.currentRev,
@@ -209929,7 +210186,7 @@ async function runView(kernel, oplog, engineStore, blobs, name, artifactId, para
209929
210186
  author: headRev.author
209930
210187
  };
209931
210188
  if (headRev.contentKind === "external-pin") {
209932
- return { kind: "external-pin", ref: headRev.contentRef, at };
210189
+ return { kind: "external-pin", ref: headRev.contentRef, at: at2 };
209933
210190
  }
209934
210191
  const dec2 = new TextDecoder();
209935
210192
  if (headRev.contentKind === "manifest") {
@@ -209938,15 +210195,15 @@ async function runView(kernel, oplog, engineStore, blobs, name, artifactId, para
209938
210195
  const e = entries.find((x2) => x2.path === path44);
209939
210196
  if (!e) throw new Error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${path44}\uFF08\u8BE5\u7248\u672C\u6709\uFF1A${entries.map((x2) => x2.path).join("\u3001")}\uFF09`);
209940
210197
  const isText = !e.bytes.includes(0);
209941
- return { kind: "file", path: path44, bytes: e.bytes.length, text: isText ? dec2.decode(e.bytes) : null, at };
210198
+ return { kind: "file", path: path44, bytes: e.bytes.length, text: isText ? dec2.decode(e.bytes) : null, at: at2 };
209942
210199
  }
209943
210200
  return {
209944
210201
  kind: "manifest",
209945
210202
  files: entries.map((e) => ({ path: e.path, bytes: e.bytes.length, binary: e.bytes.includes(0) })),
209946
- at
210203
+ at: at2
209947
210204
  };
209948
210205
  }
209949
- return { kind: "text", text: dec2.decode(await blobs.get(headRev.contentRef)), at };
210206
+ return { kind: "text", text: dec2.decode(await blobs.get(headRev.contentRef)), at: at2 };
209950
210207
  }
209951
210208
  case "queue": {
209952
210209
  const id = need2();
@@ -210160,7 +210417,6 @@ async function startOasisServer(opts) {
210160
210417
  return { accepted: r.accepted, ...r.reason ? { reason: r.reason } : {}, queued: r.queued, insertStatus: r.insertStatus };
210161
210418
  };
210162
210419
  const GRAPH_EDIT_SUMMARY_MAX = 60;
210163
- const NEUTRAL_APPROVER = "\u8D1F\u8D23\u4EBA";
210164
210420
  const truncateSummary = (s2) => {
210165
210421
  const cps = [...s2];
210166
210422
  return cps.length > GRAPH_EDIT_SUMMARY_MAX ? `${cps.slice(0, GRAPH_EDIT_SUMMARY_MAX).join("")}\u2026` : s2;
@@ -211602,7 +211858,7 @@ async function startOasisServer(opts) {
211602
211858
  const receipt = authorizedCommandReceipt(command2, review.command.args, actor, commandCardRefsOf(engine.kernel.model));
211603
211859
  notifyReviewResolved(
211604
211860
  draftId,
211605
- { status: "approved", command: command2, effectLabel: review.command.effectLabel, authorizedBy: actor, receipt },
211861
+ { status: "approved", command: command2, effectLabel: review.command.effectLabel, authorizedBy: actor, ...authorizedByName ? { authorizedByName } : {}, receipt },
211606
211862
  {
211607
211863
  origin: review.origin,
211608
211864
  kind: "command",
@@ -211628,7 +211884,7 @@ async function startOasisServer(opts) {
211628
211884
  const result = await engine.kernel.applyIntervention(plan, fresh.baseSeqs, actor);
211629
211885
  notifyReviewResolved(
211630
211886
  draftId,
211631
- { status: "approved", command: "", effectLabel: review.plan.reason, authorizedBy: actor },
211887
+ { status: "approved", command: "", effectLabel: review.plan.reason, authorizedBy: actor, ...authorizedByName ? { authorizedByName } : {} },
211632
211888
  // 状态条要的两样也得进 resume 上下文(不能只放在 resolution 里):`effectLabel` 是改图卡的
211633
211889
  // 「改动摘要」(= plan.reason,见 diagnosis 口径 1),`authorizedBy` 是「谁批的」。
211634
211890
  { origin: review.origin, kind: review.kind ?? "graph-edit", authorizedBy: actor, ...authorizedByName ? { authorizedByName } : {}, effectLabel: review.plan.reason },
@@ -212200,6 +212456,29 @@ async function startOasisServer(opts) {
212200
212456
  const origin = url.searchParams.get("origin");
212201
212457
  const workspace = url.searchParams.get("workspace") ?? void 0;
212202
212458
  const reviews = listPendingReviews(engine.kernel.model, origin === null ? workspace : void 0).filter((r) => origin === null ? true : r.origin === origin).filter((r) => !r.continuation || r.continuation.approverActorId === actor);
212459
+ const draftActorIds = /* @__PURE__ */ new Set();
212460
+ for (const r of reviews) {
212461
+ for (const op of r.plan.ops ?? []) {
212462
+ const owner = op.owner;
212463
+ if (typeof owner === "string" && owner) draftActorIds.add(owner);
212464
+ }
212465
+ for (const pr of r.priorRejections ?? []) {
212466
+ if (pr.rejectedBy) draftActorIds.add(pr.rejectedBy);
212467
+ }
212468
+ }
212469
+ const draftActorNames = /* @__PURE__ */ new Map();
212470
+ if (draftActorIds.size > 0) {
212471
+ const reg = engine.registry ?? opts.registry;
212472
+ await Promise.all([...draftActorIds].map(async (id) => {
212473
+ const name = (await reg?.getActor(id).catch(() => null))?.name?.trim();
212474
+ if (name) draftActorNames.set(id, name);
212475
+ }));
212476
+ }
212477
+ const draftRefs = {
212478
+ ...commandCardRefsOf(engine.kernel.model),
212479
+ actorName: (id) => draftActorNames.get(id)
212480
+ };
212481
+ const displayOpsOf = (ops) => (ops ?? []).map((op) => graphEditOpDisplayLabel(op, draftRefs));
212203
212482
  const data2 = reviews.map((r) => ({
212204
212483
  id: r.draftId,
212205
212484
  plan: r.plan,
@@ -212219,8 +212498,17 @@ async function startOasisServer(opts) {
212219
212498
  ...r.kind !== void 0 ? { kind: r.kind } : {},
212220
212499
  ...r.command !== void 0 ? { command: r.command } : {},
212221
212500
  ...r.continuation ? { continuation: r.continuation } : {},
212501
+ // Bug 0238:改图卡列的那几行 op,按名字现拼给前端(`plan.ops` 原样保留给 agent 面)。
212502
+ displayOps: displayOpsOf(r.plan.ops),
212222
212503
  // ADR 0569 D4:显式重提的卡带着此前的驳回记录,前端在卡上列给审批人看。
212223
- ...r.priorRejections && r.priorRejections.length > 0 ? { priorRejections: r.priorRejections } : {}
212504
+ // 同样补名字:`rejectedByName` 是「谁驳的」,`displayOps` 是「当时的改动」那几行。
212505
+ ...r.priorRejections && r.priorRejections.length > 0 ? {
212506
+ priorRejections: r.priorRejections.map((pr) => ({
212507
+ ...pr,
212508
+ ...draftActorNames.get(pr.rejectedBy) ? { rejectedByName: draftActorNames.get(pr.rejectedBy) } : {},
212509
+ displayOps: displayOpsOf(pr.ops)
212510
+ }))
212511
+ } : {}
212224
212512
  }));
212225
212513
  res.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify({ data: data2 }));
212226
212514
  return;
@@ -212766,6 +213054,11 @@ async function startOasisServer(opts) {
212766
213054
  }
212767
213055
  heldTurn = opened.turn;
212768
213056
  }
213057
+ const escalationContext = await escalationChatContextFor(
213058
+ engine.kernel,
213059
+ engine.registry ?? opts.registry,
213060
+ persistTarget
213061
+ );
212769
213062
  let plan;
212770
213063
  try {
212771
213064
  plan = persistTarget && chatStore ? await planChatContinuation({
@@ -212774,7 +213067,8 @@ async function startOasisServer(opts) {
212774
213067
  listMessages: (sid, limit) => chatStore.listMessages(sid, limit),
212775
213068
  // ADR 0604:认**本轮真正会跑的那个**,不认员工 binding(见 effectiveChatTarget 那段)。
212776
213069
  currentRuntime: effectiveChatTarget,
212777
- ...draftWorkspace ? { draftWorkspace } : {}
213070
+ ...draftWorkspace ? { draftWorkspace } : {},
213071
+ ...escalationContext ? { escalationContext } : {}
212778
213072
  }) : null;
212779
213073
  } catch (err) {
212780
213074
  await heldTurn?.settle({
@@ -214557,13 +214851,13 @@ function chatSubmissionExistsMessage(state, retryable) {
214557
214851
  }
214558
214852
  function clampSubmittedAt(value2, notBefore) {
214559
214853
  if (typeof value2 !== "string") return void 0;
214560
- const at = Date.parse(value2);
214561
- if (!Number.isFinite(at)) return void 0;
214854
+ const at2 = Date.parse(value2);
214855
+ if (!Number.isFinite(at2)) return void 0;
214562
214856
  const now = Date.now();
214563
- if (at > now || now - at > 30 * 24 * 60 * 60 * 1e3) return void 0;
214857
+ if (at2 > now || now - at2 > 30 * 24 * 60 * 60 * 1e3) return void 0;
214564
214858
  const floor = notBefore ? Date.parse(notBefore) : NaN;
214565
- if (Number.isFinite(floor) && at < floor) return void 0;
214566
- return new Date(at).toISOString();
214859
+ if (Number.isFinite(floor) && at2 < floor) return void 0;
214860
+ return new Date(at2).toISOString();
214567
214861
  }
214568
214862
  async function legacySupersedes(items, sessionId, row) {
214569
214863
  if (!items || !row.turnId) return {};
@@ -214635,6 +214929,7 @@ var init_server3 = __esm({
214635
214929
  init_workorder_detail();
214636
214930
  init_workorders();
214637
214931
  init_discuss();
214932
+ init_escalation_chat_context();
214638
214933
  init_escalation_recipient();
214639
214934
  init_planner();
214640
214935
  init_chat_parts();
@@ -215791,13 +216086,13 @@ var init_memory_assistant_store = __esm({
215791
216086
  async backfillAllHumansOn(humanIds, byActor2) {
215792
216087
  let inserted = 0;
215793
216088
  let skipped = 0;
215794
- const at = (/* @__PURE__ */ new Date()).toISOString();
216089
+ const at2 = (/* @__PURE__ */ new Date()).toISOString();
215795
216090
  for (const id of humanIds) {
215796
216091
  if (this.prefs.has(id)) {
215797
216092
  skipped++;
215798
216093
  continue;
215799
216094
  }
215800
- this.prefs.set(id, { humanActorId: id, autoAssignAssistant: true, updatedAt: at, updatedBy: byActor2 });
216095
+ this.prefs.set(id, { humanActorId: id, autoAssignAssistant: true, updatedAt: at2, updatedBy: byActor2 });
215801
216096
  inserted++;
215802
216097
  }
215803
216098
  return { inserted, skipped };
@@ -215902,7 +216197,9 @@ function systemHandoffFor(run, checkpoint = null, effects2 = []) {
215902
216197
  // 与 PG 触发器同口径(2026-08-18):risks / verificationGaps 只装业务语义的东西。会话怎么死的
215903
216198
  // 已在 summary 的 reason= 段里,不再冒充成「交付物的风险」;「没有断点」也不是「验证缺口」。
215904
216199
  risks: pendingEffects || failedEffects ? [`external effects: pending=${pendingEffects}, failed=${failedEffects}`] : [],
215905
- nextActions: structuredClone(checkpoint?.pendingSteps ?? []),
216200
+ // 与 PG 触发器同口径(2026-09-23):nextActions 是「下游怎么用这份成果」,不拿 pendingSteps
216201
+ //(执行人自己没做完的活)兜底——兜底会让下游交接出现 `[next] 提交并结案` 这种假的「上游建议」。
216202
+ nextActions: [],
215906
216203
  verificationGaps: [],
215907
216204
  userHandoff: null,
215908
216205
  createdAt: run.endedAt ?? run.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
@@ -216133,10 +216430,10 @@ var init_memory_trace_store = __esm({
216133
216430
  }
216134
216431
  /* ---------- 用量账本(与 PostgresTraceStore 同语义)---------- */
216135
216432
  /** 先写者生效;run 不存在返回 false。与 PG 一样不动 updatedAt。 */
216136
- async markRuntimeStarted(runId, at) {
216433
+ async markRuntimeStarted(runId, at2) {
216137
216434
  const run = this.runs.get(runId);
216138
216435
  if (!run || run.runtimeStartedAt != null) return false;
216139
- this.runs.set(runId, { ...run, runtimeStartedAt: at });
216436
+ this.runs.set(runId, { ...run, runtimeStartedAt: at2 });
216140
216437
  return true;
216141
216438
  }
216142
216439
  /** checkpoint 重放吸收;final 覆盖终值位;backfill 不覆盖已有终值点。 */
@@ -216942,8 +217239,8 @@ var init_memory_automation_store = __esm({
216942
217239
  this.automations.set(id, structuredClone(merged));
216943
217240
  return structuredClone(merged);
216944
217241
  }
216945
- async archiveAutomation(id, at) {
216946
- return this.updateAutomation(id, { archivedAt: at });
217242
+ async archiveAutomation(id, at2) {
217243
+ return this.updateAutomation(id, { archivedAt: at2 });
216947
217244
  }
216948
217245
  async pauseIfEnabled(id, reason) {
216949
217246
  const a = this.automations.get(id);
@@ -217532,20 +217829,20 @@ var init_memory_control_plane_store = __esm({
217532
217829
  async listAgentCredentials(companyId) {
217533
217830
  return [...this.agentCredentials.values()].filter((c) => c.companyId === companyId).map((c) => ({ ...c })).sort((a, b2) => a.actorId < b2.actorId ? -1 : a.actorId > b2.actorId ? 1 : 0);
217534
217831
  }
217535
- async revokeAgentCredential(companyId, actorId, at) {
217832
+ async revokeAgentCredential(companyId, actorId, at2) {
217536
217833
  const key2 = scopedKey(companyId, actorId);
217537
217834
  const c = this.agentCredentials.get(key2);
217538
217835
  if (!c) return false;
217539
- this.agentCredentials.set(key2, { ...c, status: "revoked", revokedAt: at });
217836
+ this.agentCredentials.set(key2, { ...c, status: "revoked", revokedAt: at2 });
217540
217837
  return true;
217541
217838
  }
217542
- async touchAgentCredential(tokenHash, at) {
217839
+ async touchAgentCredential(tokenHash, at2) {
217543
217840
  const ref2 = this.credentialsByHash.get(tokenHash);
217544
217841
  if (!ref2) return;
217545
217842
  const key2 = scopedKey(ref2.companyId, ref2.actorId);
217546
217843
  const c = this.agentCredentials.get(key2);
217547
217844
  if (!c || c.tokenHash !== tokenHash) return;
217548
- this.agentCredentials.set(key2, { ...c, lastUsedAt: at });
217845
+ this.agentCredentials.set(key2, { ...c, lastUsedAt: at2 });
217549
217846
  }
217550
217847
  // —— principal_bridge ——
217551
217848
  async putPrincipalBridge(row) {
@@ -217582,7 +217879,7 @@ var init_memory_control_plane_store = __esm({
217582
217879
  }
217583
217880
  return null;
217584
217881
  }
217585
- async updateMemberOffboardingIfVersion(companyId, operationId, expectedVersion, patch, at) {
217882
+ async updateMemberOffboardingIfVersion(companyId, operationId, expectedVersion, patch, at2) {
217586
217883
  const key2 = scopedKey(companyId, operationId);
217587
217884
  const cur = this.offboardings.get(key2);
217588
217885
  if (!cur) return { ok: false, reason: "not_found" };
@@ -217595,7 +217892,7 @@ var init_memory_control_plane_store = __esm({
217595
217892
  ...patch.ownedAgents !== void 0 ? { ownedAgents: [...patch.ownedAgents] } : {},
217596
217893
  ...patch.inFlightAssignments !== void 0 ? { inFlightAssignments: patch.inFlightAssignments.map((a) => ({ ...a })) } : {},
217597
217894
  version: cur.version + 1,
217598
- updatedAt: at
217895
+ updatedAt: at2
217599
217896
  };
217600
217897
  if (patch.error === null) delete next.error;
217601
217898
  else if (patch.error !== void 0) next.error = patch.error;
@@ -221098,8 +221395,8 @@ var init_dev_store = __esm({
221098
221395
  setState(chatSessionId, ids2, state, reason) {
221099
221396
  const list2 = this.pending.get(chatSessionId);
221100
221397
  if (!list2) return;
221101
- const at = (/* @__PURE__ */ new Date()).toISOString();
221102
- this.pending.set(chatSessionId, list2.map((x2) => ids2.has(x2.id) ? { ...x2, state, stateAt: at, ...reason ? { stateReason: reason } : {} } : x2));
221398
+ const at2 = (/* @__PURE__ */ new Date()).toISOString();
221399
+ this.pending.set(chatSessionId, list2.map((x2) => ids2.has(x2.id) ? { ...x2, state, stateAt: at2, ...reason ? { stateReason: reason } : {} } : x2));
221103
221400
  }
221104
221401
  /** 撤回 = 迁到 cancelled。**不硬删**——删了轨迹就断了。 */
221105
221402
  async removePendingMessage(chatSessionId, id) {
@@ -221154,12 +221451,12 @@ var init_dev_store = __esm({
221154
221451
  return true;
221155
221452
  }).sort((a, b2) => a.seq - b2.seq);
221156
221453
  const claimedIds = new Set(claimed.map((x2) => x2.id));
221157
- const at = (/* @__PURE__ */ new Date()).toISOString();
221454
+ const at2 = (/* @__PURE__ */ new Date()).toISOString();
221158
221455
  const list2 = this.pending.get(chatSessionId);
221159
221456
  if (list2) {
221160
- this.pending.set(chatSessionId, list2.map((x2) => claimedIds.has(x2.id) ? { ...x2, state: "delivering", stateAt: at, stateReason: x2.stateReason === "register-pending" ? "register-pending" : owner } : x2));
221457
+ this.pending.set(chatSessionId, list2.map((x2) => claimedIds.has(x2.id) ? { ...x2, state: "delivering", stateAt: at2, stateReason: x2.stateReason === "register-pending" ? "register-pending" : owner } : x2));
221161
221458
  }
221162
- return claimed.map((x2) => ({ ...x2, state: "delivering", stateAt: at, stateReason: x2.stateReason === "register-pending" ? "register-pending" : owner }));
221459
+ return claimed.map((x2) => ({ ...x2, state: "delivering", stateAt: at2, stateReason: x2.stateReason === "register-pending" ? "register-pending" : owner }));
221163
221460
  }
221164
221461
  /**
221165
221462
  * 列出这条 source 已在队列责任范围内的 `sourceMessageId`(评审阻断③;Rework r4 并入 delivered)。
@@ -221318,9 +221615,9 @@ var init_dev_store = __esm({
221318
221615
  return out;
221319
221616
  }
221320
221617
  /** 单调:第一次投递成功那一刻才是事实,重复调用不把时间往后推(同 PG 版的 `IS NULL` 闸)。 */
221321
- async markMessageDeliveredToAgent(messageId, at) {
221618
+ async markMessageDeliveredToAgent(messageId, at2) {
221322
221619
  const hit = this.findById(messageId);
221323
- if (hit && !hit.deliveredToAgentAt) hit.deliveredToAgentAt = at ?? (/* @__PURE__ */ new Date()).toISOString();
221620
+ if (hit && !hit.deliveredToAgentAt) hit.deliveredToAgentAt = at2 ?? (/* @__PURE__ */ new Date()).toISOString();
221324
221621
  }
221325
221622
  /** 与 PG 版同口径:**公司过滤排在分页之前**(先分页再筛公司会让本公司读到空,积压查询假绿)。 */
221326
221623
  pendingRows(opts) {
@@ -221568,8 +221865,8 @@ var init_dev_store = __esm({
221568
221865
  }
221569
221866
  // 送达标记也要落盘:它是「还没送到 agent」这条待补投队列的唯一事实来源,
221570
221867
  // 只活在内存里的话 serve 一重启就会把已经送到的又送一遍。
221571
- async markMessageDeliveredToAgent(messageId, at) {
221572
- await super.markMessageDeliveredToAgent(messageId, at);
221868
+ async markMessageDeliveredToAgent(messageId, at2) {
221869
+ await super.markMessageDeliveredToAgent(messageId, at2);
221573
221870
  this.save();
221574
221871
  }
221575
221872
  save() {
@@ -222241,7 +222538,7 @@ var init_company_scoped_registry = __esm({
222241
222538
  throw new Error(`actor ${a.id} \u5DF2\u5C5E\u4E8E\u516C\u53F8 ${existing.companyId}\uFF0C\u4E0D\u80FD\u5728 ${this.companyId} \u4E0B\u91CD\u590D\u767B\u8BB0`);
222242
222539
  }
222243
222540
  await this.base.upsertActor(a);
222244
- const at = this.now();
222541
+ const at2 = this.now();
222245
222542
  const prev = existing?.employee;
222246
222543
  await this.org.upsertDigitalEmployee({
222247
222544
  id: a.id,
@@ -222259,15 +222556,15 @@ var init_company_scoped_registry = __esm({
222259
222556
  ...prev?.model !== void 0 ? { model: prev.model } : {},
222260
222557
  config: prev?.config ?? {},
222261
222558
  status: employeeStatusOf(a.status),
222262
- createdAt: prev?.createdAt ?? a.createdAt ?? at,
222263
- updatedAt: at
222559
+ createdAt: prev?.createdAt ?? a.createdAt ?? at2,
222560
+ updatedAt: at2
222264
222561
  });
222265
222562
  await this.org.putPrincipalBridge({
222266
222563
  companyId: this.companyId,
222267
222564
  principalType: "agent",
222268
222565
  principalId: a.id,
222269
222566
  agentId: a.id,
222270
- createdAt: at
222567
+ createdAt: at2
222271
222568
  });
222272
222569
  return;
222273
222570
  }
@@ -222971,7 +223268,7 @@ async function backfillOrgModel(control, registry2, opts = {}) {
222971
223268
  continue;
222972
223269
  }
222973
223270
  if (opts.companyId && decided !== opts.companyId) continue;
222974
- const at = now();
223271
+ const at2 = now();
222975
223272
  if (!dryRun) {
222976
223273
  await control.upsertDigitalEmployee({
222977
223274
  id: a.id,
@@ -222988,10 +223285,10 @@ async function backfillOrgModel(control, registry2, opts = {}) {
222988
223285
  tags: a.tags ?? [],
222989
223286
  config: {},
222990
223287
  status: a.status === "disabled" ? "left" : "active",
222991
- createdAt: a.createdAt ?? at,
222992
- updatedAt: at
223288
+ createdAt: a.createdAt ?? at2,
223289
+ updatedAt: at2
222993
223290
  });
222994
- await control.putPrincipalBridge({ companyId: decided, principalType: "agent", principalId: a.id, agentId: a.id, createdAt: at });
223291
+ await control.putPrincipalBridge({ companyId: decided, principalType: "agent", principalId: a.id, agentId: a.id, createdAt: at2 });
222995
223292
  }
222996
223293
  employees += 1;
222997
223294
  bridges += 1;
@@ -223704,16 +224001,16 @@ function createLivenessProbe(store) {
223704
224001
  const cur = cursors.get(sessionId);
223705
224002
  const events = await store.listEvents(sessionId, cur ? { afterSeq: cur.seq, limit: 500 } : {});
223706
224003
  let seq = cur?.seq ?? 0;
223707
- let at = cur?.at ?? null;
224004
+ let at2 = cur?.at ?? null;
223708
224005
  for (const e of events) {
223709
224006
  if (e.seq > seq) {
223710
224007
  seq = e.seq;
223711
- at = e.createdAt;
224008
+ at2 = e.createdAt;
223712
224009
  }
223713
224010
  }
223714
- if (events.length) cursors.set(sessionId, { seq, at });
224011
+ if (events.length) cursors.set(sessionId, { seq, at: at2 });
223715
224012
  const run = await store.getRun(sessionId);
223716
- const lastEventAt = maxIso2(at, run?.lastProgressAt ?? null);
224013
+ const lastEventAt = maxIso2(at2, run?.lastProgressAt ?? null);
223717
224014
  const toolCalls = await store.listToolCalls(sessionId);
223718
224015
  return { lastEventAt, openToolCall: toolCalls.some((t) => t.status === "running") };
223719
224016
  },
@@ -224252,11 +224549,11 @@ function createApiActivityLedger() {
224252
224549
  },
224253
224550
  activeDispatchIds(nowMs, windowMs) {
224254
224551
  const out = /* @__PURE__ */ new Set();
224255
- for (const [id, at] of lastSeen) if (nowMs - at <= windowMs) out.add(id);
224552
+ for (const [id, at2] of lastSeen) if (nowMs - at2 <= windowMs) out.add(id);
224256
224553
  return out;
224257
224554
  },
224258
224555
  prune(nowMs, keepMs) {
224259
- for (const [id, at] of lastSeen) if (nowMs - at > keepMs) lastSeen.delete(id);
224556
+ for (const [id, at2] of lastSeen) if (nowMs - at2 > keepMs) lastSeen.delete(id);
224260
224557
  },
224261
224558
  size: () => lastSeen.size
224262
224559
  };
@@ -224555,9 +224852,15 @@ function createUsageLedgerResolver(deps) {
224555
224852
  return chatCid ? { runId: stable, store: await deps.storeFor(chatCid) } : null;
224556
224853
  };
224557
224854
  }
224855
+ function hasModelName(model) {
224856
+ return typeof model === "string" && model.trim().length > 0;
224857
+ }
224858
+ function frameTokenTotal(usage) {
224859
+ return (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0) + (usage.cacheReadTokens ?? 0) + (usage.cacheCreationTokens ?? 0);
224860
+ }
224558
224861
  async function backfillRunModel(target, run, model, warn) {
224559
- if (!model || model.trim().length === 0) return;
224560
- if (run.effectiveModel && run.effectiveModel.trim().length > 0) return;
224862
+ if (!hasModelName(model)) return;
224863
+ if (hasModelName(run.effectiveModel)) return;
224561
224864
  try {
224562
224865
  await target.store.updateRun(target.runId, { effectiveModel: model, modelSource: "runtime" });
224563
224866
  } catch (err) {
@@ -224574,6 +224877,13 @@ function createUsageLedgerFrameHandler(deps) {
224574
224877
  settledDispatch.add(dispatchId);
224575
224878
  if (settledDispatch.size > 1e4) settledDispatch.delete(settledDispatch.values().next().value);
224576
224879
  };
224880
+ const modelless = /* @__PURE__ */ new Set();
224881
+ const notedModelless = (runId) => {
224882
+ if (modelless.has(runId)) return true;
224883
+ modelless.add(runId);
224884
+ if (modelless.size > 1e4) modelless.delete(modelless.values().next().value);
224885
+ return false;
224886
+ };
224577
224887
  return async (msg) => {
224578
224888
  if (!RUNTIME_START_FRAME_TYPES.has(msg.type)) return;
224579
224889
  const dispatchId = msg.dispatchId;
@@ -224616,6 +224926,12 @@ function createUsageLedgerFrameHandler(deps) {
224616
224926
  warn(`[usage-ledger] session_usage dispatch=${dispatchId} usageSeq=${String(msg.usageSeq)} \u975E\u6CD5\uFF0C\u4E22\u5F03`);
224617
224927
  return;
224618
224928
  }
224929
+ if (!hasModelName(msg.model) && !hasModelName(run.effectiveModel)) {
224930
+ const tokens2 = frameTokenTotal(msg.usage);
224931
+ if (tokens2 > 0 && !notedModelless(target.runId)) {
224932
+ warn(`[usage-ledger] session_usage dispatch=${dispatchId} \u2192 run ${target.runId} \u5E26\u7740 ${tokens2} \u4E2A token \u5374\u6CA1\u6709\u6A21\u578B\u540D\uFF08run \u884C\u4E5F\u662F\u7A7A\u7684\uFF09\uFF0C\u8FD9\u6BB5\u7528\u91CF\u53EA\u80FD\u5F52\u8FDB\u300C\u672A\u77E5\u6A21\u578B\u300D`);
224933
+ }
224934
+ }
224619
224935
  await target.store.recordUsagePoint({
224620
224936
  runId: target.runId,
224621
224937
  seq: msg.usageSeq,
@@ -224663,7 +224979,7 @@ var init_usage_ledger = __esm({
224663
224979
  * 标记 run 的 runtime 启动时刻(先写者生效)。同一 run 并发的多帧合并成一次写。永不 reject。
224664
224980
  * `store` 用回调给:解析公司账本本身可能要读库,已标过的 run 就不该再付这一次解析。
224665
224981
  */
224666
- mark(runId, at, store) {
224982
+ mark(runId, at2, store) {
224667
224983
  if (this.settled.has(runId)) return Promise.resolve();
224668
224984
  const running = this.inflight.get(runId);
224669
224985
  if (running) return running;
@@ -224674,7 +224990,7 @@ var init_usage_ledger = __esm({
224674
224990
  this.remember(runId);
224675
224991
  return;
224676
224992
  }
224677
- const wrote = await s2.markRuntimeStarted(runId, at);
224993
+ const wrote = await s2.markRuntimeStarted(runId, at2);
224678
224994
  if (wrote) {
224679
224995
  this.remember(runId);
224680
224996
  return;
@@ -233480,9 +233796,9 @@ function buildGapThread(input) {
233480
233796
  const group = gapThreadGroups(input).find((g2) => g2.executorId === executorId);
233481
233797
  if (!group) return null;
233482
233798
  const { ref: ref2 } = input;
233483
- const nameOf = (id) => ref2(id).name?.trim() || "\u2014";
233484
- const executorName = nameOf(group.executorId);
233485
- const coordinatorName = nameOf(group.coordinatorId);
233799
+ const nameOf2 = (id) => ref2(id).name?.trim() || "\u2014";
233800
+ const executorName = nameOf2(group.executorId);
233801
+ const coordinatorName = nameOf2(group.coordinatorId);
233486
233802
  const mention = (author) => author === group.executorId ? coordinatorName : executorName;
233487
233803
  const bubble = (o) => ({
233488
233804
  id: o.id,
@@ -233542,8 +233858,8 @@ function buildCommentThread(input) {
233542
233858
  const repliesOf = /* @__PURE__ */ new Map();
233543
233859
  for (const r of repliesAll) repliesOf.set(r.issueId, [...repliesOf.get(r.issueId) ?? [], r]);
233544
233860
  const { ref: ref2 } = input;
233545
- const nameOf = (id) => ref2(id).name?.trim() || "\u2014";
233546
- const mention = (author) => nameOf(author === a ? b2 : a);
233861
+ const nameOf2 = (id) => ref2(id).name?.trim() || "\u2014";
233862
+ const mention = (author) => nameOf2(author === a ? b2 : a);
233547
233863
  const bubble = (o) => ({
233548
233864
  id: o.id,
233549
233865
  at: o.at,
@@ -233595,8 +233911,8 @@ function buildReviewThread(input) {
233595
233911
  });
233596
233912
  if (rows.length === 0) return null;
233597
233913
  const { ref: ref2 } = input;
233598
- const nameOf = (id) => ref2(id).name?.trim() || "\u2014";
233599
- const mention = (author) => nameOf(author === a ? b2 : a);
233914
+ const nameOf2 = (id) => ref2(id).name?.trim() || "\u2014";
233915
+ const mention = (author) => nameOf2(author === a ? b2 : a);
233600
233916
  const bubble = (o) => ({
233601
233917
  id: o.id,
233602
233918
  at: o.at,
@@ -233851,11 +234167,6 @@ function coordinatorRunOfGap(gap, runs) {
233851
234167
  const overlapping = runs.filter((r) => (!closesAt || r.startedAt <= closesAt) && (!r.endedAt || r.endedAt >= opensAt)).sort((a, b2) => a.startedAt.localeCompare(b2.startedAt) || a.id.localeCompare(b2.id));
233852
234168
  return overlapping.find((r) => r.startedAt >= opensAt) ?? overlapping.at(-1);
233853
234169
  }
233854
- function escalationKindOf(issueId, authorActorId) {
233855
- if (issueId.startsWith(RETRY_EXHAUSTED_ESC_PREFIX)) return "retry_exhausted";
233856
- if (issueId.startsWith(REVIEW_EXHAUSTED_ESC_PREFIX2)) return "review_exhausted";
233857
- return isSystemActorId(authorActorId) ? "output_stall" : "manual";
233858
- }
233859
234170
  function parseStopLossFacts(kind, body2) {
233860
234171
  if (kind === "retry_exhausted") {
233861
234172
  const n2 = /连续\s*(\d+)\s*次执行失败/.exec(body2)?.[1];
@@ -233928,8 +234239,8 @@ function buildWorkorderActivity(input) {
233928
234239
  const isSystemAccept = (by) => !!by && by.startsWith("actor:system:");
233929
234240
  const managerId = resolveWorkorderManager(snap);
233930
234241
  const ownerId = snap.workorder.ownerActorId;
233931
- const nameOf = (id) => id ? ref2(id).name ?? id : "\u2014";
233932
- const managerName = () => nameOf(managerId);
234242
+ const nameOf2 = (id) => id ? ref2(id).name ?? id : "\u2014";
234243
+ const managerName = () => nameOf2(managerId);
233933
234244
  const nodeName = (nodeId) => {
233934
234245
  if (!nodeId) return "\u2014";
233935
234246
  const t = nodeById.get(nodeId)?.title;
@@ -234161,7 +234472,7 @@ function buildWorkorderActivity(input) {
234161
234472
  fold2.updatedAt = lastStampOf(w2);
234162
234473
  fold2.stuckReason = w2.outcomeDetail?.reason === "timeout" ? "timeout" : "failed";
234163
234474
  fold2.foldedRounds = (fold2.foldedRounds ?? 1) + 1;
234164
- fold2.status = ACTIVITY_COPY.foldedFailures(nameOf(fold2.executorId), name, fold2.foldedRounds);
234475
+ fold2.status = ACTIVITY_COPY.foldedFailures(nameOf2(fold2.executorId), name, fold2.foldedRounds);
234165
234476
  if (tripsHere.length) fold2.stopLossTrips = [...fold2.stopLossTrips ?? [], ...tripsHere];
234166
234477
  continue;
234167
234478
  }
@@ -234209,7 +234520,7 @@ function buildWorkorderActivity(input) {
234209
234520
  } else {
234210
234521
  const finalReviewers = node2?.isFinalOutput ? expectedReviewers(nodeId) : [];
234211
234522
  if (node2?.isFinalOutput && finalReviewers.length > 0) {
234212
- card2.status = ACTIVITY_COPY.finalDelivered(nameOf(finalReviewers[0]));
234523
+ card2.status = ACTIVITY_COPY.finalDelivered(nameOf2(finalReviewers[0]));
234213
234524
  } else {
234214
234525
  const awaits = snap.reviews.some((r) => r.targetWorkId === w2.id) || nodesWithRequirement.has(nodeId);
234215
234526
  card2.status = awaits ? ACTIVITY_COPY.doneAwaitingReview(name) : ACTIVITY_COPY.done(name);
@@ -234218,20 +234529,20 @@ function buildWorkorderActivity(input) {
234218
234529
  } else if (interrupt) {
234219
234530
  card2.phase = "stuck";
234220
234531
  card2.segmentOpen = false;
234221
- card2.status = interrupt.kind === "gap" ? ACTIVITY_COPY.interruptedByGap(name, nameOf(managerId ?? ownerId)) : ACTIVITY_COPY.interruptedByIssue(name);
234532
+ card2.status = interrupt.kind === "gap" ? ACTIVITY_COPY.interruptedByGap(name, nameOf2(managerId ?? ownerId)) : ACTIVITY_COPY.interruptedByIssue(name);
234222
234533
  if (interrupt.kind === "gap" && interrupt.authorId) {
234223
- card2.actions = [{ kind: "open_thread", label: BUTTON.view, target: gapThreadSessionId(interrupt.authorId) }];
234534
+ card2.actions = [{ kind: "open_thread", label: BUTTON.view, target: gapThreadSessionId(interrupt.authorId), variant: "quiet" }];
234224
234535
  }
234225
234536
  if (interrupt.at > card2.updatedAt) card2.updatedAt = interrupt.at;
234226
234537
  } else if (supersededBy) {
234227
234538
  card2.phase = "stuck";
234228
234539
  card2.segmentOpen = false;
234229
234540
  const editor = openerOfWork.get(supersededBy.workId);
234230
- card2.status = rootBriefNodeIds.has(supersededBy.upstreamNodeId) && editor && !isSystemActorId(editor) ? ACTIVITY_COPY.interruptedBySpecChange(nameOf(editor), name) : ACTIVITY_COPY.interruptedByUpstreamVersion(nodeName(supersededBy.upstreamNodeId), name);
234541
+ card2.status = rootBriefNodeIds.has(supersededBy.upstreamNodeId) && editor && !isSystemActorId(editor) ? ACTIVITY_COPY.interruptedBySpecChange(nameOf2(editor), name) : ACTIVITY_COPY.interruptedByUpstreamVersion(nodeName(supersededBy.upstreamNodeId), name);
234231
234542
  } else if (removedHere || killedByPlan) {
234232
234543
  card2.phase = "stuck";
234233
234544
  card2.segmentOpen = false;
234234
- card2.status = removedHere ? ACTIVITY_COPY.interruptedByNodeRemoved(name) : reassigned ? ACTIVITY_COPY.interruptedByReassign(name, nameOf(next.assigneeActorId)) : ACTIVITY_COPY.interruptedByPlanChange(name);
234545
+ card2.status = removedHere ? ACTIVITY_COPY.interruptedByNodeRemoved(name) : reassigned ? ACTIVITY_COPY.interruptedByReassign(name, nameOf2(next.assigneeActorId)) : ACTIVITY_COPY.interruptedByPlanChange(name);
234235
234546
  if (!removedHere && !reassigned) card2.planChangeUnnamed = true;
234236
234547
  if (removedHere && nodeCancelledAt > card2.updatedAt) card2.updatedAt = nodeCancelledAt;
234237
234548
  } else if (failedRound) {
@@ -234242,13 +234553,11 @@ function buildWorkorderActivity(input) {
234242
234553
  card2.stuckReason = stuckKind;
234243
234554
  const killedAt = w2.deadAt ?? w2.cancelledAt;
234244
234555
  if (killedAt) delete card2.phaseLabel;
234245
- card2.status = killedAt ? killedByWorkorderPause(w2, killedAt) ? ACTIVITY_COPY.killedByWorkorderPause(name) : ACTIVITY_COPY.killed(name) : st === "retry" ? ACTIVITY_COPY.awaitingRedispatch(nameOf(card2.executorId), name) : stuckKind === "timeout" ? ACTIVITY_COPY.timedOut(nameOf(card2.executorId)) : noOutputRound(w2) ? ACTIVITY_COPY.endedWithoutOutput(nameOf(card2.executorId), name) : ACTIVITY_COPY.failed(nameOf(card2.executorId));
234556
+ card2.status = killedAt ? killedByWorkorderPause(w2, killedAt) ? ACTIVITY_COPY.killedByWorkorderPause(name) : ACTIVITY_COPY.killed(name) : st === "retry" ? ACTIVITY_COPY.awaitingRedispatch(nameOf2(card2.executorId), name) : stuckKind === "timeout" ? ACTIVITY_COPY.timedOut(nameOf2(card2.executorId)) : noOutputRound(w2) ? ACTIVITY_COPY.endedWithoutOutput(nameOf2(card2.executorId), name) : ACTIVITY_COPY.failed(nameOf2(card2.executorId));
234246
234557
  fold2 = foldableFailure ? card2 : null;
234247
234558
  } else if (ackedRound) {
234248
234559
  card2.phase = "done";
234249
234560
  card2.status = ACTIVITY_COPY.upstreamAcked(name);
234250
- const note = w2.upstreamAck.note;
234251
- card2.detail = note.length > UPSTREAM_ACK_NOTE_CAP ? `${note.slice(0, UPSTREAM_ACK_NOTE_CAP)}\u2026` : note;
234252
234561
  } else if (held) {
234253
234562
  card2.phase = "stuck";
234254
234563
  card2.segmentOpen = false;
@@ -234283,12 +234592,12 @@ function buildWorkorderActivity(input) {
234283
234592
  if (rec2.handActorId) d.handActorId = rec2.handActorId;
234284
234593
  return d;
234285
234594
  };
234286
- const cardOpenAt = (nodeId, at) => {
234595
+ const cardOpenAt = (nodeId, at2) => {
234287
234596
  const list2 = worksOfNode.get(nodeId);
234288
234597
  if (!list2) return void 0;
234289
234598
  let hit;
234290
234599
  for (const w2 of list2) {
234291
- if (w2.createdAt > at) break;
234600
+ if (w2.createdAt > at2) break;
234292
234601
  hit = w2;
234293
234602
  }
234294
234603
  return hit ? cardOfWork.get(hit.id) : void 0;
@@ -234322,7 +234631,7 @@ function buildWorkorderActivity(input) {
234322
234631
  d.phase = "done";
234323
234632
  d.actions = [];
234324
234633
  d.executorId = subjectId;
234325
- d.status = addressed ? ACTIVITY_COPY.commentAddressed(nameOf(subjectId), nameOf(authorId), nodeName(d.nodeId)) : ACTIVITY_COPY.commentResolved(nameOf(subjectId), nodeName(d.nodeId));
234634
+ d.status = addressed ? ACTIVITY_COPY.commentAddressed(nameOf2(subjectId), nameOf2(authorId), nodeName(d.nodeId)) : ACTIVITY_COPY.commentResolved(nameOf2(subjectId), nodeName(d.nodeId));
234326
234635
  };
234327
234636
  for (const rec2 of events) {
234328
234637
  const ev = rec2.event;
@@ -234338,26 +234647,26 @@ function buildWorkorderActivity(input) {
234338
234647
  没有所指(暂停不是完成)。 */
234339
234648
  case "workorder.paused": {
234340
234649
  const reason = str5(ev.reason);
234341
- woCard(rec2, ACTIVITY_COPY.paused(nameOf(rec2.actorId)), {
234650
+ woCard(rec2, ACTIVITY_COPY.paused(nameOf2(rec2.actorId)), {
234342
234651
  notice: true,
234343
234652
  detail: reason === LEGACY_PAUSE_REASON ? void 0 : reason
234344
234653
  });
234345
234654
  break;
234346
234655
  }
234347
234656
  case "workorder.resumed":
234348
- woCard(rec2, ACTIVITY_COPY.resumedWorkorder(nameOf(rec2.actorId)), { notice: true });
234657
+ woCard(rec2, ACTIVITY_COPY.resumedWorkorder(nameOf2(rec2.actorId)), { notice: true });
234349
234658
  break;
234350
234659
  case "workorder.meta_changed": {
234351
234660
  const patch = ev.patch ?? {};
234352
234661
  if (!("goal" in patch) && !("description" in patch)) break;
234353
- woCard(rec2, ACTIVITY_COPY.goalChanged(nameOf(rec2.actorId), managerName()));
234662
+ woCard(rec2, ACTIVITY_COPY.goalChanged(nameOf2(rec2.actorId), managerName()));
234354
234663
  break;
234355
234664
  }
234356
234665
  case "plan.update_spec": {
234357
234666
  const nodeId = String(ev.nodeId ?? "");
234358
234667
  const d = cardOpenAt(nodeId, rec2.createdAt);
234359
234668
  if (d?.planChangeUnnamed) {
234360
- d.status = ACTIVITY_COPY.interruptedBySpecChange(nameOf(rec2.actorId), nodeName(nodeId));
234669
+ d.status = ACTIVITY_COPY.interruptedBySpecChange(nameOf2(rec2.actorId), nodeName(nodeId));
234361
234670
  delete d.planChangeUnnamed;
234362
234671
  }
234363
234672
  break;
@@ -234386,7 +234695,7 @@ function buildWorkorderActivity(input) {
234386
234695
  const forcedBy = str5(reasons.find((r) => r.kind === "forced")?.actorId);
234387
234696
  const parentWorkId = str5(workById.get(workId)?.parentWorkId);
234388
234697
  const reworkOfRejected = !!parentWorkId && workById.get(parentWorkId)?.acceptanceState === "rejected";
234389
- const status = reasonKinds.has("rework") || reworkOfRejected ? ACTIVITY_COPY.reworking(nodeName(nodeId)) : reasonKinds.has("resumed") ? ACTIVITY_COPY.resumed(nameOf(d.executorId), nodeName(nodeId)) : reasonKinds.has("spec_changed") ? ACTIVITY_COPY.specChanged(nodeName(nodeId)) : reasonKinds.has("issue") ? ACTIVITY_COPY.issueDriven(nodeName(nodeId)) : forcedBy ? ACTIVITY_COPY.forcedRerun(nameOf(forcedBy), nodeName(nodeId)) : ACTIVITY_COPY.working(nodeName(nodeId));
234698
+ const status = reasonKinds.has("rework") || reworkOfRejected ? ACTIVITY_COPY.reworking(nodeName(nodeId)) : reasonKinds.has("resumed") ? ACTIVITY_COPY.resumed(nameOf2(d.executorId), nodeName(nodeId)) : reasonKinds.has("spec_changed") ? ACTIVITY_COPY.specChanged(nodeName(nodeId)) : reasonKinds.has("issue") ? ACTIVITY_COPY.issueDriven(nodeName(nodeId)) : forcedBy ? ACTIVITY_COPY.forcedRerun(nameOf2(forcedBy), nodeName(nodeId)) : ACTIVITY_COPY.working(nodeName(nodeId));
234390
234699
  for (const r of reasons) {
234391
234700
  if (r.kind !== "issue") continue;
234392
234701
  const issueId = str5(r.issueId);
@@ -234397,7 +234706,7 @@ function buildWorkorderActivity(input) {
234397
234706
  if (ic && commentAuthor) {
234398
234707
  touch(ic, rec2);
234399
234708
  ic.executorId = d.executorId;
234400
- ic.status = ACTIVITY_COPY.commentHandling(nameOf(d.executorId), nameOf(commentAuthor));
234709
+ ic.status = ACTIVITY_COPY.commentHandling(nameOf2(d.executorId), nameOf2(commentAuthor));
234401
234710
  }
234402
234711
  }
234403
234712
  if (d.openWorkId === workId) {
@@ -234418,7 +234727,7 @@ function buildWorkorderActivity(input) {
234418
234727
  const d = cardOfWork.get(String(ev.workId ?? ""));
234419
234728
  if (!d) break;
234420
234729
  touch(d, rec2);
234421
- if (str5(ev.reason) !== ENGINE_RETRY_EXHAUSTED) d.detail = str5(ev.reason) ?? d.detail;
234730
+ if (!isSystemActorId(rec2.actorId)) d.detail = str5(ev.reason) ?? d.detail;
234422
234731
  break;
234423
234732
  }
234424
234733
  case "work.submit_output": {
@@ -234449,7 +234758,7 @@ function buildWorkorderActivity(input) {
234449
234758
  const bypassed = reviewers.length > 0 && isSystemAccept(by) && !voted;
234450
234759
  if (isSystemAccept(by) && !bypassed) break;
234451
234760
  const existing = acceptCards.get(workId);
234452
- const status = bypassed ? node2?.isFinalOutput ? ACTIVITY_COPY.autoAccepted(nameOf(reviewers[0])) : ACTIVITY_COPY.autoAcceptedNode(nodeName(nodeId), nameOf(reviewers[0])) : node2?.isFinalOutput ? ACTIVITY_COPY.accepted : ACTIVITY_COPY.acceptedNode(nodeName(nodeId));
234761
+ const status = bypassed ? node2?.isFinalOutput ? ACTIVITY_COPY.autoAccepted(nameOf2(reviewers[0])) : ACTIVITY_COPY.autoAcceptedNode(nodeName(nodeId), nameOf2(reviewers[0])) : node2?.isFinalOutput ? ACTIVITY_COPY.accepted : ACTIVITY_COPY.acceptedNode(nodeName(nodeId));
234453
234762
  if (existing) {
234454
234763
  touch(existing, rec2);
234455
234764
  existing.executorId = bypassed ? reviewers[0] : by;
@@ -234489,7 +234798,7 @@ function buildWorkorderActivity(input) {
234489
234798
  executorId: by,
234490
234799
  ...rec2.handActorId ? { handActorId: rec2.handActorId } : {},
234491
234800
  phase: "done",
234492
- status: ACTIVITY_COPY.gapResolved(nameOf(by), nameOf(stuck)),
234801
+ status: ACTIVITY_COPY.gapResolved(nameOf2(by), nameOf2(stuck)),
234493
234802
  artifacts: [],
234494
234803
  actions: []
234495
234804
  });
@@ -234551,10 +234860,10 @@ function buildWorkorderActivity(input) {
234551
234860
  缺口走不到这里了(F4 在上面 break)。 */
234552
234861
  phase: isBackpressure ? "stuck" : "running",
234553
234862
  status: isBackpressure ? ACTIVITY_COPY.backpressure(
234554
- nameOf(authorId),
234863
+ nameOf2(authorId),
234555
234864
  nodeName(nodeId),
234556
- nameOf((nodeId ? nodeById.get(nodeId)?.assigneeActorId : void 0) ?? ownerId)
234557
- ) : ACTIVITY_COPY.commentRaised(nameOf(authorId), nameOf(commentTargetId ?? ownerId), nodeName(nodeId)),
234865
+ nameOf2((nodeId ? nodeById.get(nodeId)?.assigneeActorId : void 0) ?? ownerId)
234866
+ ) : ACTIVITY_COPY.commentRaised(nameOf2(authorId), nameOf2(commentTargetId ?? ownerId), nodeName(nodeId)),
234558
234867
  /* **正文一律不上卡**:缺口去缺口线、回压去产物批注、留言去留言线。
234559
234868
  此前只有缺口/回压被排除,留言仍是「正文当小状态 + 展开区再印一遍」,
234560
234869
  全库实测最长 8096 字印两遍(`ws:wo-56bba3c1`),一张卡顶掉整屏。 */
@@ -234563,7 +234872,7 @@ function buildWorkorderActivity(input) {
234563
234872
  留言给「查看留言」直达留言线——线是投影出来的、恒存在,id 这里就能算;
234564
234873
  回压仍给「去处理」落到产物预览栏(那儿才有批注的处置面)。
234565
234874
  留言算不出对面是谁(该产物没负责人)时退回「去处理」,别给一个开不了的落点。 */
234566
- actions: isBackpressure || !commentTargetId ? [{ kind: "open_issue", label: BUTTON.handle, target: issueId }] : [{ kind: "open_thread", label: BUTTON.view, target: commentThreadSessionId(authorId, commentTargetId) }]
234875
+ actions: isBackpressure || !commentTargetId ? [{ kind: "open_issue", label: BUTTON.handle, target: issueId }] : [{ kind: "open_thread", label: BUTTON.view, target: commentThreadSessionId(authorId, commentTargetId), variant: "quiet" }]
234567
234876
  });
234568
234877
  break;
234569
234878
  }
@@ -234609,7 +234918,7 @@ function buildWorkorderActivity(input) {
234609
234918
  if (!target || !target.stuckReason) break;
234610
234919
  touch(target, rec2);
234611
234920
  if (target.foldedRounds && target.foldedRounds > 1) break;
234612
- target.status = target.stuckReason === "timeout" ? ACTIVITY_COPY.retriedAfterTimeout(nameOf(target.executorId), nameOf(by)) : ACTIVITY_COPY.retriedAfterFailure(nameOf(target.executorId), nameOf(by));
234921
+ target.status = target.stuckReason === "timeout" ? ACTIVITY_COPY.retriedAfterTimeout(nameOf2(target.executorId), nameOf2(by)) : ACTIVITY_COPY.retriedAfterFailure(nameOf2(target.executorId), nameOf2(by));
234613
234922
  break;
234614
234923
  }
234615
234924
  default:
@@ -234683,7 +234992,7 @@ function buildWorkorderActivity(input) {
234683
234992
  for (const { comments } of commentGroups) {
234684
234993
  const first = comments[0];
234685
234994
  const executorId = nodeOwnerOf(first.nodeId);
234686
- const author = nameOf(first.authorId);
234995
+ const author = nameOf2(first.authorId);
234687
234996
  const node2 = nodeName(first.nodeId);
234688
234997
  const ids2 = comments.map((c) => c.id);
234689
234998
  const closures = ids2.map(closureOf);
@@ -234730,7 +235039,7 @@ function buildWorkorderActivity(input) {
234730
235039
  phase,
234731
235040
  status,
234732
235041
  artifacts: [],
234733
- actions: threadPeer && threadPeer !== first.authorId ? [{ kind: "open_thread", label: BUTTON.view, target: commentThreadSessionId(first.authorId, threadPeer) }] : [],
235042
+ actions: threadPeer && threadPeer !== first.authorId ? [{ kind: "open_thread", label: BUTTON.view, target: commentThreadSessionId(first.authorId, threadPeer), variant: "quiet" }] : [],
234734
235043
  commentIssueIds: ids2
234735
235044
  });
234736
235045
  }
@@ -234752,7 +235061,7 @@ function buildWorkorderActivity(input) {
234752
235061
  const gapId = issueById.get(id)?.gapId;
234753
235062
  return typeof gapId === "string" && !!issueById.get(gapId);
234754
235063
  };
234755
- const head = kind === "retry_exhausted" ? ACTIVITY_COPY.escalationHeadRetryExhausted(nodeName(e.nodeId)) : kind === "review_exhausted" ? ACTIVITY_COPY.escalationHeadReviewExhausted(nodeName(e.nodeId)) : kind === "output_stall" ? ACTIVITY_COPY.escalationHeadOutputStall(nodeName(e.nodeId)) : gapBehind(e.id) ? ACTIVITY_COPY.escalationHeadGapEscalated(nameOf(e.authorId), nodeName(e.nodeId)) : ACTIVITY_COPY.escalationHeadManual(nameOf(stuckActor));
235064
+ const head = kind === "retry_exhausted" ? ACTIVITY_COPY.escalationHeadRetryExhausted(nodeName(e.nodeId)) : kind === "review_exhausted" ? ACTIVITY_COPY.escalationHeadReviewExhausted(nodeName(e.nodeId)) : kind === "output_stall" ? ACTIVITY_COPY.escalationHeadOutputStall(nodeName(e.nodeId)) : gapBehind(e.id) ? ACTIVITY_COPY.escalationHeadGapEscalated(nameOf2(e.authorId), nodeName(e.nodeId)) : ACTIVITY_COPY.escalationHeadManual(nameOf2(stuckActor));
234756
235065
  const howTo = kind === "retry_exhausted" ? ACTIVITY_COPY.escalationHowToRetryExhausted : kind === "review_exhausted" ? ACTIVITY_COPY.escalationHowToReviewExhausted : kind === "output_stall" ? ACTIVITY_COPY.escalationHowToOutputStall : void 0;
234757
235066
  const closing = issueById.get(e.id);
234758
235067
  const closeEvent = plainResolveEvents.get(e.id);
@@ -234761,7 +235070,7 @@ function buildWorkorderActivity(input) {
234761
235070
  const noteOf = (id) => text5(issueById.get(id)?.resolvedNote) ?? text5(plainResolveEvents.get(id)?.note);
234762
235071
  const rerunClosed = closingNote === ESCALATION_RERUN_NOTE;
234763
235072
  const rerunOrdinal = escalations.filter((x2) => x2.nodeId === e.nodeId && noteOf(x2.id) === ESCALATION_RERUN_NOTE && (resolvedAt(x2.id) ?? "") <= (closedAt ?? "")).length;
234764
- const doneStatus = rerunClosed ? ACTIVITY_COPY.escalationRerun(nameOf(closedBy), Math.max(rerunOrdinal, 1)) : ACTIVITY_COPY.escalationHandled(head, nameOf(closedBy), closingNote);
235073
+ const doneStatus = rerunClosed ? ACTIVITY_COPY.escalationRerun(nameOf2(closedBy), Math.max(rerunOrdinal, 1)) : ACTIVITY_COPY.escalationHandled(head, nameOf2(closedBy), closingNote);
234765
235074
  const retryExhaustedSoFar = escalations.filter((x2) => x2.nodeId === e.nodeId && escalationKindOf(x2.id, issueById.get(x2.id)?.authorActorId ?? x2.authorId) === "retry_exhausted" && x2.at <= e.at).length;
234766
235075
  const viewerIsTarget = !input.viewerActorId || input.viewerActorId === target;
234767
235076
  const offerRerun = kind === "retry_exhausted" && viewerIsTarget && retryExhaustedSoFar < 2 && !!e.nodeId;
@@ -234786,7 +235095,7 @@ function buildWorkorderActivity(input) {
234786
235095
  卡在人身上——颜色说的是这一段的状态,不是「轮到你了没有」。 */
234787
235096
  awaitingHuman: open3,
234788
235097
  ...open3 ? { phaseLabel: inDiscussion ? PHASE_LABEL.escalationInProgress : PHASE_LABEL.escalationPending } : {},
234789
- status: open3 ? ACTIVITY_COPY.escalationPendingWith(head, nameOf(target), howTo) : doneStatus,
235098
+ status: open3 ? ACTIVITY_COPY.escalationPendingWith(head, nameOf2(target), howTo) : doneStatus,
234790
235099
  /* 上报正文**不上卡**——与缺口 / 回压同一条口径。此前这里把整封信塞进展开区,
234791
235100
  `ws:wo-635d7add` 那条渲染出的是一屏字,连内部 artifact id 都印在卡面上。
234792
235101
  全文的去处,就是那个「去处理」按钮。 */
@@ -234797,13 +235106,16 @@ function buildWorkorderActivity(input) {
234797
235106
  按钮文案按**查看者**分两态(Bug 0151 / PR #2003 / 用例 T-31):不是收件人就写「查看留言」
234798
235107
  ——他点进去只有只读视图,按钮不该承诺一件他做不到的事。查看者取不到时保持「去处理」。
234799
235108
  关掉之后按钮不收走、只换成「查看留言」:那间讨论房是这条上报唯一的来龙去脉。 */
234800
- actions: !open3 ? [{ kind: "discuss_escalation", label: BUTTON.view, target: e.id }] : offerRerun ? [
235109
+ actions: !open3 ? [{ kind: "discuss_escalation", label: BUTTON.view, target: e.id, variant: "quiet" }] : offerRerun ? [
234801
235110
  { kind: "rerun_node", label: BUTTON.rerun, target: e.id, variant: "primary" },
234802
235111
  { kind: "discuss_escalation", label: BUTTON.handle, target: e.id, variant: "secondary" }
234803
235112
  ] : [{
234804
235113
  kind: "discuss_escalation",
234805
235114
  label: viewerIsTarget ? BUTTON.handle : BUTTON.view,
234806
- target: e.id
235115
+ target: e.id,
235116
+ /* 不是收件人 ⇒ 他点进去只有只读视图,分量跟着降到 `quiet`(Bug 0151 只换了词、
235117
+ 没换分量,于是旁观者看到的仍是一颗和「去处理」一样重的黑钮)。 */
235118
+ ...viewerIsTarget ? {} : { variant: "quiet" }
234807
235119
  }]
234808
235120
  });
234809
235121
  }
@@ -234816,7 +235128,7 @@ function buildWorkorderActivity(input) {
234816
235128
  const nodeId = gap.aboutNodeId ?? gap.raisedByNodeId;
234817
235129
  const name = nodeName(nodeId);
234818
235130
  const resolvedAt = gap.resolvedAt ?? null;
234819
- const inWindow2 = (at) => !!at && at >= gap.createdAt && (!resolvedAt || at <= resolvedAt);
235131
+ const inWindow2 = (at2) => !!at2 && at2 >= gap.createdAt && (!resolvedAt || at2 <= resolvedAt);
234820
235132
  const escalated = snap.issues.find((i) => i.kind === "escalation" && escalationKindOf(i.id, i.authorActorId) === "manual" && (i.gapId === gapId || (i.aboutNodeId ?? i.raisedByNodeId) === nodeId && inWindow2(i.createdAt)));
234821
235133
  const run = coordinatorRunOfGap(
234822
235134
  { createdAt: gap.createdAt, resolvedAt },
@@ -234849,12 +235161,12 @@ function buildWorkorderActivity(input) {
234849
235161
  那时按 `segmentOpen` 走暖橙——真要人动手的是它升级出去的那张升级卡,红归那一张。
234850
235162
  显式写 `false` 而不是省略:省略 = 不表态,前端会退回老规则(`stuck` + 开着 ⇒ 砖红)。 */
234851
235163
  awaitingHuman: false,
234852
- status: resolvedAt ? ACTIVITY_COPY.coordinatorFixedGap(nameOf(coordinatorId), nameOf(executorId)) : escalated ? ACTIVITY_COPY.coordinatorEscalated(nameOf(coordinatorId), name, nameOf(recipient)) : failedRun ? ACTIVITY_COPY.coordinatorFailed(name) : ACTIVITY_COPY.coordinatingGap(nameOf(coordinatorId), name),
235164
+ status: resolvedAt ? ACTIVITY_COPY.coordinatorFixedGap(nameOf2(coordinatorId), nameOf2(executorId)) : escalated ? ACTIVITY_COPY.coordinatorEscalated(nameOf2(coordinatorId), name, nameOf2(recipient)) : failedRun ? ACTIVITY_COPY.coordinatorFailed(name) : ACTIVITY_COPY.coordinatingGap(nameOf2(coordinatorId), name),
234853
235165
  artifacts: [],
234854
235166
  /* 点进去 = **这段协调轨迹**(run 在 `agent_runs` 里,`runId` 直接给)+ 缺口线。
234855
235167
  查不到那一段运行 ⇒ 不给轨迹入口,卡与那颗「查看留言」照旧。 */
234856
235168
  ...run ? { traceAvailable: true, runId: run.id } : {},
234857
- actions: [{ kind: "open_thread", label: BUTTON.view, target: gapThreadSessionId(executorId) }]
235169
+ actions: [{ kind: "open_thread", label: BUTTON.view, target: gapThreadSessionId(executorId), variant: "quiet" }]
234858
235170
  };
234859
235171
  coordinatorCards.push(draft);
234860
235172
  if (resolvedAt) gapsClosedByCoordinatorCard.add(gapId);
@@ -234874,7 +235186,7 @@ function buildWorkorderActivity(input) {
234874
235186
  if (card2.phaseLabel !== PHASE_LABEL.failed) continue;
234875
235187
  const last = trips.at(-1);
234876
235188
  const name = nodeName(card2.nodeId);
234877
- const who = nameOf(card2.executorId);
235189
+ const who = nameOf2(card2.executorId);
234878
235190
  const n = last.count ?? card2.foldedRounds ?? card2.traceWorkIds?.length ?? 1;
234879
235191
  const sentence = last.kind === "retry_exhausted" ? ACTIVITY_COPY.retryExhausted(who, name, n, lastFailureOf(card2, last) ?? last.lastReason) : ACTIVITY_COPY.outputStalled(who, name, n, last.cost);
234880
235192
  card2.status = trips.length > 1 ? ACTIVITY_COPY.stopLossAgain(sentence, trips.length) : sentence;
@@ -234890,13 +235202,13 @@ function buildWorkorderActivity(input) {
234890
235202
  if (pending.length === 0) continue;
234891
235203
  const acceptor = pending[0];
234892
235204
  const produced = cardOfWork.get(w2.id);
234893
- const at = produced?.updatedAt ?? w2.lastActivityAt ?? w2.endedAt ?? w2.createdAt;
235205
+ const at2 = produced?.updatedAt ?? w2.lastActivityAt ?? w2.endedAt ?? w2.createdAt;
234894
235206
  acceptCards.set(w2.id, {
234895
235207
  id: `accept:${w2.id}`,
234896
235208
  // 待验收卡挂在其产出卡之后:借产出卡的 seq +0.5 保持相邻,不去伪造一个事件 seq。
234897
235209
  seq: (cardOfWork.get(w2.id)?.seq ?? 0) + 0.5,
234898
- at,
234899
- updatedAt: at,
235210
+ at: at2,
235211
+ updatedAt: at2,
234900
235212
  nodeId: w2.nodeId,
234901
235213
  executorId: acceptor,
234902
235214
  phase: "not_started",
@@ -234960,7 +235272,7 @@ function buildWorkorderActivity(input) {
234960
235272
  /* 同一人担多个责任组时,展开区留一份**逐组结论**(只有判定词、没有意见正文)——小状态只有
234961
235273
  一句总判定,说不清哪个组过了哪个组没过。意见正文一律走下面的意见条。 */
234962
235274
  ...summary.latest.length > 1 ? {
234963
- detail: summary.latest.map((r) => `${nameOf(r.reviewerActorId)}\uFF08\u8BC4\u5BA1\u7EC4 ${groups.indexOf(r.reviewGroup) + 1}\uFF09\uFF1A${reviewLabel(r)}`).join("\n")
235275
+ detail: summary.latest.map((r) => `${nameOf2(r.reviewerActorId)}\uFF08\u8BC4\u5BA1\u7EC4 ${groups.indexOf(r.reviewGroup) + 1}\uFF09\uFF1A${reviewLabel(r)}`).join("\n")
234964
235276
  } : {},
234965
235277
  ...reviewNotes.length ? { reviewNotes } : {},
234966
235278
  ...reviewLine ? { reviewThreadSessionId: reviewLine } : {},
@@ -235076,11 +235388,12 @@ function buildWorkorderActivity(input) {
235076
235388
  cards.sort((a, b2) => a.at.localeCompare(b2.at) || a.seq - b2.seq || a.id.localeCompare(b2.id));
235077
235389
  return { workorderId, cards, truncated };
235078
235390
  }
235079
- var ACTIVITY_EVENT_KINDS, LEGACY_PAUSE_REASON, ACTIVITY_EVENT_LIMIT, UPSTREAM_ACK_NOTE_CAP, ACTIVITY_COPY, REWORK_ANNOTATION_PREFIX, RECOVERY_ANNOTATION_PREFIX, ENGINE_RETRY_EXHAUSTED, BUTTON, PHASE_LABEL, COORDINATOR_CARD_PREFIX, coordinatorCardId, RETRY_EXHAUSTED_ESC_PREFIX, REVIEW_EXHAUSTED_ESC_PREFIX2, isStopLoss;
235391
+ var ACTIVITY_EVENT_KINDS, LEGACY_PAUSE_REASON, ACTIVITY_EVENT_LIMIT, ACTIVITY_COPY, REWORK_ANNOTATION_PREFIX, RECOVERY_ANNOTATION_PREFIX, BUTTON, PHASE_LABEL, COORDINATOR_CARD_PREFIX, coordinatorCardId, isStopLoss;
235080
235392
  var init_activity2 = __esm({
235081
235393
  "../server/src/domains/collab/activity.ts"() {
235082
235394
  "use strict";
235083
235395
  init_src();
235396
+ init_escalation_kind();
235084
235397
  init_src6();
235085
235398
  init_activity_notice();
235086
235399
  init_gap_thread();
@@ -235123,7 +235436,6 @@ var init_activity2 = __esm({
235123
235436
  ];
235124
235437
  LEGACY_PAUSE_REASON = "\u6682\u505C\u6D3E\u53D1";
235125
235438
  ACTIVITY_EVENT_LIMIT = 2e3;
235126
- UPSTREAM_ACK_NOTE_CAP = 300;
235127
235439
  ACTIVITY_COPY = {
235128
235440
  goalConfirmed: "\u76EE\u6807\u5DF2\u786E\u8BA4\uFF0C\u4EFB\u52A1\u6309\u76EE\u6807\u5F00\u59CB\u6267\u884C\u3002",
235129
235441
  /**
@@ -235396,7 +235708,13 @@ var init_activity2 = __esm({
235396
235708
  commentUpdated: (author, node2) => `\u5DF2\u6309 ${author} \u7684\u7559\u8A00\u66F4\u65B0\u4E86\u4E00\u7248\u300A${node2}\u300B\u3002`,
235397
235709
  commentReplied: (author) => `\u5DF2\u56DE\u590D ${author} \u7684\u7559\u8A00\uFF0C\u672C\u6B21\u4E0D\u6539\u3002`,
235398
235710
  commentViewed: (author) => `\u770B\u8FC7 ${author} \u7684\u7559\u8A00\uFF0C\u65E0\u9700\u4FEE\u6539\u3002`,
235399
- /** 确认沿用(ADR 0607):上游换版,执行人确认不影响已接受的交付——理由放 `detail`(截断见 UPSTREAM_ACK_NOTE_CAP)。 */
235711
+ /**
235712
+ * 确认沿用(ADR 0607):上游换版,执行人确认不影响已接受的交付。
235713
+ *
235714
+ * 🚨 卡上**只有这一句**——`ack --note` 带的那段理由不再进展开区(Bug 0236)。它是执行 agent
235715
+ * 自由写的,除了长度截断没有任何语域约束,产品负责人 2026-09-23 在真页面上看到的是
235716
+ * 「任务1:…沿用 `wk:artifact:qa:…:1`,不产新版。」这种任务书编号腔 + 裸 work id。
235717
+ */
235400
235718
  upstreamAcked: (node2) => `\u4E0A\u6E38\u6709\u65B0\u7248\uFF0C\u786E\u8BA4\u4E0D\u5F71\u54CD\u300A${node2}\u300B\uFF0C\u6CBF\u7528\u4E0A\u4E00\u7248\u4EA4\u4ED8\u3002`,
235401
235719
  commentWithdrawn: (author) => `${author} \u64A4\u56DE\u4E86\u7559\u8A00\uFF0C\u65E0\u9700\u5904\u7406\u3002`,
235402
235720
  /** 节点被移出计划(任务还没到头):引擎把挂在上面的留言一并按「不改」关掉(`plan.delete_node`)。 */
@@ -235419,7 +235737,6 @@ var init_activity2 = __esm({
235419
235737
  };
235420
235738
  REWORK_ANNOTATION_PREFIX = "ann:rework:";
235421
235739
  RECOVERY_ANNOTATION_PREFIX = "ann:recovery:";
235422
- ENGINE_RETRY_EXHAUSTED = "failed exhausted";
235423
235740
  BUTTON = {
235424
235741
  approve: "\u5BA1\u6838\u901A\u8FC7",
235425
235742
  reject: "\u5BA1\u6838\u4E0D\u901A\u8FC7",
@@ -235450,8 +235767,6 @@ var init_activity2 = __esm({
235450
235767
  };
235451
235768
  COORDINATOR_CARD_PREFIX = "coordinator:";
235452
235769
  coordinatorCardId = (gapId) => `${COORDINATOR_CARD_PREFIX}${gapId}`;
235453
- RETRY_EXHAUSTED_ESC_PREFIX = "esc:retry-exhausted:";
235454
- REVIEW_EXHAUSTED_ESC_PREFIX2 = "esc:review-exhausted:";
235455
235770
  isStopLoss = (kind) => kind === "retry_exhausted" || kind === "output_stall";
235456
235771
  }
235457
235772
  });
@@ -235770,10 +236085,10 @@ function changeConfirmSummary(r) {
235770
236085
  }
235771
236086
  function latestOtherLetterActivity(an, me) {
235772
236087
  let best;
235773
- const consider = (at, by, seq) => {
235774
- if (!at || by === void 0 || by === me) return;
236088
+ const consider = (at2, by, seq) => {
236089
+ if (!at2 || by === void 0 || by === me) return;
235775
236090
  const s2 = seq ?? -1;
235776
- if (!best || s2 > best.seq) best = { at, by, seq: s2 };
236091
+ if (!best || s2 > best.seq) best = { at: at2, by, seq: s2 };
235777
236092
  };
235778
236093
  for (const t of an.thread) consider(t.ts, t.author, t.seq);
235779
236094
  if (an.resolvedBy !== void 0) consider(an.resolvedAt, an.resolvedBy, an.resolvedAtSeq);
@@ -235814,7 +236129,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
235814
236129
  return v2 === void 0 ? {} : { overdue: v2 };
235815
236130
  };
235816
236131
  const downstreamCount = (id) => consumersOf(model, id).length;
235817
- const firstSentence2 = (s2, max = 80) => (s2 ?? "").replace(/\s+/g, " ").trim().slice(0, max);
236132
+ const firstSentence3 = (s2, max = 80) => (s2 ?? "").replace(/\s+/g, " ").trim().slice(0, max);
235818
236133
  const creatorOf = /* @__PURE__ */ new Map();
235819
236134
  for (const a of model.artifacts.values()) {
235820
236135
  if (a.type === "brief") creatorOf.set(a.workspace, a.owner);
@@ -235935,7 +236250,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
235935
236250
  // 仍回落工单详情。
235936
236251
  ...r.origin ? { chatSessionId: r.origin } : {},
235937
236252
  ...anchorArt ? { title: nodeLabel(anchorArt) } : {},
235938
- detail: `${actorName(r.proposedBy) || "\u7BA1\u7406\u8005"}\uFF1A${r.command ? commandCardLine(r.command) : firstSentence2(r.plan.reason)}`,
236253
+ detail: `${actorName(r.proposedBy) || "\u7BA1\u7406\u8005"}\uFF1A${r.command ? commandCardLine(r.command) : firstSentence3(r.plan.reason)}`,
235939
236254
  ...r.kind !== "command" && opCount > 0 ? { impact: `\u6D89\u53CA ${opCount} \u5904\u6539\u52A8${r.nonMonotonicOps.length > 0 ? " \xB7 \u542B\u9500\u6BC1\u6027" : ""}` } : {},
235940
236255
  actor: actorRef2(r.proposedBy),
235941
236256
  ...overdueField(r.at)
@@ -235959,7 +236274,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
235959
236274
  actionRequired: true,
235960
236275
  summary: `\u6709\u4EBA\u5728\u300C${label2}\u300D\u7684\u4FE1\u91CC @ \u4E86\u4F60\uFF0C\u7B49\u4F60\u56DE\u8BDD\uFF1A${(lastPost?.body ?? an.body).slice(0, 100)}`,
235961
236276
  title: label2,
235962
- detail: `${(lastPost ? actorName(lastPost.author) : "") || "\u6709\u4EBA"} @ \u4E86\u4F60\uFF1A${firstSentence2(lastPost?.body ?? an.body)}`,
236277
+ detail: `${(lastPost ? actorName(lastPost.author) : "") || "\u6709\u4EBA"} @ \u4E86\u4F60\uFF1A${firstSentence3(lastPost?.body ?? an.body)}`,
235963
236278
  ...lastPost ? { actor: actorRef2(lastPost.author) } : {},
235964
236279
  ...overdueField(an.createdAt)
235965
236280
  });
@@ -235984,7 +236299,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
235984
236299
  actionRequired: false,
235985
236300
  summary: `\u4F60\u7684\u4FE1\u6709\u65B0\u52A8\u9759\uFF08${phrase}\uFF09\u300C${nodeLabel(a)}\u300D\uFF1A${lastNote.slice(0, 100)}\u2014\u2014\u4E0D\u8BA4\u53EF\u53EF\u5728\u4FE1\u4E2D\u56DE\u5E16`,
235986
236301
  title: nodeLabel(a),
235987
- detail: `${actorName(activity.by) || "\u5BF9\u65B9"} \u56DE\u5E94\u4E86\u4F60\u7684\u4FE1\uFF1A${firstSentence2(lastNote)}`,
236302
+ detail: `${actorName(activity.by) || "\u5BF9\u65B9"} \u56DE\u5E94\u4E86\u4F60\u7684\u4FE1\uFF1A${firstSentence3(lastNote)}`,
235988
236303
  actor: actorRef2(activity.by)
235989
236304
  // 通知型不判 overdue(诊断明说),不设 overdue 字段。
235990
236305
  });
@@ -236004,7 +236319,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
236004
236319
  actionRequired: true,
236005
236320
  summary: `\u5F85\u4F60\u9A8C\u6536\uFF1A${label2}\uFF08${pendingHead.id}\uFF09\u2014\u2014\u8BE5\u7248\u7B54\u590D\u4E86\u4F60\u7684\u4FE1`,
236006
236321
  title: label2,
236007
- detail: `${actorName(pendingHead.author) || "agent"} \u4EA4\u4E86\u65B0\u7248\u7B54\u590D\u4F60\u7684\u4FE1\uFF1A${firstSentence2(pendingHead.reason)}`,
236322
+ detail: `${actorName(pendingHead.author) || "agent"} \u4EA4\u4E86\u65B0\u7248\u7B54\u590D\u4F60\u7684\u4FE1\uFF1A${firstSentence3(pendingHead.reason)}`,
236008
236323
  actor: actorRef2(pendingHead.author),
236009
236324
  ...overdueField(pendingHead.createdAt)
236010
236325
  });
@@ -236031,7 +236346,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
236031
236346
  actionRequired: true,
236032
236347
  summary: `\u5F85\u4F60\u5BA1\u6279\uFF1A${label2}`,
236033
236348
  title: label2,
236034
- ...gp ? { detail: `${actorName(gp.headAuthor) || "\u4F5C\u8005"} \u4EA4\u4E86\u65B0\u7248\uFF1A${firstSentence2(headReason)}`, actor: actorRef2(gp.headAuthor) } : {},
236349
+ ...gp ? { detail: `${actorName(gp.headAuthor) || "\u4F5C\u8005"} \u4EA4\u4E86\u65B0\u7248\uFF1A${firstSentence3(headReason)}`, actor: actorRef2(gp.headAuthor) } : {},
236035
236350
  ...impactParts.length > 0 ? { impact: impactParts.join(" \xB7 ") } : {},
236036
236351
  ...overdueField(gate.at)
236037
236352
  });
@@ -236054,7 +236369,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
236054
236369
  actionRequired: true,
236055
236370
  summary: `\u4EA7\u51FA\u88AB\u6253\u56DE\uFF0C\u9700\u8FD4\u5DE5\uFF1A${label2}`,
236056
236371
  title: label2,
236057
- ...rejectVote ? { detail: `${actorName(rejectVote.author) || "\u8BC4\u5BA1"} \u6253\u56DE\uFF1A${firstSentence2(rejectVote.note ?? "\u89C1\u8BC4\u5BA1\u610F\u89C1")}`, actor: actorRef2(rejectVote.author) } : {},
236372
+ ...rejectVote ? { detail: `${actorName(rejectVote.author) || "\u8BC4\u5BA1"} \u6253\u56DE\uFF1A${firstSentence3(rejectVote.note ?? "\u89C1\u8BC4\u5BA1\u610F\u89C1")}`, actor: actorRef2(rejectVote.author) } : {},
236058
236373
  ...reworkDs > 0 ? { impact: `\u6321\u7740\u4E0B\u6E38 ${reworkDs} \u4E2A\u8282\u70B9` } : {},
236059
236374
  ...overdueField(latest.createdAt)
236060
236375
  });
@@ -236094,7 +236409,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
236094
236409
  actionRequired: true,
236095
236410
  summary: `\u4E0B\u6E38\u56DE\u538B\u5F85\u5904\u7406\uFF1A${pushback.body}`,
236096
236411
  title: label2,
236097
- detail: `\u4E0B\u6E38\u56DE\u538B\uFF1A${firstSentence2(pushback.body)}`,
236412
+ detail: `\u4E0B\u6E38\u56DE\u538B\uFF1A${firstSentence3(pushback.body)}`,
236098
236413
  actor: actorRef2(pushback.author),
236099
236414
  ...pushbackDs > 0 ? { impact: `\u5B83\u88AB\u4F60\u5361\u7740 ${pushbackDs} \u4E2A\u4E0B\u6E38\u8282\u70B9` } : {},
236100
236415
  ...overdueField(pushbackSince)
@@ -236158,8 +236473,8 @@ function backfillInboxUnread(items, markers) {
236158
236473
  }
236159
236474
  }
236160
236475
  function applyReadAllWatermark(items, markers) {
236161
- const at = markers.find((m2) => m2.scope === INBOX_READ_ALL_SCOPE)?.readAt;
236162
- const atMs = at ? Date.parse(at) : Number.NaN;
236476
+ const at2 = markers.find((m2) => m2.scope === INBOX_READ_ALL_SCOPE)?.readAt;
236477
+ const atMs = at2 ? Date.parse(at2) : Number.NaN;
236163
236478
  if (!Number.isFinite(atMs)) return;
236164
236479
  for (const item of items) {
236165
236480
  const sinceMs = Date.parse(item.since);
@@ -236699,10 +237014,10 @@ var init_notification_store = __esm({
236699
237014
  async listPending() {
236700
237015
  return [...this.rows.values()].filter((r) => r.status === "pending");
236701
237016
  }
236702
- async refresh(id, patch, at) {
237017
+ async refresh(id, patch, at2) {
236703
237018
  const r = this.rows.get(id);
236704
237019
  if (!r || r.status !== "pending") return;
236705
- const next = { ...r, title: patch.title, updatedAt: at };
237020
+ const next = { ...r, title: patch.title, updatedAt: at2 };
236706
237021
  for (const k2 of ["workspaceTitle", "actorId", "cardId", "item"]) {
236707
237022
  if (patch[k2] === void 0) delete next[k2];
236708
237023
  else next[k2] = patch[k2];
@@ -236710,11 +237025,11 @@ var init_notification_store = __esm({
236710
237025
  this.rows.set(id, next);
236711
237026
  this.save();
236712
237027
  }
236713
- async rekey(id, sourceKey, patch, at) {
237028
+ async rekey(id, sourceKey, patch, at2) {
236714
237029
  const r = this.rows.get(id);
236715
237030
  if (!r || r.status !== "pending" || this.findLive(r.recipient, sourceKey, r.category)) return false;
236716
237031
  this.rows.set(id, { ...r, sourceKey, ...patch.nodeId ? { nodeId: patch.nodeId } : {} });
236717
- await this.refresh(id, patch, at);
237032
+ await this.refresh(id, patch, at2);
236718
237033
  return true;
236719
237034
  }
236720
237035
  async close(id, closure) {
@@ -236734,21 +237049,21 @@ var init_notification_store = __esm({
236734
237049
  const cur = parseCursor(opts.before);
236735
237050
  return [...this.rows.values()].filter((r) => r.recipient === recipient).filter((r) => !opts.status || r.status === opts.status).filter((r) => !cur || r.enteredAt < cur.at || r.enteredAt === cur.at && r.id < cur.id).sort(newerFirst).slice(0, pageSize(opts.limit));
236736
237051
  }
236737
- async markRead(recipient, ids2, at) {
237052
+ async markRead(recipient, ids2, at2) {
236738
237053
  let changed = false;
236739
237054
  for (const id of ids2) {
236740
237055
  const r = this.rows.get(id);
236741
- if (!r || r.recipient !== recipient || r.readAt && r.readAt >= at) continue;
236742
- this.rows.set(id, { ...r, readAt: at });
237056
+ if (!r || r.recipient !== recipient || r.readAt && r.readAt >= at2) continue;
237057
+ this.rows.set(id, { ...r, readAt: at2 });
236743
237058
  changed = true;
236744
237059
  }
236745
237060
  if (changed) this.save();
236746
237061
  }
236747
- async markAllRead(recipient, at) {
237062
+ async markAllRead(recipient, at2) {
236748
237063
  let n = 0;
236749
237064
  for (const [id, r] of this.rows) {
236750
237065
  if (r.recipient !== recipient || r.readAt) continue;
236751
- this.rows.set(id, { ...r, readAt: at });
237066
+ this.rows.set(id, { ...r, readAt: at2 });
236752
237067
  n++;
236753
237068
  }
236754
237069
  if (n > 0) this.save();
@@ -236862,7 +237177,7 @@ var init_notification_store = __esm({
236862
237177
  const r = await this.sql.query(`SELECT * FROM ${this.t} WHERE status = 'pending'`);
236863
237178
  return r.rows.map(fromRow);
236864
237179
  }
236865
- async refresh(id, patch, at) {
237180
+ async refresh(id, patch, at2) {
236866
237181
  await this.sql.query(
236867
237182
  `UPDATE ${this.t} SET title = $2, workspace_title = $3, actor_id = $4, card_id = $5, item = $6, updated_at = $7
236868
237183
  WHERE id = $1 AND status = 'pending'`,
@@ -236873,11 +237188,11 @@ var init_notification_store = __esm({
236873
237188
  patch.actorId ?? null,
236874
237189
  patch.cardId ?? null,
236875
237190
  patch.item ? JSON.stringify(patch.item) : null,
236876
- at
237191
+ at2
236877
237192
  ]
236878
237193
  );
236879
237194
  }
236880
- async rekey(id, sourceKey, patch, at) {
237195
+ async rekey(id, sourceKey, patch, at2) {
236881
237196
  try {
236882
237197
  const r = await this.sql.query(
236883
237198
  `UPDATE ${this.t} SET source_key = $2, node_id = COALESCE($3, node_id), title = $4, workspace_title = $5,
@@ -236892,7 +237207,7 @@ var init_notification_store = __esm({
236892
237207
  patch.actorId ?? null,
236893
237208
  patch.cardId ?? null,
236894
237209
  patch.item ? JSON.stringify(patch.item) : null,
236895
- at
237210
+ at2
236896
237211
  ]
236897
237212
  );
236898
237213
  return (r.rowCount ?? 0) > 0;
@@ -236936,18 +237251,18 @@ var init_notification_store = __esm({
236936
237251
  );
236937
237252
  return r.rows.map(fromRow);
236938
237253
  }
236939
- async markRead(recipient, ids2, at) {
237254
+ async markRead(recipient, ids2, at2) {
236940
237255
  if (ids2.length === 0) return;
236941
237256
  await this.sql.query(
236942
237257
  `UPDATE ${this.t} SET read_at = GREATEST(COALESCE(read_at, $3::timestamptz), $3::timestamptz)
236943
237258
  WHERE recipient = $1 AND id = ANY($2::text[])`,
236944
- [recipient, [...ids2], at]
237259
+ [recipient, [...ids2], at2]
236945
237260
  );
236946
237261
  }
236947
- async markAllRead(recipient, at) {
237262
+ async markAllRead(recipient, at2) {
236948
237263
  const r = await this.sql.query(
236949
237264
  `UPDATE ${this.t} SET read_at = $2::timestamptz WHERE recipient = $1 AND read_at IS NULL`,
236950
- [recipient, at]
237265
+ [recipient, at2]
236951
237266
  );
236952
237267
  return r.rowCount ?? 0;
236953
237268
  }
@@ -237055,11 +237370,11 @@ async function buildAudit(source, q2 = {}, model) {
237055
237370
  items.push(model && titleOf ? enrichAudit(entry, model, titleOf, anchors) : entry);
237056
237371
  lastCursor = cursor;
237057
237372
  };
237058
- const match = (actor, kind, at) => {
237373
+ const match = (actor, kind, at2) => {
237059
237374
  if (q2.actor && actor !== q2.actor) return false;
237060
237375
  if (q2.kind && kind !== q2.kind) return false;
237061
- if (q2.from && at !== void 0 && at < q2.from) return false;
237062
- if (q2.to && at !== void 0 && at > q2.to) return false;
237376
+ if (q2.from && at2 !== void 0 && at2 < q2.from) return false;
237377
+ if (q2.to && at2 !== void 0 && at2 > q2.to) return false;
237063
237378
  return true;
237064
237379
  };
237065
237380
  if (q2.latest) {
@@ -238491,8 +238806,8 @@ var init_statistics = __esm({
238491
238806
  this.active = true;
238492
238807
  for (const s2 of v2.segments) this.amount.addSegment(s2);
238493
238808
  this.flags.addView(v2);
238494
- const at = v2.run.runtimeStartedAt ?? v2.run.startedAt;
238495
- if (!this.firstRun || at < (this.firstRun.runtimeStartedAt ?? this.firstRun.startedAt)) this.firstRun = v2.run;
238809
+ const at2 = v2.run.runtimeStartedAt ?? v2.run.startedAt;
238810
+ if (!this.firstRun || at2 < (this.firstRun.runtimeStartedAt ?? this.firstRun.startedAt)) this.firstRun = v2.run;
238496
238811
  }
238497
238812
  addCell(o) {
238498
238813
  if (!o.active) return;
@@ -240973,8 +241288,8 @@ var init_service6 = __esm({
240973
241288
  return this.isPast(inv.expiresAt);
240974
241289
  }
240975
241290
  /** 统一时间源下「这个时刻过去了没有」。邀请与链接共用,避免两处各写一次比较。 */
240976
- isPast(at) {
240977
- return Date.parse(at) <= Date.parse(this.now());
241291
+ isPast(at2) {
241292
+ return Date.parse(at2) <= Date.parse(this.now());
240978
241293
  }
240979
241294
  async requireCompany(companyId) {
240980
241295
  const c = await this.store.getCompany(companyId);
@@ -241064,7 +241379,7 @@ var init_offboarding = __esm({
241064
241379
  throw new CompanyError(409, "LAST_OWNER", "\u516C\u53F8\u81F3\u5C11\u8981\u7559 1 \u4E2A owner\uFF0C\u4E0D\u80FD\u79FB\u9664\u6700\u540E\u4E00\u4E2A owner");
241065
241380
  }
241066
241381
  const { ownedAgents, inFlight } = await this.snapshot(companyId, accountId);
241067
- const at = this.now();
241382
+ const at2 = this.now();
241068
241383
  const started = await this.store.startMemberOffboarding({
241069
241384
  operationId: `off:${(0, import_node_crypto58.randomUUID)()}`,
241070
241385
  companyId,
@@ -241077,8 +241392,8 @@ var init_offboarding = __esm({
241077
241392
  inFlightAssignments: inFlight,
241078
241393
  agentDecisions: [],
241079
241394
  assignmentDecisions: [],
241080
- createdAt: at,
241081
- updatedAt: at
241395
+ createdAt: at2,
241396
+ updatedAt: at2
241082
241397
  });
241083
241398
  let op = started.operation;
241084
241399
  if (!started.created) {
@@ -241087,7 +241402,7 @@ var init_offboarding = __esm({
241087
241402
  op.operationId,
241088
241403
  op.version,
241089
241404
  { ownedAgents: ownedAgents.map((a) => a.id), inFlightAssignments: inFlight },
241090
- at
241405
+ at2
241091
241406
  );
241092
241407
  if (refreshed.ok) op = refreshed.operation;
241093
241408
  else if (refreshed.reason === "stale") op = refreshed.current;
@@ -241768,9 +242083,9 @@ function looksLikeEmail(s2) {
241768
242083
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s2);
241769
242084
  }
241770
242085
  function maskEmail(email2) {
241771
- const at = email2.indexOf("@");
241772
- if (at <= 0) return "***";
241773
- return `${email2[0]}***${email2.slice(at)}`;
242086
+ const at2 = email2.indexOf("@");
242087
+ if (at2 <= 0) return "***";
242088
+ return `${email2[0]}***${email2.slice(at2)}`;
241774
242089
  }
241775
242090
  function createAuth(opts) {
241776
242091
  const now = opts.now ?? (() => Date.now());
@@ -242478,8 +242793,8 @@ function runtimeActivityQueryOf(query) {
242478
242793
  timeZone: query.get("timeZone") ?? void 0
242479
242794
  };
242480
242795
  }
242481
- function bucketIndexOf(slice, at) {
242482
- const ms = Date.parse(at);
242796
+ function bucketIndexOf(slice, at2) {
242797
+ const ms = Date.parse(at2);
242483
242798
  const { buckets, window: window3 } = slice.resolved;
242484
242799
  if (!Number.isFinite(ms) || ms < Date.parse(window3.from) || ms > Date.parse(window3.to)) return -1;
242485
242800
  for (let i = buckets.length - 1; i >= 0; i--) {
@@ -243790,8 +244105,8 @@ function notificationSourceKey(model, item) {
243790
244105
  return gen ? `${base}@${gen}` : base;
243791
244106
  }
243792
244107
  function generationOfKey(sourceKey) {
243793
- const at = sourceKey.lastIndexOf("@");
243794
- return at >= 0 ? sourceKey.slice(at + 1) : void 0;
244108
+ const at2 = sourceKey.lastIndexOf("@");
244109
+ return at2 >= 0 ? sourceKey.slice(at2 + 1) : void 0;
243795
244110
  }
243796
244111
  function workNumber(workId) {
243797
244112
  const m2 = /:(\d+)$/.exec(workId);
@@ -243820,7 +244135,7 @@ function classifyClosure(row, facts) {
243820
244135
  const item = row.item;
243821
244136
  const onNode = (rec2) => node2 !== null && nodeOfEvent(rec2) === node2;
243822
244137
  const evs = facts.events;
243823
- const at = (rec2) => rec2.createdAt;
244138
+ const at2 = (rec2) => rec2.createdAt;
243824
244139
  if (row.kind === "change-confirm" && facts.draftOutcome) {
243825
244140
  const o = facts.draftOutcome;
243826
244141
  if (o.invalidated) return o.by === me ? handled2(me, "\u5DF2\u5904\u7406", facts.now) : invalidated("handled-by-other", facts.now, o.by);
@@ -243835,12 +244150,12 @@ function classifyClosure(row, facts) {
243835
244150
  const e = payload(rec2, "plan.delete_node");
243836
244151
  return !!e && e.nodeId === node2 && e.sealReason === "cancelled";
243837
244152
  });
243838
- if (sealCancel) add({ rec: sealCancel, closure: invalidated(facts.workorderCancelled ? "workorder-cancelled" : "node-cancelled", at(sealCancel), sealCancel.actorId) });
244153
+ if (sealCancel) add({ rec: sealCancel, closure: invalidated(facts.workorderCancelled ? "workorder-cancelled" : "node-cancelled", at2(sealCancel), sealCancel.actorId) });
243839
244154
  const deleted = evs.find((rec2) => {
243840
244155
  const e = payload(rec2, "plan.delete_node");
243841
244156
  return !!e && e.nodeId === node2 && e.sealReason !== "accepted" && e.sealReason !== "cancelled";
243842
244157
  });
243843
- if (deleted) add({ rec: deleted, closure: invalidated("node-cancelled", at(deleted), deleted.actorId) });
244158
+ if (deleted) add({ rec: deleted, closure: invalidated("node-cancelled", at2(deleted), deleted.actorId) });
243844
244159
  add(resolvedByOther(row, evs, me, onNode));
243845
244160
  const gen = generationOfKey(row.sourceKey);
243846
244161
  if (gen) {
@@ -243852,7 +244167,7 @@ function classifyClosure(row, facts) {
243852
244167
  const s2 = payload(rec2, "work.submit_output");
243853
244168
  return !!s2 && nodeOfWork(s2.workId) === node2 && isNewer(s2.workId);
243854
244169
  });
243855
- if (newer) add({ rec: newer, closure: invalidated("superseded", at(newer), newer.actorId) });
244170
+ if (newer) add({ rec: newer, closure: invalidated("superseded", at2(newer), newer.actorId) });
243856
244171
  }
243857
244172
  const reassign = evs.find((rec2) => {
243858
244173
  const a = payload(rec2, "plan.assign_actor");
@@ -243860,7 +244175,7 @@ function classifyClosure(row, facts) {
243860
244175
  const r = payload(rec2, "plan.update_review_requirements");
243861
244176
  return !!r && r.nodeId === node2 && reviewKinds.has(row.kind) && !r.reviewers.some((x2) => x2.reviewerActorId === me);
243862
244177
  });
243863
- if (reassign) add({ rec: reassign, closure: invalidated("reassigned", at(reassign), reassign.actorId) });
244178
+ if (reassign) add({ rec: reassign, closure: invalidated("reassigned", at2(reassign), reassign.actorId) });
243864
244179
  const myReviewPrefix = gen ? `rv:${gen}:${me}:` : void 0;
243865
244180
  const withdrawn = evs.find((rec2) => {
243866
244181
  const k2 = payload(rec2, "review.kill") ?? payload(rec2, "review.timeout");
@@ -243868,7 +244183,7 @@ function classifyClosure(row, facts) {
243868
244183
  if (item?.waitingRowId !== void 0 && k2.reviewId === item.waitingRowId) return true;
243869
244184
  return row.kind === "review-request" && !!myReviewPrefix && k2.reviewId.startsWith(myReviewPrefix);
243870
244185
  });
243871
- if (withdrawn) add({ rec: withdrawn, closure: invalidated("source-changed", at(withdrawn), withdrawn.actorId) });
244186
+ if (withdrawn) add({ rec: withdrawn, closure: invalidated("source-changed", at2(withdrawn), withdrawn.actorId) });
243872
244187
  const first = evidence.reduce((best, f2) => !best || f2.rec.seq < best.rec.seq ? f2 : best, null);
243873
244188
  if (first) return first.closure;
243874
244189
  if (facts.workorderCancelled) return invalidated("workorder-cancelled", facts.now);
@@ -244000,8 +244315,8 @@ var init_notification_ledger = __esm({
244000
244315
  "issue.resolve"
244001
244316
  ];
244002
244317
  payload = (rec2, kind) => rec2.event.kind === kind ? rec2.event : null;
244003
- handled2 = (closedBy, result, at) => ({ status: "handled", closedAt: at, closedBy, result });
244004
- invalidated = (invalidReason, at, closedBy) => ({ status: "invalidated", closedAt: at, invalidReason, ...closedBy ? { closedBy } : {} });
244318
+ handled2 = (closedBy, result, at2) => ({ status: "handled", closedAt: at2, closedBy, result });
244319
+ invalidated = (invalidReason, at2, closedBy) => ({ status: "invalidated", closedAt: at2, invalidReason, ...closedBy ? { closedBy } : {} });
244005
244320
  found = (rec2, closure) => ({ rec: rec2, closure });
244006
244321
  ownerKinds = /* @__PURE__ */ new Set(["assigned", "rework", "stale", "pushback", "work-waiting"]);
244007
244322
  reviewKinds = /* @__PURE__ */ new Set(["review-request", "review-waiting"]);
@@ -244642,14 +244957,14 @@ function classifyGitError(fallback, err, where) {
244642
244957
  const raw = err;
244643
244958
  const msg = String(raw.stderr ?? raw.message ?? err).trim();
244644
244959
  if (/bad permissions|invalid format|could not read Username|permission denied|authentication failed|publickey/i.test(msg)) {
244645
- return new GitReadonlyBundleError("CREDENTIAL_FORMAT_ERROR", `git \u51ED\u8BC1\u683C\u5F0F\u6216\u8BA4\u8BC1\u5931\u8D25\uFF08${where}\uFF09\uFF1A${oneLine(msg)}`);
244960
+ return new GitReadonlyBundleError("CREDENTIAL_FORMAT_ERROR", `git \u51ED\u8BC1\u683C\u5F0F\u6216\u8BA4\u8BC1\u5931\u8D25\uFF08${where}\uFF09\uFF1A${oneLine2(msg)}`);
244646
244961
  }
244647
244962
  if (/not our ref|unadvertised object|reference is not a tree|could not parse|bad object|Not a valid object name|did not match any file/i.test(msg)) {
244648
- return new GitReadonlyBundleError("COMMIT_NOT_FOUND", `\u76EE\u6807 commit \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BFB\uFF08${where}\uFF09\uFF1A${oneLine(msg)}`);
244963
+ return new GitReadonlyBundleError("COMMIT_NOT_FOUND", `\u76EE\u6807 commit \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BFB\uFF08${where}\uFF09\uFF1A${oneLine2(msg)}`);
244649
244964
  }
244650
- return new GitReadonlyBundleError(fallback, `git ${fallback}\uFF08${where}\uFF09\uFF1A${oneLine(msg)}`);
244965
+ return new GitReadonlyBundleError(fallback, `git ${fallback}\uFF08${where}\uFF09\uFF1A${oneLine2(msg)}`);
244651
244966
  }
244652
- function oneLine(msg) {
244967
+ function oneLine2(msg) {
244653
244968
  return msg.split("\n").map((s2) => s2.trim()).filter(Boolean).slice(0, 3).join(" ");
244654
244969
  }
244655
244970
  var import_node_child_process16, import_node_crypto62, fs27, os8, path24, GitReadonlyBundleError, HEX40, FETCH_TIMEOUT_MS2;
@@ -245990,7 +246305,7 @@ function renderResumePack(pack) {
245990
246305
  if (cp) lines.push(`- Recoverability: ${cp.recoverability}`);
245991
246306
  if (done.length > 0) lines.push(`- \u4E0A\u4E00\u8D9F\u5DF2\u5B8C\u6210\u7684\u6B65\u9AA4\uFF1A${done.join("\u3001")}`);
245992
246307
  for (const ref2 of durable) {
245993
- lines.push(` - durable: ${ref2.kind}:${ref2.id}${ref2.version ? `@${ref2.version}` : ""}${ref2.label ? ` \u2014 ${ref2.label}` : ""}`);
246308
+ lines.push(` - durable: ${renderRefId(ref2)}${ref2.version ? `@${ref2.version}` : ""}${ref2.label ? ` \u2014 ${ref2.label}` : ""}`);
245994
246309
  }
245995
246310
  if (cp && cp.pendingSteps.length > 0) {
245996
246311
  for (const step of cp.pendingSteps) lines.push(` - pending: ${step}`);
@@ -246035,6 +246350,11 @@ function parseResumePackSnapshot(content3) {
246035
246350
  return null;
246036
246351
  }
246037
246352
  }
246353
+ function renderRefId(ref2) {
246354
+ const kind = ref2.kind.trim();
246355
+ const id = ref2.id.trim();
246356
+ return kind && !id.startsWith(`${kind}:`) ? `${kind}:${id}` : id;
246357
+ }
246038
246358
  function renderWorkVersion(work) {
246039
246359
  const current = work.currentWorkId ?? "none";
246040
246360
  const delivered = work.acceptedWorkId ?? "none";
@@ -246132,20 +246452,29 @@ function renderCoordinatorView(view, taskBackground) {
246132
246452
  `- Actor: ${node2.actorId ?? "unassigned"}; role: ${node2.role ?? "unassigned"}`
246133
246453
  );
246134
246454
  if (node2.dependsOn.length > 0) lines.push(`- Depends on: ${node2.dependsOn.join(", ")}`);
246135
- if (node2.conclusion?.trim()) lines.push(`- Conclusion: ${node2.conclusion.trim()}`);
246455
+ if (node2.conclusion?.trim()) {
246456
+ lines.push(node2.work.acceptedWorkId ? `- Conclusion (delivered ${node2.work.acceptedWorkId}): ${node2.conclusion.trim()}` : `- Conclusion: ${node2.conclusion.trim()}`);
246457
+ }
246136
246458
  if (node2.recoverySource) {
246137
246459
  const source = node2.recoverySource;
246138
246460
  lines.push(
246139
246461
  `- Recovery source: Attempt ${source.recoveredFromAttempt.attemptNo ?? "?"} \u2192 Attempt ${source.currentAttempt.attemptNo ?? "?"}`
246140
246462
  );
246141
246463
  if (source.recoveryCheckpoint) {
246142
- lines.push(` - Recovery checkpoint: #${source.recoveryCheckpoint.seq} (${source.recoveryCheckpoint.recoverability})`);
246464
+ lines.push(
246465
+ ` - Recovery checkpoint: #${source.recoveryCheckpoint.seq} (${source.recoveryCheckpoint.recoverability}) from Attempt ${source.recoveredFromAttempt.attemptNo ?? "?"}`
246466
+ );
246143
246467
  for (const step of source.recoveryCheckpoint.pendingSteps) lines.push(` - Recovery pending: ${step}`);
246144
246468
  }
246145
- if (source.recoveryHandoff?.producedBy === "agent") {
246146
- lines.push(` - Recovery Agent handoff: ${source.recoveryHandoff.summary}`);
246147
- } else if (source.recoveryHandoff?.producedBy === "system_reconstructed") {
246148
- lines.push(` - Recovery system reconstruction (not an Agent conclusion): ${source.recoveryHandoff.summary}`);
246469
+ if (source.recoveryHandoff) {
246470
+ const handoffFrom = source.recoveryHandoff.attemptId === source.recoveredFromAttempt.id ? `Attempt ${source.recoveredFromAttempt.attemptNo ?? "?"}` : `attempt ${source.recoveryHandoff.attemptId}`;
246471
+ if (source.recoveryHandoff.producedBy === "agent") {
246472
+ lines.push(` - Recovery Agent handoff (${handoffFrom}): ${source.recoveryHandoff.summary}`);
246473
+ } else if (source.recoveryHandoff.producedBy === "system_reconstructed") {
246474
+ lines.push(
246475
+ ` - Recovery system reconstruction (${handoffFrom}, not an Agent conclusion): ${source.recoveryHandoff.summary}`
246476
+ );
246477
+ }
246149
246478
  }
246150
246479
  for (const risk of source.recoveryHandoff?.risks ?? []) lines.push(` - Recovery risk: ${risk}`);
246151
246480
  }
@@ -246155,11 +246484,12 @@ function renderCoordinatorView(view, taskBackground) {
246155
246484
  }
246156
246485
  if (node2.handoffProducer === "agent" && node2.summary.trim() && !sameCoordinatorText(node2.summary, node2.conclusion)) {
246157
246486
  lines.push(`- Technical notes: ${node2.summary}`);
246158
- } else if (node2.handoffProducer === "system_reconstructed" && node2.summary.startsWith("[system_reconstructed]")) {
246487
+ } else if (node2.handoffProducer === "system_reconstructed" && node2.summary.startsWith("[system_reconstructed]") && node2.status !== "succeeded") {
246159
246488
  lines.push(`- Execution diagnostic: ${node2.summary}`);
246160
246489
  }
246161
246490
  for (const output of node2.changedOutputs) {
246162
- lines.push(` - Durable output: ${output.kind}:${output.id}${output.version ? `@${output.version}` : ""}`);
246491
+ if (!output.version) continue;
246492
+ lines.push(` - Durable output: ${renderRefId(output)}@${output.version}`);
246163
246493
  }
246164
246494
  const openItems = [
246165
246495
  ...node2.unresolvedIssues.map((value2) => `[unresolved] ${value2}`),
@@ -246938,7 +247268,7 @@ function nodeCoordinatorFactsFromSnapshot(snapshot) {
246938
247268
  state: currentWorkId === null ? "not_started" : currentWork ? workState(currentWork, hasOutput(currentWork, artifactCountByWork.get(currentWork.id) ?? 0)) : "unavailable"
246939
247269
  };
246940
247270
  const accepted = node2.latestAcceptId ? workById.get(node2.latestAcceptId) : void 0;
246941
- const conclusion = accepted?.conclusion?.trim() || snapshot.works.filter((work2) => work2.nodeId === node2.id && work2.status === "success" && work2.conclusion?.trim()).sort((a, b2) => a.createdAt.localeCompare(b2.createdAt)).at(-1)?.conclusion?.trim();
247271
+ const conclusion = accepted?.conclusion?.trim();
246942
247272
  const sealed = node2.cancelledAt ? { reason: node2.sealReason ?? "cancelled", at: node2.cancelledAt } : null;
246943
247273
  out[node2.id] = {
246944
247274
  work,
@@ -247110,6 +247440,86 @@ var init_execution_continuity2 = __esm({
247110
247440
  }
247111
247441
  });
247112
247442
 
247443
+ // ../server/src/domains/collab/escalation-opening-body.ts
247444
+ function retryFacts(body2) {
247445
+ const n = num3(/连续\s*(\d+)\s*次执行失败/.exec(body2)?.[1]);
247446
+ const reason = /末次失败原因(原文):([^\n]+)/.exec(body2)?.[1]?.trim();
247447
+ return { ...n !== void 0 ? { count: { n, unit: "\u8F6E" } } : {}, ...reason ? { lastReason: firstSentence2(reason) } : {} };
247448
+ }
247449
+ function reviewFacts(body2) {
247450
+ const n = num3(/评审连续\s*(\d+)\s*次失败/.exec(body2)?.[1]);
247451
+ return n !== void 0 ? { count: { n, unit: "\u8F6E" } } : {};
247452
+ }
247453
+ function stallFacts(body2) {
247454
+ const rounds = num3(/(?:跑了|有)\s*(\d+)\s*轮/.exec(body2)?.[1]);
247455
+ const runs = rounds === void 0 ? num3(/(?:跑了|累计有)\s*(\d+)\s*次/.exec(body2)?.[1]) : void 0;
247456
+ const minutes = num3(/最近\s*(\d+)\s*分钟/.exec(body2)?.[1]);
247457
+ const rawCost = /约\s*\$([\d.]+)/.exec(body2)?.[1];
247458
+ const cost = rawCost !== void 0 && Number.isFinite(Number(rawCost)) ? `$${Number(rawCost).toFixed(2)}` : void 0;
247459
+ const remark = body2.split("\u6700\u8FD1\u4E00\u6B21\u8FD0\u884C\u7684\u6536\u5C3E\u53D1\u8A00\uFF08\u5F80\u5F80\u76F4\u63A5\u5199\u7740\u5361\u5728\u54EA\uFF09\uFF1A\n")[1]?.trim();
247460
+ const who = /^(执行人|评审员)\s+(actor:\S+)/.exec(body2.trim());
247461
+ return {
247462
+ ...rounds !== void 0 ? { count: { n: rounds, unit: "\u8F6E" } } : runs !== void 0 ? { count: { n: runs, unit: "\u6B21\u8FD0\u884C" } } : {},
247463
+ ...minutes !== void 0 ? { minutes } : {},
247464
+ ...cost ? { cost } : {},
247465
+ ...remark ? { remark } : {},
247466
+ ...who ? { actorId: who[2], stalled: who[1] === "\u8BC4\u5BA1\u5458" ? "review" : "produce" } : {}
247467
+ };
247468
+ }
247469
+ function firstSentence2(text7) {
247470
+ const stripped = text7.replace(/^\s*\[[^\]]*\]\s*/, "").trim();
247471
+ return stripped.split(/[。!?\n]/)[0].trim() || stripped;
247472
+ }
247473
+ function stalledActorIdOf(kind, body2) {
247474
+ return kind === "output_stall" ? stallFacts(body2).actorId : void 0;
247475
+ }
247476
+ function renderEscalationOpeningBody(facts) {
247477
+ const body2 = facts.body.trim();
247478
+ if (facts.kind === "manual") return body2;
247479
+ if (facts.kind === "retry_exhausted") {
247480
+ const { count: count3, lastReason } = retryFacts(body2);
247481
+ if (!count3) return body2;
247482
+ return [
247483
+ `${facts.actorName ?? "\u8FD9\u4E00\u6B65\u7684\u6267\u884C\u4EBA"}${at(facts.nodeLabel)}\u8FDE\u7EED ${count3.n} \u8F6E\u90FD\u6CA1\u8DD1\u6210\uFF0C\u81EA\u52A8\u91CD\u8BD5\u5DF2\u7ECF\u7528\u5B8C\u2014\u2014\u8FD9\u4E00\u6B65\u4E0D\u4F1A\u518D\u81EA\u52A8\u91CD\u6765\u4E86\u3002`,
247484
+ ...lastReason ? [`\u6700\u540E\u4E00\u6B21\u5931\u8D25\u8BB0\u4E0B\u7684\u539F\u56E0\uFF1A${lastReason}`] : [],
247485
+ "\u9700\u8981\u4F60\u5B9A\u4E00\u4E0B\u63A5\u4E0B\u6765\u600E\u4E48\u529E\uFF1A\u6309\u539F\u65B9\u6848\u518D\u8BD5\u4E00\u6B21\u3001\u6539\u4E86\u4EFB\u52A1\u8BF4\u660E\u518D\u8DD1\uFF0C\u8FD8\u662F\u6362\u4E2A\u4EBA\u505A\u3002"
247486
+ ].join("\n\n");
247487
+ }
247488
+ if (facts.kind === "review_exhausted") {
247489
+ const { count: count3 } = reviewFacts(body2);
247490
+ if (!count3) return body2;
247491
+ return [
247492
+ `\u300A${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300B\u7684\u8BC4\u5BA1\u8FDE\u7EED ${count3.n} ${count3.unit}\u6CA1\u6536\u9F50\uFF0C\u8FD9\u4E00\u8F6E\u8BC4\u5BA1\u5DF2\u7ECF\u505C\u4E0B\u6765\u4E86\u3002`,
247493
+ "\u9700\u8981\u4F60\u5B9A\u4E00\u4E0B\u63A5\u4E0B\u6765\u600E\u4E48\u529E\uFF1A\u91CD\u5F00\u4E00\u8F6E\u8BC4\u5BA1\u3001\u6362\u8BC4\u5BA1\u4EBA\uFF0C\u8FD8\u662F\u6309\u73B0\u72B6\u5148\u653E\u884C\u3002"
247494
+ ].join("\n\n");
247495
+ }
247496
+ const { count: count2, minutes, cost, remark, stalled } = stallFacts(body2);
247497
+ if (!count2) return body2;
247498
+ const subject = stalled ? `${facts.actorName ?? (stalled === "review" ? "\u8FD9\u4E00\u6B65\u7684\u8BC4\u5BA1\u5458" : "\u8FD9\u4E00\u6B65\u7684\u6267\u884C\u4EBA")}${at(facts.nodeLabel)}` : `\u300A${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300B`;
247499
+ const window3 = minutes !== void 0 ? `\u6700\u8FD1 ${minutes} \u5206\u949F\u91CC` : "\u6700\u8FD1\u4E00\u6BB5\u65F6\u95F4\u91CC";
247500
+ const spent = cost ? `\uFF08\u8FD9\u4E9B\u7A7A\u8DD1\u5408\u8BA1\u5DF2\u7ECF\u82B1\u6389\u7EA6 ${cost}\uFF09` : "";
247501
+ const each = count2.unit === "\u8F6E" ? "\u6BCF\u4E00\u8F6E" : "\u6BCF\u4E00\u6B21";
247502
+ const stopped = stalled === "review" ? "\u7CFB\u7EDF\u5DF2\u7ECF\u505C\u6389\u8FD9\u540D\u8BC4\u5BA1\u5458\u5728\u8FD9\u4E00\u6B65\u4E0A\u7684\u8BC4\u5BA1\u2014\u2014\u4EA4\u4ED8\u5185\u5BB9\u539F\u6837\u4FDD\u7559\uFF0C\u6062\u590D\u4E4B\u540E\u53EF\u4EE5\u63A5\u7740\u6295\u7968\u3002" : "\u7CFB\u7EDF\u5DF2\u7ECF\u5148\u628A\u8FD9\u4E00\u6B65\u7684\u6D3E\u53D1\u6682\u505C\u4E0B\u6765\u6B62\u635F\u3002";
247503
+ return [
247504
+ `${subject}${window3}${stalled === "review" ? "\u8BC4\u5BA1\u4E86" : "\u8DD1\u4E86"} ${count2.n} ${count2.unit}\uFF0C${each}\u90FD\u4EC0\u4E48\u90FD\u6CA1\u4EA4\u51FA\u6765${spent}\u3002${stopped}`,
247505
+ ...remark ? [`\u5B83\u6700\u540E\u4E00\u6B21\u8FD0\u884C\u7684\u6536\u5C3E\u53D1\u8A00\uFF08\u5F80\u5F80\u76F4\u63A5\u5199\u7740\u5361\u5728\u54EA\uFF09\uFF1A
247506
+ ${remark}`] : [],
247507
+ "\u53CD\u590D\u96F6\u4EA7\u51FA\u901A\u5E38\u4E0D\u662F\u67D0\u4E00\u6B21\u8FD0\u884C\u5931\u8D25\uFF0C\u800C\u662F\u5361\u5728\u4E00\u4E2A\u518D\u8BD5\u4E5F\u8FC7\u4E0D\u53BB\u7684\u574E\u4E0A\u2014\u2014\u7F3A\u51ED\u636E\u3001\u8FDE\u4E0D\u4E0A\u5916\u90E8\u670D\u52A1\uFF0C\u6216\u8005\u9677\u8FDB\u4E86\u4E00\u4E2A\u6B7B\u5FAA\u73AF\u3002\u9700\u8981\u4F60\u770B\u4E00\u773C\u662F\u4EC0\u4E48\u5361\u4F4F\u4E86\uFF1B\u786E\u8BA4\u4E4B\u540E\u5728\u8FD9\u91CC\u544A\u8BC9\u6211\uFF0C\u6211\u6765\u628A\u8FD9\u4E00\u6B65\u6062\u590D\u3002"
247508
+ ].join("\n\n");
247509
+ }
247510
+ var num3, at;
247511
+ var init_escalation_opening_body = __esm({
247512
+ "../server/src/domains/collab/escalation-opening-body.ts"() {
247513
+ "use strict";
247514
+ num3 = (v2) => {
247515
+ if (v2 === void 0) return void 0;
247516
+ const n = Number(v2);
247517
+ return Number.isFinite(n) ? n : void 0;
247518
+ };
247519
+ at = (nodeLabel2) => nodeLabel2 ? `\u5728\u300A${nodeLabel2}\u300B\u4E0A` : "\u5728\u8FD9\u4E00\u6B65\u4E0A";
247520
+ }
247521
+ });
247522
+
247113
247523
  // ../server/src/domains/collab/escalation-opening.ts
247114
247524
  function buildEscalationOpeningMessage(input) {
247115
247525
  const escalationId = input.escalationId?.trim();
@@ -247117,30 +247527,43 @@ function buildEscalationOpeningMessage(input) {
247117
247527
  const context2 = escalationContextOf(input.snap, escalationId);
247118
247528
  const body2 = context2?.issue.body.trim();
247119
247529
  if (!context2 || !body2) return null;
247120
- const { issue: issue2, gap, recipientActorId } = context2;
247530
+ const { issue: issue2, gap, node: node2, kind, recipientActorId, agentId } = context2;
247121
247531
  const name = input.ref(recipientActorId).name?.trim();
247122
247532
  const gapBody = gap?.body.trim();
247123
247533
  const gapMarker = gap ? `
247124
247534
 
247125
247535
  [\u5173\u8054\u7F3A\u53E3] ${gap.id}` : "";
247126
- const issueBody = gapBody && gapMarker && body2.endsWith(gapMarker) ? body2.slice(0, -gapMarker.length).trimEnd() : body2;
247536
+ const rawBody = gapBody && gapMarker && body2.endsWith(gapMarker) ? body2.slice(0, -gapMarker.length).trimEnd() : body2;
247537
+ const actorId = stalledActorIdOf(kind, rawBody) ?? (kind === "retry_exhausted" ? issue2.authorActorId : void 0);
247538
+ const actorName = actorId ? input.ref(actorId).name?.trim() : void 0;
247539
+ const issueBody = renderEscalationOpeningBody({
247540
+ kind,
247541
+ body: rawBody,
247542
+ ...node2?.title ? { nodeLabel: node2.title } : {},
247543
+ ...actorName ? { actorName } : {}
247544
+ });
247127
247545
  const content3 = `${name ? `@${name} ` : ""}${issueBody}${gapBody ? `
247128
247546
 
247129
247547
  \u5173\u8054\u7F3A\u53E3\uFF1A
247130
247548
  ${gapBody}` : ""}`;
247549
+ const bySelf = !!agentId && issue2.authorActorId === agentId;
247131
247550
  return {
247132
247551
  id: `${ESCALATION_OPENING_ID_PREFIX}${escalationId}`,
247133
247552
  sessionId: input.sessionId,
247134
247553
  role: "assistant",
247135
247554
  content: content3,
247136
247555
  seq: -1,
247137
- createdAt: issue2?.createdAt ?? input.fallbackAt
247556
+ createdAt: issue2?.createdAt ?? input.fallbackAt,
247557
+ // 裸 `actor:system` 就是内核的 `SYSTEM_ACTOR`(`core/src/kernel.ts`);契约侧同一个串以前缀常量给出。
247558
+ ...bySelf ? {} : { authorActorId: SYSTEM_ACTOR_ID_PREFIX }
247138
247559
  };
247139
247560
  }
247140
247561
  var ESCALATION_OPENING_ID_PREFIX;
247141
247562
  var init_escalation_opening = __esm({
247142
247563
  "../server/src/domains/collab/escalation-opening.ts"() {
247143
247564
  "use strict";
247565
+ init_src();
247566
+ init_escalation_opening_body();
247144
247567
  init_escalation_recipient();
247145
247568
  ESCALATION_OPENING_ID_PREFIX = "synthetic:escalation-opening:";
247146
247569
  }
@@ -247851,10 +248274,10 @@ function createChatSessionsDomain(opts) {
247851
248274
  return { add: [], resolved: [] };
247852
248275
  });
247853
248276
  for (const itemId of projected.resolved) {
247854
- const at = snapshotEntries.findIndex((e) => e.itemId === itemId);
247855
- const entry = snapshotEntries[at];
248277
+ const at2 = snapshotEntries.findIndex((e) => e.itemId === itemId);
248278
+ const entry = snapshotEntries[at2];
247856
248279
  const payload2 = entry?.payload && typeof entry.payload === "object" && !Array.isArray(entry.payload) ? entry.payload : null;
247857
- if (entry && payload2) snapshotEntries[at] = { ...entry, payload: { ...payload2, resolved: true } };
248280
+ if (entry && payload2) snapshotEntries[at2] = { ...entry, payload: { ...payload2, resolved: true } };
247858
248281
  }
247859
248282
  const legacyCards = await legacySendFailureCards(snapshotEntries, {
247860
248283
  turns,
@@ -247865,8 +248288,8 @@ function createChatSessionsDomain(opts) {
247865
248288
  return [];
247866
248289
  });
247867
248290
  for (const { after, entry } of [...projected.add, ...legacyCards]) {
247868
- const at = snapshotEntries.findIndex((e) => e.itemId === after);
247869
- snapshotEntries.splice(at + 1, 0, entry);
248291
+ const at2 = snapshotEntries.findIndex((e) => e.itemId === after);
248292
+ snapshotEntries.splice(at2 + 1, 0, entry);
247870
248293
  }
247871
248294
  }
247872
248295
  const outputCards = await sessionOutputCards(snapshotEntries, store2, chatSessionId).catch((e) => {
@@ -247874,8 +248297,8 @@ function createChatSessionsDomain(opts) {
247874
248297
  return [];
247875
248298
  });
247876
248299
  for (const { after, entry } of outputCards) {
247877
- const at = snapshotEntries.findIndex((e) => e.itemId === after);
247878
- snapshotEntries.splice(at + 1, 0, entry);
248300
+ const at2 = snapshotEntries.findIndex((e) => e.itemId === after);
248301
+ snapshotEntries.splice(at2 + 1, 0, entry);
247879
248302
  }
247880
248303
  const oldestOrd = snapshotEntries.find((e) => e.ord !== null)?.ord ?? null;
247881
248304
  const body2 = {
@@ -247984,6 +248407,8 @@ function createChatSessionsDomain(opts) {
247984
248407
  for (const record9 of records) {
247985
248408
  const expert = actors ? await actors.getActor(record9.expertActorId).catch(() => null) : null;
247986
248409
  const touches = await ledger.listTouches(record9.id).catch(() => []);
248410
+ const artifacts = delegationArtifactsView(record9);
248411
+ const ending = delegationEndingOfRecord(record9, artifacts);
247987
248412
  items.push({
247988
248413
  id: record9.id,
247989
248414
  childSessionId: record9.childSessionId,
@@ -247994,8 +248419,10 @@ function createChatSessionsDomain(opts) {
247994
248419
  ...expert?.avatar ? { expertAvatar: expert.avatar } : {},
247995
248420
  state: record9.state,
247996
248421
  ...record9.failureKind ? { failureKind: record9.failureKind } : {},
247997
- /* 给人看的那一档由服务端算(Bug 0221):委派卡、徽章、子会话面板三处渲染同一个值。 */
247998
- ending: delegationEndingOfRecord(record9, delegationArtifactsView(record9)),
248422
+ /* 给人看的那一档由服务端算(Bug 0221):委派卡、徽章、子会话面板三处渲染同一个值。
248423
+ **还在跑的不下发**(Bug 0234):`ending` 是收口那一刻的说法,给一条 `running` 的委派
248424
+ 配上「已完成」,卡头(读 `state`)与展开行(读 `ending`)就会当场自相矛盾。 */
248425
+ ...ending ? { ending } : {},
247999
248426
  settledSeq: record9.settledSeq,
248000
248427
  ...record9.label ? { label: record9.label } : {},
248001
248428
  ...record9.taskDigest ? { taskDigest: record9.taskDigest } : {},
@@ -248007,7 +248434,7 @@ function createChatSessionsDomain(opts) {
248007
248434
  touches: touches.map((t) => ({ messageId: touchAnchorMessageId(t.messageId), kind: t.kind, at: t.at })),
248008
248435
  /* 与协调者读口**同一个函数**——两侧 artifacts 有「逐字同源」的既有断言。它顺带给每份产物
248009
248436
  填上 `childMessageId`(子会话面板把产出卡挂到产出它的那一轮下面要用)。 */
248010
- artifacts: delegationArtifactsView(record9),
248437
+ artifacts,
248011
248438
  replyAnchors: delegationReplyAnchors(record9),
248012
248439
  createdAt: record9.createdAt,
248013
248440
  ...record9.settledAt ? { settledAt: record9.settledAt } : {}
@@ -248318,26 +248745,26 @@ function createChatSessionsDomain(opts) {
248318
248745
  throw new ApiError(409, "STALE_OUTPUT", "\u8BE5\u6587\u4EF6\u5DF2\u88AB\u66F4\u65B0\u8FC7\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u540E\u518D\u4FDD\u5B58");
248319
248746
  }
248320
248747
  const blobRef2 = await blobAccess.put(new Uint8Array(bytes2));
248321
- const at = (/* @__PURE__ */ new Date()).toISOString();
248748
+ const at2 = (/* @__PURE__ */ new Date()).toISOString();
248322
248749
  await store2.mergeOutputCopies(session.id, [{
248323
248750
  path: path44,
248324
248751
  name: name2,
248325
248752
  blobRef: blobRef2,
248326
248753
  contentType: copy.contentType ?? null,
248327
248754
  size: bytes2.byteLength,
248328
- mtime: at,
248329
- copiedAt: at,
248330
- editedAt: at
248755
+ mtime: at2,
248756
+ copiedAt: at2,
248757
+ editedAt: at2
248331
248758
  }]);
248332
248759
  const fingerprints = await store2.readOutputFingerprints(session.id) ?? {};
248333
- await store2.writeOutputFingerprints(session.id, { ...fingerprints, [path44]: { size: bytes2.byteLength, mtime: at } });
248760
+ await store2.writeOutputFingerprints(session.id, { ...fingerprints, [path44]: { size: bytes2.byteLength, mtime: at2 } });
248334
248761
  const item2 = {
248335
248762
  id: `workdir:${path44}`,
248336
248763
  name: name2,
248337
248764
  kind: "file",
248338
248765
  content_type: copy.contentType ?? null,
248339
248766
  size: bytes2.byteLength,
248340
- updated_at: at,
248767
+ updated_at: at2,
248341
248768
  source: "output",
248342
248769
  blob_ref: blobRef2,
248343
248770
  path: path44,
@@ -248611,6 +249038,63 @@ var init_chat_sessions2 = __esm({
248611
249038
  }
248612
249039
  });
248613
249040
 
249041
+ // ../server/src/domains/chat-sessions/agent-default-runtime-store.ts
249042
+ function completeOverride(s2) {
249043
+ const nodeId = s2.overrideNodeId?.trim();
249044
+ const runtimeKind = s2.overrideRuntimeKind?.trim();
249045
+ return nodeId && runtimeKind ? { nodeId, runtimeKind } : null;
249046
+ }
249047
+ async function agentDefaultRuntimeForNewSession(s2, deps) {
249048
+ if (completeOverride(s2)) return null;
249049
+ const resolvers = deps.resolvers();
249050
+ if (!resolvers) return null;
249051
+ const companyId = s2.companyId ?? deps.companyId();
249052
+ const binding = await resolvers.resolveBinding(companyId, s2.aiActorId).catch(() => null);
249053
+ let agentModel = null;
249054
+ try {
249055
+ agentModel = resolvers.resolveActorModel ? await resolvers.resolveActorModel(companyId, s2.aiActorId) : null;
249056
+ } catch {
249057
+ agentModel = null;
249058
+ }
249059
+ return chatSessionInitialRuntime({
249060
+ binding,
249061
+ agentModel,
249062
+ requested: {
249063
+ // 半条覆盖按「没给」处理(规矩 1 后半句);完整的那一支上面已经返回了。
249064
+ override: null,
249065
+ /* 记录上已经**显式**带了 `model` 就尊重它(`POST /api/chat-sessions` 走完三态判断之后落下来的
249066
+ 就是这一支:`null` 在那儿的意思是「用户明确选了跟随运行时默认」,不许被员工配置顶掉)。
249067
+ 没带这一项(其余入口都不带)= 没人表达过意见 → 抄员工那一页配的型号。 */
249068
+ ...s2.model !== void 0 ? { model: s2.model } : {}
249069
+ }
249070
+ });
249071
+ }
249072
+ function withAgentDefaultRuntime(store, deps) {
249073
+ const createSession = async (s2) => {
249074
+ let patched = s2;
249075
+ try {
249076
+ const initial = await agentDefaultRuntimeForNewSession(s2, deps);
249077
+ if (initial) patched = { ...s2, ...initial };
249078
+ } catch (err) {
249079
+ console.warn(`[chat-session] \u6284\u5458\u5DE5\u9ED8\u8BA4\u8FD0\u884C\u914D\u7F6E\u5931\u8D25\uFF08\u672C\u6761\u4F1A\u8BDD\u4E09\u5217\u7559\u7A7A\uFF0C\u4E0D\u5F71\u54CD\u5EFA\u4F1A\u8BDD\uFF09\uFF1A${String(err)}`);
249080
+ }
249081
+ return store.createSession(patched);
249082
+ };
249083
+ return new Proxy(store, {
249084
+ get(target, prop, _receiver) {
249085
+ if (prop === "createSession") return createSession;
249086
+ const value2 = Reflect.get(target, prop, target);
249087
+ return typeof value2 === "function" ? value2.bind(target) : value2;
249088
+ }
249089
+ });
249090
+ }
249091
+ var init_agent_default_runtime_store = __esm({
249092
+ "../server/src/domains/chat-sessions/agent-default-runtime-store.ts"() {
249093
+ "use strict";
249094
+ init_session_runtime_target();
249095
+ }
249096
+ });
249097
+
248614
249098
  // ../server/src/domains/playbooks/registry.ts
248615
249099
  function deriveGraph(structure, filerReviews) {
248616
249100
  const idOf = (n) => `${n.type}:${n.title}`;
@@ -249983,11 +250467,11 @@ function validateTitleTemplate(tpl) {
249983
250467
  const unknown2 = residue.match(/\{\{[^}]*\}\}/);
249984
250468
  return unknown2 ? unknown2[0] : null;
249985
250469
  }
249986
- function renderDate(at, tz) {
250470
+ function renderDate(at2, tz) {
249987
250471
  try {
249988
- return new Intl.DateTimeFormat("en-CA", { timeZone: tz || "UTC", year: "numeric", month: "2-digit", day: "2-digit" }).format(at);
250472
+ return new Intl.DateTimeFormat("en-CA", { timeZone: tz || "UTC", year: "numeric", month: "2-digit", day: "2-digit" }).format(at2);
249989
250473
  } catch {
249990
- return at.toISOString().slice(0, 10);
250474
+ return at2.toISOString().slice(0, 10);
249991
250475
  }
249992
250476
  }
249993
250477
  function eventCommandKey(runId) {
@@ -250787,8 +251271,8 @@ var init_service9 = __esm({
250787
251271
  EVENT_RETRY_MAX_ATTEMPTS = 5;
250788
251272
  eventAttempts = (run) => eventDispatchState(run).attempts ?? 0;
250789
251273
  eventLastAttemptAt = (run) => {
250790
- const at = eventDispatchState(run).lastAttemptAt;
250791
- return at ? Date.parse(at) : null;
251274
+ const at2 = eventDispatchState(run).lastAttemptAt;
251275
+ return at2 ? Date.parse(at2) : null;
250792
251276
  };
250793
251277
  eventLastError = (run) => eventDispatchState(run).lastError ?? null;
250794
251278
  CHAT_REPLY_MAX = 2e4;
@@ -253188,14 +253672,14 @@ function isExplicitlyDispatchFenced(run) {
253188
253672
  const fence = metadataObject(run.metadata).dispatchFence;
253189
253673
  return fence !== null && typeof fence === "object" && !Array.isArray(fence);
253190
253674
  }
253191
- async function fenceDispatch(trace, dispatchId, reason, at = (/* @__PURE__ */ new Date()).toISOString()) {
253675
+ async function fenceDispatch(trace, dispatchId, reason, at2 = (/* @__PURE__ */ new Date()).toISOString()) {
253192
253676
  const run = await trace.getRun(dispatchId);
253193
253677
  if (!run) return false;
253194
253678
  if (isExplicitlyDispatchFenced(run)) return true;
253195
253679
  await trace.updateRun(dispatchId, {
253196
253680
  metadata: {
253197
253681
  ...metadataObject(run.metadata),
253198
- dispatchFence: { at, reason }
253682
+ dispatchFence: { at: at2, reason }
253199
253683
  }
253200
253684
  });
253201
253685
  return true;
@@ -256528,13 +257012,13 @@ var init_postgres_assistant_store = __esm({
256528
257012
  }
256529
257013
  async backfillAllHumansOn(humanIds, byActor2) {
256530
257014
  if (humanIds.length === 0) return { inserted: 0, skipped: 0 };
256531
- const at = (/* @__PURE__ */ new Date()).toISOString();
257015
+ const at2 = (/* @__PURE__ */ new Date()).toISOString();
256532
257016
  let inserted = 0;
256533
257017
  for (const id of humanIds) {
256534
257018
  const r = await this.pool.query(
256535
257019
  `INSERT INTO ${this.s}.human_prefs (human_actor_id, auto_assign_assistant, updated_at, updated_by)
256536
257020
  VALUES ($1, true, $2, $3) ON CONFLICT (human_actor_id) DO NOTHING`,
256537
- [id, at, byActor2]
257021
+ [id, at2, byActor2]
256538
257022
  );
256539
257023
  inserted += r.rowCount ?? 0;
256540
257024
  }
@@ -256712,11 +257196,11 @@ var init_postgres_channels = __esm({
256712
257196
  [l.channelType, l.appId, l.chatId, l.chatSessionId, l.updatedAt]
256713
257197
  );
256714
257198
  }
256715
- async markInbound(channelType, appId, messageId, at) {
257199
+ async markInbound(channelType, appId, messageId, at2) {
256716
257200
  const r = await this.pool.query(
256717
257201
  `INSERT INTO ${this.s}.channel_inbound_dedup (channel_type, app_id, message_id, at)
256718
257202
  VALUES ($1,$2,$3,$4) ON CONFLICT (channel_type, app_id, message_id) DO NOTHING`,
256719
- [channelType, appId, messageId, at]
257203
+ [channelType, appId, messageId, at2]
256720
257204
  );
256721
257205
  return (r.rowCount ?? 0) > 0;
256722
257206
  }
@@ -258329,17 +258813,17 @@ var init_postgres_control_plane = __esm({
258329
258813
  );
258330
258814
  return r.rows.map(rowToAgentCredential);
258331
258815
  }
258332
- async revokeAgentCredential(companyId, actorId, at) {
258816
+ async revokeAgentCredential(companyId, actorId, at2) {
258333
258817
  const r = await this.pool.query(
258334
258818
  `UPDATE ${this.s}.agent_credentials SET status = 'revoked', revoked_at = $3 WHERE company_id = $1 AND agent_id = $2`,
258335
- [companyId, actorId, at]
258819
+ [companyId, actorId, at2]
258336
258820
  );
258337
258821
  return (r.rowCount ?? 0) > 0;
258338
258822
  }
258339
- async touchAgentCredential(tokenHash, at) {
258823
+ async touchAgentCredential(tokenHash, at2) {
258340
258824
  await this.pool.query(
258341
258825
  `UPDATE ${this.s}.agent_credentials SET last_used_at = $2 WHERE token_hash = $1`,
258342
- [tokenHash, at]
258826
+ [tokenHash, at2]
258343
258827
  );
258344
258828
  }
258345
258829
  // —— principal_bridge ——
@@ -258414,7 +258898,7 @@ var init_postgres_control_plane = __esm({
258414
258898
  );
258415
258899
  return r.rows[0] ? rowToOffboarding(r.rows[0]) : null;
258416
258900
  }
258417
- async updateMemberOffboardingIfVersion(companyId, operationId, expectedVersion, patch, at) {
258901
+ async updateMemberOffboardingIfVersion(companyId, operationId, expectedVersion, patch, at2) {
258418
258902
  const sets = [`version = version + 1`];
258419
258903
  const params = [companyId, operationId, expectedVersion];
258420
258904
  const put3 = (col, value2, cast = "") => {
@@ -258427,7 +258911,7 @@ var init_postgres_control_plane = __esm({
258427
258911
  if (patch.ownedAgents !== void 0) put3("owned_agents", JSON.stringify(patch.ownedAgents), "::jsonb");
258428
258912
  if (patch.inFlightAssignments !== void 0) put3("in_flight_assignments", JSON.stringify(patch.inFlightAssignments), "::jsonb");
258429
258913
  if (patch.error !== void 0) put3("error", patch.error);
258430
- put3("updated_at", at);
258914
+ put3("updated_at", at2);
258431
258915
  const r = await this.pool.query(
258432
258916
  `UPDATE ${this.s}.member_offboardings SET ${sets.join(", ")}
258433
258917
  WHERE company_id = $1 AND operation_id = $2 AND version = $3 RETURNING *`,
@@ -258930,7 +259414,18 @@ var init_postgres_trace = __esm({
258930
259414
  (generated_handoff_id, NEW.id, COALESCE(NEW.job_key, NEW.trigger_ref, 'attempt:' || NEW.id), NEW.part,
258931
259415
  'system_reconstructed', mapped_outcome,
258932
259416
  reconstructed_summary, NEW.output_refs, '[]'::jsonb, reconstructed_risks,
258933
- COALESCE(latest_pending, '[]'::jsonb), reconstructed_gaps, NULL,
259417
+ -- \u2605 2026-09-23\uFF1Anext_actions \u4E0D\u518D\u7528 checkpoint \u7684 pendingSteps \u515C\u5E95\u3002
259418
+ --
259419
+ -- \u8FD9\u4E00\u680F\u7684\u8BED\u4E49\u662F\u300C\u4E0B\u6E38\u600E\u4E48\u7528\u8FD9\u4EFD\u6210\u679C\u300D\uFF08TASK.md \u539F\u6587\uFF1A--next\uFF1A\u4E0B\u6E38\u5982\u4F55\u4F7F\u7528\u6210\u679C\uFF0C\u4E0D\u662F\u4F60\u5269\u4F59
259420
+ -- \u6CA1\u505A\u7684\u5DE5\u4F5C\uFF09\uFF0C\u800C pendingSteps \u6070\u6070\u662F\u6267\u884C\u4EBA\u81EA\u5DF1\u6CA1\u505A\u5B8C\u7684\u6D3B\u3002\u515C\u5E95\u7684\u540E\u679C\uFF1A\u7EBF\u4E0A 114 \u4EFD\u4EA4\u4ED8\u8BB0\u5F55
259421
+ -- \u91CC 106 \u4EFD\u5E26 next\uFF0C\u5176\u4E2D 59 \u4EFD\u662F conclude / \u63D0\u4EA4\u5E76\u7ED3\u6848 \u8FD9\u7C7B\u81EA\u7559\u5F85\u529E\uFF0C\u8FD8\u88AB\u4E0B\u6E38\u4EA4\u63A5\u7684\u7ED3\u5C3E\u53E5
259422
+ -- \u58F0\u660E\u6210\u300C\u4EE5\u4E0A\u5F00\u653E\u9879\u662F\u4E0A\u6E38\u6267\u884C\u4EBA\u4EA4\u4F5C\u4E1A\u65F6\u81EA\u5DF1\u5199\u7684\u300D\u2014\u2014\u4E00\u53E5\u5047\u8BDD\uFF08\u5B9E\u8BC1\uFF1Aws:wo-2481b4cb \u7684\u4E0B\u6E38
259423
+ -- \u300C\u8C03\u7814\u62A5\u544A\u300D\u6536\u5230\u7684 _HANDOFF.md \u53EA\u6709\u4E00\u884C - [next] \u63D0\u4EA4\u5E76\u7ED3\u6848\uFF09\u3002\u6539\u6210\u7A7A\u4E4B\u540E\uFF0C\u8FD9\u4E00\u680F\u8981\u4E48\u662F
259424
+ -- \u6267\u884C\u4EBA propose --next \u4EB2\u624B\u5199\u7684\uFF0C\u8981\u4E48\u6CA1\u6709\u3002
259425
+ --
259426
+ -- pendingSteps \u4E0D\u4F1A\u56E0\u6B64\u4E22\u5931\uFF1A\u4E2D\u65AD\u7EED\u8DD1\u8BFB\u7684\u662F checkpoint \u672C\u8EAB\uFF08RESUME.md\uFF09\uFF0C\u534F\u8C03\u8005\u89C6\u56FE\u5BF9
259427
+ -- running/stalled/blocked/failed \u8282\u70B9\u5355\u72EC\u6E32\u67D3 Pending \u884C\uFF08progress \u6BB5\uFF09\uFF0C\u4E24\u5904\u90FD\u4E0D\u8BFB\u8FD9\u4E00\u680F\u3002
259428
+ '[]'::jsonb, reconstructed_gaps, NULL,
258934
259429
  COALESCE(NEW.ended_at, NEW.updated_at, NEW.started_at))
258935
259430
  -- \u2605 2026-08-17\uFF1A\u7EC8\u6001\u91CD\u5EFA\u4ECE\u300C\u6574\u884C\u8986\u76D6\u300D\u6539\u6210\u300C**\u53EA\u586B\u7A7A**\u300D\u3002
258936
259431
  --
@@ -259545,10 +260040,10 @@ var init_postgres_trace = __esm({
259545
260040
  * 条件 UPDATE 让后到的帧成为 0 行的空操作,不需要先读再判。run 不存在同样是 0 行 → false。
259546
260041
  * 不动 updated_at:这是观测事实的补记,不是一次 run 状态变更。
259547
260042
  */
259548
- async markRuntimeStarted(runId, at) {
260043
+ async markRuntimeStarted(runId, at2) {
259549
260044
  const r = await this.pool.query(
259550
260045
  `UPDATE ${this.s}.agent_runs SET runtime_started_at=$2 WHERE id=$1 AND runtime_started_at IS NULL`,
259551
- [runId, at]
260046
+ [runId, at2]
259552
260047
  );
259553
260048
  return (r.rowCount ?? 0) > 0;
259554
260049
  }
@@ -261289,8 +261784,8 @@ var init_postgres_automations = __esm({
261289
261784
  if (r.rowCount !== 1) throw new Error(`automation not found: ${id}`);
261290
261785
  return await this.getAutomation(id);
261291
261786
  }
261292
- async archiveAutomation(id, at) {
261293
- return this.updateAutomation(id, { archivedAt: at });
261787
+ async archiveAutomation(id, at2) {
261788
+ return this.updateAutomation(id, { archivedAt: at2 });
261294
261789
  }
261295
261790
  async pauseIfEnabled(id, reason) {
261296
261791
  const r = await this.pool.query(
@@ -261686,13 +262181,13 @@ var init_postgres_automations = __esm({
261686
262181
  );
261687
262182
  return r.rows.map(rowToTrigger);
261688
262183
  }
261689
- async completeEventBaseline(triggerId, at) {
262184
+ async completeEventBaseline(triggerId, at2) {
261690
262185
  await this.pool.query(
261691
262186
  `UPDATE ${this.s}.automation_triggers
261692
262187
  SET event_filters = jsonb_set(COALESCE(event_filters, '{}'::jsonb), '{baselineAt}', to_jsonb($2::text), true),
261693
262188
  enabled = true
261694
262189
  WHERE id = $1 AND kind = 'event'`,
261695
- [triggerId, at]
262190
+ [triggerId, at2]
261696
262191
  );
261697
262192
  }
261698
262193
  async resetEventBaseline(triggerId) {
@@ -262519,11 +263014,11 @@ var init_postgres_chat_sessions = __esm({
262519
263014
  * 标「已送到 agent」。`delivered_to_agent_at IS NULL` 是**单调闸**:第一次投递成功那一刻才是
262520
263015
  * 事实,重复调用不把时间往后推(提案 §4.3.1:投递成功之后不撤回、不重投)。
262521
263016
  */
262522
- async markMessageDeliveredToAgent(messageId, at) {
263017
+ async markMessageDeliveredToAgent(messageId, at2) {
262523
263018
  await this.pool.query(
262524
263019
  `UPDATE ${this.s}.chat_messages SET delivered_to_agent_at = $2
262525
263020
  WHERE id = $1 AND delivered_to_agent_at IS NULL`,
262526
- [messageId, at ?? (/* @__PURE__ */ new Date()).toISOString()]
263021
+ [messageId, at2 ?? (/* @__PURE__ */ new Date()).toISOString()]
262527
263022
  );
262528
263023
  }
262529
263024
  /**
@@ -263513,7 +264008,7 @@ var init_postgres_chat_items = __esm({
263513
264008
  }
263514
264009
  }
263515
264010
  async insertItem(q2, input) {
263516
- const at = input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
264011
+ const at2 = input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
263517
264012
  const status = input.status ?? "streaming";
263518
264013
  const payload2 = JSON.stringify(scrubPgJson(input.payload));
263519
264014
  const metadata = input.metadata === void 0 || input.metadata === null ? null : JSON.stringify(scrubPgJson(input.metadata));
@@ -263548,7 +264043,7 @@ var init_postgres_chat_items = __esm({
263548
264043
  scrubPgString(input.providerItemKey ?? null),
263549
264044
  payload2,
263550
264045
  metadata,
263551
- at,
264046
+ at2,
263552
264047
  input.version ?? null,
263553
264048
  input.ord ?? null
263554
264049
  ]
@@ -263556,11 +264051,11 @@ var init_postgres_chat_items = __esm({
263556
264051
  return rowToItem(r.rows[0]);
263557
264052
  }
263558
264053
  async applyOp(itemId, op, opts) {
263559
- const at = opts?.at ?? (/* @__PURE__ */ new Date()).toISOString();
264054
+ const at2 = opts?.at ?? (/* @__PURE__ */ new Date()).toISOString();
263560
264055
  const bumpTurnVersion = `(SELECT COALESCE(MAX(x.turn_version), 0) + 1 FROM ${this.s}.chat_items x
263561
264056
  WHERE x.session_id = c.session_id AND x.turn_id = c.turn_id)`;
263562
264057
  let setExpr;
263563
- const args = [itemId, at];
264058
+ const args = [itemId, at2];
263564
264059
  switch (op.op) {
263565
264060
  case "append_text":
263566
264061
  args.push(scrubPgString(op.text));
@@ -264331,12 +264826,12 @@ function toRecord2(row) {
264331
264826
  ...row.label ? { label: row.label } : {},
264332
264827
  ...row.task_digest ? { taskDigest: row.task_digest } : {},
264333
264828
  roundSummaries: row.round_summaries ?? [],
264334
- consecutiveFails: num3(row.consecutive_fails),
264335
- settledSeq: num3(row.settled_seq),
264829
+ consecutiveFails: num4(row.consecutive_fails),
264830
+ settledSeq: num4(row.settled_seq),
264336
264831
  createdAt: iso6(row.created_at),
264337
264832
  ...row.settled_at ? { settledAt: iso6(row.settled_at) } : {},
264338
264833
  ...row.dispatched_at ? { dispatchedAt: iso6(row.dispatched_at) } : {},
264339
- dispatchSeq: num3(row.dispatch_seq ?? 0)
264834
+ dispatchSeq: num4(row.dispatch_seq ?? 0)
264340
264835
  };
264341
264836
  }
264342
264837
  function toTouch(row) {
@@ -264350,7 +264845,7 @@ function toTouch(row) {
264350
264845
  at: iso6(row.at)
264351
264846
  };
264352
264847
  }
264353
- var iso6, num3, terminalGuard, PostgresDelegationStore;
264848
+ var iso6, num4, terminalGuard, PostgresDelegationStore;
264354
264849
  var init_postgres_delegations = __esm({
264355
264850
  "../storage/src/postgres-delegations.ts"() {
264356
264851
  "use strict";
@@ -264358,7 +264853,7 @@ var init_postgres_delegations = __esm({
264358
264853
  init_src();
264359
264854
  init_pg_ident();
264360
264855
  iso6 = (v2) => v2 instanceof Date ? v2.toISOString() : new Date(v2).toISOString();
264361
- num3 = (v2) => typeof v2 === "number" ? v2 : Number(v2);
264856
+ num4 = (v2) => typeof v2 === "number" ? v2 : Number(v2);
264362
264857
  terminalGuard = (state) => state !== void 0 && state !== "running" ? " AND state = 'running'" : "";
264363
264858
  PostgresDelegationStore = class _PostgresDelegationStore {
264364
264859
  constructor(pool, s2) {
@@ -264541,18 +265036,18 @@ var init_postgres_delegations = __esm({
264541
265036
  );
264542
265037
  return r.rows[0] ? toRecord2(r.rows[0]) : null;
264543
265038
  }
264544
- async claimDispatch(id, at, opts) {
265039
+ async claimDispatch(id, at2, opts) {
264545
265040
  const r = opts?.reclaimBefore ? await this.pool.query(
264546
265041
  `UPDATE ${this.s}.chat_session_delegations SET dispatched_at = $2
264547
265042
  WHERE id = $1
264548
265043
  AND (dispatched_at IS NULL
264549
265044
  OR (state = 'running' AND child_run_id IS NULL AND dispatched_at < $3))
264550
265045
  RETURNING *`,
264551
- [id, at, opts.reclaimBefore]
265046
+ [id, at2, opts.reclaimBefore]
264552
265047
  ) : await this.pool.query(
264553
265048
  `UPDATE ${this.s}.chat_session_delegations SET dispatched_at = $2
264554
265049
  WHERE id = $1 AND dispatched_at IS NULL RETURNING *`,
264555
- [id, at]
265050
+ [id, at2]
264556
265051
  );
264557
265052
  return r.rows[0] ? toRecord2(r.rows[0]) : null;
264558
265053
  }
@@ -264590,12 +265085,12 @@ var init_postgres_delegations = __esm({
264590
265085
  );
264591
265086
  return Number(r.rows[0]?.n ?? 0);
264592
265087
  }
264593
- async markTouchesConsumed(delegationId, messageIds, at) {
265088
+ async markTouchesConsumed(delegationId, messageIds, at2) {
264594
265089
  if (!messageIds.length) return;
264595
265090
  await this.pool.query(
264596
265091
  `UPDATE ${this.s}.chat_session_delegation_touches SET consumed_at = $3
264597
265092
  WHERE delegation_id = $1 AND message_id = ANY($2::text[]) AND consumed_at IS NULL`,
264598
- [delegationId, messageIds, at]
265093
+ [delegationId, messageIds, at2]
264599
265094
  );
264600
265095
  }
264601
265096
  /**
@@ -265841,12 +266336,12 @@ var init_postgres_dispatches = __esm({
265841
266336
  }
265842
266337
  return out;
265843
266338
  }
265844
- async closeStaleNeverStarted(olderThanMs, at) {
266339
+ async closeStaleNeverStarted(olderThanMs, at2) {
265845
266340
  const res = await this.pool.query(
265846
266341
  `UPDATE "${this.s}".dispatches
265847
266342
  SET ended_at = $1::timestamptz, outcome = 'failed', reason = 'never-started'
265848
266343
  WHERE started_at IS NULL AND ended_at IS NULL AND created_at < $1::timestamptz - ($2 || ' milliseconds')::interval`,
265849
- [at ?? (/* @__PURE__ */ new Date()).toISOString(), String(olderThanMs)]
266344
+ [at2 ?? (/* @__PURE__ */ new Date()).toISOString(), String(olderThanMs)]
265850
266345
  );
265851
266346
  return res.rowCount ?? 0;
265852
266347
  }
@@ -268415,8 +268910,8 @@ var init_cutover_aware_dispatches = __esm({
268415
268910
  async closeOpenByTarget(kind, targetId, opts) {
268416
268911
  return (await this.pickWritable()).closeOpenByTarget(kind, targetId, opts);
268417
268912
  }
268418
- async closeStaleNeverStarted(olderThanMs, at) {
268419
- return (await this.pickWritable()).closeStaleNeverStarted(olderThanMs, at);
268913
+ async closeStaleNeverStarted(olderThanMs, at2) {
268914
+ return (await this.pickWritable()).closeStaleNeverStarted(olderThanMs, at2);
268420
268915
  }
268421
268916
  async listByWorkorder(workorderId) {
268422
268917
  return (await this.pick()).listByWorkorder(workorderId);
@@ -268504,8 +268999,8 @@ var init_cutover_aware_dispatches = __esm({
268504
268999
  async closeOpenByTarget(kind, targetId, opts) {
268505
269000
  return (await this.each("closeOpenByTarget", (l) => l.closeOpenByTarget(kind, targetId, opts))).flat();
268506
269001
  }
268507
- async closeStaleNeverStarted(olderThanMs, at) {
268508
- return (await this.each("closeStaleNeverStarted", (l) => l.closeStaleNeverStarted(olderThanMs, at))).reduce((a, b2) => a + b2, 0);
269002
+ async closeStaleNeverStarted(olderThanMs, at2) {
269003
+ return (await this.each("closeStaleNeverStarted", (l) => l.closeStaleNeverStarted(olderThanMs, at2))).reduce((a, b2) => a + b2, 0);
268509
269004
  }
268510
269005
  // ── 读:并集 ───────────────────────────────────────────────────────────────
268511
269006
  async listOpen() {
@@ -268749,9 +269244,9 @@ var init_cutover_aware_trace = __esm({
268749
269244
  // 写走 pickWritable(frozen 窗口内拒,与 updateRun 同闸);读走 pick(切走后读引擎 schema,miss 不回落)。
268750
269245
  // 落点 store 没实现可选方法时:写返回「没写」(与上面 updateUsageAggregates 同口径);
268751
269246
  // 统计读**抛错**而不是返回空——空数组会被当成「确认的零用量」画出来,而数据契约 §4.5 要的是 503。
268752
- async markRuntimeStarted(runId, at) {
269247
+ async markRuntimeStarted(runId, at2) {
268753
269248
  const s2 = await this.pickWritable();
268754
- return s2.markRuntimeStarted ? s2.markRuntimeStarted(runId, at) : false;
269249
+ return s2.markRuntimeStarted ? s2.markRuntimeStarted(runId, at2) : false;
268755
269250
  }
268756
269251
  async recordUsagePoint(input) {
268757
269252
  const s2 = await this.pickWritable();
@@ -269126,9 +269621,9 @@ var init_cutover_aware_trace = __esm({
269126
269621
  if (s2.updateUsageAggregates) await s2.updateUsageAggregates(run);
269127
269622
  }
269128
269623
  // 用量账本的两个写:与 updateRun 同理——解析不出公司就抛,不落默认公司(落错库不会报错)。
269129
- async markRuntimeStarted(runId, at) {
269624
+ async markRuntimeStarted(runId, at2) {
269130
269625
  const s2 = await this.writable(runId, "markRuntimeStarted");
269131
- return s2.markRuntimeStarted ? s2.markRuntimeStarted(runId, at) : false;
269626
+ return s2.markRuntimeStarted ? s2.markRuntimeStarted(runId, at2) : false;
269132
269627
  }
269133
269628
  async recordUsagePoint(input) {
269134
269629
  const s2 = await this.writable(input.runId, "recordUsagePoint");
@@ -270580,8 +271075,8 @@ async function copyBlobsIdempotent(pool, companyId, companySchema, manifestId, o
270580
271075
  distribution[r.companyId] = (distribution[r.companyId] ?? 0) + 1;
270581
271076
  if (r.companyId !== companyId) continue;
270582
271077
  const body2 = r.key.slice("blobs:".length);
270583
- const at = body2.lastIndexOf("@");
270584
- mine.add(at >= 0 ? body2.slice(0, at) : body2);
271078
+ const at2 = body2.lastIndexOf("@");
271079
+ mine.add(at2 >= 0 ? body2.slice(0, at2) : body2);
270585
271080
  }
270586
271081
  let copied = 0;
270587
271082
  const client = await pool.connect();
@@ -272020,7 +272515,7 @@ async function backfillUsageLedger(ledger, opts) {
272020
272515
  for (const id of ids2) sample(report.runtimeStartedAt, id);
272021
272516
  if (opts.dryRun) continue;
272022
272517
  await inTx(ledger.pool, async (c) => {
272023
- const at = now();
272518
+ const at2 = now();
272024
272519
  const upd = await c.query(
272025
272520
  `UPDATE ${s2}.agent_runs SET runtime_started_at = started_at
272026
272521
  WHERE id = ANY($1::text[]) AND runtime_started_at IS NULL
@@ -272029,7 +272524,7 @@ async function backfillUsageLedger(ledger, opts) {
272029
272524
  );
272030
272525
  for (const r of upd.rows) {
272031
272526
  report.runtimeStartedAt.changed += 1;
272032
- await audit(c, s2, opts.manifestId, r.id, "runtime_started_at", null, r.runtime_started_at, at);
272527
+ await audit(c, s2, opts.manifestId, r.id, "runtime_started_at", null, r.runtime_started_at, at2);
272033
272528
  }
272034
272529
  });
272035
272530
  }
@@ -272074,7 +272569,7 @@ async function backfillUsageLedger(ledger, opts) {
272074
272569
  for (const p2 of plan) sample(report.chat, p2.id);
272075
272570
  if (opts.dryRun || plan.length === 0) continue;
272076
272571
  await inTx(ledger.pool, async (c) => {
272077
- const at = now();
272572
+ const at2 = now();
272078
272573
  for (const p2 of plan) {
272079
272574
  let touched = false;
272080
272575
  if (p2.session) {
@@ -272084,7 +272579,7 @@ async function backfillUsageLedger(ledger, opts) {
272084
272579
  );
272085
272580
  if (r.rowCount) {
272086
272581
  touched = true;
272087
- await audit(c, s2, opts.manifestId, p2.id, "chat_session_id", null, p2.session, at);
272582
+ await audit(c, s2, opts.manifestId, p2.id, "chat_session_id", null, p2.session, at2);
272088
272583
  }
272089
272584
  }
272090
272585
  if (p2.turn) {
@@ -272095,7 +272590,7 @@ async function backfillUsageLedger(ledger, opts) {
272095
272590
  if (r.rowCount) {
272096
272591
  touched = true;
272097
272592
  report.chat.turnFilled += 1;
272098
- await audit(c, s2, opts.manifestId, p2.id, "chat_turn_id", null, p2.turn, at);
272593
+ await audit(c, s2, opts.manifestId, p2.id, "chat_turn_id", null, p2.turn, at2);
272099
272594
  }
272100
272595
  }
272101
272596
  if (touched) report.chat.changed += 1;
@@ -272197,7 +272692,7 @@ async function fixClaudeResumeUsage(pool, s2, before, o) {
272197
272692
  for (let i = 0; i < plan.length; i += o.batch) {
272198
272693
  const slice = plan.slice(i, i + o.batch);
272199
272694
  await inTx(pool, async (c) => {
272200
- const at = o.now();
272695
+ const at2 = o.now();
272201
272696
  for (const p2 of slice) {
272202
272697
  const r = await c.query(
272203
272698
  `UPDATE ${s2}.agent_runs SET usage = $2::jsonb WHERE id = $1 AND usage = $3::jsonb RETURNING id`,
@@ -272214,7 +272709,7 @@ async function fixClaudeResumeUsage(pool, s2, before, o) {
272214
272709
  "claude_resume_usage",
272215
272710
  { usage: p2.current },
272216
272711
  { usage: p2.next },
272217
- at
272712
+ at2
272218
272713
  );
272219
272714
  }
272220
272715
  });
@@ -272303,7 +272798,7 @@ async function undoUsageLedgerBackfill(ledger, manifestId, opts = {}) {
272303
272798
  [manifestId]
272304
272799
  );
272305
272800
  report.auditRows = rows.length;
272306
- const at = now();
272801
+ const at2 = now();
272307
272802
  for (const row of rows) {
272308
272803
  const runId = row.run_id;
272309
272804
  const field = row.field;
@@ -272346,7 +272841,7 @@ async function undoUsageLedgerBackfill(ledger, manifestId, opts = {}) {
272346
272841
  continue;
272347
272842
  }
272348
272843
  report.restored += 1;
272349
- await audit(c, s2, undoManifest, runId, field, after, before, at);
272844
+ await audit(c, s2, undoManifest, runId, field, after, before, at2);
272350
272845
  }
272351
272846
  });
272352
272847
  return report;
@@ -273228,7 +273723,7 @@ var init_run_settlement = __esm({
273228
273723
  if (delivered2) await this.markDelivered(intent.runId, key2, intent.companyId);
273229
273724
  return { settled: false, wroteRunTerminal: false, delivered: delivered2, targetKind: existing.target.kind, key: key2 };
273230
273725
  }
273231
- const at = intent.occurredAt;
273726
+ const at2 = intent.occurredAt;
273232
273727
  const alreadyTerminal = isRunTerminalStatus(run.status);
273233
273728
  const effectiveStatus = alreadyTerminal ? run.status : intent.status;
273234
273729
  const settlement = {
@@ -273236,16 +273731,16 @@ var init_run_settlement = __esm({
273236
273731
  target: intent.target,
273237
273732
  status: effectiveStatus,
273238
273733
  reason: intent.reason,
273239
- at,
273734
+ at: at2,
273240
273735
  delivered: false,
273241
273736
  attempts: 0
273242
273737
  };
273243
273738
  const startedMs = Date.parse(run.startedAt);
273244
- const endedMs = Date.parse(at);
273739
+ const endedMs = Date.parse(at2);
273245
273740
  await this.trace.updateRun(intent.runId, {
273246
273741
  ...alreadyTerminal ? {} : {
273247
273742
  status: intent.status,
273248
- endedAt: at,
273743
+ endedAt: at2,
273249
273744
  durationMs: Number.isFinite(startedMs) && Number.isFinite(endedMs) ? Math.max(endedMs - startedMs, 0) : null,
273250
273745
  exitReason: intent.reason,
273251
273746
  ...intent.exitCode !== void 0 ? { exitCode: intent.exitCode } : {},
@@ -273931,6 +274426,7 @@ __export(src_exports2, {
273931
274426
  actorRefFieldsOf: () => actorRefFieldsOf,
273932
274427
  actorStats: () => actorStats,
273933
274428
  actorsDomain: () => actorsDomain,
274429
+ agentDefaultRuntimeForNewSession: () => agentDefaultRuntimeForNewSession,
273934
274430
  answerFallbackReason: () => answerFallbackReason,
273935
274431
  appendChatMessageOnce: () => appendChatMessageOnce,
273936
274432
  applyBuiltinSkillVariants: () => applyBuiltinSkillVariants,
@@ -274342,6 +274838,7 @@ __export(src_exports2, {
274342
274838
  variableKeyFromEnv: () => variableKeyFromEnv,
274343
274839
  warmModelPriceCache: () => warmModelPriceCache,
274344
274840
  wireRecoveredChatTurn: () => wireRecoveredChatTurn,
274841
+ withAgentDefaultRuntime: () => withAgentDefaultRuntime,
274345
274842
  workOrderFileId: () => workOrderFileId,
274346
274843
  workRuntimeExitEvent: () => workRuntimeExitEvent,
274347
274844
  workorderDraftChainDeleters: () => workorderDraftChainDeleters,
@@ -274443,6 +274940,7 @@ var init_src11 = __esm({
274443
274940
  init_dev_store();
274444
274941
  init_continuation3();
274445
274942
  init_session_runtime_target();
274943
+ init_agent_default_runtime_store();
274446
274944
  init_knowledge2();
274447
274945
  init_delegations();
274448
274946
  init_automations();
@@ -275060,7 +275558,7 @@ var DiscussionService = class {
275060
275558
  const parsed = generationSchema.safeParse(raw);
275061
275559
  if (!parsed.success) invalid("output", parsed.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join("; "));
275062
275560
  const output = parsed.data;
275063
- const at = new Date(this.now()).toISOString();
275561
+ const at2 = new Date(this.now()).toISOString();
275064
275562
  if (output.result === "update") assertSummaryLength(output.discussion.summary, "discussion.summary");
275065
275563
  if (output.result === "update" && !input.projectId && (output.topics.length || output.decisions.length || output.removals.length || output.discussion.topics.length)) {
275066
275564
  invalid("topics", "\u975E\u9879\u76EE\u8BA8\u8BBA\u4E0D\u80FD\u5173\u8054\u5171\u4EAB\u8BAE\u9898");
@@ -275082,7 +275580,7 @@ var DiscussionService = class {
275082
275580
  if (input.projectId) {
275083
275581
  const result = await this.applyChanges(tx, {
275084
275582
  projectId: input.projectId,
275085
- at,
275583
+ at: at2,
275086
275584
  mode: "chat",
275087
275585
  actorId: input.session.aiActorId,
275088
275586
  sessionId: input.session.id,
@@ -275129,7 +275627,7 @@ var DiscussionService = class {
275129
275627
  * 经校验后与讨论记录同一个事务生效;删除与合并把删之前的原内容写进 operation 留底。
275130
275628
  */
275131
275629
  async applyChanges(tx, ctx, output, hydrated) {
275132
- const { projectId: projectId2, at } = ctx;
275630
+ const { projectId: projectId2, at: at2 } = ctx;
275133
275631
  const current = await this.view(projectId2, tx);
275134
275632
  for (const [before, after] of [[ctx.before.topics, current.topics], [ctx.before.decisions, current.decisions]]) {
275135
275633
  if (JSON.stringify(before.map((r) => [r.id, r.revision]).sort()) !== JSON.stringify(after.map((r) => [r.id, r.revision]).sort())) {
@@ -275141,7 +275639,7 @@ var DiscussionService = class {
275141
275639
  projectId: projectId2,
275142
275640
  actorId: ctx.actorId,
275143
275641
  ...ctx.sessionId ? { sessionId: ctx.sessionId } : {},
275144
- at
275642
+ at: at2
275145
275643
  });
275146
275644
  const topicAliases = /* @__PURE__ */ new Map();
275147
275645
  const topicMap = new Map(current.topics.map((t) => [t.value.topicId, t.value]));
@@ -275160,9 +275658,9 @@ var DiscussionService = class {
275160
275658
  const previous3 = topicMap.get(id);
275161
275659
  const summary = (t.summary ?? previous3?.summary ?? "").trim();
275162
275660
  if (!summary) invalid("topics.summary", `\u8BAE\u9898\u300C${t.title}\u300D\u7F3A\u5C11\u7B80\u4ECB\uFF1A\u7528\u4E00\u53E5\u8BDD\u8BF4\u660E\u8FD9\u4E2A\u8BAE\u9898\u5728\u8BA8\u8BBA\u4EC0\u4E48`);
275163
- const value2 = { projectId: projectId2, topicId: id, title: t.title, summary, updated_at: previous3?.updated_at ?? at };
275661
+ const value2 = { projectId: projectId2, topicId: id, title: t.title, summary, updated_at: previous3?.updated_at ?? at2 };
275164
275662
  if (!previous3 || previous3.title !== value2.title || previous3.summary !== value2.summary) {
275165
- value2.updated_at = at;
275663
+ value2.updated_at = at2;
275166
275664
  changedTopics.add(id);
275167
275665
  }
275168
275666
  topicMap.set(id, value2);
@@ -275224,7 +275722,7 @@ var DiscussionService = class {
275224
275722
  ...rest,
275225
275723
  source_refs: source.refs,
275226
275724
  supersedes: d.record.supersedes.map((s2) => decisionAliases.get(s2) ?? s2),
275227
- updated_at: at
275725
+ updated_at: at2
275228
275726
  };
275229
275727
  if ((!old || old.record.statement !== record9.statement) && Array.from(record9.statement).length > DECISION_STATEMENT_MAX) {
275230
275728
  invalid("statement", `\u51B3\u7B56\u6B63\u6587\u8D85\u8FC7 ${DECISION_STATEMENT_MAX} \u5B57\uFF1A\u53EA\u5199\u5B9A\u4E86\u4EC0\u4E48\uFF0C\u7406\u7531\u653E rationale\u3001\u5176\u4ED6\u65B9\u6848\u653E alternatives\uFF0C\u64CD\u4F5C\u6B65\u9AA4\u548C\u547D\u4EE4\u4E0D\u5199\u8FDB\u51B3\u7B56`);
@@ -275239,7 +275737,7 @@ var DiscussionService = class {
275239
275737
  const shipped = shippedFlag ?? wasShipped;
275240
275738
  if (shipped && !wasShipped) {
275241
275739
  if (!source.shipped) invalid("shipped_ref", "\u6807\u5DF2\u4E0A\u7EBF\u5FC5\u987B\u7ED9\u51FA\u8BF4\u660E\u5DF2\u5408\u5E76\u6216\u5DF2\u90E8\u7F72\u7684\u90A3\u6761\u6D88\u606F");
275242
- shipment = { kind: "chat", name: source.shipped.human[1], at, source: source.shipped.source };
275740
+ shipment = { kind: "chat", name: source.shipped.human[1], at: at2, source: source.shipped.source };
275243
275741
  }
275244
275742
  if (shipped && record9.state !== "accepted" && !wasShipped) invalid("shipped", "\u53EA\u6709\u5DF2\u786E\u8BA4\u7684\u51B3\u7B56\u624D\u80FD\u6807\u5DF2\u4E0A\u7EBF");
275245
275743
  if (shipped) record9.shipped = true;
@@ -275249,7 +275747,7 @@ var DiscussionService = class {
275249
275747
  const candidates = [...source.authors, ...shipped && !wasShipped && source.shipped ? [source.shipped.human] : []];
275250
275748
  const author = candidates.find(([, name]) => name === record9.confirmer);
275251
275749
  if (!author) invalid("confirmer", "\u804A\u5929\u786E\u8BA4\u4EBA\u5FC5\u987B\u5BF9\u5E94\u6765\u6E90\u4E2D\u7684\u539F\u59CB\u7528\u6237\u53D1\u8A00\u4EBA");
275252
- confirmation = { kind: "chat", actorId: author[0], name: author[1], fingerprint: decisionFingerprint(record9), at };
275750
+ confirmation = { kind: "chat", actorId: author[0], name: author[1], fingerprint: decisionFingerprint(record9), at: at2 };
275253
275751
  }
275254
275752
  if (!record9.confirmer) confirmation = void 0;
275255
275753
  record9.source_refs = [...new Map([...old?.record.source_refs ?? [], ...record9.source_refs].map((r) => [JSON.stringify([r.session_id, r.message_id]), r])).values()];
@@ -275278,7 +275776,7 @@ var DiscussionService = class {
275278
275776
  }));
275279
275777
  for (const oldId of replacedIds) {
275280
275778
  const old = decisionMap.get(oldId);
275281
- decisionMap.set(oldId, { ...old, record: { ...old.record, state: "superseded", updated_at: at } });
275779
+ decisionMap.set(oldId, { ...old, record: { ...old.record, state: "superseded", updated_at: at2 } });
275282
275780
  touched.add(oldId);
275283
275781
  }
275284
275782
  for (const id of changedTopics) await tx.put("topic", entryId(projectId2, id), topicMap.get(id));
@@ -275354,32 +275852,32 @@ var DiscussionService = class {
275354
275852
  const editable = { ...parsed, shipped: parsed.shipped ?? wasShipped };
275355
275853
  const previous3 = { ...decisionEditSchema.parse(pickDecisionContent(old.value.record)), shipped: wasShipped };
275356
275854
  if (JSON.stringify(previous3) === JSON.stringify(editable)) return old;
275357
- const at = new Date(this.now()).toISOString();
275855
+ const at2 = new Date(this.now()).toISOString();
275358
275856
  const { shipped, ...content3 } = editable;
275359
275857
  if (shipped && !wasShipped && content3.state !== "accepted") invalid("shipped", "\u53EA\u6709\u5DF2\u786E\u8BA4\u7684\u51B3\u7B56\u624D\u80FD\u6807\u5DF2\u4E0A\u7EBF");
275360
275858
  const record9 = {
275361
275859
  ...old.value.record,
275362
275860
  ...content3,
275363
- updated_at: at,
275861
+ updated_at: at2,
275364
275862
  confirmer: content3.state === "accepted" ? name : content3.state === "proposed" ? null : old.value.record.confirmer
275365
275863
  };
275366
275864
  if (shipped) record9.shipped = true;
275367
275865
  else delete record9.shipped;
275368
275866
  const value2 = { ...old.value, record: record9 };
275369
275867
  if (shipped !== wasShipped) {
275370
- if (shipped) value2.shipment = { kind: "page", name, at };
275868
+ if (shipped) value2.shipment = { kind: "page", name, at: at2 };
275371
275869
  else delete value2.shipment;
275372
275870
  }
275373
275871
  const contentChanged = JSON.stringify({ ...previous3, shipped: void 0 }) !== JSON.stringify({ ...editable, shipped: void 0 });
275374
275872
  if (!contentChanged) record9.confirmer = old.value.record.confirmer;
275375
- else if (record9.state === "accepted") value2.confirmation = { kind: "page", actorId, name, fingerprint: decisionFingerprint(record9), at };
275873
+ else if (record9.state === "accepted") value2.confirmation = { kind: "page", actorId, name, fingerprint: decisionFingerprint(record9), at: at2 };
275376
275874
  else if (record9.state === "proposed") delete value2.confirmation;
275377
275875
  const current = await this.view(projectId2, tx);
275378
275876
  this.validateGraph(current.decisions.map((d) => d.value.decisionId === decisionId ? value2 : d.value));
275379
275877
  if (contentChanged && record9.state === "accepted") for (const oldId of record9.supersedes) {
275380
275878
  const replaced = current.decisions.find((d) => d.value.decisionId === oldId);
275381
275879
  assertRevision(replaced.revision, relatedRevisions[oldId] ?? 0);
275382
- await tx.put("decision", replaced.id, { ...replaced.value, record: { ...replaced.value.record, state: "superseded", updated_at: at } });
275880
+ await tx.put("decision", replaced.id, { ...replaced.value, record: { ...replaced.value.record, state: "superseded", updated_at: at2 } });
275383
275881
  }
275384
275882
  const result = await tx.put("decision", key2, value2);
275385
275883
  await this.operation(tx, actorId, "decision", key2, old.revision, result.revision);
@@ -275443,10 +275941,10 @@ var DiscussionService = class {
275443
275941
  const output = parsed.data;
275444
275942
  for (const r of output.removals) if (r.kind === "decision" && r.source_refs.length) invalid("removals.source_refs", "\u4E00\u6B21\u6027\u6574\u7406\u4E0D\u5F15\u7528\u804A\u5929\u6765\u6E90");
275445
275943
  return this.store.transaction(async (tx) => {
275446
- const at = new Date(this.now()).toISOString();
275944
+ const at2 = new Date(this.now()).toISOString();
275447
275945
  const result = await this.applyChanges(
275448
275946
  tx,
275449
- { projectId: projectId2, at, mode: "curation", actorId, before },
275947
+ { projectId: projectId2, at: at2, mode: "curation", actorId, before },
275450
275948
  { topics: output.topics, decisions: [], removals: output.removals },
275451
275949
  { decisions: [], removals: output.removals.map(() => null) }
275452
275950
  );
@@ -275460,7 +275958,7 @@ var DiscussionService = class {
275460
275958
  if (!row) invalid("shortened", `\u51B3\u7B56 ${s2.decision_id} \u4E0D\u5B58\u5728`);
275461
275959
  if (Array.from(s2.statement).length > DECISION_STATEMENT_MAX) invalid("shortened", `\u51B3\u7B56 ${s2.decision_id} \u6539\u77ED\u540E\u4ECD\u8D85\u8FC7 ${DECISION_STATEMENT_MAX} \u5B57`);
275462
275960
  if (s2.statement === row.value.record.statement && (s2.rationale ?? row.value.record.rationale) === row.value.record.rationale) continue;
275463
- const record9 = { ...row.value.record, statement: s2.statement, rationale: s2.rationale ?? row.value.record.rationale, updated_at: at };
275961
+ const record9 = { ...row.value.record, statement: s2.statement, rationale: s2.rationale ?? row.value.record.rationale, updated_at: at2 };
275464
275962
  const value2 = {
275465
275963
  ...row.value,
275466
275964
  record: record9,
@@ -275474,7 +275972,7 @@ var DiscussionService = class {
275474
275972
  id: s2.decision_id,
275475
275973
  reason: "\u4E00\u6B21\u6027\u6E05\u7406\uFF1A\u51B3\u7B56\u6B63\u6587\u6309\u65B0\u89C4\u5219\u6539\u77ED",
275476
275974
  actorId,
275477
- at,
275975
+ at: at2,
275478
275976
  before: row.value
275479
275977
  });
275480
275978
  shortened.push({ decisionId: s2.decision_id, before: row.value.record.statement, after: s2.statement });
@@ -275524,7 +276022,7 @@ var DiscussionService = class {
275524
276022
  const missing = batch.filter((row) => !given.has(row.id)).map((row) => row.id);
275525
276023
  if (missing.length) invalid("summaries", `\u8FD8\u6709 ${missing.length} \u6761\u6CA1\u4EA4\uFF1A${missing.join("\u3001")}`);
275526
276024
  return this.store.transaction(async (tx) => {
275527
- const at = new Date(this.now()).toISOString();
276025
+ const at2 = new Date(this.now()).toISOString();
275528
276026
  const out = [];
275529
276027
  for (const row of batch) {
275530
276028
  const current = await tx.get("discussion", row.id);
@@ -275538,7 +276036,7 @@ var DiscussionService = class {
275538
276036
  id: row.id,
275539
276037
  reason: `\u4E00\u6B21\u6027\u6E05\u7406\uFF1A\u8BA8\u8BBA\u6458\u8981\u6309\u65B0\u89C4\u5219\u538B\u5230 ${DISCUSSION_SUMMARY_MAX} \u5B57\u4EE5\u5185`,
275540
276038
  actorId,
275541
- at,
276039
+ at: at2,
275542
276040
  before: current.value
275543
276041
  });
275544
276042
  out.push({ sessionId: row.id, title: current.value.record.title, beforeChars: Array.from(current.value.record.summary).length, afterChars: Array.from(summary).length });
@@ -275652,7 +276150,7 @@ function fileSegment(raw, fallback) {
275652
276150
  const cleaned = raw.replace(/[\\/:*?"<>|\u0000-\u001f]+/g, "_").replace(/\s+/g, "_").replace(/^\.+/, "").replace(/_+/g, "_").replace(/^_|_$/g, "");
275653
276151
  return Array.from(cleaned).slice(0, 40).join("") || fallback;
275654
276152
  }
275655
- function oneLine2(statement) {
276153
+ function oneLine3(statement) {
275656
276154
  const first = statement.trim().split(/[。;\n]/)[0].trim();
275657
276155
  const chars = Array.from(first);
275658
276156
  return chars.length > 60 ? `${chars.slice(0, 60).join("")}\u2026` : first;
@@ -275740,7 +276238,7 @@ function renderProjectContext(input) {
275740
276238
  catalog.push(
275741
276239
  `${i + 1}. ${star}${t.value.title}\uFF08${counts2}\uFF09\u2192 \`${topicPaths[i]}\``,
275742
276240
  ...t.value.summary ? [` \u7B80\u4ECB\uFF1A${t.value.summary}`] : [],
275743
- ...accepted.map((d) => ` - ${d.value.record.shipped ? "\u3010\u5DF2\u4E0A\u7EBF\u3011" : ""}${oneLine2(d.value.record.statement)}`)
276241
+ ...accepted.map((d) => ` - ${d.value.record.shipped ? "\u3010\u5DF2\u4E0A\u7EBF\u3011" : ""}${oneLine3(d.value.record.statement)}`)
275744
276242
  );
275745
276243
  });
275746
276244
  files["PROJECT_CONTEXT.md"] = catalog.join("\n").trimEnd() + "\n";
@@ -276985,11 +277483,11 @@ function lastActivityAt(snap, nodeId) {
276985
277483
  bump(node2?.createdAt);
276986
277484
  return max;
276987
277485
  }
276988
- function nodesScanWillTouch(snap, at, ctx) {
277486
+ function nodesScanWillTouch(snap, at2, ctx) {
276989
277487
  const touched = /* @__PURE__ */ new Set();
276990
277488
  try {
276991
277489
  const { events } = scan(new WorkorderState(snap), {
276992
- at,
277490
+ at: at2,
276993
277491
  actorId: "actor:system:engine",
276994
277492
  ...ctx.config !== void 0 ? { config: ctx.config } : {},
276995
277493
  ...ctx.policy !== void 0 ? { policy: ctx.policy } : {}
@@ -278124,6 +278622,8 @@ async function startServe(opts) {
278124
278622
  let projectStateStore;
278125
278623
  let artifactStateStore;
278126
278624
  let chatSessionStore;
278625
+ let agentDefaultRuntimeResolvers = null;
278626
+ const wrapChatStore = (store, companyId) => withAgentDefaultRuntime(store, { companyId, resolvers: () => agentDefaultRuntimeResolvers });
278127
278627
  let chatTurnStore;
278128
278628
  let readMarkerStore;
278129
278629
  let platformChatRecovery;
@@ -278132,7 +278632,7 @@ async function startServe(opts) {
278132
278632
  projectStateStore = await PostgresProjectStateStore.open(pgPool, defaultCompanySchema);
278133
278633
  artifactStateStore = await PostgresArtifactStateStore.open(pgPool, defaultCompanySchema);
278134
278634
  const pgChatSessions = await PostgresChatSessionStore.open(pgPool, defaultCompanySchema, { companyId: defaultCompanyId });
278135
- chatSessionStore = pgChatSessions;
278635
+ chatSessionStore = wrapChatStore(pgChatSessions, () => defaultCompanyId);
278136
278636
  chatTurnStore = await PostgresChatTurnStore.open(pgPool, defaultCompanySchema);
278137
278637
  platformChatRecovery = PlatformChatRecoveryStore.open(pgPool, defaultCompanySchema);
278138
278638
  const backfilled = await pgChatSessions.backfillCompanyIds().catch((e) => {
@@ -278150,7 +278650,7 @@ async function startServe(opts) {
278150
278650
  } else {
278151
278651
  projectStateStore = await FileProjectStateStore.open(path28.join(opts.dir, "artifact-document-projects.json"));
278152
278652
  artifactStateStore = await FileArtifactStateStore.open(path28.join(opts.dir, "artifact-document-state.json"));
278153
- chatSessionStore = await FileChatSessionStore.open(path28.join(opts.dir, "chat-sessions.json"));
278653
+ chatSessionStore = wrapChatStore(await FileChatSessionStore.open(path28.join(opts.dir, "chat-sessions.json")), () => defaultCompanyId);
278154
278654
  chatTurnStore = await FileChatTurnStore.open(path28.join(opts.dir, "chat-session-turns.json"));
278155
278655
  readMarkerStore = await FileReadMarkerStore.open(path28.join(opts.dir, "inbox-read-markers.json"));
278156
278656
  console.log("[serve] \u4EA4\u4ED8\u7269\u72B6\u6001\u4F53\u7CFB\uFF1A\u672C\u5730 JSON dev store");
@@ -278357,18 +278857,18 @@ async function startServe(opts) {
278357
278857
  for (const id of await registry2.listVariableBindingTargetIds?.("project") ?? []) {
278358
278858
  if (id !== projectId2 && !await projectExistsIn(id, companyId ?? defaultCompanyId)) orphans.push(id);
278359
278859
  }
278360
- const at = (/* @__PURE__ */ new Date()).toISOString();
278860
+ const at2 = (/* @__PURE__ */ new Date()).toISOString();
278361
278861
  const actor = by ?? SYSTEM_ACTOR2;
278362
278862
  const text7 = (t) => `${t.kind}:${t.kind === "all" ? "" : t.id}`;
278363
278863
  for (const pid of [projectId2, ...orphans]) {
278364
- for (const r of await registry2.unbindVariableTarget({ kind: "project", id: pid }, { ...by ? { updatedBy: by } : {}, updatedAt: at })) {
278864
+ for (const r of await registry2.unbindVariableTarget({ kind: "project", id: pid }, { ...by ? { updatedBy: by } : {}, updatedAt: at2 })) {
278365
278865
  credentialAudit({
278366
278866
  kind: "credential_write",
278367
278867
  actor,
278368
278868
  variableKey: r.key,
278369
278869
  targetScope: `record:${r.variableId}`,
278370
278870
  source: pid === projectId2 ? "project-delete" : "project-delete-orphan-sweep",
278371
- timestamp: at,
278871
+ timestamp: at2,
278372
278872
  api: "records",
278373
278873
  companyId,
278374
278874
  // D-10:删项目钩子按公司起(beforeProjectDeleteFor / onProjectDeletedFor 的 companyId)
@@ -279411,7 +279911,7 @@ async function startServe(opts) {
279411
279911
  humanPrefs: (await openCompanyPlane(defaultCompanyId)).humanPrefs
279412
279912
  },
279413
279913
  buildStores: async (companyId) => {
279414
- const chatSessions = await PostgresChatSessionStore.open(pgPool, companyEngineDirName(companyId), { companyId });
279914
+ const chatSessions = wrapChatStore(await PostgresChatSessionStore.open(pgPool, companyEngineDirName(companyId), { companyId }), () => companyId);
279415
279915
  const projects = await PostgresProjectStateStore.open(pgPool, companyEngineDirName(companyId));
279416
279916
  const artifacts = await PostgresArtifactStateStore.open(pgPool, companyEngineDirName(companyId));
279417
279917
  const chatTurns = await PostgresChatTurnStore.open(pgPool, companyEngineDirName(companyId));
@@ -279630,14 +280130,14 @@ async function startServe(opts) {
279630
280130
  const chatLiveSessions = /* @__PURE__ */ new Map();
279631
280131
  const chatRunByDispatch = /* @__PURE__ */ new Map();
279632
280132
  const markServeStoppedInFlight = async () => {
279633
- const at = (/* @__PURE__ */ new Date()).toISOString();
280133
+ const at2 = (/* @__PURE__ */ new Date()).toISOString();
279634
280134
  const runIds = [...new Set([...chatLiveSessions.values()].map((c) => c.sessionId))];
279635
280135
  await Promise.all(runIds.map(async (runId) => {
279636
280136
  try {
279637
280137
  const run = await runRoutedTrace.getRun(runId);
279638
280138
  if (!run || run.status !== "running") return;
279639
280139
  const base = run.metadata && typeof run.metadata === "object" && !Array.isArray(run.metadata) ? run.metadata : {};
279640
- await runRoutedTrace.updateRun(runId, { metadata: { ...base, [SERVE_STOPPED_IN_FLIGHT_KEY]: at } });
280140
+ await runRoutedTrace.updateRun(runId, { metadata: { ...base, [SERVE_STOPPED_IN_FLIGHT_KEY]: at2 } });
279641
280141
  } catch (err) {
279642
280142
  console.warn(`[serve] \u505C\u673A\u7559\u75D5\u5931\u8D25 run=${runId}\uFF08\u8FD9\u4E00\u8F6E\u82E5\u6CA1\u63A5\u56DE\u6765\u5C06\u663E\u793A\u300C\u5BF9\u8BDD\u5DF2\u4E2D\u65AD\u300D\uFF09: ${String(err)}`);
279643
280143
  }
@@ -279766,6 +280266,11 @@ async function startServe(opts) {
279766
280266
  return plan && plan.injectedHistoryCount > 0 ? plan.runtimeMessage : void 0;
279767
280267
  };
279768
280268
  const resolveCompanyBinding = createCompanyBindingResolver({ actors, defaultCompanyId });
280269
+ const resolveAgentConfiguredModel = async (cid, actorId) => {
280270
+ const ctx = await actors.resolveCtx(cid ?? defaultCompanyId);
280271
+ return (await ctx.service.latestConfig(actorId))?.model ?? null;
280272
+ };
280273
+ agentDefaultRuntimeResolvers = { resolveBinding: resolveCompanyBinding, resolveActorModel: resolveAgentConfiguredModel };
279769
280274
  if (pgPool) {
279770
280275
  const pinPool = pgPool;
279771
280276
  void (async () => {
@@ -280308,10 +280813,7 @@ async function startServe(opts) {
280308
280813
  /* ADR 0613:建会话 / 「恢复为员工默认运行配置」这两下要读员工详情页配的型号,按**当前公司**读
280309
280814
  (与 `resolveBinding` 同一条理由:全局 `registry` 对已切 `actor-config` 的公司是冻结旧镜像)。
280310
280815
  ⚠ 只有这两下读它;解析每一轮的模型依旧不读员工配置(ADR 0610 D1)。 */
280311
- resolveActorModel: async (cid, actorId) => {
280312
- const ctx = await actors.resolveCtx(cid ?? defaultCompanyId);
280313
- return (await ctx.service.latestConfig(actorId))?.model ?? null;
280314
- },
280816
+ resolveActorModel: resolveAgentConfiguredModel,
280315
280817
  // 按 runId 路由:切换后新会话的事件落在本公司库里,共享 store 会一条都补不出 parts。
280316
280818
  // ⚠ `runRoutedTrace` 声明在本行**之后**:包成箭头函数避 TDZ(本域只需要 listEvents)。
280317
280819
  trace: { listEvents: (runId, o) => runRoutedTrace.listEvents(runId, o) },
@@ -280891,7 +281393,7 @@ async function startServe(opts) {
280891
281393
  ...await materializeSkillFiles({ service: actors.service, actorId, runtimeKind })
280892
281394
  }),
280893
281395
  uploadChatAttachment: async ({ contentBase64 }) => ({ blobRef: await assets.put(new Uint8Array(Buffer.from(contentBase64, "base64"))) }),
280894
- onDispatchCommandCompleted: async ({ dispatchId, command: command2, durableRefs, at, delivered, pendingSteps }) => {
281396
+ onDispatchCommandCompleted: async ({ dispatchId, command: command2, durableRefs, at: at2, delivered, pendingSteps }) => {
280895
281397
  const sink = await trajectoryForDispatch(dispatchId);
280896
281398
  if (pendingSteps && pendingSteps.length > 0) {
280897
281399
  sink.checkpointState?.(dispatchId, { pendingSteps: [...pendingSteps] });
@@ -280904,7 +281406,7 @@ async function startServe(opts) {
280904
281406
  // 稳定步骤 id = 命令名:同一步骤重跑时 id 一致(checkpoint 契约对 stable id 的要求),
280905
281407
  // 恢复时下一趟能看出「上一趟已经 propose 过 / 已经 gap 过」。
280906
281408
  completedStepIds: [command2],
280907
- at
281409
+ at: at2
280908
281410
  });
280909
281411
  await sink.flush?.(dispatchId);
280910
281412
  if (!delivered) return;
@@ -280923,7 +281425,7 @@ async function startServe(opts) {
280923
281425
  ...delivered.risks ? { risks: delivered.risks } : {},
280924
281426
  ...delivered.nextActions ? { nextActions: delivered.nextActions } : {},
280925
281427
  ...delivered.verificationGaps ? { verificationGaps: delivered.verificationGaps } : {},
280926
- at
281428
+ at: at2
280927
281429
  }
280928
281430
  );
280929
281431
  },
@@ -281633,17 +282135,17 @@ async function startServe(opts) {
281633
282135
  };
281634
282136
  const handshakeThrottleOpts = {};
281635
282137
  {
281636
- const num4 = (name) => {
282138
+ const num5 = (name) => {
281637
282139
  const raw = process.env[name];
281638
282140
  if (raw === void 0 || raw.trim() === "") return void 0;
281639
282141
  const n = Number(raw);
281640
282142
  return Number.isFinite(n) && n > 0 ? n : void 0;
281641
282143
  };
281642
- const mf = num4("OASIS_NODE_HANDSHAKE_MAX_FAILURES");
282144
+ const mf = num5("OASIS_NODE_HANDSHAKE_MAX_FAILURES");
281643
282145
  if (mf !== void 0) handshakeThrottleOpts.maxFailures = mf;
281644
- const w2 = num4("OASIS_NODE_HANDSHAKE_WINDOW_MS");
282146
+ const w2 = num5("OASIS_NODE_HANDSHAKE_WINDOW_MS");
281645
282147
  if (w2 !== void 0) handshakeThrottleOpts.windowMs = w2;
281646
- const b2 = num4("OASIS_NODE_HANDSHAKE_BLOCK_MS");
282148
+ const b2 = num5("OASIS_NODE_HANDSHAKE_BLOCK_MS");
281647
282149
  if (b2 !== void 0) handshakeThrottleOpts.blockMs = b2;
281648
282150
  }
281649
282151
  const dataplaneTokens = createDataplaneTokenIssuer({ secretFile: path28.join(opts.dir, "dataplane-token-secret") });
@@ -283447,8 +283949,8 @@ async function startServe(opts) {
283447
283949
  const failedWorks = snap.works.filter((w2) => w2.nodeId === node2.id && w2.outcome === "failed");
283448
283950
  if (failedWorks.length === 0) continue;
283449
283951
  const firstFailed = failedWorks.reduce((a, b2) => {
283450
- const at = (x2) => x2.endedAt ?? x2.deadAt ?? x2.createdAt;
283451
- return at(a) < at(b2) ? a : b2;
283952
+ const at2 = (x2) => x2.endedAt ?? x2.deadAt ?? x2.createdAt;
283953
+ return at2(a) < at2(b2) ? a : b2;
283452
283954
  }, failedWorks[0]);
283453
283955
  const firstFailedAt = firstFailed.endedAt ?? firstFailed.deadAt ?? firstFailed.createdAt;
283454
283956
  const sinceMs = now - Date.parse(firstFailedAt);
@@ -286686,8 +287188,8 @@ function planExec(opts) {
286686
287188
  function computeExitCode(code2, signal) {
286687
287189
  if (code2 !== null) return code2;
286688
287190
  if (signal) {
286689
- const num4 = os12.constants.signals[signal];
286690
- return 128 + (typeof num4 === "number" ? num4 : 1);
287191
+ const num5 = os12.constants.signals[signal];
287192
+ return 128 + (typeof num5 === "number" ? num5 : 1);
286691
287193
  }
286692
287194
  return 1;
286693
287195
  }
@@ -288620,9 +289122,9 @@ function buildCommandIndex() {
288620
289122
  byGroup.set(decl.group, arr);
288621
289123
  }
288622
289124
  const NAME_WIDTH = 22;
288623
- const fmtRow = (key2, indent2) => {
289125
+ const fmtRow = (key2, indent3) => {
288624
289126
  const decl = COMMAND_DECLS[key2];
288625
- const name = " ".repeat(indent2) + key2;
289127
+ const name = " ".repeat(indent3) + key2;
288626
289128
  const summary = decl ? indexSummary(decl.description) : "";
288627
289129
  return name.length < NAME_WIDTH ? ` ${name.padEnd(NAME_WIDTH)}${summary}` : ` ${name} ${summary}`;
288628
289130
  };
@@ -289242,15 +289744,16 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
289242
289744
  const p2 = JSON.parse(dataLine.slice(5).trim());
289243
289745
  if (p2.status === "approved") {
289244
289746
  receivedTerminal = true;
289747
+ const approver = p2.authorizedByName?.trim() || NEUTRAL_APPROVER;
289245
289748
  if (p2.receipt) {
289246
289749
  const by2 = p2.authorizedBy ? `
289247
- \uFF08\u5DF2\u7531 ${p2.authorizedBy} \u6388\u6743\u5E76\u4EE5\u5176\u540D\u4E49\u6267\u884C\uFF09` : "";
289750
+ \uFF08\u5DF2\u7531 ${approver} \u6388\u6743\u5E76\u4EE5\u5176\u540D\u4E49\u6267\u884C\uFF09` : "";
289248
289751
  return {
289249
289752
  message: `${p2.receipt.message}${by2}`,
289250
289753
  ...p2.receipt.data !== void 0 ? { data: p2.receipt.data } : {}
289251
289754
  };
289252
289755
  }
289253
- const by = p2.authorizedBy ? `\u5DF2\u7531 ${p2.authorizedBy} \u6388\u6743\u5E76\u4EE5\u5176\u540D\u4E49\u6267\u884C` : "\u4EBA\u5DF2\u6388\u6743\u5E76\u6267\u884C";
289756
+ const by = p2.authorizedBy ? `\u5DF2\u7531 ${approver} \u6388\u6743\u5E76\u4EE5\u5176\u540D\u4E49\u6267\u884C` : "\u4EBA\u5DF2\u6388\u6743\u5E76\u6267\u884C";
289254
289757
  return {
289255
289758
  message: `\u2713 ${by}\u300C${p2.effectLabel ?? ""}\u300D\u3002`,
289256
289759
  data: { outcome: "executed", draftId, ...p2.command ? { command: p2.command } : {} }
@@ -289292,7 +289795,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
289292
289795
  }
289293
289796
  }
289294
289797
  }
289295
- var CLI_VERSION = "2.2.70" ? "2.2.70" : "dev";
289798
+ var CLI_VERSION = "2.2.72" ? "2.2.72" : "dev";
289296
289799
  function apiHeaders(token, company) {
289297
289800
  const headers = {
289298
289801
  authorization: `Bearer ${token}`,
@@ -292394,13 +292897,13 @@ ${res.warning}`);
292394
292897
  }
292395
292898
  break;
292396
292899
  }
292397
- const at = c.at;
292398
- const which = at.isCurrentHead ? "current head" : "\u5386\u53F2\u7248\u672C";
292399
- println(`# ${at.artifactId} @ ${at.revisionId}\uFF08${which}\uFF09 by ${at.author} "${at.reason}"`);
292400
- if (at.deliveredHead === null) {
292900
+ const at2 = c.at;
292901
+ const which = at2.isCurrentHead ? "current head" : "\u5386\u53F2\u7248\u672C";
292902
+ println(`# ${at2.artifactId} @ ${at2.revisionId}\uFF08${which}\uFF09 by ${at2.author} "${at2.reason}"`);
292903
+ if (at2.deliveredHead === null) {
292401
292904
  println(`# \u26A0 \u672C\u4EA7\u7269**\u5C1A\u672A\u4EA4\u4ED8**\uFF08\u65E0\u5DF2 conclude \u7684\u7248\u672C\uFF09\u2014\u2014\u4E0B\u6E38\u8FD8\u62FF\u4E0D\u5230\u5B83\u3002`);
292402
- } else if (at.deliveredHead !== at.revisionId) {
292403
- println(`# \u26A0 \u5DF2\u4EA4\u4ED8\u7248\u672C\u662F ${at.deliveredHead}\uFF08**\u4E0B\u6E38\u6D88\u8D39\u7684\u662F\u5B83**\uFF09\u2014\u2014\u8981\u53D6\u90A3\u4E00\u7248\uFF1A\`oasis content ${at.deliveredHead}\``);
292905
+ } else if (at2.deliveredHead !== at2.revisionId) {
292906
+ println(`# \u26A0 \u5DF2\u4EA4\u4ED8\u7248\u672C\u662F ${at2.deliveredHead}\uFF08**\u4E0B\u6E38\u6D88\u8D39\u7684\u662F\u5B83**\uFF09\u2014\u2014\u8981\u53D6\u90A3\u4E00\u7248\uFF1A\`oasis content ${at2.deliveredHead}\``);
292404
292907
  } else {
292405
292908
  println(`# = \u5DF2\u4EA4\u4ED8\u7248\u672C\uFF08\u4E0B\u6E38\u6D88\u8D39\u7684\u5C31\u662F\u8FD9\u4E00\u7248\uFF09`);
292406
292909
  }
@@ -293098,7 +293601,7 @@ function shimScript() {
293098
293601
  }
293099
293602
 
293100
293603
  // src/index.ts
293101
- var PKG_VERSION = true ? "2.2.70" : "dev";
293604
+ var PKG_VERSION = true ? "2.2.72" : "dev";
293102
293605
  var LOCAL_BIN = localBin();
293103
293606
  var NPM_PREFIX = npmPrefix();
293104
293607
  var INSTANCE = DEFAULT_INSTANCE;