@sema-agent/cli 1.0.75 → 1.0.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/npm-shrinkwrap.json +8 -8
- package/package.json +3 -3
- package/sema-main.js +1176 -541
- package/sema.js +1 -1
package/sema-main.js
CHANGED
|
@@ -55924,10 +55924,11 @@ function structuredToToolUseResult(structured, modelText) {
|
|
|
55924
55924
|
}
|
|
55925
55925
|
] : []) } } : null;
|
|
55926
55926
|
case "agent": {
|
|
55927
|
-
|
|
55927
|
+
let receipt = readAsyncLaunchedAgentReceipt(s);
|
|
55928
|
+
if (receipt === null)
|
|
55928
55929
|
return null;
|
|
55929
|
-
let agentId =
|
|
55930
|
-
return
|
|
55930
|
+
let agentId = receipt.taskId;
|
|
55931
|
+
return typeof s.description != "string" || typeof s.prompt != "string" ? null : (registerOutstandingBgTask(agentId, s.description, s.prompt, receipt.seq), {
|
|
55931
55932
|
toolUseResult: {
|
|
55932
55933
|
isAsync: !0,
|
|
55933
55934
|
status: "async_launched",
|
|
@@ -56047,6 +56048,18 @@ function reportFindingsToolUseResult(structured, rawInput) {
|
|
|
56047
56048
|
}
|
|
56048
56049
|
};
|
|
56049
56050
|
}
|
|
56051
|
+
function readAsyncLaunchedAgentReceipt(structured) {
|
|
56052
|
+
if (structured === null || typeof structured != "object")
|
|
56053
|
+
return null;
|
|
56054
|
+
let s = structured;
|
|
56055
|
+
if (s.type !== "agent" || s.status !== "async_launched")
|
|
56056
|
+
return null;
|
|
56057
|
+
let taskId = s.task_id;
|
|
56058
|
+
return typeof taskId != "string" || taskId.length === 0 ? null : {
|
|
56059
|
+
taskId,
|
|
56060
|
+
...typeof s.seq == "number" && Number.isFinite(s.seq) ? { seq: s.seq } : {}
|
|
56061
|
+
};
|
|
56062
|
+
}
|
|
56050
56063
|
function readCompletedAgentCard(structured) {
|
|
56051
56064
|
if (structured === null || typeof structured != "object")
|
|
56052
56065
|
return null;
|
|
@@ -56471,6 +56484,26 @@ var labels, init_engineToolLabelStore = __esm({
|
|
|
56471
56484
|
});
|
|
56472
56485
|
|
|
56473
56486
|
// node_modules/@sema-agent/client-core/dist/subagentContentStore.js
|
|
56487
|
+
function coerceOutput(v2) {
|
|
56488
|
+
if (v2 != null) {
|
|
56489
|
+
if (typeof v2 == "string")
|
|
56490
|
+
return v2;
|
|
56491
|
+
if (Array.isArray(v2)) {
|
|
56492
|
+
let parts = [];
|
|
56493
|
+
for (let block2 of v2)
|
|
56494
|
+
if (block2 && typeof block2 == "object") {
|
|
56495
|
+
let b3 = block2;
|
|
56496
|
+
b3.type === "text" && typeof b3.text == "string" ? parts.push(b3.text) : b3.type === "image" && parts.push("[image]");
|
|
56497
|
+
}
|
|
56498
|
+
return parts.join("");
|
|
56499
|
+
}
|
|
56500
|
+
try {
|
|
56501
|
+
return JSON.stringify(v2);
|
|
56502
|
+
} catch {
|
|
56503
|
+
return String(v2);
|
|
56504
|
+
}
|
|
56505
|
+
}
|
|
56506
|
+
}
|
|
56474
56507
|
function touchLru(map2, key) {
|
|
56475
56508
|
let v2 = map2.get(key);
|
|
56476
56509
|
v2 !== void 0 && (map2.delete(key), map2.set(key, v2));
|
|
@@ -56480,7 +56513,7 @@ function stateFor(taskId, parentToolCallId) {
|
|
|
56480
56513
|
if (s)
|
|
56481
56514
|
touchLru(tasks, taskId);
|
|
56482
56515
|
else {
|
|
56483
|
-
if (tasks.size >=
|
|
56516
|
+
if (tasks.size >= MAX_TASKS) {
|
|
56484
56517
|
let oldest = tasks.keys().next().value;
|
|
56485
56518
|
oldest !== void 0 && tasks.delete(oldest);
|
|
56486
56519
|
}
|
|
@@ -56489,7 +56522,7 @@ function stateFor(taskId, parentToolCallId) {
|
|
|
56489
56522
|
return s;
|
|
56490
56523
|
}
|
|
56491
56524
|
function pushItem(s, item) {
|
|
56492
|
-
s.items.push(item), s.items.length >
|
|
56525
|
+
s.items.push(item), s.items.length > MAX_ITEMS_PER_TASK && (s.items.splice(0, s.items.length - MAX_ITEMS_PER_TASK), s.openTools.clear(), s.items.forEach((it2, i) => {
|
|
56493
56526
|
it2.kind === "tool" && it2.output === void 0 && s.openTools.set(it2.id, i);
|
|
56494
56527
|
}));
|
|
56495
56528
|
}
|
|
@@ -56506,14 +56539,20 @@ function scheduleNotify(taskId) {
|
|
|
56506
56539
|
notifyListener(id);
|
|
56507
56540
|
} catch {
|
|
56508
56541
|
}
|
|
56509
|
-
},
|
|
56542
|
+
}, NOTIFY_COALESCE_MS));
|
|
56510
56543
|
}
|
|
56511
|
-
function
|
|
56544
|
+
function registerSubagentContentAlias(parentToolCallId, taskId) {
|
|
56545
|
+
aliasContentKey(parentToolCallId, taskId);
|
|
56546
|
+
}
|
|
56547
|
+
function aliasContentKey(parentToolCallId, taskId) {
|
|
56512
56548
|
if (!parentToolCallId || !taskId || parentToolCallId === taskId)
|
|
56513
|
-
return;
|
|
56514
|
-
parentToTask.set(parentToolCallId, taskId),
|
|
56549
|
+
return !1;
|
|
56550
|
+
parentToTask.set(parentToolCallId, taskId), pendingNotify.delete(parentToolCallId) && pendingNotify.add(taskId);
|
|
56515
56551
|
let parked = tasks.get(parentToolCallId);
|
|
56516
|
-
parked && !tasks.has(taskId) && (tasks.delete(parentToolCallId), tasks.set(taskId, parked), scheduleNotify(taskId));
|
|
56552
|
+
return parked && !tasks.has(taskId) && (tasks.delete(parentToolCallId), tasks.set(taskId, parked), scheduleNotify(taskId)), !0;
|
|
56553
|
+
}
|
|
56554
|
+
function registerSubagentAlias(parentToolCallId, taskId) {
|
|
56555
|
+
aliasContentKey(parentToolCallId, taskId) && taskToParent.set(taskId, parentToolCallId);
|
|
56517
56556
|
}
|
|
56518
56557
|
function canonicalKey(ev) {
|
|
56519
56558
|
return ev.taskId !== ev.parentToolCallId ? ev.taskId : parentToTask.get(ev.parentToolCallId) ?? ev.parentToolCallId;
|
|
@@ -56589,7 +56628,7 @@ function clearSubagentContent(taskId) {
|
|
|
56589
56628
|
}
|
|
56590
56629
|
function recordBgTerminalFacts(taskId, facts2) {
|
|
56591
56630
|
if (taskId) {
|
|
56592
|
-
if (bgFacts.size >=
|
|
56631
|
+
if (bgFacts.size >= MAX_TASKS && !bgFacts.has(taskId)) {
|
|
56593
56632
|
let oldest = bgFacts.keys().next().value;
|
|
56594
56633
|
oldest !== void 0 && bgFacts.delete(oldest);
|
|
56595
56634
|
}
|
|
@@ -56602,7 +56641,7 @@ function getBgTerminalFacts(taskId) {
|
|
|
56602
56641
|
}
|
|
56603
56642
|
function recordBgParentRun(taskId, runId) {
|
|
56604
56643
|
if (!(!taskId || !runId || taskId === runId)) {
|
|
56605
|
-
if (bgParentRun.size >=
|
|
56644
|
+
if (bgParentRun.size >= MAX_TASKS * 2 && !bgParentRun.has(taskId)) {
|
|
56606
56645
|
let oldest = bgParentRun.keys().next().value;
|
|
56607
56646
|
oldest !== void 0 && bgParentRun.delete(oldest);
|
|
56608
56647
|
}
|
|
@@ -56632,9 +56671,9 @@ function subscribeSubagentContent(fn2) {
|
|
|
56632
56671
|
notifyListener === fn2 && (notifyListener = null);
|
|
56633
56672
|
};
|
|
56634
56673
|
}
|
|
56635
|
-
var tasks, parentToTask, taskToParent, notifyListener, pendingNotify, notifyTimer, bgFacts, bgParentRun, ownEngineRuns, init_subagentContentStore = __esm({
|
|
56674
|
+
var MAX_ITEMS_PER_TASK, MAX_TASKS, NOTIFY_COALESCE_MS, tasks, parentToTask, taskToParent, notifyListener, pendingNotify, notifyTimer, bgFacts, bgParentRun, ownEngineRuns, init_subagentContentStore = __esm({
|
|
56636
56675
|
"node_modules/@sema-agent/client-core/dist/subagentContentStore.js"() {
|
|
56637
|
-
tasks = /* @__PURE__ */ new Map(), parentToTask = /* @__PURE__ */ new Map(), taskToParent = /* @__PURE__ */ new Map(), notifyListener = null, pendingNotify = /* @__PURE__ */ new Set(), notifyTimer = null;
|
|
56676
|
+
MAX_ITEMS_PER_TASK = 200, MAX_TASKS = 32, NOTIFY_COALESCE_MS = 250, tasks = /* @__PURE__ */ new Map(), parentToTask = /* @__PURE__ */ new Map(), taskToParent = /* @__PURE__ */ new Map(), notifyListener = null, pendingNotify = /* @__PURE__ */ new Set(), notifyTimer = null;
|
|
56638
56677
|
bgFacts = /* @__PURE__ */ new Map();
|
|
56639
56678
|
bgParentRun = /* @__PURE__ */ new Map();
|
|
56640
56679
|
ownEngineRuns = /* @__PURE__ */ new Set();
|
|
@@ -56650,6 +56689,7 @@ var assistantArm, userArm, systemArm, diagnosticsArm, steeringInjectedArm, works
|
|
|
56650
56689
|
init_diagnostics();
|
|
56651
56690
|
init_engineToolLabelStore();
|
|
56652
56691
|
init_subagentContentStore();
|
|
56692
|
+
init_toolResult();
|
|
56653
56693
|
init_workflow();
|
|
56654
56694
|
init_ids();
|
|
56655
56695
|
init_wireShapes();
|
|
@@ -56818,7 +56858,11 @@ var assistantArm, userArm, systemArm, diagnosticsArm, steeringInjectedArm, works
|
|
|
56818
56858
|
list.length > 0 && (yield chrome({ kind: "prompt_suggestions", laneProof: MAIN, suggestions: list }));
|
|
56819
56859
|
}, toolEndResultArm = function* (m2, { ctx, idOf, cards, panel }) {
|
|
56820
56860
|
let callId = typeof m2.toolCallId == "string" ? m2.toolCallId : void 0;
|
|
56821
|
-
recordEngineToolLabel(callId, m2.label), callId !== void 0
|
|
56861
|
+
if (recordEngineToolLabel(callId, m2.label), callId !== void 0) {
|
|
56862
|
+
let launched = readAsyncLaunchedAgentReceipt(m2.structured);
|
|
56863
|
+
launched !== null && registerSubagentContentAlias(callId, launched.taskId);
|
|
56864
|
+
}
|
|
56865
|
+
callId !== void 0 && (yield* panel.settle(callId, m2.isError === !0, m2.output !== void 0 ? flattenWireOutput(m2.output) : void 0));
|
|
56822
56866
|
let p = callId !== void 0 ? cards.peek(callId) : void 0;
|
|
56823
56867
|
if (p === void 0 || callId === void 0)
|
|
56824
56868
|
return;
|
|
@@ -58120,15 +58164,15 @@ function wireAuthTokenFor(baseUrl, token) {
|
|
|
58120
58164
|
}
|
|
58121
58165
|
function makeEngineWireClient(cfg) {
|
|
58122
58166
|
try {
|
|
58123
|
-
|
|
58167
|
+
let base = {
|
|
58124
58168
|
baseUrl: cfg.baseUrl,
|
|
58125
|
-
authToken: resolveWireAuth(cfg.baseUrl, cfg.token),
|
|
58126
58169
|
// F-011 停发:缺席/空串=不给键(SDK 6.11 缺席=不发 x-agent-principal 头,owner-null)。
|
|
58127
58170
|
...cfg.principal !== void 0 && cfg.principal !== "" ? { principal: cfg.principal } : {},
|
|
58128
58171
|
...cfg.timeoutMs !== void 0 ? { timeoutMs: cfg.timeoutMs } : {},
|
|
58129
58172
|
maxRetries: cfg.maxRetries ?? 0,
|
|
58130
58173
|
...cfg.fetchImpl ? { fetch: cfg.fetchImpl } : {}
|
|
58131
|
-
}
|
|
58174
|
+
};
|
|
58175
|
+
return typeof cfg.token == "object" ? new AgentClient({ ...base, authToken: cfg.token }) : new AgentClient({ ...base, authToken: resolveWireAuth(cfg.baseUrl, cfg.token) });
|
|
58132
58176
|
} catch {
|
|
58133
58177
|
return null;
|
|
58134
58178
|
}
|
|
@@ -59805,14 +59849,24 @@ async function* runStreamInner(events3, ctx, handle2 = {}) {
|
|
|
59805
59849
|
let sub = ev;
|
|
59806
59850
|
publishSubagentContentEvent({
|
|
59807
59851
|
type: sub.type,
|
|
59808
|
-
//
|
|
59852
|
+
// 🔴 EventIdentity 上**没有** `taskId`(sdk events.d.ts 的 `interface EventIdentity` 只有
|
|
59853
|
+
// eventId / parentToolCallId,加 LIVE 白名单四臂的 sourceTaskId / bgAgentId;`taskId` 只长在
|
|
59854
|
+
// `meta` 首帧)⇒ 生产上这里恒走右臂,归账键由 store 的 `parentToTask` 补(canonicalKey)。
|
|
59855
|
+
// `??` 保留是**容将来**:哪天上游真在内容帧上发 taskId,这条直接认,不必改形。
|
|
59856
|
+
// (0.30.0 发包扫描订正:此前这行注释写「taskId is on every subagent event」,与 store 侧
|
|
59857
|
+
// `canonicalKey` 的注释互相矛盾,且被 .d.ts 直接证伪。)
|
|
59809
59858
|
taskId: sub.taskId ?? sub.parentToolCallId,
|
|
59810
59859
|
parentToolCallId: sub.parentToolCallId,
|
|
59811
59860
|
delta: sub.delta,
|
|
59812
59861
|
toolCallId: sub.toolCallId,
|
|
59813
59862
|
toolName: sub.toolName,
|
|
59814
59863
|
args: sub.args,
|
|
59815
|
-
|
|
59864
|
+
// #158 移交①([3674](d) 姊妹病,2026-08-12):此前是 `typeof sub.output === 'string' ?
|
|
59865
|
+
// sub.output : undefined` —— 而 wire 的 `tool_end.output` 是非均匀的(块数组形合法),
|
|
59866
|
+
// 于是子代 lane 的块数组 output 经本臂进内容账本**恒空**(查看态卡有工具、结果栏永远空白)。
|
|
59867
|
+
// 换用 store 自己的那个唯一字符串化口(tail 腿 engineSubagentTail 用的同一份):两条腿喂
|
|
59868
|
+
// 同一个账本,字符串化口就不能有第二份。
|
|
59869
|
+
output: coerceOutput(sub.output),
|
|
59816
59870
|
isError: sub.isError
|
|
59817
59871
|
});
|
|
59818
59872
|
continue;
|
|
@@ -59883,7 +59937,31 @@ var MAIN2, reportedDroppedTypes, DROPPED_TYPE_MEMO_CAP, DROPPED_TYPE_DISPLAY_CAP
|
|
|
59883
59937
|
}
|
|
59884
59938
|
});
|
|
59885
59939
|
|
|
59940
|
+
// node_modules/@sema-agent/client-core/dist/abortableSleep.js
|
|
59941
|
+
function abortableSleep(ms, signal) {
|
|
59942
|
+
return signal.aborted ? Promise.resolve() : new Promise((resolve57) => {
|
|
59943
|
+
let timer2 = setTimeout(() => {
|
|
59944
|
+
signal.removeEventListener("abort", onAbort), resolve57();
|
|
59945
|
+
}, ms), onAbort = () => {
|
|
59946
|
+
clearTimeout(timer2), resolve57();
|
|
59947
|
+
};
|
|
59948
|
+
signal.addEventListener("abort", onAbort, { once: !0 });
|
|
59949
|
+
});
|
|
59950
|
+
}
|
|
59951
|
+
var init_abortableSleep = __esm({
|
|
59952
|
+
"node_modules/@sema-agent/client-core/dist/abortableSleep.js"() {
|
|
59953
|
+
}
|
|
59954
|
+
});
|
|
59955
|
+
|
|
59886
59956
|
// node_modules/@sema-agent/client-core/dist/adapter/activeRunSelfHeal.js
|
|
59957
|
+
function askParkForeignGateKind(row2) {
|
|
59958
|
+
let kind = typeof row2.gateKind == "string" && row2.gateKind.length > 0 ? row2.gateKind : null;
|
|
59959
|
+
return kind !== null && !ASK_PARK_GATE_KINDS.includes(kind) ? kind : null;
|
|
59960
|
+
}
|
|
59961
|
+
function sessionOpts(deps2) {
|
|
59962
|
+
let sessionId = deps2?.sessionId;
|
|
59963
|
+
return typeof sessionId == "string" && sessionId.length > 0 ? { session: sessionId } : {};
|
|
59964
|
+
}
|
|
59887
59965
|
function describeFailure(e) {
|
|
59888
59966
|
if (typeof e == "object" && e !== null && "message" in e) {
|
|
59889
59967
|
let m2 = e.message;
|
|
@@ -59899,6 +59977,64 @@ function readStatus(record2) {
|
|
|
59899
59977
|
function reopenDelivered(verdict) {
|
|
59900
59978
|
return verdict.reopened === !0 && verdict.presented !== !1;
|
|
59901
59979
|
}
|
|
59980
|
+
function atMostOnceFailureClass(e) {
|
|
59981
|
+
let status3 = e?.status;
|
|
59982
|
+
return typeof status3 == "number" && status3 >= 400 && status3 < 500 ? "rejected" : "unknown";
|
|
59983
|
+
}
|
|
59984
|
+
function readSteerDelivery(receipt) {
|
|
59985
|
+
if (typeof receipt != "object" || receipt === null || !("delivery" in receipt))
|
|
59986
|
+
return null;
|
|
59987
|
+
let d4 = receipt.delivery;
|
|
59988
|
+
return typeof d4 == "string" && d4.length > 0 ? d4 : null;
|
|
59989
|
+
}
|
|
59990
|
+
function readSteerReceiptStatus(receipt) {
|
|
59991
|
+
if (typeof receipt != "object" || receipt === null || !("status" in receipt))
|
|
59992
|
+
return null;
|
|
59993
|
+
let s = receipt.status;
|
|
59994
|
+
return typeof s == "string" && s.length > 0 ? s : null;
|
|
59995
|
+
}
|
|
59996
|
+
function claimPollSleep(ms, signal) {
|
|
59997
|
+
return abortableSleep(ms, signal ?? new AbortController().signal);
|
|
59998
|
+
}
|
|
59999
|
+
function claimProbeLease(caller, remainingMs) {
|
|
60000
|
+
let ctl = new AbortController(), timer2 = setTimeout(() => {
|
|
60001
|
+
ctl.abort(new Error("probe deadline"));
|
|
60002
|
+
}, Math.max(1, remainingMs)), onCaller = () => {
|
|
60003
|
+
ctl.abort(caller?.reason);
|
|
60004
|
+
};
|
|
60005
|
+
return caller?.aborted === !0 ? onCaller() : caller?.addEventListener("abort", onCaller, { once: !0 }), {
|
|
60006
|
+
signal: ctl.signal,
|
|
60007
|
+
release: () => {
|
|
60008
|
+
clearTimeout(timer2), caller?.removeEventListener("abort", onCaller);
|
|
60009
|
+
}
|
|
60010
|
+
};
|
|
60011
|
+
}
|
|
60012
|
+
async function waitForClaimRelease(taskId, deps2) {
|
|
60013
|
+
let now2 = typeof deps2.now == "function" ? deps2.now : () => Date.now(), sleep10 = typeof deps2.sleep == "function" ? deps2.sleep : claimPollSleep, budgetMs = Number.isFinite(deps2.budgetMs) && deps2.budgetMs > 0 ? deps2.budgetMs : 0, startedAt = now2(), deadline = startedAt + budgetMs, waited = () => now2() - startedAt, isAborted3 = () => deps2.signal?.aborted === !0, delay = CANCEL_POLL_START_MS, lastStatus = null;
|
|
60014
|
+
for (; ; ) {
|
|
60015
|
+
if (isAborted3())
|
|
60016
|
+
return { released: !1, waitedMs: waited(), aborted: !0, lastStatus };
|
|
60017
|
+
let remaining = deadline - now2();
|
|
60018
|
+
if (remaining <= 0)
|
|
60019
|
+
return { released: !1, waitedMs: waited(), aborted: !1, lastStatus };
|
|
60020
|
+
if (await sleep10(Math.min(delay, remaining), deps2.signal), isAborted3())
|
|
60021
|
+
return { released: !1, waitedMs: waited(), aborted: !0, lastStatus };
|
|
60022
|
+
delay = Math.min(Math.round(delay * 1.5), CANCEL_POLL_MAX_MS);
|
|
60023
|
+
let status3, lease = claimProbeLease(deps2.signal, deadline - now2());
|
|
60024
|
+
try {
|
|
60025
|
+
status3 = readStatus(await deps2.get(taskId, {
|
|
60026
|
+
signal: lease.signal,
|
|
60027
|
+
...deps2.session !== void 0 ? { session: deps2.session } : {}
|
|
60028
|
+
}));
|
|
60029
|
+
} catch {
|
|
60030
|
+
if (lastStatus = null, lease.release(), isAborted3())
|
|
60031
|
+
return { released: !1, waitedMs: waited(), aborted: !0, lastStatus };
|
|
60032
|
+
continue;
|
|
60033
|
+
}
|
|
60034
|
+
if (lease.release(), lastStatus = status3, status3 !== null && CLAIM_RELEASED_STATES.includes(status3))
|
|
60035
|
+
return { released: !0, waitedMs: waited(), aborted: !1, lastStatus: status3 };
|
|
60036
|
+
}
|
|
60037
|
+
}
|
|
59902
60038
|
async function attemptActiveRunSelfHeal(signal, runs, deps2) {
|
|
59903
60039
|
let pending2 = !1;
|
|
59904
60040
|
try {
|
|
@@ -59916,7 +60052,7 @@ async function attemptActiveRunSelfHeal(signal, runs, deps2) {
|
|
|
59916
60052
|
detail: "the engine did not name the run that holds this session"
|
|
59917
60053
|
};
|
|
59918
60054
|
let gateKind2 = signal.pendingGate?.kind ?? null;
|
|
59919
|
-
if (gateKind2
|
|
60055
|
+
if (gateKind2 !== null && PLAN_REVIEW_GATE_KINDS.includes(gateKind2))
|
|
59920
60056
|
return planReviewArm(taskId, signal, deps2);
|
|
59921
60057
|
if (gateKind2 !== null && ASK_PARK_GATE_KINDS.includes(gateKind2))
|
|
59922
60058
|
return askParkArm(taskId, signal, deps2);
|
|
@@ -59926,31 +60062,95 @@ async function attemptActiveRunSelfHeal(signal, runs, deps2) {
|
|
|
59926
60062
|
return { kind: "state-unknown", taskId, detail: "this client exposes no durable run verbs" };
|
|
59927
60063
|
let record2;
|
|
59928
60064
|
try {
|
|
59929
|
-
record2 = await runs.get(taskId);
|
|
60065
|
+
record2 = await runs.get(taskId, sessionOpts(deps2));
|
|
59930
60066
|
} catch (e) {
|
|
59931
60067
|
return { kind: "state-unknown", taskId, detail: describeFailure(e) };
|
|
59932
60068
|
}
|
|
59933
60069
|
status3 = readStatus(record2);
|
|
59934
60070
|
}
|
|
59935
|
-
return status3 === null ? { kind: "state-unknown", taskId, detail: "the engine reported no status for that run" } : gateKind2 !== null ? { kind: "not-parked", taskId, status: status3 } : PLAN_REVIEW_STATES.includes(status3) ? planReviewArm(taskId, signal, deps2) : ASK_PARK_STATES.includes(status3) ? askParkArm(taskId, signal, deps2) : { kind: "not-parked", taskId, status: status3 };
|
|
60071
|
+
return status3 === null ? { kind: "state-unknown", taskId, detail: "the engine reported no status for that run" } : gateKind2 !== null ? { kind: "not-parked", taskId, status: status3 } : PLAN_REVIEW_STATES.includes(status3) ? planReviewArm(taskId, signal, deps2) : ASK_PARK_STATES.includes(status3) ? askParkArm(taskId, signal, deps2) : RUNNING_STATES.includes(status3) ? runningChoiceArm(taskId, status3, runs, deps2) : { kind: "not-parked", taskId, status: status3 };
|
|
60072
|
+
}
|
|
60073
|
+
async function planVerdict(taskId, deps2) {
|
|
60074
|
+
try {
|
|
60075
|
+
return await deps2?.reopenPlanReview?.(taskId) ?? { reopened: !1 };
|
|
60076
|
+
} catch {
|
|
60077
|
+
return { reopened: !1 };
|
|
60078
|
+
}
|
|
59936
60079
|
}
|
|
59937
|
-
function
|
|
59938
|
-
let verdict = { reopened: !1 };
|
|
60080
|
+
async function askVerdict(taskId, deps2) {
|
|
59939
60081
|
try {
|
|
59940
|
-
|
|
60082
|
+
return await deps2?.reopenAskPark?.(taskId) ?? { reopened: !1 };
|
|
59941
60083
|
} catch {
|
|
59942
|
-
|
|
60084
|
+
return { reopened: !1 };
|
|
59943
60085
|
}
|
|
60086
|
+
}
|
|
60087
|
+
async function planReviewArm(taskId, signal, deps2) {
|
|
60088
|
+
let verdict = await planVerdict(taskId, deps2);
|
|
59944
60089
|
return reopenDelivered(verdict) ? { kind: "plan-review-reopened", taskId, firstSight: verdict.firstSight === !0 } : { kind: "plan-review-reopen-failed", taskId, decidePath: signal.pendingGate?.decidePath ?? null };
|
|
59945
60090
|
}
|
|
59946
60091
|
async function askParkArm(taskId, signal, deps2) {
|
|
59947
|
-
let verdict =
|
|
60092
|
+
let verdict = await askVerdict(taskId, deps2);
|
|
60093
|
+
return reopenDelivered(verdict) ? { kind: "ask-reopened", taskId, firstSight: verdict.firstSight === !0 } : { kind: "ask-reopen-failed", taskId, decidePath: signal.pendingGate?.decidePath ?? null };
|
|
60094
|
+
}
|
|
60095
|
+
async function runningChoiceArm(taskId, status3, runs, deps2) {
|
|
60096
|
+
let notParked = { kind: "not-parked", taskId, status: status3 }, offer = deps2?.offerRunningChoice;
|
|
60097
|
+
if (typeof offer != "function")
|
|
60098
|
+
return notParked;
|
|
60099
|
+
let text2 = typeof deps2?.deniedMessage == "string" ? deps2.deniedMessage : "", canSteer = typeof runs?.steer == "function" && text2.length > 0, canCancel = typeof runs?.cancel == "function" && typeof runs?.get == "function";
|
|
60100
|
+
if (!canSteer && !canCancel)
|
|
60101
|
+
return notParked;
|
|
60102
|
+
let choice = "wait";
|
|
59948
60103
|
try {
|
|
59949
|
-
|
|
60104
|
+
choice = await offer({ taskId, status: status3, canSteer, canCancel }) ?? "wait";
|
|
59950
60105
|
} catch {
|
|
59951
|
-
|
|
60106
|
+
choice = "wait";
|
|
59952
60107
|
}
|
|
59953
|
-
|
|
60108
|
+
if (choice === "steer" && canSteer && runs?.steer !== void 0)
|
|
60109
|
+
try {
|
|
60110
|
+
let receipt = await runs.steer(taskId, { text: text2 }, sessionOpts(deps2)), delivery = readSteerDelivery(receipt), receiptStatus = readSteerReceiptStatus(receipt);
|
|
60111
|
+
if (delivery === "queued") {
|
|
60112
|
+
let verdict = receiptStatus !== null && PLAN_REVIEW_STATES.includes(receiptStatus) ? await planVerdict(taskId, deps2) : receiptStatus !== null && ASK_PARK_STATES.includes(receiptStatus) ? await askVerdict(taskId, deps2) : null;
|
|
60113
|
+
return { kind: "running-steered", taskId, delivery, status: receiptStatus, reopened: verdict };
|
|
60114
|
+
}
|
|
60115
|
+
return { kind: "running-steered", taskId, delivery, status: receiptStatus, reopened: null };
|
|
60116
|
+
} catch (e) {
|
|
60117
|
+
return { kind: "running-steer-failed", taskId, detail: describeFailure(e), delivery: atMostOnceFailureClass(e) };
|
|
60118
|
+
}
|
|
60119
|
+
if (choice === "cancel" && canCancel && runs?.cancel !== void 0 && runs.get !== void 0) {
|
|
60120
|
+
let durable = runs, durableGet = runs.get, boundGet = (id, opts) => durableGet.call(durable, id, opts), cancelFailure = null, cancelWaitMs = deps2?.cancelReleaseWaitMs ?? CANCEL_RELEASE_WAIT_MS, cancelStartedAt = Date.now(), cancelLease = claimProbeLease(deps2?.signal, cancelWaitMs);
|
|
60121
|
+
try {
|
|
60122
|
+
await durable.cancel?.(taskId, { signal: cancelLease.signal, ...sessionOpts(deps2) });
|
|
60123
|
+
} catch (e) {
|
|
60124
|
+
if (deps2?.signal?.aborted === !0)
|
|
60125
|
+
return {
|
|
60126
|
+
kind: "running-cancel-timeout",
|
|
60127
|
+
taskId,
|
|
60128
|
+
waitedMs: Date.now() - cancelStartedAt,
|
|
60129
|
+
aborted: !0,
|
|
60130
|
+
confirmedHeld: !1
|
|
60131
|
+
};
|
|
60132
|
+
let delivery = atMostOnceFailureClass(e);
|
|
60133
|
+
if (delivery === "rejected")
|
|
60134
|
+
return { kind: "running-cancel-failed", taskId, detail: describeFailure(e), delivery };
|
|
60135
|
+
cancelFailure = { detail: describeFailure(e), delivery };
|
|
60136
|
+
} finally {
|
|
60137
|
+
cancelLease.release();
|
|
60138
|
+
}
|
|
60139
|
+
let verdict = await waitForClaimRelease(taskId, {
|
|
60140
|
+
get: boundGet,
|
|
60141
|
+
budgetMs: cancelWaitMs,
|
|
60142
|
+
...deps2?.signal !== void 0 ? { signal: deps2.signal } : {},
|
|
60143
|
+
...sessionOpts(deps2)
|
|
60144
|
+
});
|
|
60145
|
+
return verdict.released ? { kind: "running-cancelled", taskId } : cancelFailure !== null ? { kind: "running-cancel-failed", taskId, ...cancelFailure } : {
|
|
60146
|
+
kind: "running-cancel-timeout",
|
|
60147
|
+
taskId,
|
|
60148
|
+
waitedMs: verdict.waitedMs,
|
|
60149
|
+
aborted: verdict.aborted,
|
|
60150
|
+
confirmedHeld: verdict.lastStatus !== null && CLAIM_HELD_STATES.includes(verdict.lastStatus)
|
|
60151
|
+
};
|
|
60152
|
+
}
|
|
60153
|
+
return notParked;
|
|
59954
60154
|
}
|
|
59955
60155
|
function gateKindPhrase(kind) {
|
|
59956
60156
|
return kind ? `a ${kind} decision` : "a decision";
|
|
@@ -59994,6 +60194,27 @@ function activeRunSelfHealBaseRow(outcome, signal, wayOut) {
|
|
|
59994
60194
|
let viaEngine = outcome.decidePath ? ` You can also decide it on the engine directly: POST ${outcome.decidePath}.` : "";
|
|
59995
60195
|
return `The previous turn is parked waiting for a plan review (run ${outcome.taskId}) and sema could not reopen that approval card. It did NOT cancel the run \u2014 that would have discarded the plan for you. Your message was NOT sent; ${wayOut} if you no longer want that plan.${viaEngine}`;
|
|
59996
60196
|
}
|
|
60197
|
+
// ── 三选卡的四种动作结局(选 ③ / 没答 / 没呈上都落 not-parked)────────────────────────────
|
|
60198
|
+
case "running-steered": {
|
|
60199
|
+
let handle2 = `run ${outcome.taskId}`, textOnly = "Only the TEXT of your message was handed over \u2014 a steer carries no attachments, so any images in that submission were NOT sent.";
|
|
60200
|
+
if (outcome.delivery === "applied")
|
|
60201
|
+
return `sema handed your message to the run that is already working (${handle2}) \u2014 the engine applied it to that run, so it is picked up at that run's next step. ${textOnly} Nothing was cancelled, and your message did NOT start a new turn \u2014 watch that run for what it does with it.`;
|
|
60202
|
+
if (outcome.delivery === "queued") {
|
|
60203
|
+
let parked = outcome.status ? `parked (status ${outcome.status})` : "parked", next = outcome.reopened !== null && reopenDelivered(outcome.reopened) ? "sema has surfaced that decision card \u2014 answering it is what lets that run resume and pick your message up." : `sema could not surface that decision card here, so nothing will resume that run until that decision is made; ${wayOut} if you no longer want it.`;
|
|
60204
|
+
return `${handle2} is not actually working right now: the engine reports it ${parked} on a decision it needs from you, so it queued your message on that park instead of running it. ${next} ${textOnly} Nothing was cancelled, and your message did NOT start a new turn.`;
|
|
60205
|
+
}
|
|
60206
|
+
return outcome.delivery === "parked_for_wake" ? `${handle2} had already finished, so the engine parked your message on that finished run instead of running it \u2014 a parked message is delivered only if this session is woken on the engine (POST /v1/sessions/:id/wake), which sema does not do here. That run is no longer holding this session: send your message again to run it as a new turn \u2014 but note that the parked copy is NOT discarded, so if anything ever wakes this session on the engine that instruction would run a second time. ${textOnly} Nothing was cancelled.` : `sema handed your message to ${handle2}, but the engine did not say how it will be delivered${outcome.status ? ` (it reported that run as ${outcome.status})` : ""}. ${textOnly} Nothing was cancelled, and your message did NOT start a new turn \u2014 watch that run before sending it again.`;
|
|
60207
|
+
}
|
|
60208
|
+
case "running-steer-failed":
|
|
60209
|
+
return outcome.delivery === "rejected" ? `The engine rejected handing your message to the running run (run ${outcome.taskId}): ${outcome.detail}. sema did NOT retry it (a steer is not safe to send twice) and it did NOT cancel that run. Your message was NOT sent; send it again if you still want it.` : `sema sent your message to the running run (run ${outcome.taskId}) but could not confirm what happened to it (${outcome.detail}). A steer is not safe to send twice, so sema did NOT retry it, and it did NOT cancel that run. That run may or may not have received your message \u2014 watch what it does next before sending it again.`;
|
|
60210
|
+
case "running-cancelled":
|
|
60211
|
+
return `You chose to cancel run ${outcome.taskId}. The engine confirmed it is no longer holding this session, so sema is sending your message now.`;
|
|
60212
|
+
case "running-cancel-timeout": {
|
|
60213
|
+
let waited = `${String(Math.max(1, Math.round(outcome.waitedMs / 1e3)))}s`;
|
|
60214
|
+
return outcome.aborted ? `sema asked the engine to cancel run ${outcome.taskId} and you interrupted while it was still confirming (${waited} in). Cancelling is asynchronous, so that run may still be winding down and may still hold this session. Your message was NOT sent; send it again in a moment, or ${wayOut}.` : outcome.confirmedHeld ? `sema asked the engine to cancel run ${outcome.taskId}, but that run still held this session ${waited} later \u2014 cancelling is asynchronous and it may still be winding down. Your message was NOT sent; send it again in a moment, or ${wayOut}.` : `sema asked the engine to cancel run ${outcome.taskId} but could not read that run's state back within ${waited}, so it cannot confirm whether the session was released. Your message was NOT sent; send it again in a moment (if that run really is gone it will just run), or ${wayOut}.`;
|
|
60215
|
+
}
|
|
60216
|
+
case "running-cancel-failed":
|
|
60217
|
+
return outcome.delivery === "unknown" ? `sema sent the cancel for run ${outcome.taskId} but could not confirm what happened to it (${outcome.detail}), and it could not read that run back as released either. That run may or may not still be holding this session. Your message was NOT sent; send it again in a moment, or ${wayOut}.` : `sema could not cancel run ${outcome.taskId} \u2014 the engine rejected that request (${outcome.detail}), so nothing was cancelled and sema cannot tell whether that run is still holding this session. Your message was NOT sent; send it again to find out, or ${wayOut}.`;
|
|
59997
60218
|
case "not-parked":
|
|
59998
60219
|
return signal?.pendingGate ? `This session is held by an earlier run (run ${outcome.taskId}, status ${outcome.status}) that is waiting on ${gateKindPhrase(signal.pendingGate.kind)} \u2014 it will not finish on its own. sema did NOT cancel it, because cancelling would decide that item for you. Your message was NOT sent; ${wayOut} if you no longer want it.` : `This session already has a run in flight (run ${outcome.taskId}, status ${outcome.status}) \u2014 most likely a turn you sent to the background. sema did NOT cancel it, because that would throw away work you asked for. Wait for it to finish, or ${wayOut}.`;
|
|
59999
60220
|
case "state-unknown":
|
|
@@ -60014,9 +60235,12 @@ function activeRunBusyHeadlessRow(signal, copy2) {
|
|
|
60014
60235
|
let startOver = `${freshSession.charAt(0).toUpperCase()}${freshSession.slice(1)}`;
|
|
60015
60236
|
return `This session is locked by an earlier run${handle2} that was never released, so this message was NOT sent. Nothing here clears on its own. ${startOver}, or release the run on the engine: ${cancelPath}`;
|
|
60016
60237
|
}
|
|
60017
|
-
var PLAN_REVIEW_GATE_KIND, ASK_PARK_GATE_KINDS, PLAN_REVIEW_STATES, ASK_PARK_STATES, DEFAULT_WAY_OUT, DEFAULT_FRESH_SESSION, init_activeRunSelfHeal = __esm({
|
|
60238
|
+
var PLAN_REVIEW_GATE_KIND, PLAN_REVIEW_GATE_KINDS, ASK_PARK_GATE_KINDS, PLAN_REVIEW_STATES, ASK_PARK_STATES, RUNNING_STATES, CLAIM_RELEASED_STATES, CLAIM_HELD_STATES, CANCEL_RELEASE_WAIT_MS, CANCEL_POLL_START_MS, CANCEL_POLL_MAX_MS, DEFAULT_WAY_OUT, DEFAULT_FRESH_SESSION, init_activeRunSelfHeal = __esm({
|
|
60018
60239
|
"node_modules/@sema-agent/client-core/dist/adapter/activeRunSelfHeal.js"() {
|
|
60019
|
-
|
|
60240
|
+
init_abortableSleep();
|
|
60241
|
+
PLAN_REVIEW_GATE_KIND = "plan_review", PLAN_REVIEW_GATE_KINDS = [PLAN_REVIEW_GATE_KIND, "dry_run_review"], ASK_PARK_GATE_KINDS = ["human", "irreversible_ask", "policy_ask", "tool_approval"];
|
|
60242
|
+
PLAN_REVIEW_STATES = ["needs_review"], ASK_PARK_STATES = ["suspended"], RUNNING_STATES = ["running"], CLAIM_RELEASED_STATES = ["completed", "failed", "blocked", "timeout"], CLAIM_HELD_STATES = ["running", "suspended", "needs_review"];
|
|
60243
|
+
CANCEL_RELEASE_WAIT_MS = 1e4, CANCEL_POLL_START_MS = 200, CANCEL_POLL_MAX_MS = 2e3;
|
|
60020
60244
|
DEFAULT_WAY_OUT = "run /clear to keep working in a fresh session", DEFAULT_FRESH_SESSION = "start a new session (drop --resume/--continue)";
|
|
60021
60245
|
}
|
|
60022
60246
|
});
|
|
@@ -61538,17 +61762,6 @@ function installSubagentActivitySink(sink2) {
|
|
|
61538
61762
|
activitySink = prev;
|
|
61539
61763
|
};
|
|
61540
61764
|
}
|
|
61541
|
-
function coerceOutput(v2) {
|
|
61542
|
-
if (v2 != null) {
|
|
61543
|
-
if (typeof v2 == "string")
|
|
61544
|
-
return v2;
|
|
61545
|
-
try {
|
|
61546
|
-
return JSON.stringify(v2);
|
|
61547
|
-
} catch {
|
|
61548
|
-
return String(v2);
|
|
61549
|
-
}
|
|
61550
|
-
}
|
|
61551
|
-
}
|
|
61552
61765
|
function isEngineSubagentTailActive(taskId) {
|
|
61553
61766
|
return activeTails.has(taskId);
|
|
61554
61767
|
}
|
|
@@ -61713,22 +61926,6 @@ var init_workflowMonitor = __esm({
|
|
|
61713
61926
|
}
|
|
61714
61927
|
});
|
|
61715
61928
|
|
|
61716
|
-
// node_modules/@sema-agent/client-core/dist/abortableSleep.js
|
|
61717
|
-
function abortableSleep(ms, signal) {
|
|
61718
|
-
return signal.aborted ? Promise.resolve() : new Promise((resolve57) => {
|
|
61719
|
-
let timer2 = setTimeout(() => {
|
|
61720
|
-
signal.removeEventListener("abort", onAbort), resolve57();
|
|
61721
|
-
}, ms), onAbort = () => {
|
|
61722
|
-
clearTimeout(timer2), resolve57();
|
|
61723
|
-
};
|
|
61724
|
-
signal.addEventListener("abort", onAbort, { once: !0 });
|
|
61725
|
-
});
|
|
61726
|
-
}
|
|
61727
|
-
var init_abortableSleep = __esm({
|
|
61728
|
-
"node_modules/@sema-agent/client-core/dist/abortableSleep.js"() {
|
|
61729
|
-
}
|
|
61730
|
-
});
|
|
61731
|
-
|
|
61732
61929
|
// node_modules/@sema-agent/client-core/dist/workflowClient.js
|
|
61733
61930
|
import { APIError as APIError2 } from "@sema-agent/sdk";
|
|
61734
61931
|
function coerceRunStatus(s) {
|
|
@@ -63647,7 +63844,7 @@ async function findPendingForTask(client3, taskId, matches2, opts) {
|
|
|
63647
63844
|
} catch (e) {
|
|
63648
63845
|
return { ok: !1, reason: `approvals.list failed: ${String(e)}` };
|
|
63649
63846
|
}
|
|
63650
|
-
let
|
|
63847
|
+
let decidable = rows2.filter((r) => askParkForeignGateKind(r) === null), pending2 = decidable.find((r) => r.taskId === taskId && matches2(typeof r.toolName == "string" ? r.toolName : void 0)) ?? decidable.find((r) => r.taskId === taskId);
|
|
63651
63848
|
return pending2 ? { ok: !0, pending: pending2, gatedCallId: pending2.toolCallId ?? pending2.boundCallId ?? void 0 } : { ok: !1, reason: "no pending checkpoint for this run (resolved/expired?)", code: "no_pending" };
|
|
63652
63849
|
}
|
|
63653
63850
|
function makeHitlCanUseTool(bridge3, prompt) {
|
|
@@ -63688,6 +63885,7 @@ function backendDeny(reason) {
|
|
|
63688
63885
|
}
|
|
63689
63886
|
var DEFAULT_DENY_REASON, MAX_DENY_REASON_CHARS, HitlSafetyError, HitlBridge, init_hitlBridge = __esm({
|
|
63690
63887
|
"node_modules/@sema-agent/client-core/dist/hitl/hitlBridge.js"() {
|
|
63888
|
+
init_activeRunSelfHeal();
|
|
63691
63889
|
init_types4();
|
|
63692
63890
|
init_host();
|
|
63693
63891
|
DEFAULT_DENY_REASON = "The user rejected this tool use", MAX_DENY_REASON_CHARS = 4096;
|
|
@@ -64054,11 +64252,13 @@ async function surfaceFsApprovalAndDecide(deps2, taskId, argsByCall, signal) {
|
|
|
64054
64252
|
let { pending: pending2, gatedCallId } = found, toolName2 = typeof pending2.toolName == "string" ? pending2.toolName : "", args = (gatedCallId !== void 0 ? argsByCall.get(gatedCallId) : void 0) ?? pending2.input ?? {};
|
|
64055
64253
|
if (typeof args != "object" || args === null)
|
|
64056
64254
|
return { kind: "failed", gatedCallId, reason: "gate has no tool input payload" };
|
|
64057
|
-
let bridge3 = new HitlBridge(deps2.client, taskId), callKey = approvalCallKey(gatedCallId, taskId), card = await surfaceApprovalCard({
|
|
64255
|
+
let bridge3 = new HitlBridge(deps2.client, taskId), callKey = approvalCallKey(gatedCallId, taskId), ruleSuggestionsReadOnly = readRuleSuggestions(pending2.ruleSuggestions), card = await surfaceApprovalCard({
|
|
64058
64256
|
toolName: toolName2,
|
|
64059
64257
|
args,
|
|
64060
64258
|
callKey,
|
|
64061
|
-
...signal ? { signal } : {}
|
|
64259
|
+
...signal ? { signal } : {},
|
|
64260
|
+
...pending2.governanceForced === !0 ? { governanceForced: !0 } : {},
|
|
64261
|
+
...ruleSuggestionsReadOnly !== void 0 ? { ruleSuggestionsReadOnly } : {}
|
|
64062
64262
|
});
|
|
64063
64263
|
switch (card.kind) {
|
|
64064
64264
|
case "failed":
|
|
@@ -64931,6 +65131,260 @@ var init_parkOwnership = __esm({
|
|
|
64931
65131
|
}
|
|
64932
65132
|
});
|
|
64933
65133
|
|
|
65134
|
+
// node_modules/@sema-agent/client-core/dist/hitl/parkRowBirthWait.js
|
|
65135
|
+
function parkRowPollDelay(ms, signal) {
|
|
65136
|
+
return abortableSleep(ms, signal ?? new AbortController().signal);
|
|
65137
|
+
}
|
|
65138
|
+
async function waitForParkRowBirth(deps2) {
|
|
65139
|
+
let now2 = typeof deps2.now == "function" ? deps2.now : () => Date.now(), sleep10 = typeof deps2.sleep == "function" ? deps2.sleep : parkRowPollDelay, budgetMs = Number.isFinite(deps2.budgetMs) && deps2.budgetMs > 0 ? deps2.budgetMs : 0, intervalMs = Number.isFinite(deps2.intervalMs) && deps2.intervalMs > 0 ? deps2.intervalMs : 1, startedAt = now2(), probes = 0, lastReason = "no decidable pending row for this park", aborted2 = () => deps2.signal?.aborted === !0, safeProbe = async (attempt, signal) => {
|
|
65140
|
+
try {
|
|
65141
|
+
return await deps2.probe(attempt, signal);
|
|
65142
|
+
} catch (e) {
|
|
65143
|
+
return { kind: "unborn", reason: `probe threw: ${String(e)}` };
|
|
65144
|
+
}
|
|
65145
|
+
}, probeWithinRemaining = async (attempt, remainingMs) => {
|
|
65146
|
+
if (budgetMs <= 0)
|
|
65147
|
+
return safeProbe(attempt, deps2.signal);
|
|
65148
|
+
let ctl = new AbortController(), timer2, deadline = new Promise((resolve57) => {
|
|
65149
|
+
timer2 = setTimeout(() => {
|
|
65150
|
+
ctl.abort(), resolve57("deadline");
|
|
65151
|
+
}, Math.max(1, remainingMs));
|
|
65152
|
+
}), caller = deps2.signal, abortProbeLane = () => {
|
|
65153
|
+
try {
|
|
65154
|
+
ctl.abort();
|
|
65155
|
+
} catch {
|
|
65156
|
+
}
|
|
65157
|
+
}, onAbort, externalAbort = new Promise((resolve57) => {
|
|
65158
|
+
if (caller !== void 0) {
|
|
65159
|
+
if (caller.aborted) {
|
|
65160
|
+
abortProbeLane(), resolve57("aborted");
|
|
65161
|
+
return;
|
|
65162
|
+
}
|
|
65163
|
+
onAbort = () => {
|
|
65164
|
+
abortProbeLane(), resolve57("aborted");
|
|
65165
|
+
};
|
|
65166
|
+
try {
|
|
65167
|
+
caller.addEventListener("abort", onAbort, { once: !0 });
|
|
65168
|
+
} catch {
|
|
65169
|
+
onAbort = void 0;
|
|
65170
|
+
}
|
|
65171
|
+
}
|
|
65172
|
+
}), merged = caller !== void 0 && typeof AbortSignal.any == "function" ? AbortSignal.any([caller, ctl.signal]) : ctl.signal;
|
|
65173
|
+
try {
|
|
65174
|
+
return await Promise.race([safeProbe(attempt, merged), deadline, externalAbort]);
|
|
65175
|
+
} finally {
|
|
65176
|
+
if (timer2 !== void 0 && clearTimeout(timer2), onAbort !== void 0 && caller !== void 0)
|
|
65177
|
+
try {
|
|
65178
|
+
caller.removeEventListener("abort", onAbort);
|
|
65179
|
+
} catch {
|
|
65180
|
+
}
|
|
65181
|
+
}
|
|
65182
|
+
};
|
|
65183
|
+
for (; ; ) {
|
|
65184
|
+
if (aborted2())
|
|
65185
|
+
return { kind: "aborted", waitedMs: now2() - startedAt, probes };
|
|
65186
|
+
probes += 1;
|
|
65187
|
+
let outcome = await probeWithinRemaining(probes, budgetMs - (now2() - startedAt));
|
|
65188
|
+
if (outcome === "aborted" || aborted2())
|
|
65189
|
+
return { kind: "aborted", waitedMs: now2() - startedAt, probes };
|
|
65190
|
+
if (outcome === "deadline")
|
|
65191
|
+
return {
|
|
65192
|
+
kind: "unborn",
|
|
65193
|
+
reason: `${lastReason} (the last read face did not answer within the remaining window)`,
|
|
65194
|
+
waitedMs: now2() - startedAt,
|
|
65195
|
+
probes
|
|
65196
|
+
};
|
|
65197
|
+
let probed = outcome;
|
|
65198
|
+
if (probed.kind === "row")
|
|
65199
|
+
return { kind: "row", row: probed.row, waitedMs: now2() - startedAt, probes };
|
|
65200
|
+
if (probed.kind === "settled")
|
|
65201
|
+
return { kind: "settled", reason: probed.reason, waitedMs: now2() - startedAt, probes };
|
|
65202
|
+
lastReason = probed.reason;
|
|
65203
|
+
let remainingMs = budgetMs - (now2() - startedAt);
|
|
65204
|
+
if (remainingMs <= 0)
|
|
65205
|
+
return { kind: "unborn", reason: lastReason, waitedMs: now2() - startedAt, probes };
|
|
65206
|
+
if (await sleep10(Math.min(intervalMs, remainingMs), deps2.signal), aborted2())
|
|
65207
|
+
return { kind: "aborted", waitedMs: now2() - startedAt, probes };
|
|
65208
|
+
}
|
|
65209
|
+
}
|
|
65210
|
+
var init_parkRowBirthWait = __esm({
|
|
65211
|
+
"node_modules/@sema-agent/client-core/dist/hitl/parkRowBirthWait.js"() {
|
|
65212
|
+
init_abortableSleep();
|
|
65213
|
+
}
|
|
65214
|
+
});
|
|
65215
|
+
|
|
65216
|
+
// node_modules/@sema-agent/client-core/dist/hitl/approvalDecisionNoteAudit.js
|
|
65217
|
+
function cleanNote(raw2) {
|
|
65218
|
+
let flat = raw2.replace(/[\u0000-\u001f\u007f-\u009f]+/g, " ").replace(/ {2,}/g, " ").trim();
|
|
65219
|
+
return flat.length <= 200 ? flat : `${flat.slice(0, 199)}\u2026`;
|
|
65220
|
+
}
|
|
65221
|
+
function readDecisionNoteAudit(ack) {
|
|
65222
|
+
if (ack === null || typeof ack != "object")
|
|
65223
|
+
return { state: "unknown" };
|
|
65224
|
+
let o = ack, note = typeof o.decisionNote == "string" && o.decisionNote.trim() !== "" ? cleanNote(o.decisionNote) : void 0;
|
|
65225
|
+
return o.noteRecorded === !1 ? { state: "not-recorded", ...note !== void 0 ? { note } : {} } : o.noteRecorded === !0 ? { state: "recorded", ...note !== void 0 ? { note } : {} } : note !== void 0 ? { state: "recorded", note } : { state: "unknown" };
|
|
65226
|
+
}
|
|
65227
|
+
function decisionNoteAuditLine(audit, opts) {
|
|
65228
|
+
if (audit.state === "unknown")
|
|
65229
|
+
return null;
|
|
65230
|
+
let quoted = audit.note !== void 0 ? `: "${audit.note}"` : "";
|
|
65231
|
+
return opts?.settledElsewhere === !0 ? audit.state === "recorded" ? `this approval was already decided elsewhere \u2014 the reason recorded on the audit trail${quoted}` : `this approval was already decided elsewhere; your reason was not saved to the audit trail \u2014 that decision stands${quoted}` : audit.state === "recorded" ? `decision reason recorded on the audit trail${quoted}` : `your decision stands \u2014 the engine did not save its reason to the audit trail${quoted}`;
|
|
65232
|
+
}
|
|
65233
|
+
var DECISION_NOTE_NOTICE_KEY, init_approvalDecisionNoteAudit = __esm({
|
|
65234
|
+
"node_modules/@sema-agent/client-core/dist/hitl/approvalDecisionNoteAudit.js"() {
|
|
65235
|
+
DECISION_NOTE_NOTICE_KEY = "approval-decision-note";
|
|
65236
|
+
}
|
|
65237
|
+
});
|
|
65238
|
+
|
|
65239
|
+
// node_modules/@sema-agent/client-core/dist/hitl/askParkRowRouting.js
|
|
65240
|
+
function classifyAskParkRows(rows2, taskId, deps2) {
|
|
65241
|
+
let isOwned = deps2?.isOwned ?? ((row2) => pendingRowIsOwnedByThisSession(row2, deps2?.ownership)), own2 = rows2.find((r) => r.taskId === taskId), sole = rows2.length === 1 ? rows2[0] : void 0, soleUnowned = sole !== void 0 && !isOwned(sole), pending2 = own2 ?? (soleUnowned ? void 0 : sole);
|
|
65242
|
+
if (pending2 === void 0)
|
|
65243
|
+
return {
|
|
65244
|
+
kind: "unborn",
|
|
65245
|
+
reason: rows2.length === 0 ? (
|
|
65246
|
+
// 空表两义:要么真孤儿 park(座位占着却没有待决行 = 引擎态异常),要么下一只门的行还没
|
|
65247
|
+
// 铸出来。两义分不开 ⇒ 按可修的那一义有界重查,窗尽才按前者如实收口。
|
|
65248
|
+
`no pending row at all for task ${taskId} \u2014 either an orphan park (a seat held with no decision outstanding) or the next gate's row is not minted yet`
|
|
65249
|
+
) : soleUnowned ? `the only pending row (task ${String(sole?.taskId)} / session ${String(sole?.sessionId)}) could not be proven to belong to this client (not in its own-run ledger, session id absent or different) \u2014 refusing to surface an approval that may be another session's` : `${String(rows2.length)} pending rows but none for task ${taskId} \u2014 ambiguous queue, refusing to surface an unrelated row`
|
|
65250
|
+
};
|
|
65251
|
+
let foreignKind = askParkForeignGateKind(pending2);
|
|
65252
|
+
return foreignKind !== null ? {
|
|
65253
|
+
kind: "unborn",
|
|
65254
|
+
reason: `the visible pending row (task ${String(pending2.taskId)}) is parked on a '${foreignKind}' gate \u2014 not an ask/approval gate; this arm will not surface or decide it, and it may also be the previous gate's row still visible during a transition`
|
|
65255
|
+
} : { kind: "row", row: pending2 };
|
|
65256
|
+
}
|
|
65257
|
+
function askParkRowGateKind(row2) {
|
|
65258
|
+
return typeof row2.gateKind == "string" && row2.gateKind.length > 0 ? row2.gateKind : null;
|
|
65259
|
+
}
|
|
65260
|
+
function askParkRowIdentity(taskId, row2) {
|
|
65261
|
+
let rowTaskId = typeof row2.taskId == "string" && row2.taskId.length > 0 ? row2.taskId : taskId, gatedCallId = row2.toolCallId ?? row2.boundCallId ?? void 0;
|
|
65262
|
+
return { rowTaskId, gatedCallId, armedKey: approvalCallKey(gatedCallId, rowTaskId) };
|
|
65263
|
+
}
|
|
65264
|
+
function askParkRowArm(row2) {
|
|
65265
|
+
let rowGateKind = askParkRowGateKind(row2), toolNameIsAsk = isAskTool(row2.toolName ?? void 0);
|
|
65266
|
+
if (rowGateKind === null)
|
|
65267
|
+
return toolNameIsAsk ? "question" : "tool-gate";
|
|
65268
|
+
if (!GENERIC_DECISION_GATE_KINDS.includes(rowGateKind))
|
|
65269
|
+
return "tool-gate";
|
|
65270
|
+
let rowHasToolName = typeof row2.toolName == "string" && row2.toolName.trim().length > 0;
|
|
65271
|
+
return toolNameIsAsk || askQuestionsFromPending(row2) !== null || !rowHasToolName ? "question" : "tool-gate";
|
|
65272
|
+
}
|
|
65273
|
+
function askParkRowStillPending(rows2, identity3) {
|
|
65274
|
+
return rows2.some((r) => identity3.gatedCallId !== void 0 ? (r.toolCallId ?? r.boundCallId ?? void 0) === identity3.gatedCallId : r.taskId === identity3.rowTaskId);
|
|
65275
|
+
}
|
|
65276
|
+
function classifyAskParkChainFailure(i) {
|
|
65277
|
+
return i.rowStillPending ? "retry" : i.cardPresented ? "row-gone-after-card" : "row-unborn";
|
|
65278
|
+
}
|
|
65279
|
+
function createRowArmSingleFlight() {
|
|
65280
|
+
let inFlight4 = /* @__PURE__ */ new Map(), starting = /* @__PURE__ */ new Set();
|
|
65281
|
+
return {
|
|
65282
|
+
join: (key, start) => {
|
|
65283
|
+
if (starting.has(key))
|
|
65284
|
+
return Promise.reject(new Error(`row-arm single flight: start() re-entered join() for its own key while starting (${key})`));
|
|
65285
|
+
let joined = inFlight4.get(key);
|
|
65286
|
+
if (joined !== void 0)
|
|
65287
|
+
return joined;
|
|
65288
|
+
let settle2, fail6, run2 = new Promise((resolve57, reject3) => {
|
|
65289
|
+
settle2 = resolve57, fail6 = reject3;
|
|
65290
|
+
});
|
|
65291
|
+
inFlight4.set(key, run2);
|
|
65292
|
+
let release2 = () => {
|
|
65293
|
+
inFlight4.get(key) === run2 && inFlight4.delete(key);
|
|
65294
|
+
};
|
|
65295
|
+
run2.then(release2, release2), starting.add(key);
|
|
65296
|
+
try {
|
|
65297
|
+
let started2 = start();
|
|
65298
|
+
started2 === run2 ? fail6?.(new Error("row-arm single flight: start() returned the in-flight placeholder for the same key")) : settle2?.(started2);
|
|
65299
|
+
} catch (e) {
|
|
65300
|
+
fail6?.(e);
|
|
65301
|
+
} finally {
|
|
65302
|
+
starting.delete(key);
|
|
65303
|
+
}
|
|
65304
|
+
return run2;
|
|
65305
|
+
},
|
|
65306
|
+
size: () => inFlight4.size,
|
|
65307
|
+
clear: () => {
|
|
65308
|
+
inFlight4.clear();
|
|
65309
|
+
}
|
|
65310
|
+
};
|
|
65311
|
+
}
|
|
65312
|
+
var ASK_PARK_ROW_WAIT_MS, ASK_PARK_ROW_POLL_MS, GENERIC_DECISION_GATE_KINDS, init_askParkRowRouting = __esm({
|
|
65313
|
+
"node_modules/@sema-agent/client-core/dist/hitl/askParkRowRouting.js"() {
|
|
65314
|
+
init_activeRunSelfHeal();
|
|
65315
|
+
init_frameRouter();
|
|
65316
|
+
init_gateIdentity();
|
|
65317
|
+
init_parkOwnership();
|
|
65318
|
+
ASK_PARK_ROW_WAIT_MS = 15e3, ASK_PARK_ROW_POLL_MS = 500;
|
|
65319
|
+
GENERIC_DECISION_GATE_KINDS = ["human", "policy_ask"];
|
|
65320
|
+
}
|
|
65321
|
+
});
|
|
65322
|
+
|
|
65323
|
+
// node_modules/@sema-agent/client-core/dist/hitl/resumeRunningCard.js
|
|
65324
|
+
function resumeRunningLivenessRow(msSinceLastActivity) {
|
|
65325
|
+
let ms = msSinceLastActivity;
|
|
65326
|
+
return typeof ms != "number" || !Number.isFinite(ms) || ms < 0 ? null : `The engine last recorded activity on it ${String(Math.round(ms / 1e3))}s ago.`;
|
|
65327
|
+
}
|
|
65328
|
+
function resumeRunningQuestionText(i) {
|
|
65329
|
+
let head = `This conversation was resumed while an earlier turn is still executing on the engine (run ${i.taskId}, status ${i.status}). sema did not touch it. What should it do?`, liveness = resumeRunningLivenessRow(i.msSinceLastActivity);
|
|
65330
|
+
return liveness === null ? head : `${head}
|
|
65331
|
+
${liveness}`;
|
|
65332
|
+
}
|
|
65333
|
+
function resumeRunningOptions(i) {
|
|
65334
|
+
let options = [
|
|
65335
|
+
{
|
|
65336
|
+
// 🔴 默认焦点 —— 三条路里唯一零副作用的一条,所以它是手滑回车的落点。
|
|
65337
|
+
// 🔴 措辞:这一项**不许**承诺「它会留在某个任务面板里」—— 这张卡的前提恰恰是「那条 run 活得
|
|
65338
|
+
// 比上一个客户端进程久」,新进程里没有任何腿会为它建行(③ 的处置本身也是显式零动作)。
|
|
65339
|
+
// 默认焦点上的一句假 affordance 是最坏的一格:手滑回车的人拿到一条既看不见、也停不掉、
|
|
65340
|
+
// 还占着会话锁的 run。换成两句**可证的**真话:本屏不会列出它;它还占着会话,所以下一条
|
|
65341
|
+
// 消息会再撞上它(那时 409 三选卡会带着 steer/cancel 两条真出路出现)。
|
|
65342
|
+
label: RESUME_CHOICE_BACKGROUND_LABEL,
|
|
65343
|
+
description: "Leaves the run alone. It keeps executing on the engine, but this screen will not show it and it will not be listed here \u2014 your next message runs into it again, and sema asks you then."
|
|
65344
|
+
}
|
|
65345
|
+
];
|
|
65346
|
+
return i.canAttach && options.push({
|
|
65347
|
+
label: RESUME_CHOICE_ATTACH_LABEL,
|
|
65348
|
+
// 🔴 第二句是**知情同意**那一半(见 {@link resumeAttachReplayDisclosure}):resume 入口没有
|
|
65349
|
+
// 事件锚可用,durable 尾只能从这条 run 的第一帧读起,所以崩溃前已经落盘并被 resume 还原到
|
|
65350
|
+
// 屏上的那一段会再出现一次。用户按下之前就得看见这句 —— 一个会做出用户没预料到的事的
|
|
65351
|
+
// 选项,和一个按了没用的选项同样是假 affordance。
|
|
65352
|
+
description: "Follows that run from here: sema replays it from the engine ledger and keeps streaming it into this conversation. Anything from that turn already shown above will appear a second time \u2014 sema has no resume marker for it."
|
|
65353
|
+
}), i.canCancel && options.push({
|
|
65354
|
+
label: RESUME_CHOICE_CANCEL_LABEL,
|
|
65355
|
+
description: "Stops that run on the engine (whatever it has been doing is discarded) and frees this session for a new turn."
|
|
65356
|
+
}), options;
|
|
65357
|
+
}
|
|
65358
|
+
function resumeChoiceFromLabels(selected) {
|
|
65359
|
+
if (!Array.isArray(selected) || selected.length !== 1)
|
|
65360
|
+
return "background";
|
|
65361
|
+
let label = selected[0];
|
|
65362
|
+
return label === RESUME_CHOICE_ATTACH_LABEL ? "attach" : label === RESUME_CHOICE_CANCEL_LABEL ? "cancel" : "background";
|
|
65363
|
+
}
|
|
65364
|
+
function resumeRunningNoUiGuidance(i) {
|
|
65365
|
+
let sid = typeof i.sessionId == "string" && i.sessionId.length > 0 ? i.sessionId : null, attach = sid === null ? "sema --resume (pick this session from the list)" : `sema --resume ${sid}`, T3 = RESUME_RUNNING_GUIDANCE_TAG;
|
|
65366
|
+
return [
|
|
65367
|
+
`${T3} run ${i.taskId} from an earlier turn is still executing on the engine, and this lane has no card to ask you on. sema did NOT cancel it and did NOT attach to it.`,
|
|
65368
|
+
`${T3} attach=${attach}`,
|
|
65369
|
+
`${T3} cancel=POST /v1/runs/${i.taskId}/cancel`,
|
|
65370
|
+
// 🔴 这条车道连 REPL 都不挂载,更没有任何本地面板可看。给的是引擎侧真读面。
|
|
65371
|
+
`${T3} background=do nothing \u2014 run ${i.taskId} keeps executing on the engine; this client does not list it (read it with GET /v1/runs/${i.taskId})`
|
|
65372
|
+
].join(`
|
|
65373
|
+
`);
|
|
65374
|
+
}
|
|
65375
|
+
function resumeAttachReplayDisclosure(taskId) {
|
|
65376
|
+
return `sema: attaching to run ${taskId} \u2014 sema is replaying it from the engine's ledger, so anything from that turn already shown above will appear again below. There is no resume marker for a run that outlived its shell. The replayed turns are not billed into this session's cost again either \u2014 the engine's own record (GET /v1/runs/${taskId}) is the authority on what that run really spent.`;
|
|
65377
|
+
}
|
|
65378
|
+
function resumeRunningCancelUnconfirmedRow(taskId) {
|
|
65379
|
+
return `sema: the cancel for run ${taskId} did not come back confirmed, so that run may still be executing. This screen does not list it \u2014 read its real state on the engine (GET /v1/runs/${taskId}) before assuming this session is free.`;
|
|
65380
|
+
}
|
|
65381
|
+
var RESUME_CHOICE_ATTACH_LABEL, RESUME_CHOICE_CANCEL_LABEL, RESUME_CHOICE_BACKGROUND_LABEL, RESUME_CHOICE_HEADER, RESUME_RUNNING_NO_UI_EXIT_CODE, RESUME_RUNNING_GUIDANCE_TAG, init_resumeRunningCard = __esm({
|
|
65382
|
+
"node_modules/@sema-agent/client-core/dist/hitl/resumeRunningCard.js"() {
|
|
65383
|
+
RESUME_CHOICE_ATTACH_LABEL = "Attach and watch", RESUME_CHOICE_CANCEL_LABEL = "Cancel it", RESUME_CHOICE_BACKGROUND_LABEL = "Leave it running in the background", RESUME_CHOICE_HEADER = "Earlier run still in flight";
|
|
65384
|
+
RESUME_RUNNING_NO_UI_EXIT_CODE = 75, RESUME_RUNNING_GUIDANCE_TAG = "sema: resume-running:";
|
|
65385
|
+
}
|
|
65386
|
+
});
|
|
65387
|
+
|
|
64934
65388
|
// node_modules/@sema-agent/client-core/dist/hitl/approvalsFeed.js
|
|
64935
65389
|
function digestOf(rows2) {
|
|
64936
65390
|
return rows2.map((r) => [r.sessionId ?? "", r.taskId ?? "", r.toolCallId ?? "", r.boundCallId ?? "", r.boundInputHash ?? "", r.toolName ?? ""].join("")).sort().join("");
|
|
@@ -65293,6 +65747,16 @@ function toolPermissionRequestIdDomain(requestId) {
|
|
|
65293
65747
|
if (typeof requestId == "string")
|
|
65294
65748
|
return TOOL_PERMISSION_REQUEST_ID_DOMAINS.find((d4) => requestId.startsWith(d4));
|
|
65295
65749
|
}
|
|
65750
|
+
function toolPermissionRequestId(domain2, id) {
|
|
65751
|
+
if (!TOOL_PERMISSION_REQUEST_ID_DOMAINS.includes(domain2))
|
|
65752
|
+
throw new Error(`toolPermissionRequestId: \u672A\u767B\u8BB0\u7684 requestId \u57DF \u2014\u2014 \u53EA\u8BA4 ${TOOL_PERMISSION_REQUEST_ID_DOMAINS.join(" / ")}(\u57DF\u524D\u7F00\u5C31\u662F\u51B3\u65AD\u7684\u8DEF\u7531\u4F9D\u636E,\u57DF\u5916\u952E\u65E0\u5904\u53EF\u53BB)`);
|
|
65753
|
+
if (typeof id != "string" || id.length === 0)
|
|
65754
|
+
throw new Error(`toolPermissionRequestId: \u57DF ${domain2} \u7684 id \u5FC5\u987B\u662F\u975E\u7A7A\u4E32(\u6536\u5230 ${typeof id})\u2014\u2014 \u534A\u622A\u952E\u4F1A\u88AB\u8BFB\u53E3\u8BA4\u6210\u672C\u57DF,\u5374\u8DEF\u7531\u4E0D\u5230\u4EFB\u4F55\u76EE\u6807`);
|
|
65755
|
+
let nested2 = toolPermissionRequestIdDomain(id);
|
|
65756
|
+
if (nested2 !== void 0)
|
|
65757
|
+
throw new Error(`toolPermissionRequestId: \u57DF ${domain2} \u7684 id \u672C\u8EAB\u5DF2\u5E26\u57DF\u524D\u7F00 ${nested2} \u2014\u2014 \u628A\u94F8\u597D\u7684 requestId \u5F53 id \u518D\u5582\u8FDB\u6765\u4F1A\u5F97\u5230\u53CC\u524D\u7F00\u952E(durable \u7684 id \u6BB5\u53EF\u4EE5\u542B\u5192\u53F7,\u4F46\u4E0D\u80FD\u4EE5\u57DF\u524D\u7F00\u5F00\u5934)`);
|
|
65758
|
+
return `${domain2}${id}`;
|
|
65759
|
+
}
|
|
65296
65760
|
function isLocalSessionRecord(s) {
|
|
65297
65761
|
return checkLocalSessionRecord(s) === !0;
|
|
65298
65762
|
}
|
|
@@ -66547,6 +67011,8 @@ __export(dist_exports, {
|
|
|
66547
67011
|
ADAPTER_COVERAGE: () => ADAPTER_COVERAGE,
|
|
66548
67012
|
ADAPTER_DIVERGENCES: () => ADAPTER_DIVERGENCES,
|
|
66549
67013
|
ASK_PARK_GATE_KINDS: () => ASK_PARK_GATE_KINDS,
|
|
67014
|
+
ASK_PARK_ROW_POLL_MS: () => ASK_PARK_ROW_POLL_MS,
|
|
67015
|
+
ASK_PARK_ROW_WAIT_MS: () => ASK_PARK_ROW_WAIT_MS,
|
|
66550
67016
|
ASK_PARK_STATES: () => ASK_PARK_STATES,
|
|
66551
67017
|
ATTACHMENTS_DEFAULT_ON_KEYS: () => ATTACHMENTS_DEFAULT_ON_KEYS,
|
|
66552
67018
|
ATTACHMENTS_ENV: () => ATTACHMENTS_ENV,
|
|
@@ -66559,6 +67025,7 @@ __export(dist_exports, {
|
|
|
66559
67025
|
CANCEL_DENY_BUDGET_MS: () => CANCEL_DENY_BUDGET_MS,
|
|
66560
67026
|
CANCEL_DENY_WARN_TEXT: () => CANCEL_DENY_WARN_TEXT,
|
|
66561
67027
|
CANCEL_MESSAGE: () => CANCEL_MESSAGE,
|
|
67028
|
+
CANCEL_RELEASE_WAIT_MS: () => CANCEL_RELEASE_WAIT_MS,
|
|
66562
67029
|
CATALOG_CACHE_RELATIVE_PATH: () => CATALOG_CACHE_RELATIVE_PATH,
|
|
66563
67030
|
CATALOG_CACHE_STALE_MS: () => CATALOG_CACHE_STALE_MS,
|
|
66564
67031
|
CATALOG_DEFAULT_HOSTS: () => CATALOG_DEFAULT_HOSTS,
|
|
@@ -66568,6 +67035,8 @@ __export(dist_exports, {
|
|
|
66568
67035
|
CC_STOP_SEMANTICS_MIN_SERVER: () => CC_STOP_SEMANTICS_MIN_SERVER,
|
|
66569
67036
|
CHROME_ARMS: () => CHROME_ARMS,
|
|
66570
67037
|
CHROME_EVENT_KINDS: () => CHROME_EVENT_KINDS,
|
|
67038
|
+
CLAIM_HELD_STATES: () => CLAIM_HELD_STATES,
|
|
67039
|
+
CLAIM_RELEASED_STATES: () => CLAIM_RELEASED_STATES,
|
|
66571
67040
|
CLASSIFIER_DENY_SIGNATURE: () => CLASSIFIER_DENY_SIGNATURE,
|
|
66572
67041
|
CLIENT_VERBS: () => CLIENT_VERBS,
|
|
66573
67042
|
CONFIG_LIMIT_INVALID: () => CONFIG_LIMIT_INVALID,
|
|
@@ -66581,6 +67050,7 @@ __export(dist_exports, {
|
|
|
66581
67050
|
ControlSafetyError: () => ControlSafetyError,
|
|
66582
67051
|
DEADLINE_SEC_MAX: () => DEADLINE_SEC_MAX,
|
|
66583
67052
|
DEADLINE_SEC_MIN: () => DEADLINE_SEC_MIN,
|
|
67053
|
+
DECISION_NOTE_NOTICE_KEY: () => DECISION_NOTE_NOTICE_KEY,
|
|
66584
67054
|
DEFAULT_CATALOG_SOURCES: () => DEFAULT_CATALOG_SOURCES,
|
|
66585
67055
|
DEFAULT_CATALOG_TIMEOUT_MS: () => DEFAULT_CATALOG_TIMEOUT_MS,
|
|
66586
67056
|
DEFAULT_DENY_REASON: () => DEFAULT_DENY_REASON,
|
|
@@ -66669,6 +67139,7 @@ __export(dist_exports, {
|
|
|
66669
67139
|
PERMISSION_MODE_INTENTS: () => PERMISSION_MODE_INTENTS,
|
|
66670
67140
|
PLAN_REVIEW_APPROVE_LABEL: () => PLAN_REVIEW_APPROVE_LABEL,
|
|
66671
67141
|
PLAN_REVIEW_GATE_KIND: () => PLAN_REVIEW_GATE_KIND,
|
|
67142
|
+
PLAN_REVIEW_GATE_KINDS: () => PLAN_REVIEW_GATE_KINDS,
|
|
66672
67143
|
PLAN_REVIEW_QUESTION_ID_PREFIX: () => PLAN_REVIEW_QUESTION_ID_PREFIX,
|
|
66673
67144
|
PLAN_REVIEW_REJECT_LABEL: () => PLAN_REVIEW_REJECT_LABEL,
|
|
66674
67145
|
PLAN_REVIEW_STATES: () => PLAN_REVIEW_STATES,
|
|
@@ -66681,8 +67152,15 @@ __export(dist_exports, {
|
|
|
66681
67152
|
REMEMBER_NOT_APPLIED_WARN_TEXT: () => REMEMBER_NOT_APPLIED_WARN_TEXT,
|
|
66682
67153
|
REOPEN_ID_TAIL: () => REOPEN_ID_TAIL,
|
|
66683
67154
|
REQUEST_FIELD_MATRIX: () => REQUEST_FIELD_MATRIX,
|
|
67155
|
+
RESUME_CHOICE_ATTACH_LABEL: () => RESUME_CHOICE_ATTACH_LABEL,
|
|
67156
|
+
RESUME_CHOICE_BACKGROUND_LABEL: () => RESUME_CHOICE_BACKGROUND_LABEL,
|
|
67157
|
+
RESUME_CHOICE_CANCEL_LABEL: () => RESUME_CHOICE_CANCEL_LABEL,
|
|
67158
|
+
RESUME_CHOICE_HEADER: () => RESUME_CHOICE_HEADER,
|
|
67159
|
+
RESUME_RUNNING_GUIDANCE_TAG: () => RESUME_RUNNING_GUIDANCE_TAG,
|
|
67160
|
+
RESUME_RUNNING_NO_UI_EXIT_CODE: () => RESUME_RUNNING_NO_UI_EXIT_CODE,
|
|
66684
67161
|
RETAIN_BACKGROUND_ENV: () => RETAIN_BACKGROUND_ENV,
|
|
66685
67162
|
REWIND_ERROR_CODE_PREFIXES: () => REWIND_ERROR_CODE_PREFIXES,
|
|
67163
|
+
RUNNING_STATES: () => RUNNING_STATES,
|
|
66686
67164
|
SANDBOX_CASCADE_CONFLICT_400_ANCHOR: () => SANDBOX_CASCADE_CONFLICT_400_ANCHOR,
|
|
66687
67165
|
SANDBOX_K8S_ONLY_400_ANCHOR: () => SANDBOX_K8S_ONLY_400_ANCHOR,
|
|
66688
67166
|
SANDBOX_NO_IMAGE_INDEX_400_ANCHOR: () => SANDBOX_NO_IMAGE_INDEX_400_ANCHOR,
|
|
@@ -66785,8 +67263,13 @@ __export(dist_exports, {
|
|
|
66785
67263
|
armedKeyFromQuestionId: () => armedKeyFromQuestionId,
|
|
66786
67264
|
asModelFallbackReason: () => asModelFallbackReason,
|
|
66787
67265
|
askGateQuestionId: () => askGateQuestionId,
|
|
67266
|
+
askParkForeignGateKind: () => askParkForeignGateKind,
|
|
67267
|
+
askParkRowArm: () => askParkRowArm,
|
|
67268
|
+
askParkRowIdentity: () => askParkRowIdentity,
|
|
67269
|
+
askParkRowStillPending: () => askParkRowStillPending,
|
|
66788
67270
|
askQuestionsFromPending: () => askQuestionsFromPending,
|
|
66789
67271
|
assistantTaskToBackgroundRow: () => assistantTaskToBackgroundRow,
|
|
67272
|
+
atMostOnceFailureClass: () => atMostOnceFailureClass,
|
|
66790
67273
|
attachmentsForRequest: () => attachmentsForRequest,
|
|
66791
67274
|
attemptActiveRunSelfHeal: () => attemptActiveRunSelfHeal,
|
|
66792
67275
|
awaitTaskAgentsWire: () => awaitTaskAgentsWire,
|
|
@@ -66804,6 +67287,8 @@ __export(dist_exports, {
|
|
|
66804
67287
|
ccStopSemanticsFromVersion: () => ccStopSemanticsFromVersion,
|
|
66805
67288
|
classifierDenyFromToolEnd: () => classifierDenyFromToolEnd,
|
|
66806
67289
|
classifierDenyNoticeText: () => classifierDenyNoticeText,
|
|
67290
|
+
classifyAskParkChainFailure: () => classifyAskParkChainFailure,
|
|
67291
|
+
classifyAskParkRows: () => classifyAskParkRows,
|
|
66807
67292
|
classifyHookNoticeFrame: () => classifyHookNoticeFrame,
|
|
66808
67293
|
classifyTaskStopConflict: () => classifyTaskStopConflict,
|
|
66809
67294
|
clearAllRetainedFleetRows: () => clearAllRetainedFleetRows,
|
|
@@ -66831,8 +67316,10 @@ __export(dist_exports, {
|
|
|
66831
67316
|
createBackgroundView: () => createBackgroundView,
|
|
66832
67317
|
createFleetLedger: () => createFleetLedger,
|
|
66833
67318
|
createLiveWorkflowSource: () => createLiveWorkflowSource,
|
|
67319
|
+
createRowArmSingleFlight: () => createRowArmSingleFlight,
|
|
66834
67320
|
createWireToCcAdapter: () => createWireToCcAdapter,
|
|
66835
67321
|
decidePlanReview: () => decidePlanReview,
|
|
67322
|
+
decisionNoteAuditLine: () => decisionNoteAuditLine,
|
|
66836
67323
|
defaultMaxTokensFor: () => defaultMaxTokensFor,
|
|
66837
67324
|
deferToolsForRequest: () => deferToolsForRequest,
|
|
66838
67325
|
degradedToolResultBody: () => degradedToolResultBody,
|
|
@@ -67070,9 +67557,13 @@ __export(dist_exports, {
|
|
|
67070
67557
|
publishQuestionFrameFor: () => publishQuestionFrameFor,
|
|
67071
67558
|
publishSubagentContentEvent: () => publishSubagentContentEvent,
|
|
67072
67559
|
pushSubagentLocalEcho: () => pushSubagentLocalEcho,
|
|
67560
|
+
readAsyncLaunchedAgentReceipt: () => readAsyncLaunchedAgentReceipt,
|
|
67073
67561
|
readCompletedAgentCard: () => readCompletedAgentCard,
|
|
67562
|
+
readDecisionNoteAudit: () => readDecisionNoteAudit,
|
|
67074
67563
|
readEngineActiveBgTasks: () => readEngineActiveBgTasks,
|
|
67075
67564
|
readEngineActiveBgTasksFor: () => readEngineActiveBgTasksFor,
|
|
67565
|
+
readSteerDelivery: () => readSteerDelivery,
|
|
67566
|
+
readSteerReceiptStatus: () => readSteerReceiptStatus,
|
|
67076
67567
|
readToolApprovalRespondAck: () => readToolApprovalRespondAck,
|
|
67077
67568
|
recordBgParentRun: () => recordBgParentRun,
|
|
67078
67569
|
recordBgTerminalFacts: () => recordBgTerminalFacts,
|
|
@@ -67089,6 +67580,7 @@ __export(dist_exports, {
|
|
|
67089
67580
|
registerOutstandingBgTask: () => registerOutstandingBgTask,
|
|
67090
67581
|
registerOutstandingWorkflowRun: () => registerOutstandingWorkflowRun,
|
|
67091
67582
|
registerSubagentAlias: () => registerSubagentAlias,
|
|
67583
|
+
registerSubagentContentAlias: () => registerSubagentContentAlias,
|
|
67092
67584
|
renderTaskNotificationXml: () => renderTaskNotificationXml,
|
|
67093
67585
|
reopenPlanReviewCard: () => reopenPlanReviewCard,
|
|
67094
67586
|
reportFindingsToolUseResult: () => reportFindingsToolUseResult,
|
|
@@ -67110,6 +67602,13 @@ __export(dist_exports, {
|
|
|
67110
67602
|
resolveWebSearch: () => resolveWebSearch,
|
|
67111
67603
|
resolveWireAuth: () => resolveWireAuth,
|
|
67112
67604
|
respondToQuestion: () => respondToQuestion,
|
|
67605
|
+
resumeAttachReplayDisclosure: () => resumeAttachReplayDisclosure,
|
|
67606
|
+
resumeChoiceFromLabels: () => resumeChoiceFromLabels,
|
|
67607
|
+
resumeRunningCancelUnconfirmedRow: () => resumeRunningCancelUnconfirmedRow,
|
|
67608
|
+
resumeRunningLivenessRow: () => resumeRunningLivenessRow,
|
|
67609
|
+
resumeRunningNoUiGuidance: () => resumeRunningNoUiGuidance,
|
|
67610
|
+
resumeRunningOptions: () => resumeRunningOptions,
|
|
67611
|
+
resumeRunningQuestionText: () => resumeRunningQuestionText,
|
|
67113
67612
|
retainBackgroundFromEnv: () => retainBackgroundFromEnv,
|
|
67114
67613
|
rewindSpecForMode: () => rewindSpecForMode,
|
|
67115
67614
|
rowIdTail: () => rowIdTail,
|
|
@@ -67175,6 +67674,7 @@ __export(dist_exports, {
|
|
|
67175
67674
|
toolEndResultToUserFrame: () => toolEndResultToUserFrame,
|
|
67176
67675
|
toolNameIsFsWrite: () => toolNameIsFsWrite,
|
|
67177
67676
|
toolNameIsShellExec: () => toolNameIsShellExec,
|
|
67677
|
+
toolPermissionRequestId: () => toolPermissionRequestId,
|
|
67178
67678
|
toolPermissionRequestIdDomain: () => toolPermissionRequestIdDomain,
|
|
67179
67679
|
turnEndUsage: () => turnEndUsage,
|
|
67180
67680
|
turnUsageToModelUsage: () => turnUsageToModelUsage,
|
|
@@ -67189,6 +67689,8 @@ __export(dist_exports, {
|
|
|
67189
67689
|
validateWebSearchChoice: () => validateWebSearchChoice,
|
|
67190
67690
|
versionSupportsDetach: () => versionSupportsDetach,
|
|
67191
67691
|
versionSupportsLimits: () => versionSupportsLimits,
|
|
67692
|
+
waitForClaimRelease: () => waitForClaimRelease,
|
|
67693
|
+
waitForParkRowBirth: () => waitForParkRowBirth,
|
|
67192
67694
|
wasGateArmed: () => wasGateArmed,
|
|
67193
67695
|
wasGateArmedFor: () => wasGateArmedFor,
|
|
67194
67696
|
webSearchFromEnv: () => webSearchFromEnv,
|
|
@@ -67303,6 +67805,10 @@ var init_dist = __esm({
|
|
|
67303
67805
|
init_gateIdentity();
|
|
67304
67806
|
init_armedGateRegistry();
|
|
67305
67807
|
init_parkOwnership();
|
|
67808
|
+
init_parkRowBirthWait();
|
|
67809
|
+
init_approvalDecisionNoteAudit();
|
|
67810
|
+
init_askParkRowRouting();
|
|
67811
|
+
init_resumeRunningCard();
|
|
67306
67812
|
init_approvalsFeed();
|
|
67307
67813
|
init_compensations();
|
|
67308
67814
|
init_printNotification();
|
|
@@ -80955,12 +81461,14 @@ function settingsJsonTheme() {
|
|
|
80955
81461
|
try {
|
|
80956
81462
|
let v2 = resolveUserSetting("theme");
|
|
80957
81463
|
if (typeof v2 == "string") return v2;
|
|
80958
|
-
} catch {
|
|
81464
|
+
} catch (e) {
|
|
81465
|
+
failOpen("theme-source-user-setting", void 0, String(e));
|
|
80959
81466
|
}
|
|
80960
81467
|
try {
|
|
80961
81468
|
let raw2 = readFileSync10(join31(homedir14(), ".sema", "settings.json"), "utf8"), parsed = JSON.parse(raw2);
|
|
80962
81469
|
if (typeof parsed.theme == "string") return parsed.theme;
|
|
80963
|
-
} catch {
|
|
81470
|
+
} catch (e) {
|
|
81471
|
+
failOpen("theme-source-settings-file", void 0, String(e));
|
|
80964
81472
|
}
|
|
80965
81473
|
}
|
|
80966
81474
|
function resolveThemeSetting(setting) {
|
|
@@ -80973,7 +81481,8 @@ function semaInitialTheme() {
|
|
|
80973
81481
|
function persistThemeToSettings(setting) {
|
|
80974
81482
|
try {
|
|
80975
81483
|
updateSettingsForSource("userSettings", { theme: setting }), resetUserSettingCache();
|
|
80976
|
-
} catch {
|
|
81484
|
+
} catch (e) {
|
|
81485
|
+
failOpen("theme-write-user-setting", void 0, String(e));
|
|
80977
81486
|
}
|
|
80978
81487
|
}
|
|
80979
81488
|
function detectFromColorFgBg() {
|
|
@@ -80989,6 +81498,7 @@ var cachedSystemTheme, init_systemTheme = __esm({
|
|
|
80989
81498
|
"build-src/src/utils/systemTheme.ts"() {
|
|
80990
81499
|
init_settings2();
|
|
80991
81500
|
init_userSetting();
|
|
81501
|
+
init_failOpen();
|
|
80992
81502
|
}
|
|
80993
81503
|
});
|
|
80994
81504
|
|
|
@@ -114247,7 +114757,7 @@ function readReceiptStatus(receipt) {
|
|
|
114247
114757
|
return typeof s == "string" && s.length > 0 ? s : null;
|
|
114248
114758
|
}
|
|
114249
114759
|
function cancelReleaseWaitMs() {
|
|
114250
|
-
return cancelReleaseWaitOverrideMs ??
|
|
114760
|
+
return cancelReleaseWaitOverrideMs ?? CANCEL_RELEASE_WAIT_MS2;
|
|
114251
114761
|
}
|
|
114252
114762
|
function sleep2(ms, signal) {
|
|
114253
114763
|
return signal?.aborted === !0 ? Promise.resolve() : new Promise((resolve57) => {
|
|
@@ -114266,14 +114776,14 @@ function claimProbeSignal(caller, deadline) {
|
|
|
114266
114776
|
let ac = new AbortController(), abort = (s) => ac.abort(s.reason);
|
|
114267
114777
|
return caller.aborted ? abort(caller) : caller.addEventListener("abort", () => abort(caller), { once: !0 }), budget.addEventListener("abort", () => abort(budget), { once: !0 }), ac.signal;
|
|
114268
114778
|
}
|
|
114269
|
-
async function
|
|
114270
|
-
let startedAt = Date.now(), deadline = startedAt + budgetMs, waited = () => Date.now() - startedAt, isAborted3 = () => signal?.aborted === !0, delay =
|
|
114779
|
+
async function waitForClaimRelease2(taskId, get4, budgetMs, signal) {
|
|
114780
|
+
let startedAt = Date.now(), deadline = startedAt + budgetMs, waited = () => Date.now() - startedAt, isAborted3 = () => signal?.aborted === !0, delay = CANCEL_POLL_START_MS2;
|
|
114271
114781
|
for (; ; ) {
|
|
114272
114782
|
if (isAborted3()) return { released: !1, waitedMs: waited(), aborted: !0 };
|
|
114273
114783
|
let remaining = deadline - Date.now();
|
|
114274
114784
|
if (remaining <= 0) return { released: !1, waitedMs: waited(), aborted: !1 };
|
|
114275
114785
|
if (await sleep2(Math.min(delay, remaining), signal), isAborted3()) return { released: !1, waitedMs: waited(), aborted: !0 };
|
|
114276
|
-
delay = Math.min(Math.round(delay * 1.5),
|
|
114786
|
+
delay = Math.min(Math.round(delay * 1.5), CANCEL_POLL_MAX_MS2);
|
|
114277
114787
|
let status3;
|
|
114278
114788
|
try {
|
|
114279
114789
|
status3 = readStatus2(await get4(taskId, { signal: claimProbeSignal(signal, deadline) }));
|
|
@@ -114282,7 +114792,7 @@ async function waitForClaimRelease(taskId, get4, budgetMs, signal) {
|
|
|
114282
114792
|
if (e?.status === 404) return { released: !0, waitedMs: waited(), aborted: !1 };
|
|
114283
114793
|
continue;
|
|
114284
114794
|
}
|
|
114285
|
-
if (status3 !== null &&
|
|
114795
|
+
if (status3 !== null && CLAIM_RELEASED_STATES2.includes(status3)) return { released: !0, waitedMs: waited(), aborted: !1 };
|
|
114286
114796
|
}
|
|
114287
114797
|
}
|
|
114288
114798
|
async function attemptActiveRunSelfHeal2(signal, runs, deps2) {
|
|
@@ -114292,6 +114802,11 @@ async function attemptActiveRunSelfHeal2(signal, runs, deps2) {
|
|
|
114292
114802
|
} catch {
|
|
114293
114803
|
pending2 = !1;
|
|
114294
114804
|
}
|
|
114805
|
+
if (pending2 && deps2?.listOwnedPendingApprovals !== void 0)
|
|
114806
|
+
try {
|
|
114807
|
+
await deps2.listOwnedPendingApprovals() === 0 && (pending2 = !1);
|
|
114808
|
+
} catch {
|
|
114809
|
+
}
|
|
114295
114810
|
if (pending2) return { kind: "decision-pending", taskId: signal.activeTaskId };
|
|
114296
114811
|
let taskId = signal.activeTaskId;
|
|
114297
114812
|
if (taskId === null)
|
|
@@ -114300,28 +114815,28 @@ async function attemptActiveRunSelfHeal2(signal, runs, deps2) {
|
|
|
114300
114815
|
taskId: null,
|
|
114301
114816
|
detail: "the engine did not name the run that holds this session"
|
|
114302
114817
|
};
|
|
114303
|
-
let
|
|
114818
|
+
let planVerdict2 = async () => {
|
|
114304
114819
|
try {
|
|
114305
114820
|
return await deps2?.reopenPlanReview?.(taskId) ?? { reopened: !1 };
|
|
114306
114821
|
} catch {
|
|
114307
114822
|
return { reopened: !1 };
|
|
114308
114823
|
}
|
|
114309
|
-
},
|
|
114824
|
+
}, askVerdict2 = async () => {
|
|
114310
114825
|
try {
|
|
114311
114826
|
return await deps2?.reopenAskPark?.(taskId) ?? { reopened: !1 };
|
|
114312
114827
|
} catch {
|
|
114313
114828
|
return { reopened: !1 };
|
|
114314
114829
|
}
|
|
114315
114830
|
}, reopenPlanArm = async () => {
|
|
114316
|
-
let verdict = await
|
|
114831
|
+
let verdict = await planVerdict2();
|
|
114317
114832
|
return verdict.reopened === !0 ? { kind: "plan-review-reopened", taskId, firstSight: verdict.firstSight === !0 } : { kind: "plan-review-reopen-failed", taskId, decidePath: signal.pendingGate?.decidePath ?? null };
|
|
114318
114833
|
}, reopenAskArm = async () => {
|
|
114319
|
-
let verdict = await
|
|
114834
|
+
let verdict = await askVerdict2();
|
|
114320
114835
|
return verdict.reopened === !0 ? { kind: "ask-reopened", taskId, firstSight: verdict.firstSight === !0 } : { kind: "ask-reopen-failed", taskId, decidePath: signal.pendingGate?.decidePath ?? null };
|
|
114321
|
-
},
|
|
114836
|
+
}, runningChoiceArm2 = async (status4) => {
|
|
114322
114837
|
let notParked = { kind: "not-parked", taskId, status: status4 }, offer = deps2?.offerRunningChoice;
|
|
114323
114838
|
if (typeof offer != "function") return notParked;
|
|
114324
|
-
let text2 = typeof deps2?.deniedMessage == "string" ? deps2.deniedMessage : "", steer = runs?.steer, cancel = runs?.cancel, get4 = runs?.get, canSteer = typeof steer == "function" && text2.length > 0, canCancel = typeof cancel == "function" && typeof get4 == "function";
|
|
114839
|
+
let text2 = typeof deps2?.deniedMessage == "string" ? deps2.deniedMessage : "", steer = typeof runs?.steer == "function" ? runs.steer.bind(runs) : void 0, cancel = typeof runs?.cancel == "function" ? runs.cancel.bind(runs) : void 0, get4 = typeof runs?.get == "function" ? runs.get.bind(runs) : void 0, canSteer = typeof steer == "function" && text2.length > 0, canCancel = typeof cancel == "function" && typeof get4 == "function";
|
|
114325
114840
|
if (!canSteer && !canCancel) return notParked;
|
|
114326
114841
|
let choice = "wait";
|
|
114327
114842
|
try {
|
|
@@ -114333,7 +114848,7 @@ async function attemptActiveRunSelfHeal2(signal, runs, deps2) {
|
|
|
114333
114848
|
try {
|
|
114334
114849
|
let receipt = await steer(taskId, { text: text2 }), delivery = readDelivery(receipt), receiptStatus = readReceiptStatus(receipt);
|
|
114335
114850
|
if (delivery === "queued") {
|
|
114336
|
-
let verdict = receiptStatus !== null && PLAN_REVIEW_STATES2.includes(receiptStatus) ? await
|
|
114851
|
+
let verdict = receiptStatus !== null && PLAN_REVIEW_STATES2.includes(receiptStatus) ? await planVerdict2() : receiptStatus !== null && ASK_PARK_STATES2.includes(receiptStatus) ? await askVerdict2() : null;
|
|
114337
114852
|
return { kind: "running-steered", taskId, delivery, status: receiptStatus, reopened: verdict };
|
|
114338
114853
|
}
|
|
114339
114854
|
return { kind: "running-steered", taskId, delivery, status: receiptStatus, reopened: null };
|
|
@@ -114346,12 +114861,12 @@ async function attemptActiveRunSelfHeal2(signal, runs, deps2) {
|
|
|
114346
114861
|
} catch (e) {
|
|
114347
114862
|
return { kind: "running-cancel-failed", taskId, detail: describeFailure2(e) };
|
|
114348
114863
|
}
|
|
114349
|
-
let verdict = await
|
|
114864
|
+
let verdict = await waitForClaimRelease2(taskId, get4, cancelReleaseWaitMs(), deps2?.signal);
|
|
114350
114865
|
return verdict.released ? { kind: "running-cancelled", taskId } : { kind: "running-cancel-timeout", taskId, waitedMs: verdict.waitedMs, aborted: verdict.aborted };
|
|
114351
114866
|
}
|
|
114352
114867
|
return notParked;
|
|
114353
114868
|
}, gateKind2 = signal.pendingGate?.kind ?? null;
|
|
114354
|
-
if (gateKind2 !== null &&
|
|
114869
|
+
if (gateKind2 !== null && PLAN_REVIEW_GATE_KINDS2.includes(gateKind2)) return reopenPlanArm();
|
|
114355
114870
|
if (gateKind2 !== null && ASK_PARK_GATE_KINDS2.includes(gateKind2)) return reopenAskArm();
|
|
114356
114871
|
let status3 = signal.activeTaskStatus;
|
|
114357
114872
|
if (status3 === null) {
|
|
@@ -114365,7 +114880,7 @@ async function attemptActiveRunSelfHeal2(signal, runs, deps2) {
|
|
|
114365
114880
|
}
|
|
114366
114881
|
status3 = readStatus2(record2);
|
|
114367
114882
|
}
|
|
114368
|
-
return status3 === null ? { kind: "state-unknown", taskId, detail: "the engine reported no status for that run" } : gateKind2 !== null ? { kind: "not-parked", taskId, status: status3 } : PLAN_REVIEW_STATES2.includes(status3) ? reopenPlanArm() : ASK_PARK_STATES2.includes(status3) ? reopenAskArm() :
|
|
114883
|
+
return status3 === null ? { kind: "state-unknown", taskId, detail: "the engine reported no status for that run" } : gateKind2 !== null ? { kind: "not-parked", taskId, status: status3 } : PLAN_REVIEW_STATES2.includes(status3) ? reopenPlanArm() : ASK_PARK_STATES2.includes(status3) ? reopenAskArm() : RUNNING_STATES2.includes(status3) ? runningChoiceArm2(status3) : { kind: "not-parked", taskId, status: status3 };
|
|
114369
114884
|
}
|
|
114370
114885
|
function gateKindPhrase2(kind) {
|
|
114371
114886
|
return kind ? `a ${kind} decision` : "a decision";
|
|
@@ -114439,11 +114954,11 @@ function activeRunBusyHeadlessRow2(signal) {
|
|
|
114439
114954
|
// 用户唯一能读到的就是这一段话。
|
|
114440
114955
|
governanceOriginClause2(signal) : status3 ? `This session is held by an earlier run${handle2} with status ${status3}, so this message was NOT sent. The engine reported no decision pending on that run: if it is still working, wait for it to finish; if it will never settle, release it with ${cancelPath} (that discards whatever it was doing). Or ${freshSession}.` : `This session is locked by an earlier run${handle2} that was never released, so this message was NOT sent. Nothing here clears on its own. Start a new session (drop --resume/--continue), or release the run on the engine: ${cancelPath}`;
|
|
114441
114956
|
}
|
|
114442
|
-
var PLAN_REVIEW_STATES2, ASK_PARK_STATES2,
|
|
114957
|
+
var PLAN_REVIEW_STATES2, ASK_PARK_STATES2, PLAN_REVIEW_GATE_KINDS2, ASK_PARK_GATE_KINDS2, RUNNING_STATES2, CLAIM_RELEASED_STATES2, CANCEL_RELEASE_WAIT_MS2, CANCEL_POLL_START_MS2, CANCEL_POLL_MAX_MS2, cancelReleaseWaitOverrideMs, INTERACTIVE_WAY_OUT, init_activeRunSelfHeal2 = __esm({
|
|
114443
114958
|
"build-src/src/sema/activeRunSelfHeal.ts"() {
|
|
114444
114959
|
init_dist();
|
|
114445
|
-
PLAN_REVIEW_STATES2 = ["needs_review"], ASK_PARK_STATES2 = ["suspended"],
|
|
114446
|
-
|
|
114960
|
+
PLAN_REVIEW_STATES2 = ["needs_review"], ASK_PARK_STATES2 = ["suspended"], PLAN_REVIEW_GATE_KINDS2 = ["plan_review", "dry_run_review"], ASK_PARK_GATE_KINDS2 = ["human", "irreversible_ask", "policy_ask", "tool_approval"], RUNNING_STATES2 = ["running"], CLAIM_RELEASED_STATES2 = ["completed", "failed", "blocked", "timeout"];
|
|
114961
|
+
CANCEL_RELEASE_WAIT_MS2 = 1e4, CANCEL_POLL_START_MS2 = 200, CANCEL_POLL_MAX_MS2 = 2e3, cancelReleaseWaitOverrideMs = null;
|
|
114447
114962
|
INTERACTIVE_WAY_OUT = "run /clear to keep working in a fresh session";
|
|
114448
114963
|
}
|
|
114449
114964
|
});
|
|
@@ -178379,7 +178894,8 @@ function _resetPlanReviewReopenSeqForTest() {
|
|
|
178379
178894
|
for (let [, entry] of activeReopenByCanonical)
|
|
178380
178895
|
try {
|
|
178381
178896
|
entry.unregister();
|
|
178382
|
-
} catch {
|
|
178897
|
+
} catch (e) {
|
|
178898
|
+
failOpen("plan-review-reopen-unregister", void 0, String(e));
|
|
178383
178899
|
}
|
|
178384
178900
|
activeReopenByCanonical.clear();
|
|
178385
178901
|
}
|
|
@@ -178435,6 +178951,7 @@ var APPROVE_LABEL2, REJECT_LABEL2, reopenSeq, activeReopenByCanonical, init_plan
|
|
|
178435
178951
|
init_dist();
|
|
178436
178952
|
init_armedGateRegistry2();
|
|
178437
178953
|
init_transcriptSystemNotice();
|
|
178954
|
+
init_failOpen();
|
|
178438
178955
|
APPROVE_LABEL2 = PLAN_REVIEW_APPROVE_LABEL, REJECT_LABEL2 = PLAN_REVIEW_REJECT_LABEL, reopenSeq = 0, activeReopenByCanonical = /* @__PURE__ */ new Map();
|
|
178439
178956
|
}
|
|
178440
178957
|
});
|
|
@@ -178483,95 +179000,19 @@ var DECIDE_RETRY_DELAY_MS, delayOverrideMs, init_decideRetry = __esm({
|
|
|
178483
179000
|
}
|
|
178484
179001
|
});
|
|
178485
179002
|
|
|
178486
|
-
// build-src/src/sema/parkRowBirthWait.ts
|
|
178487
|
-
function abortableDelay(ms, signal) {
|
|
178488
|
-
return signal?.aborted === !0 ? Promise.resolve() : new Promise((resolve57) => {
|
|
178489
|
-
let done = () => {
|
|
178490
|
-
clearTimeout(timer2);
|
|
178491
|
-
try {
|
|
178492
|
-
signal?.removeEventListener("abort", done);
|
|
178493
|
-
} catch {
|
|
178494
|
-
}
|
|
178495
|
-
resolve57();
|
|
178496
|
-
}, timer2 = setTimeout(done, ms);
|
|
178497
|
-
try {
|
|
178498
|
-
signal?.addEventListener("abort", done, { once: !0 });
|
|
178499
|
-
} catch {
|
|
178500
|
-
}
|
|
178501
|
-
});
|
|
178502
|
-
}
|
|
178503
|
-
async function waitForParkRowBirth(deps2) {
|
|
178504
|
-
let now2 = typeof deps2.now == "function" ? deps2.now : () => Date.now(), sleep10 = typeof deps2.sleep == "function" ? deps2.sleep : abortableDelay, budgetMs = Number.isFinite(deps2.budgetMs) && deps2.budgetMs > 0 ? deps2.budgetMs : 0, intervalMs = Number.isFinite(deps2.intervalMs) && deps2.intervalMs > 0 ? deps2.intervalMs : 1, startedAt = now2(), probes = 0, lastReason = "no decidable pending row for this park", aborted2 = () => deps2.signal?.aborted === !0, safeProbe = async (attempt, signal) => {
|
|
178505
|
-
try {
|
|
178506
|
-
return await deps2.probe(attempt, signal);
|
|
178507
|
-
} catch (e) {
|
|
178508
|
-
return { kind: "unborn", reason: `probe threw: ${String(e)}` };
|
|
178509
|
-
}
|
|
178510
|
-
}, probeWithinRemaining = async (attempt, remainingMs) => {
|
|
178511
|
-
if (budgetMs <= 0) return safeProbe(attempt, deps2.signal);
|
|
178512
|
-
let ctl = new AbortController(), timer2, deadline = new Promise((resolve57) => {
|
|
178513
|
-
timer2 = setTimeout(() => {
|
|
178514
|
-
ctl.abort(), resolve57("deadline");
|
|
178515
|
-
}, Math.max(1, remainingMs));
|
|
178516
|
-
}), caller = deps2.signal, onAbort, externalAbort = new Promise((resolve57) => {
|
|
178517
|
-
if (caller !== void 0) {
|
|
178518
|
-
if (caller.aborted) {
|
|
178519
|
-
resolve57("aborted");
|
|
178520
|
-
return;
|
|
178521
|
-
}
|
|
178522
|
-
onAbort = () => resolve57("aborted");
|
|
178523
|
-
try {
|
|
178524
|
-
caller.addEventListener("abort", onAbort, { once: !0 });
|
|
178525
|
-
} catch {
|
|
178526
|
-
onAbort = void 0;
|
|
178527
|
-
}
|
|
178528
|
-
}
|
|
178529
|
-
}), merged = caller !== void 0 && typeof AbortSignal.any == "function" ? AbortSignal.any([caller, ctl.signal]) : ctl.signal;
|
|
178530
|
-
try {
|
|
178531
|
-
return await Promise.race([safeProbe(attempt, merged), deadline, externalAbort]);
|
|
178532
|
-
} finally {
|
|
178533
|
-
if (timer2 !== void 0 && clearTimeout(timer2), onAbort !== void 0 && caller !== void 0)
|
|
178534
|
-
try {
|
|
178535
|
-
caller.removeEventListener("abort", onAbort);
|
|
178536
|
-
} catch {
|
|
178537
|
-
}
|
|
178538
|
-
}
|
|
178539
|
-
};
|
|
178540
|
-
for (; ; ) {
|
|
178541
|
-
if (aborted2()) return { kind: "aborted", waitedMs: now2() - startedAt, probes };
|
|
178542
|
-
probes += 1;
|
|
178543
|
-
let outcome = await probeWithinRemaining(probes, budgetMs - (now2() - startedAt));
|
|
178544
|
-
if (outcome === "aborted" || aborted2()) return { kind: "aborted", waitedMs: now2() - startedAt, probes };
|
|
178545
|
-
if (outcome === "deadline")
|
|
178546
|
-
return {
|
|
178547
|
-
kind: "unborn",
|
|
178548
|
-
reason: `${lastReason} (the last read face did not answer within the remaining window)`,
|
|
178549
|
-
waitedMs: now2() - startedAt,
|
|
178550
|
-
probes
|
|
178551
|
-
};
|
|
178552
|
-
let probed = outcome;
|
|
178553
|
-
if (probed.kind === "row") return { kind: "row", row: probed.row, waitedMs: now2() - startedAt, probes };
|
|
178554
|
-
if (probed.kind === "settled")
|
|
178555
|
-
return { kind: "settled", reason: probed.reason, waitedMs: now2() - startedAt, probes };
|
|
178556
|
-
lastReason = probed.reason;
|
|
178557
|
-
let remainingMs = budgetMs - (now2() - startedAt);
|
|
178558
|
-
if (remainingMs <= 0) return { kind: "unborn", reason: lastReason, waitedMs: now2() - startedAt, probes };
|
|
178559
|
-
if (await sleep10(Math.min(intervalMs, remainingMs), deps2.signal), aborted2()) return { kind: "aborted", waitedMs: now2() - startedAt, probes };
|
|
178560
|
-
}
|
|
178561
|
-
}
|
|
178562
|
-
var init_parkRowBirthWait = __esm({
|
|
178563
|
-
"build-src/src/sema/parkRowBirthWait.ts"() {
|
|
178564
|
-
}
|
|
178565
|
-
});
|
|
178566
|
-
|
|
178567
179003
|
// build-src/src/sema/askParkReopen.ts
|
|
178568
179004
|
var askParkReopen_exports = {};
|
|
178569
179005
|
__export(askParkReopen_exports, {
|
|
178570
179006
|
_resetAskParkReopenInFlightForTest: () => _resetAskParkReopenInFlightForTest,
|
|
179007
|
+
_rowArmFlightForTest: () => _rowArmFlightForTest,
|
|
178571
179008
|
_setAskParkRowWaitForTest: () => _setAskParkRowWaitForTest,
|
|
178572
179009
|
askParkRowWaitMs: () => askParkRowWaitMs,
|
|
179010
|
+
countOwnedPendingApprovals: () => countOwnedPendingApprovals,
|
|
178573
179011
|
reopenAskParkCard: () => reopenAskParkCard
|
|
178574
179012
|
});
|
|
179013
|
+
async function countOwnedPendingApprovals(client3) {
|
|
179014
|
+
return ((await client3.approvals.list()).pending ?? []).filter((row2) => pendingRowIsOwnedByThisSession(row2, ownershipDeps)).length;
|
|
179015
|
+
}
|
|
178575
179016
|
function reopenAskParkCard(taskId, client3, signal) {
|
|
178576
179017
|
if (typeof taskId != "string" || taskId.length === 0) return Promise.resolve({ reopened: !1 });
|
|
178577
179018
|
let inFlight4 = inFlightReopenByTask.get(taskId);
|
|
@@ -178586,7 +179027,10 @@ function reopenAskParkCard(taskId, client3, signal) {
|
|
|
178586
179027
|
), run2;
|
|
178587
179028
|
}
|
|
178588
179029
|
function _resetAskParkReopenInFlightForTest() {
|
|
178589
|
-
inFlightReopenByTask.clear(),
|
|
179030
|
+
inFlightReopenByTask.clear(), rowArmSingleFlight().clear();
|
|
179031
|
+
}
|
|
179032
|
+
function _rowArmFlightForTest() {
|
|
179033
|
+
return rowArmSingleFlight();
|
|
178590
179034
|
}
|
|
178591
179035
|
function _setAskParkRowWaitForTest(o) {
|
|
178592
179036
|
o.budgetMs !== void 0 && (rowWaitOverrideMs = o.budgetMs), o.intervalMs !== void 0 && (rowPollOverrideMs = o.intervalMs);
|
|
@@ -178604,29 +179048,19 @@ async function probeOwnedAskRow(taskId, client3, signal) {
|
|
|
178604
179048
|
} catch (e) {
|
|
178605
179049
|
return { kind: "unborn", reason: `approvals.list failed for task ${taskId}: ${String(e)}` };
|
|
178606
179050
|
}
|
|
178607
|
-
|
|
178608
|
-
if (!pending2)
|
|
178609
|
-
return {
|
|
178610
|
-
kind: "unborn",
|
|
178611
|
-
reason: rows2.length === 0 ? (
|
|
178612
|
-
// 空表两义(#269):要么真孤儿 park(座位占着却没有待决行 = 引擎态异常),要么下一只门的
|
|
178613
|
-
// 行还没铸出来。两义分不开 ⇒ 按可修的那一义有界重查,窗尽才按前者如实收口。
|
|
178614
|
-
`no pending row at all for task ${taskId} \u2014 either an orphan park (a seat held with no decision outstanding) or the next gate's row is not minted yet`
|
|
178615
|
-
) : soleUnowned ? `the only pending row (task ${String(sole?.taskId)} / session ${String(sole?.sessionId)}) could not be proven to belong to this shell (not in its own-run ledger, session id absent or different) \u2014 refusing to surface an approval that may be another session's` : `${String(rows2.length)} pending rows but none for task ${taskId} \u2014 ambiguous queue, refusing to surface an unrelated row`
|
|
178616
|
-
};
|
|
178617
|
-
let rowGateKind = typeof pending2.gateKind == "string" && pending2.gateKind.length > 0 ? pending2.gateKind : null;
|
|
178618
|
-
return rowGateKind !== null && !ASK_PARK_GATE_KINDS2.includes(rowGateKind) ? {
|
|
178619
|
-
kind: "unborn",
|
|
178620
|
-
reason: `the visible pending row (task ${String(pending2.taskId)}) is parked on a '${rowGateKind}' gate \u2014 not an ask/approval gate; this arm will not surface or decide it, and it may also be the previous gate's row still visible during a transition`
|
|
178621
|
-
} : { kind: "row", row: pending2 };
|
|
179051
|
+
return classifyAskParkRows(rows2, taskId, { ownership: ownershipDeps });
|
|
178622
179052
|
}
|
|
178623
179053
|
async function reopenAskParkCardOnce(taskId, client3, signal) {
|
|
178624
179054
|
try {
|
|
178625
179055
|
if (typeof taskId != "string" || taskId.length === 0) return { reopened: !1 };
|
|
178626
|
-
let deadlineAt = Date.now() + askParkRowWaitMs();
|
|
179056
|
+
let deadlineAt = Date.now() + askParkRowWaitMs(), flight = rowArmSingleFlight();
|
|
178627
179057
|
for (; ; ) {
|
|
178628
179058
|
let found = await waitForParkRowBirth({
|
|
178629
|
-
|
|
179059
|
+
// 🔴 第二参 = 重查环给的**本拍**合流信号(外部 Esc × 剩余预算),必须原样透传进真实读面
|
|
179060
|
+
// ——包的 `ParkRowBirthWaitDeps.probe` 头注把这条写成红线。丢掉它(改回零参、或顶替成
|
|
179061
|
+
// 外层 caller signal)⇒「有界」只在判决面成立:窗尽时环如实收口,而那条挂死的
|
|
179062
|
+
// `approvals.list` 没人去掐,连接活到进程结束。常驻反钉 = activeRunSelfHeal 套 N-o1。
|
|
179063
|
+
probe: (_attempt, probeSignal) => probeOwnedAskRow(taskId, client3, probeSignal ?? signal),
|
|
178630
179064
|
budgetMs: Math.max(0, deadlineAt - Date.now()),
|
|
178631
179065
|
intervalMs: askParkRowPollMs(),
|
|
178632
179066
|
...signal ? { signal } : {}
|
|
@@ -178635,7 +179069,7 @@ async function reopenAskParkCardOnce(taskId, client3, signal) {
|
|
|
178635
179069
|
return process.env.SEMA_DEBUG && console.error(
|
|
178636
179070
|
`[sema][askParkReopen] no decidable pending row for task ${taskId} after ${String(found.waitedMs)}ms / ${String(found.probes)} probe(s) \u2014 ${found.kind === "aborted" ? "the wait was interrupted" : found.reason} \u2014 reporting reopened:false`
|
|
178637
179071
|
), { reopened: !1 };
|
|
178638
|
-
let armed3 = await armPendingRowCoalesced(taskId, found.row, client3);
|
|
179072
|
+
let armed3 = await armPendingRowCoalesced(flight, taskId, found.row, client3);
|
|
178639
179073
|
if (armed3.kind === "verdict") return armed3.verdict;
|
|
178640
179074
|
if (Date.now() >= deadlineAt || signal?.aborted === !0)
|
|
178641
179075
|
return process.env.SEMA_DEBUG && console.error(
|
|
@@ -178649,36 +179083,32 @@ async function reopenAskParkCardOnce(taskId, client3, signal) {
|
|
|
178649
179083
|
return process.env.SEMA_DEBUG && console.error(`[sema][askParkReopen] reopen lane for task ${taskId} threw (${String(e)}) \u2014 reporting reopened:false`), { reopened: !1 };
|
|
178650
179084
|
}
|
|
178651
179085
|
}
|
|
178652
|
-
function
|
|
178653
|
-
let
|
|
178654
|
-
return
|
|
179086
|
+
function rowArmSingleFlight() {
|
|
179087
|
+
let epoch = getLiveSessionEpoch();
|
|
179088
|
+
return (rowArmFlight === null || epoch !== rowArmFlightEpoch) && (rowArmFlightEpoch = epoch, rowArmFlight = createRowArmSingleFlight()), rowArmFlight;
|
|
178655
179089
|
}
|
|
178656
|
-
function armPendingRowCoalesced(taskId, pending2, client3) {
|
|
178657
|
-
let identity3 =
|
|
178658
|
-
|
|
178659
|
-
|
|
178660
|
-
|
|
178661
|
-
), inFlight4;
|
|
178662
|
-
let run2 = armPendingRow(taskId, pending2, client3, identity3);
|
|
178663
|
-
return inFlightArmByRow.set(identity3.armedKey, run2), run2.then(
|
|
178664
|
-
() => inFlightArmByRow.delete(identity3.armedKey),
|
|
178665
|
-
() => inFlightArmByRow.delete(identity3.armedKey)
|
|
178666
|
-
), run2;
|
|
179090
|
+
function armPendingRowCoalesced(flight, taskId, pending2, client3) {
|
|
179091
|
+
let identity3 = askParkRowIdentity(taskId, pending2);
|
|
179092
|
+
return flight.size() > 0 && process.env.SEMA_DEBUG && console.error(
|
|
179093
|
+
`[sema][askParkReopen] row-arm single flight holds ${String(flight.size())} in-flight chain(s); a card for row ${identity3.armedKey} that is already being presented will be joined instead of minting a second one (requested by task ${taskId})`
|
|
179094
|
+
), flight.join(identity3.armedKey, () => armPendingRow(taskId, pending2, client3, identity3));
|
|
178667
179095
|
}
|
|
178668
179096
|
async function armPendingRow(taskId, pending2, client3, identity3) {
|
|
178669
179097
|
try {
|
|
178670
179098
|
let { rowTaskId, gatedCallId, armedKey } = identity3, firstSight = !wasGateArmed2(armedKey), rowStillPending = async () => {
|
|
178671
179099
|
try {
|
|
178672
|
-
return (await client3.approvals.list()).pending
|
|
178673
|
-
(r) => gatedCallId !== void 0 ? (r.toolCallId ?? r.boundCallId ?? void 0) === gatedCallId : r.taskId === rowTaskId
|
|
178674
|
-
);
|
|
179100
|
+
return askParkRowStillPending((await client3.approvals.list()).pending, identity3);
|
|
178675
179101
|
} catch {
|
|
178676
179102
|
return !0;
|
|
178677
179103
|
}
|
|
178678
|
-
},
|
|
178679
|
-
if (process.env.SEMA_DEBUG
|
|
178680
|
-
|
|
178681
|
-
|
|
179104
|
+
}, askQuestions = askQuestionsFromPending(pending2), questionGate = askParkRowArm(pending2) === "question";
|
|
179105
|
+
if (process.env.SEMA_DEBUG) {
|
|
179106
|
+
let rowGateKind = typeof pending2.gateKind == "string" && pending2.gateKind.length > 0 ? pending2.gateKind : null;
|
|
179107
|
+
console.error(
|
|
179108
|
+
`[sema][askParkReopen] routing row (task ${rowTaskId} \xB7 gateKind ${rowGateKind ?? "null"} \xB7 toolName ${String(pending2.toolName ?? "null")} \xB7 callId ${String(gatedCallId ?? "null")}) \u21D2 ${questionGate ? "question" : "tool-gate"} arm`
|
|
179109
|
+
);
|
|
179110
|
+
}
|
|
179111
|
+
if (questionGate) {
|
|
178682
179112
|
if (!hasQuestionOverlay())
|
|
178683
179113
|
return process.env.SEMA_DEBUG && console.error(
|
|
178684
179114
|
`[sema][askParkReopen] question arm for task ${rowTaskId} has no overlay subscriber (headless / REPL not mounted) \u2014 reporting reopened:false`
|
|
@@ -178693,7 +179123,8 @@ async function armPendingRow(taskId, pending2, client3, identity3) {
|
|
|
178693
179123
|
let questionId = `ask-park:${rowTaskId}${REOPEN_ID_TAIL}${String(reopenSeq2)}`, unregister = registerLocalQuestionResponder(questionId, async (_id, answer) => {
|
|
178694
179124
|
try {
|
|
178695
179125
|
unregister();
|
|
178696
|
-
} catch {
|
|
179126
|
+
} catch (e) {
|
|
179127
|
+
failOpen("ask-park-reopen-unregister", void 0, String(e));
|
|
178697
179128
|
}
|
|
178698
179129
|
let deliver = async () => {
|
|
178699
179130
|
try {
|
|
@@ -178730,7 +179161,13 @@ async function armPendingRow(taskId, pending2, client3, identity3) {
|
|
|
178730
179161
|
), { kind: "verdict", verdict: { reopened: !1 } };
|
|
178731
179162
|
let cardPresented = !1, unsubscribeArm = onGateArmed((key) => {
|
|
178732
179163
|
key === armedKey && (cardPresented = !0);
|
|
178733
|
-
}), chainNote = { vanishedBeforeCard: null }, classifyChainFailure = async (detail) =>
|
|
179164
|
+
}), chainNote = { vanishedBeforeCard: null }, classifyChainFailure = async (detail) => {
|
|
179165
|
+
let disposition = classifyAskParkChainFailure({
|
|
179166
|
+
rowStillPending: await rowStillPending(),
|
|
179167
|
+
cardPresented
|
|
179168
|
+
});
|
|
179169
|
+
return disposition === "retry" ? { ok: !1, detail } : (disposition === "row-unborn" && (chainNote.vanishedBeforeCard = detail), { ok: !0 });
|
|
179170
|
+
}, runToolChain = async () => {
|
|
178734
179171
|
try {
|
|
178735
179172
|
let out6 = await surfaceFsApprovalAndDecide({ client: client3 }, rowTaskId, /* @__PURE__ */ new Map());
|
|
178736
179173
|
return out6.kind !== "failed" ? { ok: !0 } : classifyChainFailure(out6.reason);
|
|
@@ -178764,17 +179201,198 @@ async function armPendingRow(taskId, pending2, client3, identity3) {
|
|
|
178764
179201
|
), { kind: "verdict", verdict: { reopened: !1 } };
|
|
178765
179202
|
}
|
|
178766
179203
|
}
|
|
178767
|
-
var reopenSeq2, ownershipDeps, inFlightReopenByTask,
|
|
179204
|
+
var reopenSeq2, ownershipDeps, inFlightReopenByTask, rowWaitOverrideMs, rowPollOverrideMs, rowArmFlightEpoch, rowArmFlight, init_askParkReopen = __esm({
|
|
178768
179205
|
"build-src/src/sema/askParkReopen.ts"() {
|
|
178769
179206
|
init_dist();
|
|
178770
179207
|
init_liveSessionStore();
|
|
178771
|
-
init_activeRunSelfHeal2();
|
|
178772
179208
|
init_armedGateRegistry2();
|
|
178773
179209
|
init_decideRetry();
|
|
178774
|
-
|
|
178775
|
-
reopenSeq2 = 0, ownershipDeps = {
|
|
178776
|
-
|
|
178777
|
-
|
|
179210
|
+
init_failOpen();
|
|
179211
|
+
reopenSeq2 = 0, ownershipDeps = {
|
|
179212
|
+
currentSessionId: getLiveSessionId,
|
|
179213
|
+
isOwnRun: (taskIdTail) => {
|
|
179214
|
+
if (isOwnEngineRun(taskIdTail)) return !0;
|
|
179215
|
+
let persisted = restoredEngineTaskId();
|
|
179216
|
+
return typeof persisted == "string" && persisted.length > 0 && taskIdTail === rowIdTail(persisted);
|
|
179217
|
+
}
|
|
179218
|
+
};
|
|
179219
|
+
inFlightReopenByTask = /* @__PURE__ */ new Map();
|
|
179220
|
+
rowWaitOverrideMs = null, rowPollOverrideMs = null;
|
|
179221
|
+
rowArmFlightEpoch = -1, rowArmFlight = null;
|
|
179222
|
+
}
|
|
179223
|
+
});
|
|
179224
|
+
|
|
179225
|
+
// build-src/src/sema/activeRunRunningChoice.ts
|
|
179226
|
+
function choiceAnswerWaitMs() {
|
|
179227
|
+
return answerWaitOverrideMs ?? CHOICE_ANSWER_WAIT_MS;
|
|
179228
|
+
}
|
|
179229
|
+
function openRunningChoiceCardCount() {
|
|
179230
|
+
return openCardCount;
|
|
179231
|
+
}
|
|
179232
|
+
async function offerActiveRunChoice(req) {
|
|
179233
|
+
try {
|
|
179234
|
+
let { taskId } = req;
|
|
179235
|
+
if (typeof taskId != "string" || taskId.length === 0 || !req.canSteer && !req.canCancel || !hasQuestionOverlay() || req.signal?.aborted === !0) return "wait";
|
|
179236
|
+
if (offeringByTask.has(taskId))
|
|
179237
|
+
return process.env.SEMA_DEBUG && console.error(
|
|
179238
|
+
`[sema][activeRunRunningChoice] a choice card for run ${taskId} is already open \u2014 this caller waits instead of minting a second card`
|
|
179239
|
+
), "wait";
|
|
179240
|
+
offeringByTask.add(taskId);
|
|
179241
|
+
try {
|
|
179242
|
+
let options = [
|
|
179243
|
+
...req.canSteer ? [
|
|
179244
|
+
{
|
|
179245
|
+
label: RUNNING_CHOICE_STEER_LABEL,
|
|
179246
|
+
// 🔴 两句都是**兑现得了**的话(1.0.75 车B):①「it picks it up at its next step」对一条
|
|
179247
|
+
// 已经结束/已经 park 的 run 不成立 —— 引擎的回执才知道真到了哪儿(delivery 三分形),
|
|
179248
|
+
// 所以这里只说「交给引擎」,不替引擎承诺投递时点;②steer 的 wire body 只有 `text`
|
|
179249
|
+
// (SDK runs.steer 签名无 images 位),同一次提交里的图片不随行,按下之前就得知道。
|
|
179250
|
+
// 🔴 不许把「一定说得清落点」写成承诺(二次评审 [medium]):回执有**读不出投递语义**
|
|
179251
|
+
// 与**送达未知**(5xx / 回执路上断连)两条真分支,而 steer 非幂等 —— 对一条可能已经
|
|
179252
|
+
// 注入的指令说「我会告诉你它到底去哪了」,下一行的「无法确认」就当场打脸。
|
|
179253
|
+
description: 'Hands the TEXT of your message to the engine for the run that is already working \u2014 attachments do not ride along, and sema reports back whatever the engine says about where it landed (which can be "unconfirmed"). Nothing is cancelled.'
|
|
179254
|
+
}
|
|
179255
|
+
] : [],
|
|
179256
|
+
...req.canCancel ? [
|
|
179257
|
+
{
|
|
179258
|
+
label: RUNNING_CHOICE_CANCEL_LABEL,
|
|
179259
|
+
description: "Stops that run (whatever it has been doing is discarded), waits for it to release the session, then sends your message as a new turn."
|
|
179260
|
+
}
|
|
179261
|
+
] : [],
|
|
179262
|
+
{
|
|
179263
|
+
label: RUNNING_CHOICE_WAIT_LABEL,
|
|
179264
|
+
description: "Leaves the run alone. Your message is NOT sent \u2014 send it again whenever you want."
|
|
179265
|
+
}
|
|
179266
|
+
], decided = await presentChoiceCard({
|
|
179267
|
+
taskId,
|
|
179268
|
+
header: RUNNING_CHOICE_HEADER,
|
|
179269
|
+
question: `An earlier turn is still running in this session (run ${taskId}, status ${req.status}), so your message was not sent \u2014 a session runs one turn at a time. What should sema do with it?`,
|
|
179270
|
+
options,
|
|
179271
|
+
decode: choiceFromAnswer,
|
|
179272
|
+
onNoAnswer: "wait",
|
|
179273
|
+
...req.signal ? { signal: req.signal } : {}
|
|
179274
|
+
});
|
|
179275
|
+
return decided === NOT_PRESENTED ? "wait" : decided;
|
|
179276
|
+
} finally {
|
|
179277
|
+
offeringByTask.delete(taskId);
|
|
179278
|
+
}
|
|
179279
|
+
} catch {
|
|
179280
|
+
return "wait";
|
|
179281
|
+
}
|
|
179282
|
+
}
|
|
179283
|
+
async function offerResumeRunningChoice(req) {
|
|
179284
|
+
try {
|
|
179285
|
+
let { taskId } = req;
|
|
179286
|
+
if (typeof taskId != "string" || taskId.length === 0 || !req.canAttach && !req.canCancel || !hasQuestionOverlay() || req.signal?.aborted === !0) return "unavailable";
|
|
179287
|
+
if (offeringByTask.has(taskId))
|
|
179288
|
+
return process.env.SEMA_DEBUG && console.error(
|
|
179289
|
+
`[sema][activeRunRunningChoice] a choice card for run ${taskId} is already open \u2014 the resume entry stands down instead of minting a second card`
|
|
179290
|
+
), "unavailable";
|
|
179291
|
+
offeringByTask.add(taskId);
|
|
179292
|
+
try {
|
|
179293
|
+
let decided = await presentChoiceCard({
|
|
179294
|
+
taskId,
|
|
179295
|
+
header: RESUME_CHOICE_HEADER,
|
|
179296
|
+
question: resumeRunningQuestionText(req),
|
|
179297
|
+
// 🔴 顺序 = 默认焦点(裁点③:③ 必须是 options[0])—— 判据单源在 resumeRunningOptions。
|
|
179298
|
+
options: resumeRunningOptions(req),
|
|
179299
|
+
decode: (answer) => resumeChoiceFromLabels(answer?.answers?.[0]?.selected),
|
|
179300
|
+
// Esc / 看门狗到点 ⇒ ③(零动作)。#155:破坏性动作只认显式选择。
|
|
179301
|
+
onNoAnswer: "background",
|
|
179302
|
+
...req.signal ? { signal: req.signal } : {}
|
|
179303
|
+
});
|
|
179304
|
+
return decided === NOT_PRESENTED ? "unavailable" : decided;
|
|
179305
|
+
} finally {
|
|
179306
|
+
offeringByTask.delete(taskId);
|
|
179307
|
+
}
|
|
179308
|
+
} catch {
|
|
179309
|
+
return "unavailable";
|
|
179310
|
+
}
|
|
179311
|
+
}
|
|
179312
|
+
async function presentChoiceCard(spec) {
|
|
179313
|
+
let taskId = spec.taskId;
|
|
179314
|
+
cardSeq += 1;
|
|
179315
|
+
let questionId = `${QUESTION_ID_PREFIX}${taskId}${REOPEN_ID_TAIL}${String(cardSeq)}`, settle2 = () => {
|
|
179316
|
+
}, decided = new Promise((resolve57) => {
|
|
179317
|
+
settle2 = resolve57;
|
|
179318
|
+
}), unregister = registerLocalQuestionResponder(questionId, (_id, answer) => (settle2(spec.decode(answer)), Promise.resolve({ ok: !0 }))), retired = !1, counted = !1, retire = () => {
|
|
179319
|
+
if (!retired) {
|
|
179320
|
+
retired = !0, counted && (counted = !1, openCardCount = Math.max(0, openCardCount - 1));
|
|
179321
|
+
try {
|
|
179322
|
+
unregister();
|
|
179323
|
+
} catch {
|
|
179324
|
+
}
|
|
179325
|
+
publishQuestionFrame({ type: "question_complete", questionId });
|
|
179326
|
+
}
|
|
179327
|
+
}, frame = {
|
|
179328
|
+
type: "question",
|
|
179329
|
+
questionId,
|
|
179330
|
+
questions: [
|
|
179331
|
+
{
|
|
179332
|
+
header: spec.header,
|
|
179333
|
+
question: spec.question,
|
|
179334
|
+
options: spec.options,
|
|
179335
|
+
multiSelect: !1
|
|
179336
|
+
}
|
|
179337
|
+
]
|
|
179338
|
+
}, receipt = waitForGateArmed([questionId], gateArmedWaitMs());
|
|
179339
|
+
if (publishQuestionFrame(frame), !await receipt)
|
|
179340
|
+
return process.env.SEMA_DEBUG && console.error(
|
|
179341
|
+
`[sema][activeRunRunningChoice] question frame ${questionId} published but no presentation receipt arrived within ${String(gateArmedWaitMs())}ms \u2014 treating it as no decision`
|
|
179342
|
+
), retire(), NOT_PRESENTED;
|
|
179343
|
+
counted = !0, openCardCount += 1;
|
|
179344
|
+
let watchdog = watchdogToNoAnswer(spec.onNoAnswer), abortWatch = abortToNoAnswer(spec.signal, spec.onNoAnswer), choice;
|
|
179345
|
+
try {
|
|
179346
|
+
choice = await Promise.race([decided, abortWatch.promise, watchdog.promise]);
|
|
179347
|
+
} finally {
|
|
179348
|
+
watchdog.cancel(), abortWatch.cancel();
|
|
179349
|
+
}
|
|
179350
|
+
return retire(), choice;
|
|
179351
|
+
}
|
|
179352
|
+
function abortToNoAnswer(signal, onNoAnswer) {
|
|
179353
|
+
if (signal === void 0) return { promise: new Promise(() => {
|
|
179354
|
+
}), cancel: () => {
|
|
179355
|
+
} };
|
|
179356
|
+
if (signal.aborted) return { promise: Promise.resolve(onNoAnswer), cancel: () => {
|
|
179357
|
+
} };
|
|
179358
|
+
let onAbort = () => {
|
|
179359
|
+
};
|
|
179360
|
+
return {
|
|
179361
|
+
promise: new Promise((resolve57) => {
|
|
179362
|
+
onAbort = () => resolve57(onNoAnswer), signal.addEventListener("abort", onAbort, { once: !0 });
|
|
179363
|
+
}),
|
|
179364
|
+
cancel: () => {
|
|
179365
|
+
try {
|
|
179366
|
+
signal.removeEventListener("abort", onAbort);
|
|
179367
|
+
} catch {
|
|
179368
|
+
}
|
|
179369
|
+
}
|
|
179370
|
+
};
|
|
179371
|
+
}
|
|
179372
|
+
function watchdogToNoAnswer(onNoAnswer) {
|
|
179373
|
+
let timer2;
|
|
179374
|
+
return {
|
|
179375
|
+
promise: new Promise((resolve57) => {
|
|
179376
|
+
timer2 = setTimeout(() => resolve57(onNoAnswer), choiceAnswerWaitMs());
|
|
179377
|
+
}),
|
|
179378
|
+
cancel: () => {
|
|
179379
|
+
timer2 !== void 0 && clearTimeout(timer2);
|
|
179380
|
+
}
|
|
179381
|
+
};
|
|
179382
|
+
}
|
|
179383
|
+
function choiceFromAnswer(answer) {
|
|
179384
|
+
let selected = answer?.answers?.[0]?.selected;
|
|
179385
|
+
if (!Array.isArray(selected) || selected.length !== 1) return "wait";
|
|
179386
|
+
let label = selected[0];
|
|
179387
|
+
return label === RUNNING_CHOICE_STEER_LABEL ? "steer" : label === RUNNING_CHOICE_CANCEL_LABEL ? "cancel" : "wait";
|
|
179388
|
+
}
|
|
179389
|
+
var RUNNING_CHOICE_STEER_LABEL, RUNNING_CHOICE_CANCEL_LABEL, RUNNING_CHOICE_WAIT_LABEL, RUNNING_CHOICE_HEADER, QUESTION_ID_PREFIX, CHOICE_ANSWER_WAIT_MS, answerWaitOverrideMs, cardSeq, offeringByTask, openCardCount, NOT_PRESENTED, init_activeRunRunningChoice = __esm({
|
|
179390
|
+
"build-src/src/sema/activeRunRunningChoice.ts"() {
|
|
179391
|
+
init_dist();
|
|
179392
|
+
init_armedGateRegistry2();
|
|
179393
|
+
RUNNING_CHOICE_STEER_LABEL = "Queue it into the running turn", RUNNING_CHOICE_CANCEL_LABEL = "Cancel that run and send this message now", RUNNING_CHOICE_WAIT_LABEL = "Do nothing for now", RUNNING_CHOICE_HEADER = "Session busy", QUESTION_ID_PREFIX = "active-run:", CHOICE_ANSWER_WAIT_MS = 3e5, answerWaitOverrideMs = null;
|
|
179394
|
+
cardSeq = 0, offeringByTask = /* @__PURE__ */ new Set(), openCardCount = 0;
|
|
179395
|
+
NOT_PRESENTED = /* @__PURE__ */ Symbol("sema.choiceCardNotPresented");
|
|
178778
179396
|
}
|
|
178779
179397
|
});
|
|
178780
179398
|
|
|
@@ -179068,63 +179686,6 @@ var REATTACH_BACKOFF_START_MS, REATTACH_BACKOFF_CAP_MS, REATTACH_WINDOW_MS, PROD
|
|
|
179068
179686
|
});
|
|
179069
179687
|
|
|
179070
179688
|
// build-src/src/sema/resumeRunningArm.ts
|
|
179071
|
-
function resumeRunningLivenessRow(msSinceLastActivity) {
|
|
179072
|
-
let ms = msSinceLastActivity;
|
|
179073
|
-
return typeof ms != "number" || !Number.isFinite(ms) || ms < 0 ? null : `The engine last recorded activity on it ${String(Math.round(ms / 1e3))}s ago.`;
|
|
179074
|
-
}
|
|
179075
|
-
function resumeRunningQuestionText(i) {
|
|
179076
|
-
let head = `This conversation was resumed while an earlier turn is still executing on the engine (run ${i.taskId}, status ${i.status}). sema did not touch it. What should it do?`, liveness = resumeRunningLivenessRow(i.msSinceLastActivity);
|
|
179077
|
-
return liveness === null ? head : `${head}
|
|
179078
|
-
${liveness}`;
|
|
179079
|
-
}
|
|
179080
|
-
function resumeRunningOptions(i) {
|
|
179081
|
-
let options = [
|
|
179082
|
-
{
|
|
179083
|
-
// 🔴 默认焦点(裁点③)—— 三条路里唯一零副作用的一条,所以它是手滑回车的落点。
|
|
179084
|
-
// 🔴 措辞(1.0.75 车B / cli-049):这一项曾写「stays visible in /tasks」——**假的**。`/tasks`
|
|
179085
|
-
// 面板读的是纯进程内的 `AppState.tasks`,而这张卡的前提恰恰是「那条 run 活得比上一个壳
|
|
179086
|
-
// 进程久」,新进程里没有任何腿会为它建行(③ 的处置本身也是显式零动作)。默认焦点上的一句
|
|
179087
|
-
// 假 affordance 是最坏的一格:手滑回车的人拿到一条既看不见、也停不掉、还占着会话锁的 run。
|
|
179088
|
-
// 换成两句**可证的**真话:本屏不会列出它;它还占着会话,所以下一条消息会再撞上它(那时
|
|
179089
|
-
// C3 三选卡会带着 steer/cancel 两条真出路出现)。
|
|
179090
|
-
label: RESUME_CHOICE_BACKGROUND_LABEL,
|
|
179091
|
-
description: "Leaves the run alone. It keeps executing on the engine, but this screen will not show it and it will not be listed here \u2014 your next message runs into it again, and sema asks you then."
|
|
179092
|
-
}
|
|
179093
|
-
];
|
|
179094
|
-
return i.canAttach && options.push({
|
|
179095
|
-
label: RESUME_CHOICE_ATTACH_LABEL,
|
|
179096
|
-
// 🔴 第二句是**知情同意**那一半(二次评审 r1-[high] 处置,见 resumeAttachReplayDisclosure):
|
|
179097
|
-
// resume 入口没有事件锚可用,durable 尾只能从这条 run 的第一帧读起,所以崩溃前已经落盘
|
|
179098
|
-
// 并被 resume 还原到屏上的那一段会再出现一次。用户按下之前就得看见这句 —— 一个会做出
|
|
179099
|
-
// 用户没预料到的事的选项,和一个按了没用的选项同样是假 affordance。
|
|
179100
|
-
description: "Follows that run from here: sema replays it from the engine ledger and keeps streaming it into this conversation. Anything from that turn already shown above will appear a second time \u2014 sema has no resume marker for it."
|
|
179101
|
-
}), i.canCancel && options.push({
|
|
179102
|
-
label: RESUME_CHOICE_CANCEL_LABEL,
|
|
179103
|
-
description: "Stops that run on the engine (whatever it has been doing is discarded) and frees this session for a new turn."
|
|
179104
|
-
}), options;
|
|
179105
|
-
}
|
|
179106
|
-
function resumeChoiceFromLabels(selected) {
|
|
179107
|
-
if (!Array.isArray(selected) || selected.length !== 1) return "background";
|
|
179108
|
-
let label = selected[0];
|
|
179109
|
-
return label === RESUME_CHOICE_ATTACH_LABEL ? "attach" : label === RESUME_CHOICE_CANCEL_LABEL ? "cancel" : "background";
|
|
179110
|
-
}
|
|
179111
|
-
function resumeRunningNoUiGuidance(i) {
|
|
179112
|
-
let sid = typeof i.sessionId == "string" && i.sessionId.length > 0 ? i.sessionId : null, attach = sid === null ? "sema --resume (pick this session from the list)" : `sema --resume ${sid}`, T3 = RESUME_RUNNING_GUIDANCE_TAG;
|
|
179113
|
-
return [
|
|
179114
|
-
`${T3} run ${i.taskId} from an earlier turn is still executing on the engine, and this lane has no card to ask you on. sema did NOT cancel it and did NOT attach to it.`,
|
|
179115
|
-
`${T3} attach=${attach}`,
|
|
179116
|
-
`${T3} cancel=POST /v1/runs/${i.taskId}/cancel`,
|
|
179117
|
-
// 🔴 同 cli-049:这条车道更没有 `/tasks` 可看(headless 连 REPL 都不挂载)。给的是引擎侧真读面。
|
|
179118
|
-
`${T3} background=do nothing \u2014 run ${i.taskId} keeps executing on the engine; this client does not list it (read it with GET /v1/runs/${i.taskId})`
|
|
179119
|
-
].join(`
|
|
179120
|
-
`);
|
|
179121
|
-
}
|
|
179122
|
-
function resumeAttachReplayDisclosure(taskId) {
|
|
179123
|
-
return `sema: attaching to run ${taskId} \u2014 sema is replaying it from the engine's ledger, so anything from that turn already shown above will appear again below. There is no resume marker for a run that outlived its shell. The replayed turns are not billed into this session's cost again either \u2014 the engine's own record (GET /v1/runs/${taskId}) is the authority on what that run really spent.`;
|
|
179124
|
-
}
|
|
179125
|
-
function resumeRunningCancelUnconfirmedRow(taskId) {
|
|
179126
|
-
return `sema: the cancel for run ${taskId} did not come back confirmed, so that run may still be executing. This screen does not list it \u2014 read its real state on the engine (GET /v1/runs/${taskId}) before assuming this session is free.`;
|
|
179127
|
-
}
|
|
179128
179689
|
function resumeRunningActionableVerbs(deps2) {
|
|
179129
179690
|
return {
|
|
179130
179691
|
canAttach: deps2.canAttach === !0 && typeof deps2.attach == "function",
|
|
@@ -179254,186 +179815,10 @@ async function* resumeAttachStream(taskId, deps2, opts) {
|
|
|
179254
179815
|
deps: deps2
|
|
179255
179816
|
});
|
|
179256
179817
|
}
|
|
179257
|
-
var
|
|
179818
|
+
var init_resumeRunningArm = __esm({
|
|
179258
179819
|
"build-src/src/sema/resumeRunningArm.ts"() {
|
|
179259
|
-
init_interactiveReattach();
|
|
179260
|
-
RESUME_CHOICE_ATTACH_LABEL = "Attach and watch", RESUME_CHOICE_CANCEL_LABEL = "Cancel it", RESUME_CHOICE_BACKGROUND_LABEL = "Leave it running in the background", RESUME_CHOICE_HEADER = "Earlier run still in flight";
|
|
179261
|
-
RESUME_RUNNING_NO_UI_EXIT_CODE = 75, RESUME_RUNNING_GUIDANCE_TAG = "sema: resume-running:";
|
|
179262
|
-
}
|
|
179263
|
-
});
|
|
179264
|
-
|
|
179265
|
-
// build-src/src/sema/activeRunRunningChoice.ts
|
|
179266
|
-
function choiceAnswerWaitMs() {
|
|
179267
|
-
return answerWaitOverrideMs ?? CHOICE_ANSWER_WAIT_MS;
|
|
179268
|
-
}
|
|
179269
|
-
function openRunningChoiceCardCount() {
|
|
179270
|
-
return openCardCount;
|
|
179271
|
-
}
|
|
179272
|
-
async function offerActiveRunChoice(req) {
|
|
179273
|
-
try {
|
|
179274
|
-
let { taskId } = req;
|
|
179275
|
-
if (typeof taskId != "string" || taskId.length === 0 || !req.canSteer && !req.canCancel || !hasQuestionOverlay() || req.signal?.aborted === !0) return "wait";
|
|
179276
|
-
if (offeringByTask.has(taskId))
|
|
179277
|
-
return process.env.SEMA_DEBUG && console.error(
|
|
179278
|
-
`[sema][activeRunRunningChoice] a choice card for run ${taskId} is already open \u2014 this caller waits instead of minting a second card`
|
|
179279
|
-
), "wait";
|
|
179280
|
-
offeringByTask.add(taskId);
|
|
179281
|
-
try {
|
|
179282
|
-
let options = [
|
|
179283
|
-
...req.canSteer ? [
|
|
179284
|
-
{
|
|
179285
|
-
label: RUNNING_CHOICE_STEER_LABEL,
|
|
179286
|
-
// 🔴 两句都是**兑现得了**的话(1.0.75 车B):①「it picks it up at its next step」对一条
|
|
179287
|
-
// 已经结束/已经 park 的 run 不成立 —— 引擎的回执才知道真到了哪儿(delivery 三分形),
|
|
179288
|
-
// 所以这里只说「交给引擎」,不替引擎承诺投递时点;②steer 的 wire body 只有 `text`
|
|
179289
|
-
// (SDK runs.steer 签名无 images 位),同一次提交里的图片不随行,按下之前就得知道。
|
|
179290
|
-
// 🔴 不许把「一定说得清落点」写成承诺(二次评审 [medium]):回执有**读不出投递语义**
|
|
179291
|
-
// 与**送达未知**(5xx / 回执路上断连)两条真分支,而 steer 非幂等 —— 对一条可能已经
|
|
179292
|
-
// 注入的指令说「我会告诉你它到底去哪了」,下一行的「无法确认」就当场打脸。
|
|
179293
|
-
description: 'Hands the TEXT of your message to the engine for the run that is already working \u2014 attachments do not ride along, and sema reports back whatever the engine says about where it landed (which can be "unconfirmed"). Nothing is cancelled.'
|
|
179294
|
-
}
|
|
179295
|
-
] : [],
|
|
179296
|
-
...req.canCancel ? [
|
|
179297
|
-
{
|
|
179298
|
-
label: RUNNING_CHOICE_CANCEL_LABEL,
|
|
179299
|
-
description: "Stops that run (whatever it has been doing is discarded), waits for it to release the session, then sends your message as a new turn."
|
|
179300
|
-
}
|
|
179301
|
-
] : [],
|
|
179302
|
-
{
|
|
179303
|
-
label: RUNNING_CHOICE_WAIT_LABEL,
|
|
179304
|
-
description: "Leaves the run alone. Your message is NOT sent \u2014 send it again whenever you want."
|
|
179305
|
-
}
|
|
179306
|
-
], decided = await presentChoiceCard({
|
|
179307
|
-
taskId,
|
|
179308
|
-
header: RUNNING_CHOICE_HEADER,
|
|
179309
|
-
question: `An earlier turn is still running in this session (run ${taskId}, status ${req.status}), so your message was not sent \u2014 a session runs one turn at a time. What should sema do with it?`,
|
|
179310
|
-
options,
|
|
179311
|
-
decode: choiceFromAnswer,
|
|
179312
|
-
onNoAnswer: "wait",
|
|
179313
|
-
...req.signal ? { signal: req.signal } : {}
|
|
179314
|
-
});
|
|
179315
|
-
return decided === NOT_PRESENTED ? "wait" : decided;
|
|
179316
|
-
} finally {
|
|
179317
|
-
offeringByTask.delete(taskId);
|
|
179318
|
-
}
|
|
179319
|
-
} catch {
|
|
179320
|
-
return "wait";
|
|
179321
|
-
}
|
|
179322
|
-
}
|
|
179323
|
-
async function offerResumeRunningChoice(req) {
|
|
179324
|
-
try {
|
|
179325
|
-
let { taskId } = req;
|
|
179326
|
-
if (typeof taskId != "string" || taskId.length === 0 || !req.canAttach && !req.canCancel || !hasQuestionOverlay() || req.signal?.aborted === !0) return "unavailable";
|
|
179327
|
-
if (offeringByTask.has(taskId))
|
|
179328
|
-
return process.env.SEMA_DEBUG && console.error(
|
|
179329
|
-
`[sema][activeRunRunningChoice] a choice card for run ${taskId} is already open \u2014 the resume entry stands down instead of minting a second card`
|
|
179330
|
-
), "unavailable";
|
|
179331
|
-
offeringByTask.add(taskId);
|
|
179332
|
-
try {
|
|
179333
|
-
let decided = await presentChoiceCard({
|
|
179334
|
-
taskId,
|
|
179335
|
-
header: RESUME_CHOICE_HEADER,
|
|
179336
|
-
question: resumeRunningQuestionText(req),
|
|
179337
|
-
// 🔴 顺序 = 默认焦点(裁点③:③ 必须是 options[0])—— 判据单源在 resumeRunningOptions。
|
|
179338
|
-
options: resumeRunningOptions(req),
|
|
179339
|
-
decode: (answer) => resumeChoiceFromLabels(answer?.answers?.[0]?.selected),
|
|
179340
|
-
// Esc / 看门狗到点 ⇒ ③(零动作)。#155:破坏性动作只认显式选择。
|
|
179341
|
-
onNoAnswer: "background",
|
|
179342
|
-
...req.signal ? { signal: req.signal } : {}
|
|
179343
|
-
});
|
|
179344
|
-
return decided === NOT_PRESENTED ? "unavailable" : decided;
|
|
179345
|
-
} finally {
|
|
179346
|
-
offeringByTask.delete(taskId);
|
|
179347
|
-
}
|
|
179348
|
-
} catch {
|
|
179349
|
-
return "unavailable";
|
|
179350
|
-
}
|
|
179351
|
-
}
|
|
179352
|
-
async function presentChoiceCard(spec) {
|
|
179353
|
-
let taskId = spec.taskId;
|
|
179354
|
-
cardSeq += 1;
|
|
179355
|
-
let questionId = `${QUESTION_ID_PREFIX}${taskId}${REOPEN_ID_TAIL}${String(cardSeq)}`, settle2 = () => {
|
|
179356
|
-
}, decided = new Promise((resolve57) => {
|
|
179357
|
-
settle2 = resolve57;
|
|
179358
|
-
}), unregister = registerLocalQuestionResponder(questionId, (_id, answer) => (settle2(spec.decode(answer)), Promise.resolve({ ok: !0 }))), retired = !1, counted = !1, retire = () => {
|
|
179359
|
-
if (!retired) {
|
|
179360
|
-
retired = !0, counted && (counted = !1, openCardCount = Math.max(0, openCardCount - 1));
|
|
179361
|
-
try {
|
|
179362
|
-
unregister();
|
|
179363
|
-
} catch {
|
|
179364
|
-
}
|
|
179365
|
-
publishQuestionFrame({ type: "question_complete", questionId });
|
|
179366
|
-
}
|
|
179367
|
-
}, frame = {
|
|
179368
|
-
type: "question",
|
|
179369
|
-
questionId,
|
|
179370
|
-
questions: [
|
|
179371
|
-
{
|
|
179372
|
-
header: spec.header,
|
|
179373
|
-
question: spec.question,
|
|
179374
|
-
options: spec.options,
|
|
179375
|
-
multiSelect: !1
|
|
179376
|
-
}
|
|
179377
|
-
]
|
|
179378
|
-
}, receipt = waitForGateArmed([questionId], gateArmedWaitMs());
|
|
179379
|
-
if (publishQuestionFrame(frame), !await receipt)
|
|
179380
|
-
return process.env.SEMA_DEBUG && console.error(
|
|
179381
|
-
`[sema][activeRunRunningChoice] question frame ${questionId} published but no presentation receipt arrived within ${String(gateArmedWaitMs())}ms \u2014 treating it as no decision`
|
|
179382
|
-
), retire(), NOT_PRESENTED;
|
|
179383
|
-
counted = !0, openCardCount += 1;
|
|
179384
|
-
let watchdog = watchdogToNoAnswer(spec.onNoAnswer), abortWatch = abortToNoAnswer(spec.signal, spec.onNoAnswer), choice;
|
|
179385
|
-
try {
|
|
179386
|
-
choice = await Promise.race([decided, abortWatch.promise, watchdog.promise]);
|
|
179387
|
-
} finally {
|
|
179388
|
-
watchdog.cancel(), abortWatch.cancel();
|
|
179389
|
-
}
|
|
179390
|
-
return retire(), choice;
|
|
179391
|
-
}
|
|
179392
|
-
function abortToNoAnswer(signal, onNoAnswer) {
|
|
179393
|
-
if (signal === void 0) return { promise: new Promise(() => {
|
|
179394
|
-
}), cancel: () => {
|
|
179395
|
-
} };
|
|
179396
|
-
if (signal.aborted) return { promise: Promise.resolve(onNoAnswer), cancel: () => {
|
|
179397
|
-
} };
|
|
179398
|
-
let onAbort = () => {
|
|
179399
|
-
};
|
|
179400
|
-
return {
|
|
179401
|
-
promise: new Promise((resolve57) => {
|
|
179402
|
-
onAbort = () => resolve57(onNoAnswer), signal.addEventListener("abort", onAbort, { once: !0 });
|
|
179403
|
-
}),
|
|
179404
|
-
cancel: () => {
|
|
179405
|
-
try {
|
|
179406
|
-
signal.removeEventListener("abort", onAbort);
|
|
179407
|
-
} catch {
|
|
179408
|
-
}
|
|
179409
|
-
}
|
|
179410
|
-
};
|
|
179411
|
-
}
|
|
179412
|
-
function watchdogToNoAnswer(onNoAnswer) {
|
|
179413
|
-
let timer2;
|
|
179414
|
-
return {
|
|
179415
|
-
promise: new Promise((resolve57) => {
|
|
179416
|
-
timer2 = setTimeout(() => resolve57(onNoAnswer), choiceAnswerWaitMs());
|
|
179417
|
-
}),
|
|
179418
|
-
cancel: () => {
|
|
179419
|
-
timer2 !== void 0 && clearTimeout(timer2);
|
|
179420
|
-
}
|
|
179421
|
-
};
|
|
179422
|
-
}
|
|
179423
|
-
function choiceFromAnswer(answer) {
|
|
179424
|
-
let selected = answer?.answers?.[0]?.selected;
|
|
179425
|
-
if (!Array.isArray(selected) || selected.length !== 1) return "wait";
|
|
179426
|
-
let label = selected[0];
|
|
179427
|
-
return label === RUNNING_CHOICE_STEER_LABEL ? "steer" : label === RUNNING_CHOICE_CANCEL_LABEL ? "cancel" : "wait";
|
|
179428
|
-
}
|
|
179429
|
-
var RUNNING_CHOICE_STEER_LABEL, RUNNING_CHOICE_CANCEL_LABEL, RUNNING_CHOICE_WAIT_LABEL, RUNNING_CHOICE_HEADER, QUESTION_ID_PREFIX, CHOICE_ANSWER_WAIT_MS, answerWaitOverrideMs, cardSeq, offeringByTask, openCardCount, NOT_PRESENTED, init_activeRunRunningChoice = __esm({
|
|
179430
|
-
"build-src/src/sema/activeRunRunningChoice.ts"() {
|
|
179431
179820
|
init_dist();
|
|
179432
|
-
|
|
179433
|
-
init_resumeRunningArm();
|
|
179434
|
-
RUNNING_CHOICE_STEER_LABEL = "Queue it into the running turn", RUNNING_CHOICE_CANCEL_LABEL = "Cancel that run and send this message now", RUNNING_CHOICE_WAIT_LABEL = "Do nothing for now", RUNNING_CHOICE_HEADER = "Session busy", QUESTION_ID_PREFIX = "active-run:", CHOICE_ANSWER_WAIT_MS = 3e5, answerWaitOverrideMs = null;
|
|
179435
|
-
cardSeq = 0, offeringByTask = /* @__PURE__ */ new Set(), openCardCount = 0;
|
|
179436
|
-
NOT_PRESENTED = /* @__PURE__ */ Symbol("sema.choiceCardNotPresented");
|
|
179821
|
+
init_interactiveReattach();
|
|
179437
179822
|
}
|
|
179438
179823
|
});
|
|
179439
179824
|
|
|
@@ -184108,7 +184493,16 @@ Fix: run \`sema doctor\` to diagnose, or restart sema to retry.`
|
|
|
184108
184493
|
// 无 decide」的 client 过门,在用户按卡之后才 TypeError。类型谓词一次收窄,零散 cast。
|
|
184109
184494
|
...(() => {
|
|
184110
184495
|
let hitl = hasHitlVerbs(client) ? client : null;
|
|
184111
|
-
return hitl ? {
|
|
184496
|
+
return hitl ? {
|
|
184497
|
+
reopenAskPark: (tid) => reopenAskParkCard(tid, hitl, signal ?? void 0),
|
|
184498
|
+
// [3892]-[3899] P0 假死锁防御的复核读口:hasPendingDecision 那个镜像在
|
|
184499
|
+
// --resume 后可能卡脏值(队列里躺着从未渲上屏的幽灵卡 ⇒ 布尔恒真,消息全被
|
|
184500
|
+
// 闸,而引擎侧 run 早已 completed)。selfHeal 在镜像说有卡时向引擎复核
|
|
184501
|
+
// **属主** pending 行数,恰 0 = 脏值正面证据 ⇒ 放行真分诊;归属过滤见
|
|
184502
|
+
// countOwnedPendingApprovals 头注(引擎全局队列有别家陈年行,裸计数恒非零
|
|
184503
|
+
// = 防御恒不触发)。mock 车道无 approvals 面 ⇒ 读口不装 = 旧行为(S-g)。
|
|
184504
|
+
listOwnedPendingApprovals: () => countOwnedPendingApprovals(hitl)
|
|
184505
|
+
} : {};
|
|
184112
184506
|
})(),
|
|
184113
184507
|
// C3([3777]/[3779])running 形的三选卡口。**一条用户消息至多一张**(runningChoiceOffered
|
|
184114
184508
|
// 一次性闸,见声明处):cancel 那条路会触发一次重发,重发再撞 409 时不许再铸卡。
|
|
@@ -184235,7 +184629,7 @@ async function probeEngineRunState(taskId) {
|
|
|
184235
184629
|
async function probeEngineRunLiveness(taskId, opts) {
|
|
184236
184630
|
let absent = { state: "unreachable", msSinceLastActivity: null };
|
|
184237
184631
|
if (typeof taskId != "string" || taskId.length === 0) return absent;
|
|
184238
|
-
let
|
|
184632
|
+
let getRaw = client.runs.get, get4 = typeof getRaw == "function" ? getRaw.bind(client.runs) : void 0;
|
|
184239
184633
|
if (typeof get4 != "function") return absent;
|
|
184240
184634
|
let row2;
|
|
184241
184635
|
try {
|
|
@@ -184264,7 +184658,8 @@ async function cancelEngineRun(taskId) {
|
|
|
184264
184658
|
}
|
|
184265
184659
|
}
|
|
184266
184660
|
async function attachToResumedRun(taskId) {
|
|
184267
|
-
|
|
184661
|
+
let eventsRaw = client.runs.events;
|
|
184662
|
+
if (typeof (typeof eventsRaw == "function" ? eventsRaw.bind(client.runs) : void 0) != "function") throw new Error(`no durable events verb on this lane (run ${taskId})`);
|
|
184268
184663
|
let sessionId = getSessionId(), ac = new AbortController(), stream5 = resumeAttachStream(
|
|
184269
184664
|
taskId,
|
|
184270
184665
|
{
|
|
@@ -184386,6 +184781,7 @@ var BG_TEAR_MAX_RESENDS, BG_RECOVERY_WAIT_MS, DRAINING_MAX_RETRIES, DEFAULT_DRAI
|
|
|
184386
184781
|
init_planReviewReopen();
|
|
184387
184782
|
init_askParkReopen();
|
|
184388
184783
|
init_activeRunRunningChoice();
|
|
184784
|
+
init_dist();
|
|
184389
184785
|
init_resumeRunningArm();
|
|
184390
184786
|
init_transcriptSystemNotice();
|
|
184391
184787
|
init_interactiveReattach();
|
|
@@ -188671,6 +189067,17 @@ var SUPPORTED_RULE_BEHAVIORS, EDITABLE_SOURCES, init_permissionsLoader = __esm({
|
|
|
188671
189067
|
});
|
|
188672
189068
|
|
|
188673
189069
|
// build-src/src/utils/permissions/PermissionUpdate.ts
|
|
189070
|
+
var PermissionUpdate_exports = {};
|
|
189071
|
+
__export(PermissionUpdate_exports, {
|
|
189072
|
+
applyPermissionUpdate: () => applyPermissionUpdate,
|
|
189073
|
+
applyPermissionUpdates: () => applyPermissionUpdates,
|
|
189074
|
+
createReadRuleSuggestion: () => createReadRuleSuggestion,
|
|
189075
|
+
extractRules: () => extractRules,
|
|
189076
|
+
hasRules: () => hasRules,
|
|
189077
|
+
persistPermissionUpdate: () => persistPermissionUpdate,
|
|
189078
|
+
persistPermissionUpdates: () => persistPermissionUpdates,
|
|
189079
|
+
supportsPersistence: () => supportsPersistence
|
|
189080
|
+
});
|
|
188674
189081
|
import { posix as posix2 } from "path";
|
|
188675
189082
|
function extractRules(updates) {
|
|
188676
189083
|
return updates ? updates.flatMap((update2) => update2.type === "addRules" ? update2.rules : []) : [];
|
|
@@ -191716,6 +192123,7 @@ __export(bashPermissions_exports, {
|
|
|
191716
192123
|
MAX_SUGGESTED_RULES_FOR_COMPOUND: () => MAX_SUGGESTED_RULES_FOR_COMPOUND,
|
|
191717
192124
|
awaitClassifierAutoApproval: () => awaitClassifierAutoApproval,
|
|
191718
192125
|
bashPermissionRule: () => bashPermissionRule,
|
|
192126
|
+
bashRuleContentHasDangerousBarePrefix: () => bashRuleContentHasDangerousBarePrefix,
|
|
191719
192127
|
bashToolCheckExactMatchPermission: () => bashToolCheckExactMatchPermission,
|
|
191720
192128
|
bashToolCheckPermission: () => bashToolCheckPermission,
|
|
191721
192129
|
bashToolHasPermission: () => bashToolHasPermission,
|
|
@@ -191767,6 +192175,14 @@ function getFirstWordPrefix(command8) {
|
|
|
191767
192175
|
let cmd = tokens[i];
|
|
191768
192176
|
return !cmd || !/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(cmd) || BARE_SHELL_PREFIXES.has(cmd) ? null : cmd;
|
|
191769
192177
|
}
|
|
192178
|
+
function bashRuleContentHasDangerousBarePrefix(ruleContent) {
|
|
192179
|
+
let first = (ruleContent.endsWith(":*") ? ruleContent.slice(0, -2) : ruleContent).trim().split(/\s+/).filter(Boolean)[0];
|
|
192180
|
+
if (first === void 0) return !1;
|
|
192181
|
+
let lowered = first.toLowerCase();
|
|
192182
|
+
if (BARE_SHELL_PREFIXES.has(lowered)) return !0;
|
|
192183
|
+
let base = lowered.split(/[/\\]/).pop();
|
|
192184
|
+
return !!(base !== void 0 && base !== "" && BARE_SHELL_PREFIXES.has(base) || base !== void 0 && base.endsWith(".exe") && BARE_SHELL_PREFIXES.has(base.slice(0, -4)));
|
|
192185
|
+
}
|
|
191770
192186
|
function suggestionForExactCommand2(command8) {
|
|
191771
192187
|
let heredocPrefix = extractPrefixBeforeHeredoc(command8);
|
|
191772
192188
|
if (heredocPrefix)
|
|
@@ -257527,7 +257943,7 @@ function stripUnderlineAnsi(content) {
|
|
|
257527
257943
|
}
|
|
257528
257944
|
var import_compiler_runtime24, React16, import_jsx_runtime27, MAX_JSON_FORMAT_LENGTH, URL_IN_JSON, init_OutputLine = __esm({
|
|
257529
257945
|
"build-src/src/components/shell/OutputLine.tsx"() {
|
|
257530
|
-
import_compiler_runtime24 = __toESM(require_compiler_runtime()), React16 = __toESM(require_react());
|
|
257946
|
+
import_compiler_runtime24 = __toESM(require_compiler_runtime(), 1), React16 = __toESM(require_react(), 1);
|
|
257531
257947
|
init_useTerminalSize();
|
|
257532
257948
|
init_ink2();
|
|
257533
257949
|
init_hyperlink();
|
|
@@ -257536,7 +257952,7 @@ var import_compiler_runtime24, React16, import_jsx_runtime27, MAX_JSON_FORMAT_LE
|
|
|
257536
257952
|
init_MessageResponse();
|
|
257537
257953
|
init_messageActions();
|
|
257538
257954
|
init_ExpandShellOutputContext();
|
|
257539
|
-
import_jsx_runtime27 = __toESM(require_jsx_runtime());
|
|
257955
|
+
import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
|
|
257540
257956
|
MAX_JSON_FORMAT_LENGTH = 1e4;
|
|
257541
257957
|
URL_IN_JSON = /https?:\/\/[^\s"'<>\\]+/g;
|
|
257542
257958
|
}
|
|
@@ -285711,7 +286127,7 @@ function FileEditToolUseRejectedMessage(t0) {
|
|
|
285711
286127
|
}
|
|
285712
286128
|
var import_compiler_runtime43, import_jsx_runtime52, MAX_LINES_TO_RENDER, init_FileEditToolUseRejectedMessage = __esm({
|
|
285713
286129
|
"build-src/src/components/FileEditToolUseRejectedMessage.tsx"() {
|
|
285714
|
-
import_compiler_runtime43 = __toESM(require_compiler_runtime()
|
|
286130
|
+
import_compiler_runtime43 = __toESM(require_compiler_runtime());
|
|
285715
286131
|
init_useTerminalSize();
|
|
285716
286132
|
init_cwd();
|
|
285717
286133
|
init_ink2();
|
|
@@ -285719,7 +286135,7 @@ var import_compiler_runtime43, import_jsx_runtime52, MAX_LINES_TO_RENDER, init_F
|
|
|
285719
286135
|
init_MessageResponse();
|
|
285720
286136
|
init_StructuredDiffList();
|
|
285721
286137
|
init_stringUtils();
|
|
285722
|
-
import_jsx_runtime52 = __toESM(require_jsx_runtime()
|
|
286138
|
+
import_jsx_runtime52 = __toESM(require_jsx_runtime()), MAX_LINES_TO_RENDER = 10;
|
|
285723
286139
|
}
|
|
285724
286140
|
});
|
|
285725
286141
|
|
|
@@ -307339,7 +307755,8 @@ async function buildHelper() {
|
|
|
307339
307755
|
await execFileP("/usr/libexec/PlistBuddy", ["-c", "Add :LSUIElement bool true", plist]), await execFileP("/usr/libexec/PlistBuddy", ["-c", "Set :CFBundleName Sema", plist]), (await execFileP("/usr/libexec/PlistBuddy", ["-c", "Add :CFBundleIdentifier string com.sema.notifier", plist])).code !== 0 && await execFileP("/usr/libexec/PlistBuddy", ["-c", "Set :CFBundleIdentifier com.sema.notifier", plist]), await execFileP("/usr/bin/touch", [app]);
|
|
307340
307756
|
try {
|
|
307341
307757
|
chmodSync4(appletBinaryPath(), 493);
|
|
307342
|
-
} catch {
|
|
307758
|
+
} catch (e) {
|
|
307759
|
+
failOpen("mac-notifier-chmod", void 0, String(e));
|
|
307343
307760
|
}
|
|
307344
307761
|
return rmSync6(tmp, { recursive: !0, force: !0 }), logForDebugging(`[mac-notifier] helper built at ${app}`), macNotifierReady();
|
|
307345
307762
|
} catch (e) {
|
|
@@ -307359,6 +307776,7 @@ var HELPER_DIR_NAME, APPLET_SOURCE, buildInFlight, SEMA_ICON_512_B64, init_macNo
|
|
|
307359
307776
|
"build-src/src/sema/macNotifier.ts"() {
|
|
307360
307777
|
init_envUtils();
|
|
307361
307778
|
init_debug();
|
|
307779
|
+
init_failOpen();
|
|
307362
307780
|
HELPER_DIR_NAME = "Sema Notifier.app", APPLET_SOURCE = `on run argv
|
|
307363
307781
|
set theTitle to "Sema"
|
|
307364
307782
|
set theMessage to ""
|
|
@@ -308502,7 +308920,7 @@ function TaskListV2({
|
|
|
308502
308920
|
visibleTasks2.map((task_0) => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(TaskItem, { task: task_0, ownerColor: task_0.owner ? teammateColors[task_0.owner] : void 0, openBlockers: task_0.blockedBy.filter((id_3) => unresolvedTaskIds.has(id_3)), activity: task_0.owner ? teammateActivity[task_0.owner] : void 0, ownerActive: task_0.owner ? activeTeammates.has(task_0.owner) : !1, columns }, task_0.id)),
|
|
308503
308921
|
maxDisplay > 0 && hiddenSummary && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(ThemedText, { dimColor: !0, children: hiddenSummary })
|
|
308504
308922
|
] });
|
|
308505
|
-
return isStandalone ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(ThemedBox_default, { flexDirection: "column", marginTop: 1, marginLeft: 2, children: [
|
|
308923
|
+
return isStandalone ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(ThemedBox_default, { flexDirection: "column", marginTop: 1, marginLeft: 2, flexShrink: 0, children: [
|
|
308506
308924
|
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(ThemedBox_default, { children: /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(ThemedText, { dimColor: !0, children: [
|
|
308507
308925
|
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(ThemedText, { bold: !0, children: tasks3.length }),
|
|
308508
308926
|
" tasks (",
|
|
@@ -308516,7 +308934,7 @@ function TaskListV2({
|
|
|
308516
308934
|
" open)"
|
|
308517
308935
|
] }) }),
|
|
308518
308936
|
content
|
|
308519
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(ThemedBox_default, { flexDirection: "column", children: content });
|
|
308937
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(ThemedBox_default, { flexDirection: "column", flexShrink: 0, children: content });
|
|
308520
308938
|
}
|
|
308521
308939
|
function getTaskIcon(status3) {
|
|
308522
308940
|
switch (status3) {
|
|
@@ -316554,7 +316972,7 @@ function useClaudeAiLimits() {
|
|
|
316554
316972
|
}
|
|
316555
316973
|
var import_react69, init_claudeAiLimitsHook = __esm({
|
|
316556
316974
|
"build-src/src/services/claudeAiLimitsHook.ts"() {
|
|
316557
|
-
import_react69 = __toESM(require_react());
|
|
316975
|
+
import_react69 = __toESM(require_react(), 1);
|
|
316558
316976
|
init_claudeAiLimits();
|
|
316559
316977
|
}
|
|
316560
316978
|
});
|
|
@@ -395840,6 +396258,7 @@ var import_compiler_runtime174, import_react144, import_jsx_runtime245, init_Plu
|
|
|
395840
396258
|
init_PluginErrors();
|
|
395841
396259
|
init_parseArgs();
|
|
395842
396260
|
init_ValidatePlugin();
|
|
396261
|
+
init_failOpen();
|
|
395843
396262
|
import_jsx_runtime245 = __toESM(require_jsx_runtime(), 1);
|
|
395844
396263
|
}
|
|
395845
396264
|
});
|
|
@@ -399696,21 +400115,20 @@ var sema_brand_default, init_sema_brand = __esm({
|
|
|
399696
400115
|
_doc: "displayName/email \u7559 null = \u8FD0\u884C\u65F6\u56DE\u9000(\u540D\u5B57\u53D6\u672C\u673A OS \u7528\u6237\u540D,\u90AE\u7BB1\u4E0D\u663E\u793A)\u3002\u522B\u70E7\u4E2A\u4EBA\u4FE1\u606F\u8FDB\u54C1\u724C\u6587\u4EF6(F-S1-1:\u65B0\u7528\u6237\u66FE\u770B\u5230 Welcome back Clay!)\u3002"
|
|
399697
400116
|
},
|
|
399698
400117
|
whatsNew: {
|
|
399699
|
-
version: "1.0.
|
|
400118
|
+
version: "1.0.76",
|
|
399700
400119
|
notes: [
|
|
399701
|
-
|
|
399702
|
-
"
|
|
399703
|
-
"
|
|
399704
|
-
`
|
|
399705
|
-
"
|
|
399706
|
-
|
|
399707
|
-
"
|
|
399708
|
-
"
|
|
399709
|
-
"`sema cloud images list/show --json` now exits non-zero when the deployment honestly has no image backend configured, instead of always exiting 0 on that path"
|
|
400120
|
+
"The agents panel no longer opens mid-turn: while a turn is in flight, the left-arrow key stays with the composer, and the footer hint plus the background-agent placeholder only advertise \u2190 when the prompt is idle and empty \u2014 the panel can no longer yank the screen away from a streaming turn",
|
|
400121
|
+
"ctrl+b (send the current work to the background) no longer takes the turn's already-backgrounded subagents down with it",
|
|
400122
|
+
"Resuming a session with a parked approval no longer risks a false deadlock: the ownership recheck that guards card re-presentation now recognizes runs by their persisted task id as well as the in-process ledger, so a first-turn park \u2192 kill \u2192 resume re-presents exactly one live card",
|
|
400123
|
+
`Approval-card rule suggestions got stricter and more honest: interpreter-style commands (python, node, npx, eval, exec, ssh and friends) are never offered as persistent allow rules in any spelling, and "won't ask again" is only claimed when the rule took effect live \u2014 otherwise the card says it fully applies after restart`,
|
|
400124
|
+
"Background subagents stream their transcript into the viewing pane while they run (per-agent detail stream), and the idle placeholder points at the agents panel instead of a stale hint",
|
|
400125
|
+
"Task list rendering no longer collapses rows in fullscreen (alt-screen) terminals",
|
|
400126
|
+
"Durable run controls from a reconnected session no longer fail due to a lost client binding on the run verbs",
|
|
400127
|
+
"Engine unchanged at 7.19.0 (same pin as 1.0.75); this release is a shell-side interaction-safety and correctness batch"
|
|
399710
400128
|
]
|
|
399711
400129
|
},
|
|
399712
|
-
productVersion: "1.0.
|
|
399713
|
-
announcement:
|
|
400130
|
+
productVersion: "1.0.76",
|
|
400131
|
+
announcement: `sema 1.0.76 \u2014 Interaction-safety batch: the agents panel no longer opens mid-turn (\u2190 stays with the composer while a turn is in flight, and every hint that advertises it follows the same predicate), ctrl+b no longer takes backgrounded subagents down with it, and resume ownership rechecks recognize persisted task ids so parked approvals re-present exactly once instead of dead-locking. Approval-card rule suggestions refuse interpreter-family commands in every spelling and only claim "won't ask again" when the rule applied live. Background subagents stream their transcripts into the viewer, and fullscreen task lists render without row collapse. Engine unchanged at 7.19.0.`
|
|
399714
400132
|
};
|
|
399715
400133
|
}
|
|
399716
400134
|
});
|
|
@@ -403312,7 +403730,8 @@ function _temp230(url3) {
|
|
|
403312
403730
|
if (url3.startsWith("file:"))
|
|
403313
403731
|
try {
|
|
403314
403732
|
openPath(fileURLToPath7(url3));
|
|
403315
|
-
} catch {
|
|
403733
|
+
} catch (e) {
|
|
403734
|
+
failOpen("fullscreen-open-file-url", void 0, String(e));
|
|
403316
403735
|
}
|
|
403317
403736
|
else
|
|
403318
403737
|
openBrowser(url3);
|
|
@@ -403387,6 +403806,7 @@ var import_compiler_runtime191, import_react160, import_jsx_runtime270, MODAL_TR
|
|
|
403387
403806
|
init_stringUtils();
|
|
403388
403807
|
init_nullRenderingAttachments();
|
|
403389
403808
|
init_PromptInputFooterSuggestions();
|
|
403809
|
+
init_failOpen();
|
|
403390
403810
|
import_jsx_runtime270 = __toESM(require_jsx_runtime(), 1), MODAL_TRANSCRIPT_PEEK = 2, ScrollChromeContext = (0, import_react160.createContext)({
|
|
403391
403811
|
setStickyPrompt: () => {
|
|
403392
403812
|
}
|
|
@@ -403911,21 +404331,20 @@ var require_sema_brand = __commonJS({
|
|
|
403911
404331
|
_doc: "displayName/email \u7559 null = \u8FD0\u884C\u65F6\u56DE\u9000(\u540D\u5B57\u53D6\u672C\u673A OS \u7528\u6237\u540D,\u90AE\u7BB1\u4E0D\u663E\u793A)\u3002\u522B\u70E7\u4E2A\u4EBA\u4FE1\u606F\u8FDB\u54C1\u724C\u6587\u4EF6(F-S1-1:\u65B0\u7528\u6237\u66FE\u770B\u5230 Welcome back Clay!)\u3002"
|
|
403912
404332
|
},
|
|
403913
404333
|
whatsNew: {
|
|
403914
|
-
version: "1.0.
|
|
404334
|
+
version: "1.0.76",
|
|
403915
404335
|
notes: [
|
|
403916
|
-
|
|
403917
|
-
"
|
|
403918
|
-
"
|
|
403919
|
-
`
|
|
403920
|
-
"
|
|
403921
|
-
|
|
403922
|
-
"
|
|
403923
|
-
"
|
|
403924
|
-
"`sema cloud images list/show --json` now exits non-zero when the deployment honestly has no image backend configured, instead of always exiting 0 on that path"
|
|
404336
|
+
"The agents panel no longer opens mid-turn: while a turn is in flight, the left-arrow key stays with the composer, and the footer hint plus the background-agent placeholder only advertise \u2190 when the prompt is idle and empty \u2014 the panel can no longer yank the screen away from a streaming turn",
|
|
404337
|
+
"ctrl+b (send the current work to the background) no longer takes the turn's already-backgrounded subagents down with it",
|
|
404338
|
+
"Resuming a session with a parked approval no longer risks a false deadlock: the ownership recheck that guards card re-presentation now recognizes runs by their persisted task id as well as the in-process ledger, so a first-turn park \u2192 kill \u2192 resume re-presents exactly one live card",
|
|
404339
|
+
`Approval-card rule suggestions got stricter and more honest: interpreter-style commands (python, node, npx, eval, exec, ssh and friends) are never offered as persistent allow rules in any spelling, and "won't ask again" is only claimed when the rule took effect live \u2014 otherwise the card says it fully applies after restart`,
|
|
404340
|
+
"Background subagents stream their transcript into the viewing pane while they run (per-agent detail stream), and the idle placeholder points at the agents panel instead of a stale hint",
|
|
404341
|
+
"Task list rendering no longer collapses rows in fullscreen (alt-screen) terminals",
|
|
404342
|
+
"Durable run controls from a reconnected session no longer fail due to a lost client binding on the run verbs",
|
|
404343
|
+
"Engine unchanged at 7.19.0 (same pin as 1.0.75); this release is a shell-side interaction-safety and correctness batch"
|
|
403925
404344
|
]
|
|
403926
404345
|
},
|
|
403927
|
-
productVersion: "1.0.
|
|
403928
|
-
announcement:
|
|
404346
|
+
productVersion: "1.0.76",
|
|
404347
|
+
announcement: `sema 1.0.76 \u2014 Interaction-safety batch: the agents panel no longer opens mid-turn (\u2190 stays with the composer while a turn is in flight, and every hint that advertises it follows the same predicate), ctrl+b no longer takes backgrounded subagents down with it, and resume ownership rechecks recognize persisted task ids so parked approvals re-present exactly once instead of dead-locking. Approval-card rule suggestions refuse interpreter-family commands in every spelling and only claim "won't ask again" when the rule applied live. Background subagents stream their transcripts into the viewer, and fullscreen task lists render without row collapse. Engine unchanged at 7.19.0.`
|
|
403929
404348
|
};
|
|
403930
404349
|
}
|
|
403931
404350
|
});
|
|
@@ -407694,7 +408113,7 @@ function livePlaceholderUuid(taskId) {
|
|
|
407694
408113
|
}
|
|
407695
408114
|
function createLivePlaceholderMessage(taskId) {
|
|
407696
408115
|
return { ...createAssistantMessage({
|
|
407697
|
-
content: "*waiting for agent output \u2014 streamed transcript appears here when available; a background agent shows tool/token progress in the agents tree and lands its outcome here on completion
|
|
408116
|
+
content: "*waiting for agent output \u2014 streamed transcript appears here when available; a background agent shows tool/token progress in the agents tree and lands its outcome here on completion. When idle with the prompt empty, press \u2190 for agents to follow its live tool/token detail meanwhile.*",
|
|
407698
408117
|
isVirtual: !0
|
|
407699
408118
|
}), uuid: livePlaceholderUuid(taskId) };
|
|
407700
408119
|
}
|
|
@@ -412398,6 +412817,23 @@ function surfaceRulePersistOutcome(ack) {
|
|
|
412398
412817
|
logForDebugging(`persistedRulesWire: surfacing rule-persist outcome failed (non-fatal): ${String(e)}`);
|
|
412399
412818
|
}
|
|
412400
412819
|
}
|
|
412820
|
+
function surfaceLocalRulePersistOutcome(outcome) {
|
|
412821
|
+
let text2 = outcome.ok ? outcome.appliedLive ? "Saved: won't ask again for this rule" : "Saved to settings \u2014 fully applies after restart (this session may ask once more)" : `"Don't ask again" was not saved (${outcome.error}) \u2014 the one-time approval is still being submitted`;
|
|
412822
|
+
try {
|
|
412823
|
+
surfaceWireNotice(
|
|
412824
|
+
{
|
|
412825
|
+
key: RULE_PERSIST_NOTICE_KEY,
|
|
412826
|
+
text: text2,
|
|
412827
|
+
color: "warning",
|
|
412828
|
+
priority: "immediate",
|
|
412829
|
+
timeoutMs: rulePersistNoticeMs
|
|
412830
|
+
},
|
|
412831
|
+
"preempt"
|
|
412832
|
+
);
|
|
412833
|
+
} catch (e) {
|
|
412834
|
+
logForDebugging(`persistedRulesWire: surfacing local rule-persist outcome failed (non-fatal): ${String(e)}`);
|
|
412835
|
+
}
|
|
412836
|
+
}
|
|
412401
412837
|
var facadeOverride, PAGE_LIMIT, MAX_PAGES, CC_DIR4, LAYER_BYTE_CAP, RULE_PERSIST_NOTICE_KEY, RULE_PERSIST_NOTICE_DEFAULT_MS, rulePersistNoticeMs, init_persistedRulesWire = __esm({
|
|
412402
412838
|
"build-src/src/sema/persistedRulesWire.ts"() {
|
|
412403
412839
|
init_main2();
|
|
@@ -416537,7 +416973,8 @@ function ErrorsTabContent({
|
|
|
416537
416973
|
try {
|
|
416538
416974
|
let config4 = await loadKnownMarketplacesConfig(), { failures } = await loadMarketplacesWithGracefulDegradation(config4);
|
|
416539
416975
|
setMarketplaceLoadFailures(failures);
|
|
416540
|
-
} catch {
|
|
416976
|
+
} catch (e) {
|
|
416977
|
+
failOpen("cmd-plugin-marketplace-load", void 0, String(e));
|
|
416541
416978
|
}
|
|
416542
416979
|
})();
|
|
416543
416980
|
}, []);
|
|
@@ -416985,6 +417422,7 @@ var import_react185, import_jsx_runtime326, TAG_USAGE, TRANSIENT_ERROR_TYPES, in
|
|
|
416985
417422
|
init_PluginErrors();
|
|
416986
417423
|
init_parseArgs();
|
|
416987
417424
|
init_ValidatePlugin();
|
|
417425
|
+
init_failOpen();
|
|
416988
417426
|
import_jsx_runtime326 = __toESM(require_jsx_runtime(), 1);
|
|
416989
417427
|
TAG_USAGE = `Usage: /plugin tag [path] [--push] [--dry-run] [-f|--force]
|
|
416990
417428
|
|
|
@@ -466951,7 +467389,13 @@ function createFleetViewControl() {
|
|
|
466951
467389
|
return process.env.SEMA_NO_LEFTARROW_AGENTS !== "1";
|
|
466952
467390
|
},
|
|
466953
467391
|
canOpenFromComposer() {
|
|
466954
|
-
return this.leftArrowOpensAgents() && !_isOpen;
|
|
467392
|
+
return this.leftArrowOpensAgents() && !_isOpen && !_turnInFlight;
|
|
467393
|
+
},
|
|
467394
|
+
setTurnInFlight(inFlight4) {
|
|
467395
|
+
_turnInFlight = !!inFlight4;
|
|
467396
|
+
},
|
|
467397
|
+
turnInFlight() {
|
|
467398
|
+
return _turnInFlight;
|
|
466955
467399
|
},
|
|
466956
467400
|
isComposerEmpty() {
|
|
466957
467401
|
return _composerEmpty;
|
|
@@ -466975,9 +467419,9 @@ function createFleetViewControl() {
|
|
|
466975
467419
|
}
|
|
466976
467420
|
};
|
|
466977
467421
|
}
|
|
466978
|
-
var _composerEmpty, g3, fleetViewControl, fleetViewControl_default, init_fleetViewControl = __esm({
|
|
467422
|
+
var _composerEmpty, _turnInFlight, g3, fleetViewControl, fleetViewControl_default, init_fleetViewControl = __esm({
|
|
466979
467423
|
"build-src/src/sema/fleetViewControl.ts"() {
|
|
466980
|
-
_composerEmpty = !0;
|
|
467424
|
+
_composerEmpty = !0, _turnInFlight = !1;
|
|
466981
467425
|
g3 = globalThis, fleetViewControl = g3.__semaFleetView ?? (g3.__semaFleetView = createFleetViewControl()), fleetViewControl_default = fleetViewControl;
|
|
466982
467426
|
}
|
|
466983
467427
|
});
|
|
@@ -469434,9 +469878,136 @@ var NUMERIC, ENV_VAR, WRAPPER_COMMANDS, toArray4, init_prefix2 = __esm({
|
|
|
469434
469878
|
}
|
|
469435
469879
|
});
|
|
469436
469880
|
|
|
469881
|
+
// build-src/src/sema/localAllowRuleWrite.ts
|
|
469882
|
+
function parseLocalAllowRule(rule, expectedToolName) {
|
|
469883
|
+
if (typeof rule != "string" || rule === "")
|
|
469884
|
+
return { ok: !1, error: "rule text is empty" };
|
|
469885
|
+
let value;
|
|
469886
|
+
try {
|
|
469887
|
+
value = permissionRuleValueFromString(rule);
|
|
469888
|
+
} catch (e) {
|
|
469889
|
+
return { ok: !1, error: `rule text did not parse (${String(e)})` };
|
|
469890
|
+
}
|
|
469891
|
+
if (typeof value.toolName != "string" || value.toolName === "")
|
|
469892
|
+
return { ok: !1, error: "rule text carries no tool name" };
|
|
469893
|
+
if (value.ruleContent === void 0 || value.ruleContent === "")
|
|
469894
|
+
return {
|
|
469895
|
+
ok: !1,
|
|
469896
|
+
error: "candidate is a whole-tool allow rule (broader than this ask) \u2014 not offered locally"
|
|
469897
|
+
};
|
|
469898
|
+
if (expectedToolName !== void 0 && value.toolName !== expectedToolName)
|
|
469899
|
+
return {
|
|
469900
|
+
ok: !1,
|
|
469901
|
+
error: `candidate names tool "${value.toolName}" but this ask is for "${expectedToolName}" \u2014 a rule for another tool would never match`
|
|
469902
|
+
};
|
|
469903
|
+
if (!hasLiteralAnchor(value.ruleContent))
|
|
469904
|
+
return {
|
|
469905
|
+
ok: !1,
|
|
469906
|
+
error: "candidate is all wildcard (matches every command for this tool) \u2014 equivalent to a whole-tool allow, not offered locally"
|
|
469907
|
+
};
|
|
469908
|
+
if (value.toolName === BASH_TOOL_NAME_FOR_RULES && bashPermissionsModule().bashRuleContentHasDangerousBarePrefix(value.ruleContent))
|
|
469909
|
+
return {
|
|
469910
|
+
ok: !1,
|
|
469911
|
+
error: "candidate is a bare interpreter/wrapper prefix (bash/sh/env/sudo/\u2026) \u2014 persisting it would authorize arbitrary commands, not offered locally"
|
|
469912
|
+
};
|
|
469913
|
+
{
|
|
469914
|
+
let setup2 = permissionSetupModule2();
|
|
469915
|
+
if (setup2.isDangerousBashPermission(value.toolName, value.ruleContent) || setup2.isDangerousPowerShellPermission(value.toolName, value.ruleContent))
|
|
469916
|
+
return {
|
|
469917
|
+
ok: !1,
|
|
469918
|
+
error: "candidate allow-rule matches a code-execution interpreter/wrapper pattern (python/node/eval/ssh/\u2026) \u2014 persisting it would authorize arbitrary code, not offered locally"
|
|
469919
|
+
};
|
|
469920
|
+
}
|
|
469921
|
+
return { ok: !0, value, canonical: permissionRuleValueToString(value) };
|
|
469922
|
+
}
|
|
469923
|
+
function localAllowRulesPermittedByPolicy() {
|
|
469924
|
+
try {
|
|
469925
|
+
return permissionsLoaderModule().shouldShowAlwaysAllowOptions();
|
|
469926
|
+
} catch {
|
|
469927
|
+
return !1;
|
|
469928
|
+
}
|
|
469929
|
+
}
|
|
469930
|
+
function hasLiteralAnchor(ruleContent) {
|
|
469931
|
+
let out6 = "";
|
|
469932
|
+
for (let i = 0; i < ruleContent.length; i++) {
|
|
469933
|
+
let ch2 = ruleContent[i];
|
|
469934
|
+
if (ch2 === "\\" && i + 1 < ruleContent.length) {
|
|
469935
|
+
out6 += ruleContent[i + 1], i++;
|
|
469936
|
+
continue;
|
|
469937
|
+
}
|
|
469938
|
+
ch2 !== "*" && (out6 += ch2);
|
|
469939
|
+
}
|
|
469940
|
+
return out6.trim() !== "";
|
|
469941
|
+
}
|
|
469942
|
+
function permissionUpdateModule() {
|
|
469943
|
+
return init_PermissionUpdate(), __toCommonJS(PermissionUpdate_exports);
|
|
469944
|
+
}
|
|
469945
|
+
function permissionsLoaderModule() {
|
|
469946
|
+
return init_permissionsLoader(), __toCommonJS(permissionsLoader_exports);
|
|
469947
|
+
}
|
|
469948
|
+
function bashPermissionsModule() {
|
|
469949
|
+
return init_bashPermissions(), __toCommonJS(bashPermissions_exports);
|
|
469950
|
+
}
|
|
469951
|
+
function permissionSetupModule2() {
|
|
469952
|
+
return init_permissionSetup(), __toCommonJS(permissionSetup_exports);
|
|
469953
|
+
}
|
|
469954
|
+
function leaderBridgeModule() {
|
|
469955
|
+
return init_leaderPermissionBridge(), __toCommonJS(leaderPermissionBridge_exports);
|
|
469956
|
+
}
|
|
469957
|
+
function persistLocalAllowRule(rule) {
|
|
469958
|
+
let parsed = parseLocalAllowRule(rule);
|
|
469959
|
+
if (!parsed.ok)
|
|
469960
|
+
return logForDebugging(`localAllowRuleWrite: refusing to persist a rule candidate \u2014 ${parsed.error}`), { ok: !1, error: parsed.error };
|
|
469961
|
+
let update2 = {
|
|
469962
|
+
type: "addRules",
|
|
469963
|
+
rules: [parsed.value],
|
|
469964
|
+
behavior: "allow",
|
|
469965
|
+
destination: "localSettings"
|
|
469966
|
+
};
|
|
469967
|
+
if (!localAllowRulesPermittedByPolicy()) {
|
|
469968
|
+
let error51 = `managed policy allows only managed permission rules \u2014 this deployment cannot save a local "don't ask again" rule`;
|
|
469969
|
+
return logForDebugging(`localAllowRuleWrite: ${error51}`), { ok: !1, error: error51 };
|
|
469970
|
+
}
|
|
469971
|
+
let mod = permissionUpdateModule(), written = !1;
|
|
469972
|
+
try {
|
|
469973
|
+
written = permissionsLoaderModule().addPermissionRulesToSettings(
|
|
469974
|
+
{ ruleValues: [parsed.value], ruleBehavior: "allow" },
|
|
469975
|
+
"localSettings"
|
|
469976
|
+
);
|
|
469977
|
+
} catch (e) {
|
|
469978
|
+
let error51 = `writing the rule to local settings threw (${String(e)})`;
|
|
469979
|
+
return logForDebugging(`localAllowRuleWrite: ${error51}`), { ok: !1, error: error51 };
|
|
469980
|
+
}
|
|
469981
|
+
if (!written) {
|
|
469982
|
+
let error51 = "local settings refused the rule (managed-rules-only policy, or a settings parse/lock/write failure) \u2014 nothing was saved";
|
|
469983
|
+
return logForDebugging(`localAllowRuleWrite: ${error51}`), { ok: !1, error: error51 };
|
|
469984
|
+
}
|
|
469985
|
+
try {
|
|
469986
|
+
let setCtx = leaderBridgeModule().getLeaderSetToolPermissionContext(), state4 = getAppStateStoreRef()?.getState?.();
|
|
469987
|
+
if (setCtx && state4?.toolPermissionContext)
|
|
469988
|
+
return setCtx(mod.applyPermissionUpdate(state4.toolPermissionContext, update2)), { ok: !0, appliedLive: !0 };
|
|
469989
|
+
logForDebugging(
|
|
469990
|
+
"localAllowRuleWrite: rule persisted to local settings, but this lane has no in-memory permission context to update (it will take effect on next start)"
|
|
469991
|
+
);
|
|
469992
|
+
} catch (e) {
|
|
469993
|
+
logForDebugging(
|
|
469994
|
+
`localAllowRuleWrite: rule persisted, but applying it to the in-memory permission context failed (non-fatal): ${String(e)}`
|
|
469995
|
+
);
|
|
469996
|
+
}
|
|
469997
|
+
return { ok: !0, appliedLive: !1 };
|
|
469998
|
+
}
|
|
469999
|
+
var BASH_TOOL_NAME_FOR_RULES, init_localAllowRuleWrite = __esm({
|
|
470000
|
+
"build-src/src/sema/localAllowRuleWrite.ts"() {
|
|
470001
|
+
init_permissionRuleParser();
|
|
470002
|
+
init_debug();
|
|
470003
|
+
init_appStateRef();
|
|
470004
|
+
BASH_TOOL_NAME_FOR_RULES = "Bash";
|
|
470005
|
+
}
|
|
470006
|
+
});
|
|
470007
|
+
|
|
469437
470008
|
// build-src/src/components/permissions/engineRuleSuggestions.tsx
|
|
469438
|
-
function readSuggestions(confirm2) {
|
|
469439
|
-
let raw2 = confirm2
|
|
470009
|
+
function readSuggestions(confirm2, key = "ruleSuggestions") {
|
|
470010
|
+
let raw2 = confirm2[key];
|
|
469440
470011
|
if (!Array.isArray(raw2)) return [];
|
|
469441
470012
|
let out6 = [];
|
|
469442
470013
|
for (let item of raw2) {
|
|
@@ -469472,6 +470043,41 @@ function tryEngineRulePersistSelection(confirm2, value, onDone) {
|
|
|
469472
470043
|
let onSelected = confirm2.onPersistRuleSelected;
|
|
469473
470044
|
return onSelected?.(rule), onDone?.(), confirm2.onAllow(confirm2.input, []), !0;
|
|
469474
470045
|
}
|
|
470046
|
+
function readLocalRedeemable(confirm2) {
|
|
470047
|
+
let expected = typeof confirm2.tool?.name == "string" ? confirm2.tool.name : void 0, out6 = [];
|
|
470048
|
+
for (let s of readSuggestions(confirm2, "ruleSuggestionsReadOnly")) {
|
|
470049
|
+
let parsed = parseLocalAllowRule(s.rule, expected);
|
|
470050
|
+
parsed.ok && out6.push({ rule: s.rule, canonical: parsed.canonical });
|
|
470051
|
+
}
|
|
470052
|
+
return out6;
|
|
470053
|
+
}
|
|
470054
|
+
function localRuleSuggestionOptions(confirm2) {
|
|
470055
|
+
if (!localAllowRulesPermittedByPolicy()) return [];
|
|
470056
|
+
let suggestions = readLocalRedeemable(confirm2);
|
|
470057
|
+
if (suggestions.length === 0) return [];
|
|
470058
|
+
let scope = getOriginalCwd();
|
|
470059
|
+
return suggestions.map((s, i) => ({
|
|
470060
|
+
label: /* @__PURE__ */ (0, import_jsx_runtime378.jsxs)(ThemedText, { children: [
|
|
470061
|
+
"Yes, and don't ask again for ",
|
|
470062
|
+
/* @__PURE__ */ (0, import_jsx_runtime378.jsx)(ThemedText, { bold: !0, children: s.canonical }),
|
|
470063
|
+
" in ",
|
|
470064
|
+
/* @__PURE__ */ (0, import_jsx_runtime378.jsx)(ThemedText, { bold: !0, children: scope })
|
|
470065
|
+
] }),
|
|
470066
|
+
value: `${LOCAL_RULE_OPTION_VALUE_PREFIX}${i}`
|
|
470067
|
+
}));
|
|
470068
|
+
}
|
|
470069
|
+
function localRuleForOptionValue(confirm2, value) {
|
|
470070
|
+
if (!value.startsWith(LOCAL_RULE_OPTION_VALUE_PREFIX)) return;
|
|
470071
|
+
let idx = Number(value.slice(LOCAL_RULE_OPTION_VALUE_PREFIX.length));
|
|
470072
|
+
if (!(!Number.isInteger(idx) || idx < 0))
|
|
470073
|
+
return readLocalRedeemable(confirm2)[idx]?.rule;
|
|
470074
|
+
}
|
|
470075
|
+
function tryLocalRulePersistSelection(confirm2, value, onDone) {
|
|
470076
|
+
let rule = localRuleForOptionValue(confirm2, value);
|
|
470077
|
+
if (rule === void 0) return !1;
|
|
470078
|
+
let onSelected = confirm2.onPersistLocalRuleSelected;
|
|
470079
|
+
return onSelected?.(rule), onDone?.(), confirm2.onAllow(confirm2.input, []), !0;
|
|
470080
|
+
}
|
|
469475
470081
|
function PersistedRuleShadowedRow({ confirm: confirm2 }) {
|
|
469476
470082
|
let shadowed = confirm2.persistedRuleShadowed;
|
|
469477
470083
|
return typeof shadowed != "string" || shadowed === "" ? null : /* @__PURE__ */ (0, import_jsx_runtime378.jsxs)(ThemedText, { dimColor: !0, children: [
|
|
@@ -469480,11 +470086,13 @@ function PersistedRuleShadowedRow({ confirm: confirm2 }) {
|
|
|
469480
470086
|
") still exists \u2014 it just cannot clear this particular call, so this one is confirmed individually."
|
|
469481
470087
|
] });
|
|
469482
470088
|
}
|
|
469483
|
-
var import_jsx_runtime378, ENGINE_RULE_OPTION_VALUE_PREFIX, init_engineRuleSuggestions = __esm({
|
|
470089
|
+
var import_jsx_runtime378, ENGINE_RULE_OPTION_VALUE_PREFIX, LOCAL_RULE_OPTION_VALUE_PREFIX, init_engineRuleSuggestions = __esm({
|
|
469484
470090
|
"build-src/src/components/permissions/engineRuleSuggestions.tsx"() {
|
|
469485
470091
|
init_ink2();
|
|
469486
470092
|
init_state();
|
|
470093
|
+
init_localAllowRuleWrite();
|
|
469487
470094
|
import_jsx_runtime378 = __toESM(require_jsx_runtime(), 1), ENGINE_RULE_OPTION_VALUE_PREFIX = "sema-engine-rule:";
|
|
470095
|
+
LOCAL_RULE_OPTION_VALUE_PREFIX = "sema-local-rule:";
|
|
469488
470096
|
}
|
|
469489
470097
|
});
|
|
469490
470098
|
|
|
@@ -470938,14 +471546,17 @@ function FilePermissionDialog({
|
|
|
470938
471546
|
ideName
|
|
470939
471547
|
} = useDiffInIDE(diffParams), onChange = (option_0, feedback2) => {
|
|
470940
471548
|
closeTabInIDE2?.(), fileDialogResult.onChange(option_0, parsedInput, feedback2?.trim());
|
|
470941
|
-
}, shadowedRow = toolUseConfirm.persistedRuleShadowed !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime384.jsx)(PersistedRuleShadowedRow, { confirm: toolUseConfirm }) : null, ruleOptions = engineRuleSuggestionOptions(toolUseConfirm), optionsWithRules = ruleOptions.length > 0 ? [...options.slice(0, -1), ...ruleOptions.map((o) => ({
|
|
471549
|
+
}, shadowedRow = toolUseConfirm.persistedRuleShadowed !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime384.jsx)(PersistedRuleShadowedRow, { confirm: toolUseConfirm }) : null, ruleOptions = [...engineRuleSuggestionOptions(toolUseConfirm), ...localRuleSuggestionOptions(toolUseConfirm)], optionsWithRules = ruleOptions.length > 0 ? [...options.slice(0, -1), ...ruleOptions.map((o) => ({
|
|
470942
471550
|
...o,
|
|
470943
471551
|
option: {
|
|
470944
471552
|
type: "accept-once"
|
|
470945
471553
|
}
|
|
470946
|
-
})), ...options.slice(-1)] : options, handleEngineRuleValue = (value) =>
|
|
470947
|
-
|
|
470948
|
-
|
|
471554
|
+
})), ...options.slice(-1)] : options, handleEngineRuleValue = (value) => {
|
|
471555
|
+
let done = () => {
|
|
471556
|
+
closeTabInIDE2?.(), onDone();
|
|
471557
|
+
};
|
|
471558
|
+
return tryEngineRulePersistSelection(toolUseConfirm, value, done) || tryLocalRulePersistSelection(toolUseConfirm, value, done);
|
|
471559
|
+
};
|
|
470949
471560
|
if (showingDiffInIDE && ideDiffConfig && path28)
|
|
470950
471561
|
return /* @__PURE__ */ (0, import_jsx_runtime384.jsx)(ShowInIDEPrompt, { onChange: (option_1, _input, feedback_0) => onChange(option_1, feedback_0), onSelectValue: handleEngineRuleValue, extraNote: shadowedRow, options: optionsWithRules, filePath: path28, input: parsedInput, ideName, symlinkTarget, rejectFeedback, acceptFeedback, setFocusedOption, onInputModeToggle: handleInputModeToggle, focusedOption, yesInputMode, noInputMode });
|
|
470951
471562
|
let isSymlinkOutsideCwd = symlinkTarget != null && relative31(getCwd(), symlinkTarget).startsWith(".."), symlinkWarning = symlinkTarget ? /* @__PURE__ */ (0, import_jsx_runtime384.jsx)(ThemedBox_default, { paddingX: 1, marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime384.jsx)(ThemedText, { color: "warning", children: isSymlinkOutsideCwd ? `This will modify ${symlinkTarget} (outside working directory) via a symlink` : `Symlink target: ${symlinkTarget}` }) }) : null, wireNote = toolUseConfirm.wireNote, wireNoteRow = typeof wireNote == "string" && wireNote.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime384.jsx)(ThemedBox_default, { paddingX: 1, marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime384.jsx)(ThemedText, { dimColor: !0, children: wireNote }) }) : null;
|
|
@@ -471552,7 +472163,7 @@ function BashPermissionRequestInner({
|
|
|
471552
472163
|
editablePrefix,
|
|
471553
472164
|
onEditablePrefixChange
|
|
471554
472165
|
}), [toolUseConfirm, classifierDescription, initialClassifierDescriptionEmpty, existingAllowDescriptions, yesInputMode, noInputMode, editablePrefix, onEditablePrefixChange]), engineRuleOptionsAppended = (base) => {
|
|
471555
|
-
let extra = engineRuleSuggestionOptions(toolUseConfirm);
|
|
472166
|
+
let extra = [...engineRuleSuggestionOptions(toolUseConfirm), ...localRuleSuggestionOptions(toolUseConfirm)];
|
|
471556
472167
|
return extra.length === 0 ? base : [...base.slice(0, -1), ...extra, ...base.slice(-1)];
|
|
471557
472168
|
}, handleToggleDebug = (0, import_react223.useCallback)(() => {
|
|
471558
472169
|
setShowPermissionDebug((prev) => !prev);
|
|
@@ -471568,7 +472179,7 @@ function BashPermissionRequestInner({
|
|
|
471568
472179
|
isActive: !1
|
|
471569
472180
|
});
|
|
471570
472181
|
function onSelect(value_0) {
|
|
471571
|
-
if (tryEngineRulePersistSelection(toolUseConfirm, value_0, onDone))
|
|
472182
|
+
if (tryEngineRulePersistSelection(toolUseConfirm, value_0, onDone) || tryLocalRulePersistSelection(toolUseConfirm, value_0, onDone))
|
|
471572
472183
|
return;
|
|
471573
472184
|
({
|
|
471574
472185
|
yes: 1,
|
|
@@ -472339,7 +472950,7 @@ function FallbackPermissionRequest(t0) {
|
|
|
472339
472950
|
}, $3[4] = t2) : t2 = $3[4], usePermissionRequestLogging(toolUseConfirm, t2);
|
|
472340
472951
|
let t3;
|
|
472341
472952
|
$3[5] !== onDone || $3[6] !== onReject || $3[7] !== toolUseConfirm ? (t3 = (value, feedback2) => {
|
|
472342
|
-
if (!tryEngineRulePersistSelection(toolUseConfirm, value, onDone))
|
|
472953
|
+
if (!tryEngineRulePersistSelection(toolUseConfirm, value, onDone) && !tryLocalRulePersistSelection(toolUseConfirm, value, onDone))
|
|
472343
472954
|
bb8: switch (value) {
|
|
472344
472955
|
case "yes": {
|
|
472345
472956
|
logUnaryEvent({
|
|
@@ -472473,7 +473084,7 @@ function FallbackPermissionRequest(t0) {
|
|
|
472473
473084
|
] }), $3[44] = toolUseConfirm.permissionResult, $3[45] = t17) : t17 = $3[45];
|
|
472474
473085
|
let t18;
|
|
472475
473086
|
$3[46] !== handleCancel || $3[47] !== handleSelect || $3[48] !== options || $3[49] !== toolAnalyticsContext ? (t18 = /* @__PURE__ */ (0, import_jsx_runtime391.jsx)(PermissionPrompt, { options: (() => {
|
|
472476
|
-
let extra = engineRuleSuggestionOptions(toolUseConfirm);
|
|
473087
|
+
let extra = [...engineRuleSuggestionOptions(toolUseConfirm), ...localRuleSuggestionOptions(toolUseConfirm)];
|
|
472477
473088
|
return extra.length === 0 ? options : [...options.slice(0, -1), ...extra, ...options.slice(-1)];
|
|
472478
473089
|
})(), onSelect: handleSelect, onCancel: handleCancel, toolAnalyticsContext, defaultFocusValue: toolUseConfirm.governanceForced === !0 ? "no" : void 0 }), $3[46] = handleCancel, $3[47] = handleSelect, $3[48] = options, $3[49] = toolAnalyticsContext, $3[50] = t18) : t18 = $3[50];
|
|
472479
473090
|
let t19;
|
|
@@ -491185,7 +491796,7 @@ async function reconcileResumePendingApprovals(deps2) {
|
|
|
491185
491796
|
debug3("an owned pending row carries no taskId handle \u2014 both reopen arms address by taskId, nothing to reopen"), verdict.skipped.push({ taskId: null, reason: "no-task-handle" });
|
|
491186
491797
|
continue;
|
|
491187
491798
|
}
|
|
491188
|
-
let kind = gateKindOf(row2), arm = kind === null ? null : ASK_PARK_GATE_KINDS2.includes(kind) ? "ask" :
|
|
491799
|
+
let kind = gateKindOf(row2), arm = kind === null ? null : ASK_PARK_GATE_KINDS2.includes(kind) ? "ask" : PLAN_REVIEW_GATE_KINDS2.includes(kind) ? "plan" : null;
|
|
491189
491800
|
if (arm === null) {
|
|
491190
491801
|
debug3(
|
|
491191
491802
|
`owned pending row (task ${taskId}) is parked on gate kind '${kind ?? "<absent>"}' \u2014 not in either triage table, refusing to route it into a known reopen arm`
|
|
@@ -491518,6 +492129,28 @@ var import_compiler_runtime299, import_react298, init_useIDEIntegration = __esm(
|
|
|
491518
492129
|
}
|
|
491519
492130
|
});
|
|
491520
492131
|
|
|
492132
|
+
// build-src/src/sema/sessionBackgroundArm.ts
|
|
492133
|
+
function engineHostsTheTurn(env5 = process.env) {
|
|
492134
|
+
let live = env5.SEMA_LIVE_BASEURL;
|
|
492135
|
+
return typeof live == "string" && live.length > 0;
|
|
492136
|
+
}
|
|
492137
|
+
function remoteHostsTheTurn(readGlobal = getIsRemoteMode, readPosture = hasRemoteConnection) {
|
|
492138
|
+
try {
|
|
492139
|
+
return readGlobal() || readPosture();
|
|
492140
|
+
} catch {
|
|
492141
|
+
return !0;
|
|
492142
|
+
}
|
|
492143
|
+
}
|
|
492144
|
+
function sessionBackgroundingAvailable(env5 = process.env) {
|
|
492145
|
+
return !engineHostsTheTurn(env5) && !remoteHostsTheTurn();
|
|
492146
|
+
}
|
|
492147
|
+
var init_sessionBackgroundArm = __esm({
|
|
492148
|
+
"build-src/src/sema/sessionBackgroundArm.ts"() {
|
|
492149
|
+
init_state();
|
|
492150
|
+
init_remoteWriteSeam();
|
|
492151
|
+
}
|
|
492152
|
+
});
|
|
492153
|
+
|
|
491521
492154
|
// build-src/src/components/SessionBackgroundHint.tsx
|
|
491522
492155
|
function SessionBackgroundHint(t0) {
|
|
491523
492156
|
let $3 = (0, import_compiler_runtime300.c)(10), {
|
|
@@ -491528,11 +492161,11 @@ function SessionBackgroundHint(t0) {
|
|
|
491528
492161
|
if (isEnvTruthy(process.env.SEMA_CODE_DISABLE_BACKGROUND_TASKS))
|
|
491529
492162
|
return;
|
|
491530
492163
|
let state4 = appStateStore.getState();
|
|
491531
|
-
hasForegroundTasks(state4) ? (backgroundAll(() => appStateStore.getState(), setAppState), getGlobalConfig().hasUsedBackgroundTask || saveGlobalConfig(_temp257)) : isLoading && handleDoublePress();
|
|
492164
|
+
hasForegroundTasks(state4) ? (backgroundAll(() => appStateStore.getState(), setAppState), getGlobalConfig().hasUsedBackgroundTask || saveGlobalConfig(_temp257)) : isLoading && sessionBackgroundingAvailable() && handleDoublePress();
|
|
491532
492165
|
}, $3[0] = appStateStore, $3[1] = handleDoublePress, $3[2] = isLoading, $3[3] = setAppState, $3[4] = t1) : t1 = $3[4];
|
|
491533
492166
|
let handleBackground = t1, hasForeground = useAppState(hasForegroundTasks), t2;
|
|
491534
492167
|
$3[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = !0, $3[5] = t2) : t2 = $3[5];
|
|
491535
|
-
let t3 = hasForeground || t2 && isLoading, t4;
|
|
492168
|
+
let t3 = hasForeground || t2 && isLoading && sessionBackgroundingAvailable(), t4;
|
|
491536
492169
|
$3[6] !== t3 ? (t4 = {
|
|
491537
492170
|
context: "Task",
|
|
491538
492171
|
isActive: t3
|
|
@@ -491558,6 +492191,7 @@ var import_compiler_runtime300, import_react299, import_jsx_runtime452, init_Ses
|
|
|
491558
492191
|
init_ink2();
|
|
491559
492192
|
init_useKeybinding();
|
|
491560
492193
|
init_useShortcutDisplay();
|
|
492194
|
+
init_sessionBackgroundArm();
|
|
491561
492195
|
init_AppState();
|
|
491562
492196
|
init_LocalShellTask();
|
|
491563
492197
|
init_config();
|
|
@@ -494708,7 +495342,7 @@ function _temp158() {
|
|
|
494708
495342
|
}
|
|
494709
495343
|
var import_compiler_runtime308, import_react313, SETTINGS_ERRORS_NOTIFICATION_KEY, init_useSettingsErrors = __esm({
|
|
494710
495344
|
"build-src/src/hooks/notifs/useSettingsErrors.tsx"() {
|
|
494711
|
-
import_compiler_runtime308 = __toESM(require_compiler_runtime()), import_react313 = __toESM(require_react());
|
|
495345
|
+
import_compiler_runtime308 = __toESM(require_compiler_runtime(), 1), import_react313 = __toESM(require_react(), 1);
|
|
494712
495346
|
init_notifications2();
|
|
494713
495347
|
init_state();
|
|
494714
495348
|
init_allErrors();
|
|
@@ -497463,7 +498097,11 @@ function REPL({
|
|
|
497463
498097
|
abortControllerRef.current = abortController;
|
|
497464
498098
|
let sendBridgeResultRef = (0, import_react332.useRef)(() => {
|
|
497465
498099
|
}), restoreMessageSyncRef = (0, import_react332.useRef)(() => {
|
|
497466
|
-
}), scrollRef = (0, import_react332.useRef)(null), modalScrollRef = (0, import_react332.useRef)(null), lastUserScrollTsRef = (0, import_react332.useRef)(0), queryGuard = React175.useRef(new QueryGuard()).current, isQueryActive = React175.useSyncExternalStore(queryGuard.subscribe, queryGuard.getSnapshot), [isExternalLoading, setIsExternalLoadingRaw] = React175.useState(remoteSessionConfig?.hasInitialPrompt ?? !1), isLoading = isQueryActive || isExternalLoading
|
|
498100
|
+
}), scrollRef = (0, import_react332.useRef)(null), modalScrollRef = (0, import_react332.useRef)(null), lastUserScrollTsRef = (0, import_react332.useRef)(0), queryGuard = React175.useRef(new QueryGuard()).current, isQueryActive = React175.useSyncExternalStore(queryGuard.subscribe, queryGuard.getSnapshot), [isExternalLoading, setIsExternalLoadingRaw] = React175.useState(remoteSessionConfig?.hasInitialPrompt ?? !1), isLoading = isQueryActive || isExternalLoading;
|
|
498101
|
+
React175.useEffect(() => {
|
|
498102
|
+
fleetViewControl_default.setTurnInFlight(isLoading);
|
|
498103
|
+
}, [isLoading]);
|
|
498104
|
+
let [userInputOnProcessing, setUserInputOnProcessingRaw] = React175.useState(void 0), userInputBaselineRef = React175.useRef(0), userMessagePendingRef = React175.useRef(!1), loadingStartTimeRef = React175.useRef(0), totalPausedMsRef = React175.useRef(0), pauseStartTimeRef = React175.useRef(null);
|
|
497467
498105
|
publishSpinnerTimingAnchors({ loadingStartTimeRef, totalPausedMsRef, pauseStartTimeRef });
|
|
497468
498106
|
let resetTimingRefs = React175.useCallback(() => {
|
|
497469
498107
|
loadingStartTimeRef.current = Date.now(), totalPausedMsRef.current = 0, pauseStartTimeRef.current = null;
|
|
@@ -508915,7 +509553,7 @@ function permissionsModule() {
|
|
|
508915
509553
|
function filesystemModule() {
|
|
508916
509554
|
return init_filesystem(), __toCommonJS(filesystem_exports);
|
|
508917
509555
|
}
|
|
508918
|
-
function
|
|
509556
|
+
function bashPermissionsModule2() {
|
|
508919
509557
|
return init_bashPermissions(), __toCommonJS(bashPermissions_exports);
|
|
508920
509558
|
}
|
|
508921
509559
|
function bashCommandsModule() {
|
|
@@ -508962,15 +509600,15 @@ function denyVerdict(ctx, req) {
|
|
|
508962
509600
|
let command8 = args.command;
|
|
508963
509601
|
if (typeof command8 == "string" && command8.trim() !== "") {
|
|
508964
509602
|
let segments = bashCommandsModule().splitCommand_DEPRECATED(command8);
|
|
508965
|
-
if (segments.length >
|
|
509603
|
+
if (segments.length > bashPermissionsModule2().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK)
|
|
508966
509604
|
throw new Error(
|
|
508967
|
-
`compound command has ${segments.length} subcommands (cap ${
|
|
509605
|
+
`compound command has ${segments.length} subcommands (cap ${bashPermissionsModule2().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK}) \u2014 fail-closed to card`
|
|
508968
509606
|
);
|
|
508969
509607
|
let candidates = segments.length > 1 ? [command8, ...segments] : [command8], candidateEvalFailed = null;
|
|
508970
509608
|
for (let cand of candidates)
|
|
508971
509609
|
if (!(typeof cand != "string" || cand.trim() === ""))
|
|
508972
509610
|
try {
|
|
508973
|
-
let result =
|
|
509611
|
+
let result = bashPermissionsModule2().bashToolCheckPermission({ command: cand }, ctx);
|
|
508974
509612
|
if (result.behavior === "deny" && result.decisionReason?.type === "rule") {
|
|
508975
509613
|
let rule = result.decisionReason.rule;
|
|
508976
509614
|
return {
|
|
@@ -508988,9 +509626,9 @@ function denyVerdict(ctx, req) {
|
|
|
508988
509626
|
let command8 = args.command;
|
|
508989
509627
|
if (typeof command8 == "string" && command8.trim() !== "") {
|
|
508990
509628
|
let fragments = /[`'"]/.test(command8) ? [] : command8.split(/[;|\n\r{}()&]+/).filter((f) => f.trim() !== "");
|
|
508991
|
-
if (fragments.length >
|
|
509629
|
+
if (fragments.length > bashPermissionsModule2().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK)
|
|
508992
509630
|
throw new Error(
|
|
508993
|
-
`powershell command has ${fragments.length} fragments (cap ${
|
|
509631
|
+
`powershell command has ${fragments.length} fragments (cap ${bashPermissionsModule2().MAX_SUBCOMMANDS_FOR_SECURITY_CHECK}) \u2014 fail-closed to card`
|
|
508994
509632
|
);
|
|
508995
509633
|
let candidates = fragments.length > 1 ? [command8, ...fragments] : [command8], candidateEvalFailed = null;
|
|
508996
509634
|
for (let cand of candidates)
|
|
@@ -509033,7 +509671,7 @@ function bashVerdict(ctx, args) {
|
|
|
509033
509671
|
let command8 = args.command;
|
|
509034
509672
|
if (typeof command8 != "string" || command8.trim() === "")
|
|
509035
509673
|
return { allow: !1, reason: "bash gate carries no command string" };
|
|
509036
|
-
let result =
|
|
509674
|
+
let result = bashPermissionsModule2().bashToolCheckPermission(
|
|
509037
509675
|
{ command: command8 },
|
|
509038
509676
|
ctx
|
|
509039
509677
|
);
|
|
@@ -509273,9 +509911,24 @@ function shellApprovalCardPort(req) {
|
|
|
509273
509911
|
// 🔴 两元素**各渲各的**,壳不写互斥逻辑(互斥由 core 铸点保证)。
|
|
509274
509912
|
...req.ruleSuggestions !== void 0 && req.ruleSuggestions.length > 0 ? { ruleSuggestions: req.ruleSuggestions } : {},
|
|
509275
509913
|
...typeof req.persistedRuleShadowed == "string" && req.persistedRuleShadowed !== "" ? { persistedRuleShadowed: req.persistedRuleShadowed } : {},
|
|
509914
|
+
// ── #249③ / [3892]③ / [3895]:**durable park 腿**的只读候选(F-003 渲染半场)────────────
|
|
509915
|
+
// 修前这一位到卡口就被整段丢掉 ⇒ 那条腿上的 Bash 审批卡恒只有 `1. Yes / 2. No`,CC 的第三态
|
|
509916
|
+
// 在**供给已经在场**(server 7.16.0 起行上就有,client-core 0.29.0 已合形窄化落卡入参)的
|
|
509917
|
+
// 情况下依然渲不出来。
|
|
509918
|
+
// 🔴 与上面的 `ruleSuggestions` **分键不合流**:那一位兑付到 respond 的 `persistRule`,本位
|
|
509919
|
+
// 的 `/decide` 体无规则位 ⇒ 兑付走 `onPersistLocalRuleSelected` 的壳侧 settings 写入,
|
|
509920
|
+
// **决断字节一个键都不多**(常驻套 localRuleSuggestionsCard ⑤-5/⑥-5 钉住)。
|
|
509921
|
+
...Array.isArray(req.ruleSuggestionsReadOnly) && req.ruleSuggestionsReadOnly.length > 0 ? { ruleSuggestionsReadOnly: req.ruleSuggestionsReadOnly } : {},
|
|
509276
509922
|
onPersistRuleSelected(rule) {
|
|
509277
509923
|
selectedPersistRule = rule;
|
|
509278
509924
|
},
|
|
509925
|
+
// durable 腿的落规则口:写壳自己的 `permissions.allow`(判定与窄化全在 localAllowRuleWrite),
|
|
509926
|
+
// 成败**都**上屏 —— 「点了『不再询问』,下次它又问」是这条腿唯一会被问的问题,静默失败等于
|
|
509927
|
+
// 把答案藏起来。🔴 刻意不碰 `selectedPersistRule`:回决字节与两态时代必须逐字节相同。
|
|
509928
|
+
onPersistLocalRuleSelected(rule) {
|
|
509929
|
+
let outcome = persistLocalAllowRule(rule);
|
|
509930
|
+
surfaceLocalRulePersistOutcome(outcome);
|
|
509931
|
+
},
|
|
509279
509932
|
// governanceForced(client-core 0.20.1 透传位,server ≥7.5.0):此门来自部署治理层
|
|
509280
509933
|
// (AUTONOMY/commandPolicy/MANUAL_MODE_SHELL_GATE/SENSITIVE_WRITE_PATTERNS),权限模式
|
|
509281
509934
|
// 表态掀不掉——呈现走 wireNote 超集车道(dim 行,与 argsOmitted 提示同位,可叠加)。
|
|
@@ -509337,6 +509990,8 @@ var asWireTool, forcedToolLoadFailureForTest, forcedToolNilExportForTest, loadFi
|
|
|
509337
509990
|
init_appStateRef();
|
|
509338
509991
|
init_debug();
|
|
509339
509992
|
init_engineGateSyncAllow();
|
|
509993
|
+
init_localAllowRuleWrite();
|
|
509994
|
+
init_persistedRulesWire();
|
|
509340
509995
|
init_armedGateRegistry2();
|
|
509341
509996
|
init_dist();
|
|
509342
509997
|
asWireTool = (t2) => t2, forcedToolLoadFailureForTest = null, forcedToolNilExportForTest = null, loadFileWrite = () => (init_FileWriteTool(), __toCommonJS(FileWriteTool_exports)).FileWriteTool, loadFileEdit = () => (init_FileEditTool(), __toCommonJS(FileEditTool_exports)).FileEditTool, loadNotebookEdit = () => (init_NotebookEditTool(), __toCommonJS(NotebookEditTool_exports)).NotebookEditTool, loadBash = () => (init_BashTool(), __toCommonJS(BashTool_exports)).BashTool, loadEngineWorkflow = () => (init_EngineWorkflowTool(), __toCommonJS(EngineWorkflowTool_exports)).EngineWorkflowTool, KNOWN_TOOL_LOADERS = {
|
|
@@ -509395,27 +510050,6 @@ var init_liveHitlAskWire = __esm({
|
|
|
509395
510050
|
}
|
|
509396
510051
|
});
|
|
509397
510052
|
|
|
509398
|
-
// build-src/src/sema/approvalDecisionNoteAudit.ts
|
|
509399
|
-
function cleanNote(raw2) {
|
|
509400
|
-
let flat = raw2.replace(/[\u0000-\u001f\u007f-\u009f]+/g, " ").replace(/ {2,}/g, " ").trim();
|
|
509401
|
-
return flat.length <= 200 ? flat : `${flat.slice(0, 199)}\u2026`;
|
|
509402
|
-
}
|
|
509403
|
-
function readDecisionNoteAudit(ack) {
|
|
509404
|
-
if (ack === null || typeof ack != "object") return { state: "unknown" };
|
|
509405
|
-
let o = ack, note = typeof o.decisionNote == "string" && o.decisionNote.trim() !== "" ? cleanNote(o.decisionNote) : void 0;
|
|
509406
|
-
return o.noteRecorded === !1 ? { state: "not-recorded", ...note !== void 0 ? { note } : {} } : o.noteRecorded === !0 ? { state: "recorded", ...note !== void 0 ? { note } : {} } : note !== void 0 ? { state: "recorded", note } : { state: "unknown" };
|
|
509407
|
-
}
|
|
509408
|
-
function decisionNoteAuditLine(audit, opts) {
|
|
509409
|
-
if (audit.state === "unknown") return null;
|
|
509410
|
-
let quoted = audit.note !== void 0 ? `: "${audit.note}"` : "";
|
|
509411
|
-
return opts?.settledElsewhere === !0 ? audit.state === "recorded" ? `this approval was already decided elsewhere \u2014 the reason recorded on the audit trail${quoted}` : `this approval was already decided elsewhere; your reason was not saved to the audit trail \u2014 that decision stands${quoted}` : audit.state === "recorded" ? `decision reason recorded on the audit trail${quoted}` : `your decision stands \u2014 the engine did not save its reason to the audit trail${quoted}`;
|
|
509412
|
-
}
|
|
509413
|
-
var DECISION_NOTE_NOTICE_KEY, init_approvalDecisionNoteAudit = __esm({
|
|
509414
|
-
"build-src/src/sema/approvalDecisionNoteAudit.ts"() {
|
|
509415
|
-
DECISION_NOTE_NOTICE_KEY = "approval-decision-note";
|
|
509416
|
-
}
|
|
509417
|
-
});
|
|
509418
|
-
|
|
509419
510053
|
// build-src/src/sema/approvalStreamWire.ts
|
|
509420
510054
|
import {
|
|
509421
510055
|
isApprovalRequestFrameV1,
|
|
@@ -509659,7 +510293,7 @@ async function* consumeStreamApprovalFrames(events3, deps2, opts = {}) {
|
|
|
509659
510293
|
release2();
|
|
509660
510294
|
}
|
|
509661
510295
|
}
|
|
509662
|
-
function
|
|
510296
|
+
function abortableDelay2(ms, signal) {
|
|
509663
510297
|
return signal.aborted ? Promise.resolve() : new Promise((resolve57) => {
|
|
509664
510298
|
let t2 = setTimeout(done, ms);
|
|
509665
510299
|
function done() {
|
|
@@ -509685,7 +510319,7 @@ async function* consumeStreamApprovalFrames(events3, deps2, opts = {}) {
|
|
|
509685
510319
|
} catch (e) {
|
|
509686
510320
|
let f = classifyAskDecisionFailure(e);
|
|
509687
510321
|
if (f.kind === "parking" && attempt < PARKING_POLL_MAX && !signal.aborted) {
|
|
509688
|
-
await
|
|
510322
|
+
await abortableDelay2(PARKING_POLL_DELAY_MS * (attempt + 1), signal);
|
|
509689
510323
|
continue;
|
|
509690
510324
|
}
|
|
509691
510325
|
reportDecisionFailure(f, askId), f.kind === "ask-lane-disabled" && await fallbackLegacyRespond(approvalId, decision, askId, signal);
|
|
@@ -509775,7 +510409,6 @@ var STREAM_APPROVAL_CAP, ASK_DECISION_DISABLED_CODE, IDEMPOTENCY_KEY_MAX, PARKIN
|
|
|
509775
510409
|
"build-src/src/sema/approvalStreamWire.ts"() {
|
|
509776
510410
|
init_dist();
|
|
509777
510411
|
init_debug();
|
|
509778
|
-
init_approvalDecisionNoteAudit();
|
|
509779
510412
|
init_appStateRef();
|
|
509780
510413
|
init_wireNoticePort();
|
|
509781
510414
|
STREAM_APPROVAL_CAP = "streamApproval", ASK_DECISION_DISABLED_CODE = "feature.approval_ask_disabled", IDEMPOTENCY_KEY_MAX = 255, PARKING_POLL_MAX = 2, PARKING_POLL_DELAY_MS = 400, CAPS_SETTLE_BUDGET_MS = 1500, LEGACY_SETTLE_GRACE_MS = 750, MAX_DECISION_NOTE_CHARS = 2048, TEARDOWN_BUDGET_MS = 1e3;
|
|
@@ -509810,7 +510443,7 @@ function classifySubmitFailure(e, signal) {
|
|
|
509810
510443
|
let status3 = statusOf2(e);
|
|
509811
510444
|
return status3 !== void 0 ? status3 === 501 ? "server-verdict" : status3 >= 500 ? "server-5xx" : "server-verdict" : isEngineTransportError(e) || isAbortShaped(e) ? "transport" : "local-error";
|
|
509812
510445
|
}
|
|
509813
|
-
function
|
|
510446
|
+
function abortableDelay(ms, signal) {
|
|
509814
510447
|
return signal?.aborted === !0 ? Promise.resolve() : new Promise((resolve57) => {
|
|
509815
510448
|
let t2 = setTimeout(done, ms);
|
|
509816
510449
|
function done() {
|
|
@@ -509844,7 +510477,7 @@ async function submitWithTransportRetry(send, o) {
|
|
|
509844
510477
|
if (retriable && attempt < attempts && !overBudget) {
|
|
509845
510478
|
if (logForDebugging(
|
|
509846
510479
|
`[sema][wire] approval submit ${o.label}: attempt ${String(attempt)}/${String(attempts)} failed (${kind}) \u2014 retrying in ${String(delay)}ms with the SAME request`
|
|
509847
|
-
), retried = !0, await
|
|
510480
|
+
), retried = !0, await abortableDelay(delay, o.signal), o.signal?.aborted === !0)
|
|
509848
510481
|
throw logForDebugging(`[sema][wire] approval submit ${o.label}: aborted during backoff \u2014 no further attempt`), e;
|
|
509849
510482
|
continue;
|
|
509850
510483
|
}
|
|
@@ -528763,7 +529396,7 @@ Usage: sema --remote "your task description"`, () => gracefulShutdown(1));
|
|
|
528763
529396
|
pendingHookMessages
|
|
528764
529397
|
}, renderAndRun);
|
|
528765
529398
|
}
|
|
528766
|
-
}).version("sema 1.0.
|
|
529399
|
+
}).version("sema 1.0.76", "-v, --version", "Output the version number"), program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)"), program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux."), canUserConfigureAdvisor() && program2.addOption(new Option("--advisor <model>", "Enable the server-side advisor tool with the specified model (alias or full ID).").hideHelp()), program2.addOption(new Option("--bg, --background", "Start the session as a background agent and return immediately (manage with `sema agents`)")), program2.command("ps").description("List background sessions").action(async () => {
|
|
528767
529400
|
await (await Promise.resolve().then(() => (init_bg2(), bg_exports))).psHandler([]), process.exit(process.exitCode ?? 0);
|
|
528768
529401
|
}), program2.command("logs [id]").description("Print a background session's recent terminal output").action(async (id) => {
|
|
528769
529402
|
await (await Promise.resolve().then(() => (init_bg2(), bg_exports))).logsHandler(id, []), process.exit(process.exitCode ?? 0);
|
|
@@ -531425,7 +532058,8 @@ function seedSemaSettings() {
|
|
|
531425
532058
|
}
|
|
531426
532059
|
try {
|
|
531427
532060
|
resetUserSettingCache();
|
|
531428
|
-
} catch {
|
|
532061
|
+
} catch (e) {
|
|
532062
|
+
failOpen("settings-seed-cache-reset", void 0, String(e));
|
|
531429
532063
|
}
|
|
531430
532064
|
return { wrote: !0, path: file2, added };
|
|
531431
532065
|
}
|
|
@@ -531433,6 +532067,7 @@ var SEMA_SETTINGS_DEFAULTS, init_semaSettingsSeed = __esm({
|
|
|
531433
532067
|
"build-src/src/sema/mock/semaSettingsSeed.ts"() {
|
|
531434
532068
|
init_envUtils();
|
|
531435
532069
|
init_userSetting();
|
|
532070
|
+
init_failOpen();
|
|
531436
532071
|
SEMA_SETTINGS_DEFAULTS = {
|
|
531437
532072
|
theme: "dark",
|
|
531438
532073
|
// LOAD-BEARING: dark → RGB-orange logo + white ⏺ bullet (matches real 187 on a dark terminal)
|