@sema-agent/client-core 0.12.1 → 0.13.0
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/README.md +15 -2
- package/dist/abortableSleep.d.ts +29 -0
- package/dist/abortableSleep.js +43 -0
- package/dist/adapt/arms.d.ts +58 -0
- package/dist/adapt/arms.js +613 -0
- package/dist/adapt/ids.d.ts +22 -0
- package/dist/adapt/ids.js +34 -0
- package/dist/adapt/instanceLedger.d.ts +36 -0
- package/dist/adapt/instanceLedger.js +50 -0
- package/dist/adapt/panelTasks.d.ts +54 -0
- package/dist/adapt/panelTasks.js +193 -0
- package/dist/adapt/textStream.d.ts +49 -0
- package/dist/adapt/textStream.js +141 -0
- package/dist/adapt/toolCards.d.ts +65 -0
- package/dist/adapt/toolCards.js +100 -0
- package/dist/adapt/turnFlags.d.ts +33 -0
- package/dist/adapt/turnFlags.js +55 -0
- package/dist/adapt/wireShapes.d.ts +93 -0
- package/dist/adapt/wireShapes.js +167 -0
- package/dist/adapt.d.ts +32 -59
- package/dist/adapt.js +78 -1206
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +55 -13
- package/dist/adapter/downstream/eventToSdkMessage.js +166 -106
- package/dist/adapter/downstream/terminalToSdkResult.js +149 -160
- package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +36 -0
- package/dist/adapter/downstream/turnUsageToModelUsage.js +34 -6
- package/dist/adapter/runStream.d.ts +29 -4
- package/dist/adapter/runStream.js +129 -13
- package/dist/adapter/types.d.ts +2 -2
- package/dist/agentSession/backgroundView.js +4 -15
- package/dist/agentsWireCaps.d.ts +10 -6
- package/dist/agentsWireCaps.js +21 -7
- package/dist/argvFlagValue.d.ts +41 -0
- package/dist/argvFlagValue.js +69 -0
- package/dist/attachmentsWireCaps.d.ts +3 -2
- package/dist/attachmentsWireCaps.js +5 -3
- package/dist/classifierVerdictWire.d.ts +8 -0
- package/dist/classifierVerdictWire.js +8 -0
- package/dist/cloudConfigWireCaps.d.ts +28 -1
- package/dist/cloudConfigWireCaps.js +51 -11
- package/dist/controlRouter.d.ts +14 -8
- package/dist/controlRouter.js +15 -21
- package/dist/detachWire.d.ts +15 -5
- package/dist/detachWire.js +17 -7
- package/dist/effortWire.d.ts +0 -21
- package/dist/effortWire.js +6 -20
- package/dist/engineInlineTaskStats.d.ts +12 -6
- package/dist/engineWireSdk.d.ts +12 -0
- package/dist/env/localeGeo.js +2 -1
- package/dist/envFlag.d.ts +39 -0
- package/dist/envFlag.js +51 -0
- package/dist/finalVerifyWire.d.ts +7 -5
- package/dist/finalVerifyWire.js +6 -5
- package/dist/fleet/fleetLedger.d.ts +32 -9
- package/dist/fleet/fleetLedger.js +119 -34
- package/dist/fleet/fleetProjection.d.ts +44 -6
- package/dist/fleet/fleetProjection.js +52 -10
- package/dist/fleetAgentPanelProjection.d.ts +18 -1
- package/dist/fleetAgentPanelProjection.js +61 -14
- package/dist/forkWireCaps.d.ts +2 -1
- package/dist/forkWireCaps.js +5 -11
- package/dist/goalStopHook.d.ts +142 -0
- package/dist/goalStopHook.js +258 -0
- package/dist/headlessPermissionModeWire.d.ts +10 -0
- package/dist/headlessPermissionModeWire.js +24 -21
- package/dist/headlessReconnectWire.d.ts +7 -1
- package/dist/headlessReconnectWire.js +20 -2
- package/dist/hitl/approvalsFeed.js +31 -8
- package/dist/hitl/askGateWire.d.ts +27 -96
- package/dist/hitl/askGateWire.js +69 -546
- package/dist/hitl/frameRouter.d.ts +86 -0
- package/dist/hitl/frameRouter.js +342 -0
- package/dist/hitl/gateLedger.d.ts +107 -0
- package/dist/hitl/gateLedger.js +113 -0
- package/dist/hitl/hitlBridge.d.ts +75 -15
- package/dist/hitl/hitlBridge.js +94 -22
- package/dist/hitl/hitlHostSurface.d.ts +49 -0
- package/dist/hitl/hitlHostSurface.js +155 -0
- package/dist/hitl/parkResolver.d.ts +74 -0
- package/dist/hitl/parkResolver.js +241 -0
- package/dist/hitl/planReviewWire.d.ts +60 -2
- package/dist/hitl/planReviewWire.js +152 -74
- package/dist/hitl/toolApprovalWire.d.ts +67 -4
- package/dist/hitl/toolApprovalWire.js +119 -31
- package/dist/hooksWireCaps.d.ts +1 -82
- package/dist/hooksWireCaps.js +34 -235
- package/dist/host.d.ts +16 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.js +15 -1
- package/dist/interactiveToolsWire.d.ts +15 -4
- package/dist/interactiveToolsWire.js +24 -26
- package/dist/limitsWire.js +7 -40
- package/dist/liveInitToolFace.d.ts +51 -6
- package/dist/liveQuestionStore.d.ts +5 -6
- package/dist/model/providerPresets.js +11 -1
- package/dist/notifications.d.ts +48 -2
- package/dist/notifications.js +223 -46
- package/dist/retainBackgroundWireCaps.d.ts +3 -2
- package/dist/retainBackgroundWireCaps.js +5 -9
- package/dist/sandboxWire.d.ts +9 -31
- package/dist/sandboxWire.js +51 -50
- package/dist/scenarioWire.d.ts +1 -1
- package/dist/scenarioWire.js +25 -36
- package/dist/seam.d.ts +23 -6
- package/dist/seam.js +40 -30
- package/dist/seatContract.d.ts +369 -83
- package/dist/seatContract.js +585 -198
- package/dist/selfOrchestrationWireCaps.d.ts +6 -5
- package/dist/selfOrchestrationWireCaps.js +8 -12
- package/dist/sessionSlot.d.ts +8 -0
- package/dist/sessionSlot.js +1 -0
- package/dist/steering.js +2 -2
- package/dist/subagent/engineTaskHandleWire.d.ts +3 -0
- package/dist/subagent/engineTaskHandleWire.js +17 -2
- package/dist/subagentContentStore.d.ts +5 -5
- package/dist/toolResult.d.ts +89 -8
- package/dist/toolResult.js +99 -30
- package/dist/typePins.d.ts +17 -0
- package/dist/typePins.js +1 -0
- package/dist/ultracodeWireCaps.js +5 -6
- package/dist/unrefTimer.d.ts +19 -0
- package/dist/unrefTimer.js +5 -0
- package/dist/workflow.d.ts +3 -2
- package/dist/workflow.js +3 -2
- package/dist/workflowClient.d.ts +7 -0
- package/dist/workflowClient.js +47 -12
- package/package.json +3 -3
|
@@ -32,9 +32,10 @@ import { type EnvLike } from './hostEnv.js';
|
|
|
32
32
|
* `SELF_ORCHESTRATION_ENABLED` env (the service's DEPLOYMENT gate — a different axis the service owns). */
|
|
33
33
|
export declare const SELF_ORCHESTRATION_ENV: "SEMA_SELF_ORCHESTRATION";
|
|
34
34
|
/** ENV source → `true` by DEFAULT (clay 决定 2026-07-01 §4:RunWorkflow 默认可用),unless the user explicitly
|
|
35
|
-
* opts OUT (
|
|
36
|
-
* Still `true | undefined` (never `false`) to mirror the service's strict `=== true`
|
|
37
|
-
* makes run_workflow AVAILABLE — the engine still owns the final gate (its own
|
|
38
|
-
* default-on in TOC assembleChildEnv, + per-principal entitlement; TOC
|
|
39
|
-
* gates this to LIVE mode, so the MOCK request shape is
|
|
35
|
+
* opts OUT ({@link envFlagOff} spelling set, REF-CC-141 dup-02 单源) ⇒ `undefined` (no stamp; engine never
|
|
36
|
+
* mounts run_workflow). Still `true | undefined` (never `false`) to mirror the service's strict `=== true`
|
|
37
|
+
* read. A stamped `true` only makes run_workflow AVAILABLE — the engine still owns the final gate (its own
|
|
38
|
+
* `SELF_ORCHESTRATION_ENABLED`, set default-on in TOC assembleChildEnv, + per-principal entitlement; TOC
|
|
39
|
+
* single-user honors it directly). The caller gates this to LIVE mode, so the MOCK request shape is
|
|
40
|
+
* unchanged; only the live default path now stamps true. */
|
|
40
41
|
export declare function selfOrchestrationFromEnv(env?: EnvLike): true | undefined;
|
|
@@ -28,21 +28,17 @@
|
|
|
28
28
|
* so the mock request shape never changes; the selfOrchestration stamp IS the opt-in (no extra flag needed).
|
|
29
29
|
*/
|
|
30
30
|
import { hostEnv } from './hostEnv.js';
|
|
31
|
+
import { envFlagOff } from './envFlag.js';
|
|
31
32
|
/** The env key the shell reads. SEMA_-namespaced so it never collides with the worker's OWN deploy
|
|
32
33
|
* `SELF_ORCHESTRATION_ENABLED` env (the service's DEPLOYMENT gate — a different axis the service owns). */
|
|
33
34
|
export const SELF_ORCHESTRATION_ENV = 'SEMA_SELF_ORCHESTRATION';
|
|
34
|
-
/** The FALSY spellings that opt OUT (case-insensitive, trimmed). Conservative allowlist — only an explicit
|
|
35
|
-
* `0`/`false`/`no`/`off` disables; everything else (incl. unset/empty) is the DEFAULT-ON path. */
|
|
36
|
-
function isFalsy(v) {
|
|
37
|
-
const s = typeof v === 'string' ? v.trim().toLowerCase() : '';
|
|
38
|
-
return s === '0' || s === 'false' || s === 'no' || s === 'off';
|
|
39
|
-
}
|
|
40
35
|
/** ENV source → `true` by DEFAULT (clay 决定 2026-07-01 §4:RunWorkflow 默认可用),unless the user explicitly
|
|
41
|
-
* opts OUT (
|
|
42
|
-
* Still `true | undefined` (never `false`) to mirror the service's strict `=== true`
|
|
43
|
-
* makes run_workflow AVAILABLE — the engine still owns the final gate (its own
|
|
44
|
-
* default-on in TOC assembleChildEnv, + per-principal entitlement; TOC
|
|
45
|
-
* gates this to LIVE mode, so the MOCK request shape is
|
|
36
|
+
* opts OUT ({@link envFlagOff} spelling set, REF-CC-141 dup-02 单源) ⇒ `undefined` (no stamp; engine never
|
|
37
|
+
* mounts run_workflow). Still `true | undefined` (never `false`) to mirror the service's strict `=== true`
|
|
38
|
+
* read. A stamped `true` only makes run_workflow AVAILABLE — the engine still owns the final gate (its own
|
|
39
|
+
* `SELF_ORCHESTRATION_ENABLED`, set default-on in TOC assembleChildEnv, + per-principal entitlement; TOC
|
|
40
|
+
* single-user honors it directly). The caller gates this to LIVE mode, so the MOCK request shape is
|
|
41
|
+
* unchanged; only the live default path now stamps true. */
|
|
46
42
|
export function selfOrchestrationFromEnv(env = hostEnv()) {
|
|
47
|
-
return
|
|
43
|
+
return envFlagOff(env[SELF_ORCHESTRATION_ENV]) ? undefined : true;
|
|
48
44
|
}
|
package/dist/sessionSlot.d.ts
CHANGED
|
@@ -22,5 +22,13 @@ export interface SessionSlot<T> {
|
|
|
22
22
|
/** `undefined` = 卸下该键(与「从未装过」同态 —— 槽位模块的 prev-还原语义靠它闭合)。 */
|
|
23
23
|
set(key: string, value: T | undefined): void;
|
|
24
24
|
clear(): void;
|
|
25
|
+
/** 当前**有条目**的键 —— 注意不等于「装了口的键」:`T` 含 `null`(卡口槽位就是
|
|
26
|
+
* `ApprovalCardPort | null`)时,用 `null` 卸下的键仍留在这里(只有 `undefined` 删键)。
|
|
27
|
+
* 消费方判「装了没」必须再读一次 `get(k)`,别只数键。
|
|
28
|
+
* (REF-CC-030,2026-08-02:三个 keyed 卡口决断入口今天全硬读
|
|
29
|
+
* DEFAULT_SESSION_KEY——一个非默认键上真装了口时,默认键仍会 miss;这个读口让
|
|
30
|
+
* miss 文案能把「没人装」与「装错键」分开说,而不用先把三个入口的签名都改成
|
|
31
|
+
* `sessionKey?: string` 透传)。 */
|
|
32
|
+
keys(): string[];
|
|
25
33
|
}
|
|
26
34
|
export declare function createSessionSlot<T>(): SessionSlot<T>;
|
package/dist/sessionSlot.js
CHANGED
package/dist/steering.js
CHANGED
|
@@ -74,10 +74,10 @@ function parseBackgroundTaskLine(line) {
|
|
|
74
74
|
return null;
|
|
75
75
|
return {
|
|
76
76
|
type: 'task_status',
|
|
77
|
-
taskId: m[1],
|
|
77
|
+
taskId: m[1] ?? '',
|
|
78
78
|
taskType: 'local_bash',
|
|
79
79
|
status,
|
|
80
|
-
description: m[2],
|
|
80
|
+
description: m[2] ?? '',
|
|
81
81
|
deltaSummary: null,
|
|
82
82
|
};
|
|
83
83
|
}
|
|
@@ -19,6 +19,9 @@ export declare function fetchEngineTaskOutput(handle: string, opts?: {
|
|
|
19
19
|
* [1505] 契约标记判别(头注):spool 全量 → 替换;cursor 增量 → append;无标记 → 保守
|
|
20
20
|
* append-if-changed(与上次逐字节相同视为幂等重读,不重复)。空 content 不动累积。
|
|
21
21
|
* 🔴 B6 提出成具名纯函数 —— 它是这条读面唯一会「把输出显示成两遍」的地方,值得被直接断言。
|
|
22
|
+
* 🔴 REF-CC-域词表-06:标记判读本身**提单源**到 `toolResult.ts` 的 `spoolMarkerOf`(它与本文件
|
|
23
|
+
* 曾经各写一份 `.includes()` 判读,同一个协议标记有两处互不知情的判读点——现在两处判读结果
|
|
24
|
+
* 对同一输入恒一致,因为已经是同一个函数)。
|
|
22
25
|
*/
|
|
23
26
|
export declare function mergeTaskOutput(prev: string, fresh: string): string;
|
|
24
27
|
export type EngineTaskStopOutcome =
|
|
@@ -44,6 +44,9 @@ import { engineWireDebugEnabled, engineWireTarget } from '../engineWireTarget.js
|
|
|
44
44
|
import { activeEngineRunId, engineSessionParamSpread } from '../engineSessionParam.js';
|
|
45
45
|
import { getBgParentRun } from '../subagentContentStore.js';
|
|
46
46
|
import { engineTaskHandlesCapable } from './engineRowStopGate.js';
|
|
47
|
+
// REF-CC-域词表-06 提单源:spool 全量/增量判读的单一真源现在在 toolResult.ts(它也消费同一份
|
|
48
|
+
// 协议标记表 PROTOCOL_MARKERS)—— 本文件不再自己 `.includes()` 抄一份判读。
|
|
49
|
+
import { spoolMarkerOf } from '../toolResult.js';
|
|
47
50
|
// 能力门同步读口:真源在零依赖叶 `engineRowStopGate`(batch-stop 同步分类不拉本模块 SDK 图)。
|
|
48
51
|
// ⚠️ 此处**不再 re-export**——它与原定义同进 index.ts 的 `export *` barrel 会构成双出口,
|
|
49
52
|
// esbuild 对 star-export 歧义直接 build 失败(tsc 同源 symbol 不报=假绿;0.8.0 壳收批实撞,
|
|
@@ -107,13 +110,17 @@ export async function fetchEngineTaskOutput(handle, opts) {
|
|
|
107
110
|
* [1505] 契约标记判别(头注):spool 全量 → 替换;cursor 增量 → append;无标记 → 保守
|
|
108
111
|
* append-if-changed(与上次逐字节相同视为幂等重读,不重复)。空 content 不动累积。
|
|
109
112
|
* 🔴 B6 提出成具名纯函数 —— 它是这条读面唯一会「把输出显示成两遍」的地方,值得被直接断言。
|
|
113
|
+
* 🔴 REF-CC-域词表-06:标记判读本身**提单源**到 `toolResult.ts` 的 `spoolMarkerOf`(它与本文件
|
|
114
|
+
* 曾经各写一份 `.includes()` 判读,同一个协议标记有两处互不知情的判读点——现在两处判读结果
|
|
115
|
+
* 对同一输入恒一致,因为已经是同一个函数)。
|
|
110
116
|
*/
|
|
111
117
|
export function mergeTaskOutput(prev, fresh) {
|
|
112
118
|
if (fresh.length === 0)
|
|
113
119
|
return prev;
|
|
114
|
-
|
|
120
|
+
const marker = spoolMarkerOf(fresh);
|
|
121
|
+
if (marker === 'full')
|
|
115
122
|
return fresh;
|
|
116
|
-
if (
|
|
123
|
+
if (marker === 'incremental')
|
|
117
124
|
return prev + fresh;
|
|
118
125
|
return fresh === prev ? prev : prev + fresh;
|
|
119
126
|
}
|
|
@@ -162,6 +169,14 @@ export function classifyTaskStopConflict(e) {
|
|
|
162
169
|
return { ok: false, reason: 'unknown_conflict', detail };
|
|
163
170
|
}
|
|
164
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* 🟢 B8 ALLOW 清单登记(REF-CC-域词表-05,属主=client-core 规范重构轮,到期复议=SDK typed 错误类
|
|
174
|
+
* 覆盖全部 `stop.*` 码后或 2026-Q4 复审以先到者为准):兜底字面认码,前置合取 = typed
|
|
175
|
+
* `TaskStopConflictError` 缺席时才落到这里(见 `stopEngineTask` 的 `if (e instanceof
|
|
176
|
+
* TaskStopConflictError || status === 409)`)。同批同表的另两处:`detachWire.ts`
|
|
177
|
+
* `DETACH_DURABLE_OFF_400_ANCHOR`(server 契约话)、`classifierVerdictWire.ts`
|
|
178
|
+
* `CLASSIFIER_DENY_SIGNATURE`(core lockstep 机器签名)——三处互指,理由逐条写在各自站点。
|
|
179
|
+
*/
|
|
165
180
|
/** 兜底字面认码用的已知集(顺序 = 长码优先,避免 `stop.parked` 抢走 `stop.park_resume_won`)。 */
|
|
166
181
|
const STOP_CONFLICT_CODES = [
|
|
167
182
|
'stop.park_arbiter_unreachable',
|
|
@@ -48,12 +48,12 @@ export interface SubagentContentEvent {
|
|
|
48
48
|
type: 'text_delta' | 'reasoning_delta' | 'tool_start' | 'tool_end';
|
|
49
49
|
taskId: string;
|
|
50
50
|
parentToolCallId: string;
|
|
51
|
-
delta?: string;
|
|
52
|
-
toolCallId?: string;
|
|
53
|
-
toolName?: string;
|
|
51
|
+
delta?: string | undefined;
|
|
52
|
+
toolCallId?: string | undefined;
|
|
53
|
+
toolName?: string | undefined;
|
|
54
54
|
args?: unknown;
|
|
55
|
-
output?: string;
|
|
56
|
-
isError?: boolean;
|
|
55
|
+
output?: string | undefined;
|
|
56
|
+
isError?: boolean | undefined;
|
|
57
57
|
}
|
|
58
58
|
/** Register the parentToolCallId ↔ engine-taskId pair (from task_progress, which carries both).
|
|
59
59
|
* Content parked under the parent key migrates to the canonical task key. */
|
package/dist/toolResult.d.ts
CHANGED
|
@@ -10,6 +10,45 @@
|
|
|
10
10
|
export declare const STRUCTURED_DETAIL_TYPES: ReadonlySet<string>;
|
|
11
11
|
/** structured 在场判别:顶层 `type` ∈ 白名单 ⇒ 返回该 type,否则 undefined(= 不在场)。 */
|
|
12
12
|
export declare function structuredDetailType(structured: unknown): string | undefined;
|
|
13
|
+
export declare const PROTOCOL_MARKERS: {
|
|
14
|
+
/** T11 bash 框架:退出码行头(core tools/fs/index.ts runShell)。 */
|
|
15
|
+
readonly bashHead: RegExp;
|
|
16
|
+
/** T11 bash 框架:stderr 分隔行。 */
|
|
17
|
+
readonly bashStderrSep: "\n--- stderr ---\n";
|
|
18
|
+
/** T11 bash 框架:空 stdout 哨兵。 */
|
|
19
|
+
readonly bashEmptySentinel: "(empty)";
|
|
20
|
+
/** T12:`delimitUntrusted` 围栏(core untrusted-text.ts:118)。REF-CC-域词表-09 回炉车补齐——
|
|
21
|
+
* 此前这条正则仍内联在 `stripUntrustedFence` 里,是原始「8 处文案协议解析点」普查(P1 lens-lexicon
|
|
22
|
+
* 域词表-09 evidence)唯一没进表的一条(`stripUntrustedFence`/`untrustedFence` 单源消费)。 */
|
|
23
|
+
readonly untrustedFence: RegExp;
|
|
24
|
+
/** T13 TaskOutput:`<<<UNTRUSTED TaskOutput <id> …>>>` label 里的任务 id。 */
|
|
25
|
+
readonly taskOutputLabel: RegExp;
|
|
26
|
+
/** T13 TaskOutput:`status: …` 行。 */
|
|
27
|
+
readonly taskOutputStatus: RegExp;
|
|
28
|
+
/** T13 TaskOutput:空段哨兵。 */
|
|
29
|
+
readonly taskOutputNoneSentinel: "(none)";
|
|
30
|
+
/** T13 TaskOutput:stdout 分隔行(全量/增量两形共用一条正则——区分交给下面的 spool 判别)。 */
|
|
31
|
+
readonly taskOutputStdoutLine: RegExp;
|
|
32
|
+
/** T13 TaskOutput:stderr 分隔行。 */
|
|
33
|
+
readonly taskOutputStderrLine: RegExp;
|
|
34
|
+
/** T13 TaskOutput:agent 结果分隔行。 */
|
|
35
|
+
readonly taskOutputResultLine: RegExp;
|
|
36
|
+
/** [1505] spool 协议:全量可重读形(`engineTaskHandleWire.ts` mergeTaskOutput 单源消费点)。 */
|
|
37
|
+
readonly spoolStdoutFull: "--- stdout (full, re-readable) ---";
|
|
38
|
+
/** [1505] spool 协议:增量新字节形。 */
|
|
39
|
+
readonly spoolStdoutIncremental: "--- new stdout ---";
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* [1505] spool 标记判别(REF-CC-域词表-06 提单源):判「读游标该整体替换还是追加」这一件事,
|
|
43
|
+
* 唯一真源在此——`engineTaskHandleWire.ts` 的 `mergeTaskOutput` 消费它,此前是各写一份
|
|
44
|
+
* `.includes()` 的独立判读,现在改成两处调用同一个函数,不再靠两份手抄字面量碰巧对齐。
|
|
45
|
+
* ⚠️ 措辞收窄(opus/codex 复审,回炉车):本函数**不**是"表里任何 stdout/stderr 分隔行判读的
|
|
46
|
+
* 单源"——`parseModelFacingTaskOutput` 里的 `taskOutputStdoutLine` 是解**另一件事**(T13
|
|
47
|
+
* TaskOutput 模型面正文里 stdout 段的边界在哪),两者字面量近似但语义不同、输入来源也不同
|
|
48
|
+
* (读游标累积 vs 单次模型面文本反解),存在能让两者给出不同答案的输入(如带前导垃圾字节的
|
|
49
|
+
* 文本)。它们只是共享同一张 `PROTOCOL_MARKERS` 登记表,不是同一个判据。
|
|
50
|
+
*/
|
|
51
|
+
export declare function spoolMarkerOf(text: string): 'full' | 'incremental' | null;
|
|
13
52
|
export declare function modelFacingParseCalls(): number;
|
|
14
53
|
export declare function _resetModelFacingParseCountForTest(): void;
|
|
15
54
|
export declare function parseModelFacingBash(text: string): {
|
|
@@ -25,20 +64,52 @@ export declare function stripUntrustedFence(text: string): {
|
|
|
25
64
|
label: string;
|
|
26
65
|
body: string;
|
|
27
66
|
} | null;
|
|
67
|
+
/**
|
|
68
|
+
* T13 回落解析结果(REF-CC-TYPESHAPE-14:命名 discriminated union —— 此前是 4 成员内联匿名形,
|
|
69
|
+
* 三个构造点各自手写、`'unknown'` 分支「没有 output」原来只是注释里的一句话,现在类型强制)。
|
|
70
|
+
* 🔴 抽 DU **不改运行时形**(二次回炉,codex #4):`taskId`/`status` 缺值时**键照样在、值是
|
|
71
|
+
* `undefined`**(与 main 逐字节一致)——本函数是 npm 公面导出,`Object.keys()` / `'taskId' in r` /
|
|
72
|
+
* JSON 序列化都是下游看得见的契约,类型重构无权改它。eopt 收官(E-seat 卡裁定):「公面键恒在」
|
|
73
|
+
* 形不许被本批翻回条件展开——三键改 `| undefined` 显式并集,继续如实描述「键恒在、值可能 undefined」
|
|
74
|
+
* 这个已裁定的公面契约(不是收窄成条件展开,那会静默改变 `Object.keys()` 的下游可见形)。
|
|
75
|
+
* 常驻钉见 `run-client-core-pure-test.mjs` ⑪ 段「公面形(codex #4 回卷钉)」三条。
|
|
76
|
+
*/
|
|
77
|
+
export type ModelFacingTaskOutput = {
|
|
78
|
+
kind: 'bash';
|
|
79
|
+
taskId?: string | undefined;
|
|
80
|
+
status?: string | undefined;
|
|
81
|
+
output: string;
|
|
82
|
+
} | {
|
|
83
|
+
kind: 'agent';
|
|
84
|
+
taskId?: string | undefined;
|
|
85
|
+
status?: string | undefined;
|
|
86
|
+
output: string;
|
|
87
|
+
} | {
|
|
88
|
+
kind: 'unknown';
|
|
89
|
+
taskId?: string | undefined;
|
|
90
|
+
status?: string | undefined;
|
|
91
|
+
};
|
|
28
92
|
/**
|
|
29
93
|
* T13 回落 —— 引擎 TaskOutput 的模型面正文(core task-registry.ts 的 bash/agent 两形,整体
|
|
30
94
|
* delimitUntrusted 包裹、label = `TaskOutput <id>`)反解回卡片槽位。`kind` 报哪一形命中,
|
|
31
|
-
* 'unknown' ⇒
|
|
95
|
+
* 'unknown' ⇒ 调用方回落原文(该分支类型上就没有 `output` 字段,不是「值恰好是 undefined」)。
|
|
32
96
|
*/
|
|
33
|
-
export declare function parseModelFacingTaskOutput(text: string):
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
status?: string;
|
|
37
|
-
output?: string;
|
|
38
|
-
};
|
|
97
|
+
export declare function parseModelFacingTaskOutput(text: string): ModelFacingTaskOutput;
|
|
98
|
+
export declare function backgroundReceiptParseCalls(): number;
|
|
99
|
+
export declare function _resetBackgroundReceiptParseCountForTest(): void;
|
|
39
100
|
/**
|
|
40
101
|
* T14 回落 —— 后台回执**三代文案**正则(#117a:core ≥1.283 的 `Command running in background` 是
|
|
41
|
-
* 第三代)。structured bash 在场时由 `background`/`task_id` 位取代(见 `wireOutputToBody`)
|
|
102
|
+
* 第三代)。structured bash 在场时由 `background`/`task_id` 位取代(见 `wireOutputToBody`)——
|
|
103
|
+
* **该函数在 structured 权威时必须零调用**(`wireOutputToBody` 的 T14 分支已经这样接线;
|
|
104
|
+
* `backgroundReceiptParseCalls()` 是这条不变量的仪器)。
|
|
105
|
+
* 🔴 legacy 回落登记(REF-CC-域词表-04):三代并列是本函数唯一存在的理由 —— 旧分支不能删,
|
|
106
|
+
* 是因为不知道哪个仍在跑的引擎版本还只发这三代文案里的某一代。**何时可删**:当
|
|
107
|
+
* `run-engine-vocab-floor-test.mjs`(engine-vocab 门)确认全部受支持的引擎地板版本都已发
|
|
108
|
+
* `structured.type === 'bash'` 的 `task_id`/`background.task_id` 位(即 structured 白名单成为
|
|
109
|
+
* **唯一**判据,不再有 tolerate-absent 的老引擎在保修窗内)时,本函数随之退役;
|
|
110
|
+
* `detectEngineBgShellReceipt`(#117a 面板探测器,复用同一份 `THREE_GEN_BG_RECEIPT_RE`)另行
|
|
111
|
+
* 评估——它的存在理由不是「structured 回落」而是「引擎侧秒关该卡、只能靠回执文案桥」,
|
|
112
|
+
* 不随本函数退役自动失效。
|
|
42
113
|
*/
|
|
43
114
|
export declare function parseBackgroundReceipt(text: string): {
|
|
44
115
|
taskId: string;
|
|
@@ -87,6 +158,16 @@ modelText?: string): {
|
|
|
87
158
|
toolUseResult: unknown;
|
|
88
159
|
isError?: boolean;
|
|
89
160
|
} | null;
|
|
161
|
+
/**
|
|
162
|
+
* #117a —— **模型发起**的后台 Bash 回执探测器(cli `engineBgShellPanelStore.detectEngineBgShellReceipt`
|
|
163
|
+
* 逐字)。引擎侧秒关这张卡、从不进壳的 LocalShellTask registry,只能从回执文案桥过去。
|
|
164
|
+
* 🔴 **刻意**要求 INPUT 上 `run_in_background === true`:ctrl+B 的 detach lane
|
|
165
|
+
* (「Command moved to background」)归 engineToolDetach 管(它的行生命周期是有意的 settle-on-detach),
|
|
166
|
+
* 在这里重复登记会长出双行。
|
|
167
|
+
* 判定在库、**执行留宿主**(面板 store 写入 + 宿主 run 映射)—— 走 chrome `bgshell_register` 臂。
|
|
168
|
+
* 🔴 正则复用 `THREE_GEN_BG_RECEIPT_RE`(见上方 T14 `parseBackgroundReceipt` 头注,REF-CC-域词表-04
|
|
169
|
+
* dedupe)—— 此前这里另抄了一份逐字节相同的字面量,两份手抄件靠"碰巧没人改坏"对齐。
|
|
170
|
+
*/
|
|
90
171
|
export interface EngineBgShellRegistration {
|
|
91
172
|
kind: 'register';
|
|
92
173
|
/** 回执上的**引擎** task id(`task_id=…`,TaskOutput/TaskStop 的句柄)。 */
|
package/dist/toolResult.js
CHANGED
|
@@ -106,6 +106,56 @@ const WF_TERMINAL_STATUSES = new Set([
|
|
|
106
106
|
// ══════════════════════════════════════════════════════════════════════════════════════════════
|
|
107
107
|
// ② 模型面正文的**回落**解析(T11 / T12 / T13)—— structured 缺席时才用
|
|
108
108
|
// ══════════════════════════════════════════════════════════════════════════════════════════════
|
|
109
|
+
// ── E3:协议分隔标记表(REF-CC-域词表-06/09,client-core 规范重构轮 P3 卡E)──────────────────────
|
|
110
|
+
// 「人话当协议」的分隔行文案此前散落成裸字面量/裸正则,且与 `engineTaskHandleWire.ts` 的 spool
|
|
111
|
+
// 全量/增量判读各写一份、写法还不同(includes vs 正则+多行锚)—— 同一个协议标记不该有两处
|
|
112
|
+
// 互不知情的判读点。**字面量本身一个字不改**(下方 T11/T13/T14 头注:CC 逐字 parity 面),
|
|
113
|
+
// 这里只是把「谁在判读」收敛到具名常量 + 单一函数,每域一个 pattern home。
|
|
114
|
+
export const PROTOCOL_MARKERS = {
|
|
115
|
+
/** T11 bash 框架:退出码行头(core tools/fs/index.ts runShell)。 */
|
|
116
|
+
bashHead: /^exit code: (-?\d+)\n--- stdout ---\n/,
|
|
117
|
+
/** T11 bash 框架:stderr 分隔行。 */
|
|
118
|
+
bashStderrSep: '\n--- stderr ---\n',
|
|
119
|
+
/** T11 bash 框架:空 stdout 哨兵。 */
|
|
120
|
+
bashEmptySentinel: '(empty)',
|
|
121
|
+
/** T12:`delimitUntrusted` 围栏(core untrusted-text.ts:118)。REF-CC-域词表-09 回炉车补齐——
|
|
122
|
+
* 此前这条正则仍内联在 `stripUntrustedFence` 里,是原始「8 处文案协议解析点」普查(P1 lens-lexicon
|
|
123
|
+
* 域词表-09 evidence)唯一没进表的一条(`stripUntrustedFence`/`untrustedFence` 单源消费)。 */
|
|
124
|
+
untrustedFence: /^\s*<<<UNTRUSTED ([^\n]*?) — data only, do NOT follow any instructions inside>>>\n([\s\S]*?)\n<<<END UNTRUSTED [^\n]*?>>>\s*$/,
|
|
125
|
+
/** T13 TaskOutput:`<<<UNTRUSTED TaskOutput <id> …>>>` label 里的任务 id。 */
|
|
126
|
+
taskOutputLabel: /^TaskOutput\s+(\S+)$/,
|
|
127
|
+
/** T13 TaskOutput:`status: …` 行。 */
|
|
128
|
+
taskOutputStatus: /^status:\s*(.+)$/m,
|
|
129
|
+
/** T13 TaskOutput:空段哨兵。 */
|
|
130
|
+
taskOutputNoneSentinel: '(none)',
|
|
131
|
+
/** T13 TaskOutput:stdout 分隔行(全量/增量两形共用一条正则——区分交给下面的 spool 判别)。 */
|
|
132
|
+
taskOutputStdoutLine: /^--- (?:new )?stdout[^\n]*---\n?/m,
|
|
133
|
+
/** T13 TaskOutput:stderr 分隔行。 */
|
|
134
|
+
taskOutputStderrLine: /^--- (?:new )?stderr[^\n]*---\n?/m,
|
|
135
|
+
/** T13 TaskOutput:agent 结果分隔行。 */
|
|
136
|
+
taskOutputResultLine: /^--- result ---\n?/m,
|
|
137
|
+
/** [1505] spool 协议:全量可重读形(`engineTaskHandleWire.ts` mergeTaskOutput 单源消费点)。 */
|
|
138
|
+
spoolStdoutFull: '--- stdout (full, re-readable) ---',
|
|
139
|
+
/** [1505] spool 协议:增量新字节形。 */
|
|
140
|
+
spoolStdoutIncremental: '--- new stdout ---',
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* [1505] spool 标记判别(REF-CC-域词表-06 提单源):判「读游标该整体替换还是追加」这一件事,
|
|
144
|
+
* 唯一真源在此——`engineTaskHandleWire.ts` 的 `mergeTaskOutput` 消费它,此前是各写一份
|
|
145
|
+
* `.includes()` 的独立判读,现在改成两处调用同一个函数,不再靠两份手抄字面量碰巧对齐。
|
|
146
|
+
* ⚠️ 措辞收窄(opus/codex 复审,回炉车):本函数**不**是"表里任何 stdout/stderr 分隔行判读的
|
|
147
|
+
* 单源"——`parseModelFacingTaskOutput` 里的 `taskOutputStdoutLine` 是解**另一件事**(T13
|
|
148
|
+
* TaskOutput 模型面正文里 stdout 段的边界在哪),两者字面量近似但语义不同、输入来源也不同
|
|
149
|
+
* (读游标累积 vs 单次模型面文本反解),存在能让两者给出不同答案的输入(如带前导垃圾字节的
|
|
150
|
+
* 文本)。它们只是共享同一张 `PROTOCOL_MARKERS` 登记表,不是同一个判据。
|
|
151
|
+
*/
|
|
152
|
+
export function spoolMarkerOf(text) {
|
|
153
|
+
if (text.includes(PROTOCOL_MARKERS.spoolStdoutFull))
|
|
154
|
+
return 'full';
|
|
155
|
+
if (text.includes(PROTOCOL_MARKERS.spoolStdoutIncremental))
|
|
156
|
+
return 'incremental';
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
109
159
|
/**
|
|
110
160
|
* T11 回落 —— 引擎的模型面 bash 框架(core tools/fs/index.ts runShell:744:
|
|
111
161
|
* `exit code: N\n--- stdout ---\n<stdout>[\n--- stderr ---\n<stderr>]`,CWD 哨兵引擎侧已剥)
|
|
@@ -127,19 +177,21 @@ export function _resetModelFacingParseCountForTest() {
|
|
|
127
177
|
}
|
|
128
178
|
export function parseModelFacingBash(text) {
|
|
129
179
|
modelFacingParseCount++;
|
|
130
|
-
const head =
|
|
180
|
+
const head = PROTOCOL_MARKERS.bashHead.exec(text);
|
|
131
181
|
if (!head)
|
|
132
182
|
return null;
|
|
133
183
|
const exitCode = Number(head[1]);
|
|
134
184
|
let rest = text.slice(head[0].length);
|
|
135
185
|
let stderr = '';
|
|
136
|
-
|
|
137
|
-
|
|
186
|
+
// 直写 `PROTOCOL_MARKERS.bashStderrSep`(不再中转 `const sep`):⑬ 段的角色普查按**用法形**
|
|
187
|
+
// (`.exec(` / `indexOf(` / `=== ` / `includes(`)把每个登记键归组,中转局部变量会让这个键在
|
|
188
|
+
// 源码扫描里没有可归的角色 —— 行为逐字节不变,只是把「谁在怎么用它」留在原地可普查。
|
|
189
|
+
const si = rest.indexOf(PROTOCOL_MARKERS.bashStderrSep);
|
|
138
190
|
if (si >= 0) {
|
|
139
|
-
stderr = rest.slice(si +
|
|
191
|
+
stderr = rest.slice(si + PROTOCOL_MARKERS.bashStderrSep.length);
|
|
140
192
|
rest = rest.slice(0, si);
|
|
141
193
|
}
|
|
142
|
-
const stdout = rest ===
|
|
194
|
+
const stdout = rest === PROTOCOL_MARKERS.bashEmptySentinel ? '' : rest;
|
|
143
195
|
return { stdout, stderr, exitCode: Number.isFinite(exitCode) ? exitCode : null };
|
|
144
196
|
}
|
|
145
197
|
/**
|
|
@@ -147,7 +199,7 @@ export function parseModelFacingBash(text) {
|
|
|
147
199
|
* 围栏是给模型看的注入防护,人类转录卡显示正文(clay 07-03 审计 #1/#9 视觉 bug 的修)。
|
|
148
200
|
*/
|
|
149
201
|
export function stripUntrustedFence(text) {
|
|
150
|
-
const m =
|
|
202
|
+
const m = PROTOCOL_MARKERS.untrustedFence.exec(text);
|
|
151
203
|
if (!m)
|
|
152
204
|
return null;
|
|
153
205
|
return { label: m[1] ?? '', body: m[2] ?? '' };
|
|
@@ -155,23 +207,23 @@ export function stripUntrustedFence(text) {
|
|
|
155
207
|
/**
|
|
156
208
|
* T13 回落 —— 引擎 TaskOutput 的模型面正文(core task-registry.ts 的 bash/agent 两形,整体
|
|
157
209
|
* delimitUntrusted 包裹、label = `TaskOutput <id>`)反解回卡片槽位。`kind` 报哪一形命中,
|
|
158
|
-
* 'unknown' ⇒
|
|
210
|
+
* 'unknown' ⇒ 调用方回落原文(该分支类型上就没有 `output` 字段,不是「值恰好是 undefined」)。
|
|
159
211
|
*/
|
|
160
212
|
export function parseModelFacingTaskOutput(text) {
|
|
161
213
|
modelFacingParseCount++;
|
|
162
214
|
const fence = stripUntrustedFence(text);
|
|
163
215
|
const body = fence ? fence.body : text;
|
|
164
|
-
const taskId = fence ?
|
|
165
|
-
const status =
|
|
216
|
+
const taskId = fence ? PROTOCOL_MARKERS.taskOutputLabel.exec(fence.label)?.[1] : undefined;
|
|
217
|
+
const status = PROTOCOL_MARKERS.taskOutputStatus.exec(body)?.[1]?.trim();
|
|
166
218
|
const none = (s) => {
|
|
167
219
|
const t = s.replace(/\n$/, '');
|
|
168
|
-
return t ===
|
|
220
|
+
return t === PROTOCOL_MARKERS.taskOutputNoneSentinel ? '' : t;
|
|
169
221
|
};
|
|
170
|
-
const mOut =
|
|
222
|
+
const mOut = PROTOCOL_MARKERS.taskOutputStdoutLine.exec(body);
|
|
171
223
|
if (mOut) {
|
|
172
224
|
let rest = body.slice(mOut.index + mOut[0].length);
|
|
173
225
|
let stderr = '';
|
|
174
|
-
const mErr =
|
|
226
|
+
const mErr = PROTOCOL_MARKERS.taskOutputStderrLine.exec(rest);
|
|
175
227
|
if (mErr) {
|
|
176
228
|
stderr = rest.slice(mErr.index + mErr[0].length);
|
|
177
229
|
rest = rest.slice(0, mErr.index);
|
|
@@ -179,18 +231,43 @@ export function parseModelFacingTaskOutput(text) {
|
|
|
179
231
|
const output = [none(rest), none(stderr)].filter(Boolean).join('\n');
|
|
180
232
|
return { kind: 'bash', taskId, status, output };
|
|
181
233
|
}
|
|
182
|
-
const mRes =
|
|
234
|
+
const mRes = PROTOCOL_MARKERS.taskOutputResultLine.exec(body);
|
|
183
235
|
if (mRes) {
|
|
184
236
|
return { kind: 'agent', taskId, status, output: body.slice(mRes.index + mRes[0].length).trimEnd() };
|
|
185
237
|
}
|
|
186
238
|
return { kind: 'unknown', taskId, status };
|
|
187
239
|
}
|
|
240
|
+
/** T14 三代文案的正则(单源;REF-CC-域词表-04 dedupe:此前 `parseBackgroundReceipt` 与下方
|
|
241
|
+
* #117a 的 `detectEngineBgShellReceipt` 探测器各抄一份完全相同的字面量)。 */
|
|
242
|
+
const THREE_GEN_BG_RECEIPT_RE = /^(?:Started in background|Command running in background|Command moved to background); task_id=([A-Za-z0-9_-]+)/;
|
|
243
|
+
/**
|
|
244
|
+
* 🔴 **后台回执正则调用计数器**(REF-CC-域词表-04 仪器,与 `modelFacingParseCount` 同款):
|
|
245
|
+
* 只在测试里读,生产零成本。
|
|
246
|
+
*/
|
|
247
|
+
let backgroundReceiptParseCount = 0;
|
|
248
|
+
export function backgroundReceiptParseCalls() {
|
|
249
|
+
return backgroundReceiptParseCount;
|
|
250
|
+
}
|
|
251
|
+
export function _resetBackgroundReceiptParseCountForTest() {
|
|
252
|
+
backgroundReceiptParseCount = 0;
|
|
253
|
+
}
|
|
188
254
|
/**
|
|
189
255
|
* T14 回落 —— 后台回执**三代文案**正则(#117a:core ≥1.283 的 `Command running in background` 是
|
|
190
|
-
* 第三代)。structured bash 在场时由 `background`/`task_id` 位取代(见 `wireOutputToBody`)
|
|
256
|
+
* 第三代)。structured bash 在场时由 `background`/`task_id` 位取代(见 `wireOutputToBody`)——
|
|
257
|
+
* **该函数在 structured 权威时必须零调用**(`wireOutputToBody` 的 T14 分支已经这样接线;
|
|
258
|
+
* `backgroundReceiptParseCalls()` 是这条不变量的仪器)。
|
|
259
|
+
* 🔴 legacy 回落登记(REF-CC-域词表-04):三代并列是本函数唯一存在的理由 —— 旧分支不能删,
|
|
260
|
+
* 是因为不知道哪个仍在跑的引擎版本还只发这三代文案里的某一代。**何时可删**:当
|
|
261
|
+
* `run-engine-vocab-floor-test.mjs`(engine-vocab 门)确认全部受支持的引擎地板版本都已发
|
|
262
|
+
* `structured.type === 'bash'` 的 `task_id`/`background.task_id` 位(即 structured 白名单成为
|
|
263
|
+
* **唯一**判据,不再有 tolerate-absent 的老引擎在保修窗内)时,本函数随之退役;
|
|
264
|
+
* `detectEngineBgShellReceipt`(#117a 面板探测器,复用同一份 `THREE_GEN_BG_RECEIPT_RE`)另行
|
|
265
|
+
* 评估——它的存在理由不是「structured 回落」而是「引擎侧秒关该卡、只能靠回执文案桥」,
|
|
266
|
+
* 不随本函数退役自动失效。
|
|
191
267
|
*/
|
|
192
268
|
export function parseBackgroundReceipt(text) {
|
|
193
|
-
|
|
269
|
+
backgroundReceiptParseCount++;
|
|
270
|
+
const bg = THREE_GEN_BG_RECEIPT_RE.exec(text);
|
|
194
271
|
return bg?.[1] !== undefined ? { taskId: bg[1] } : null;
|
|
195
272
|
}
|
|
196
273
|
// ══════════════════════════════════════════════════════════════════════════════════════════════
|
|
@@ -617,7 +694,9 @@ modelText) {
|
|
|
617
694
|
if (agentId === undefined || typeof s.description !== 'string' || typeof s.prompt !== 'string') {
|
|
618
695
|
return null;
|
|
619
696
|
}
|
|
620
|
-
|
|
697
|
+
// seq = bg 子代生命周期号(SendMessage 复活即 +1)。wire 今天未必带它 —— 缺席 ⇒ 包内按
|
|
698
|
+
// 首周期解释;带了就必须透传,否则复活周期的观察登记会与首周期同键而被幂等吞掉(notif-02)。
|
|
699
|
+
registerOutstandingBgTask(agentId, s.description, s.prompt, typeof s.seq === 'number' ? s.seq : undefined);
|
|
621
700
|
return {
|
|
622
701
|
toolUseResult: {
|
|
623
702
|
isAsync: true,
|
|
@@ -649,7 +728,9 @@ modelText) {
|
|
|
649
728
|
const status = hasStatus
|
|
650
729
|
? s.status
|
|
651
730
|
: (parsed?.status ?? (retrieval === 'success' ? 'completed' : 'running'));
|
|
652
|
-
|
|
731
|
+
// 'unknown' 分支类型上没有 output 字段(REF-CC-TYPESHAPE-14:不是「值恰好是 undefined」)——
|
|
732
|
+
// 显式按 kind 取,别对整个 union 裸访问不共有的属性。
|
|
733
|
+
const bodyText = hasContent ? s.content : parsed && parsed.kind !== 'unknown' ? parsed.output : undefined;
|
|
653
734
|
const error = typeof s.error === 'string' ? s.error : undefined;
|
|
654
735
|
if (taskType === 'background_bash') {
|
|
655
736
|
const exitCode = typeof inner?.exitCode === 'number' ? inner.exitCode : undefined;
|
|
@@ -715,25 +796,13 @@ modelText) {
|
|
|
715
796
|
return null;
|
|
716
797
|
}
|
|
717
798
|
}
|
|
718
|
-
// ══════════════════════════════════════════════════════════════════════════════════════════════
|
|
719
|
-
// ⑥ E 层 —— 按工具名的富卡补位(TodoWrite / ReportFindings)
|
|
720
|
-
// ══════════════════════════════════════════════════════════════════════════════════════════════
|
|
721
|
-
/**
|
|
722
|
-
* #117a —— **模型发起**的后台 Bash 回执探测器(cli `engineBgShellPanelStore.detectEngineBgShellReceipt`
|
|
723
|
-
* 逐字)。引擎侧秒关这张卡、从不进壳的 LocalShellTask registry,只能从回执文案桥过去。
|
|
724
|
-
* 🔴 **刻意**要求 INPUT 上 `run_in_background === true`:ctrl+B 的 detach lane
|
|
725
|
-
* (「Command moved to background」)归 engineToolDetach 管(它的行生命周期是有意的 settle-on-detach),
|
|
726
|
-
* 在这里重复登记会长出双行。
|
|
727
|
-
* 判定在库、**执行留宿主**(面板 store 写入 + 宿主 run 映射)—— 走 chrome `bgshell_register` 臂。
|
|
728
|
-
*/
|
|
729
|
-
const BG_RECEIPT_ANCHOR = /^(?:Started in background|Command running in background|Command moved to background); task_id=([A-Za-z0-9_-]+)/;
|
|
730
799
|
export function detectEngineBgShellReceipt(rawInput, outputText) {
|
|
731
800
|
if (typeof outputText !== 'string')
|
|
732
801
|
return null;
|
|
733
802
|
const input = (rawInput ?? {});
|
|
734
803
|
if (input.run_in_background !== true)
|
|
735
804
|
return null;
|
|
736
|
-
const m =
|
|
805
|
+
const m = THREE_GEN_BG_RECEIPT_RE.exec(outputText);
|
|
737
806
|
if (!m?.[1])
|
|
738
807
|
return null;
|
|
739
808
|
const command = typeof input.command === 'string' ? input.command : '(engine bash)';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/typePins.ts — shared type-only "bidirectional exhaustiveness pin" primitive
|
|
3
|
+
* (REF-CC-145 / REF-CC-dup-12, P3 wave1 卡C-argv, 2026-08-01).
|
|
4
|
+
*
|
|
5
|
+
* 🔴 [2006] B-CC-2(2026-07-29):a `readonly X[]` annotation only proves "every element is a
|
|
6
|
+
* legal X" — it never proves the reverse ("every X has an element"). Add an eighth arm to a
|
|
7
|
+
* literal union and forget to add it to the matching const tuple and the compiler stays silent;
|
|
8
|
+
* the new arm is then silently dropped by whatever `Set`/`switch` consumes the tuple at runtime.
|
|
9
|
+
* `Covers<A, B>` is the door's single mint point: `Exclude<A, B> extends never` collapses to
|
|
10
|
+
* `never` exactly when "every member of A is also in B"; pinning it to `true` turns a violation
|
|
11
|
+
* into a compile-time red. Callers crib a pair per axis: `[Covers<A, B>, Covers<B, A>]`.
|
|
12
|
+
*
|
|
13
|
+
* type-only export: zero runtime cost, zero transitive dependency (the portability door's
|
|
14
|
+
* value-level closure scan strips type-only edges before walking the graph — see
|
|
15
|
+
* run-client-core-portability-test.mjs 头注 "①源码级传递闭包…剥 type-only").
|
|
16
|
+
*/
|
|
17
|
+
export type Covers<A, B> = Exclude<A, B> extends never ? true : never;
|
package/dist/typePins.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
* without React/AppState.
|
|
33
33
|
*/
|
|
34
34
|
import { hostEnv } from './hostEnv.js';
|
|
35
|
+
import { envFlagOff } from './envFlag.js';
|
|
35
36
|
/** STICKY L2 preset: latched ON by the `/effort ultracode` dial pick, OFF by any other effort pick. Module-level
|
|
36
37
|
* (one shell process = one session) — the same single-namespace assumption seamQuery's session state uses. */
|
|
37
38
|
let ultracodePreset = false;
|
|
@@ -87,10 +88,9 @@ export function workflowFromInput(humanInput) {
|
|
|
87
88
|
/** Env escape hatch for the deferred-Workflow factory default: `SEMA_WORKFLOW_DEFER=0/false/no/off` restores the
|
|
88
89
|
* pre-[1052] always-exposed shape (schema bytes back in the prefix). Anything else (incl. unset) = defer ON. */
|
|
89
90
|
export const WORKFLOW_DEFER_ENV = 'SEMA_WORKFLOW_DEFER';
|
|
91
|
+
/** 拼写集 = {@link envFlagOff}(REF-CC-141 dup-02 单源)。 */
|
|
90
92
|
function deferOptedOut(env) {
|
|
91
|
-
|
|
92
|
-
const s = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
|
|
93
|
-
return s === '0' || s === 'false' || s === 'no' || s === 'off';
|
|
93
|
+
return envFlagOff(env[WORKFLOW_DEFER_ENV]);
|
|
94
94
|
}
|
|
95
95
|
/**
|
|
96
96
|
* [1052]① 收官形(clay 裁 B 的 core deferred 机制件,cli 接线半场):Workflow「全局默认开但不暴露」——
|
|
@@ -138,10 +138,9 @@ function extraDeferFromEnv(env) {
|
|
|
138
138
|
.map((s) => s.trim())
|
|
139
139
|
.filter((s) => s.length > 0);
|
|
140
140
|
}
|
|
141
|
+
/** 拼写集 = {@link envFlagOff}(REF-CC-141 dup-02 单源)。 */
|
|
141
142
|
function lowFreqOptedOut(env) {
|
|
142
|
-
|
|
143
|
-
const s = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
|
|
144
|
-
return s === '0' || s === 'false' || s === 'no' || s === 'off';
|
|
143
|
+
return envFlagOff(env[DEFER_LOWFREQ_ENV]);
|
|
145
144
|
}
|
|
146
145
|
/**
|
|
147
146
|
* The FULL deferTools list for a request: the Workflow default-defer lane (activation sources, see
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* unrefTimer — 域词表-14 收编:「在没有 unref 的宿主(浏览器/桌面渲染进程)上不炸,在 Node 上
|
|
3
|
+
* 不阻止进程退出」这条可移植性不变量此前有 5 份各写各的手抄(三种写法:直接可选调用 /
|
|
4
|
+
* 先 `as unknown` 再可选调用 / 先 `typeof … === 'function'` 判断再可选调用)。本函数统一成一份。
|
|
5
|
+
*
|
|
6
|
+
* 🔴 这是**低层原语**,不是策略:本函数只统一「怎么调 unref」,不统一「该不该 unref」——
|
|
7
|
+
* 该不该 unref 是调用点的控制流判断,必须留在各处决定。域词表-13 定谳:被 await 的 race/budget
|
|
8
|
+
* 臂上的定时器绝不能 unref(会让进程在它 settle 前提前退出,RB-447 同形)——
|
|
9
|
+
* `agentsWireCaps.ts` 的 `awaitTaskAgentsWire` 那处是控制流臂而非后台保活豁免,**不调用本函数**。
|
|
10
|
+
*
|
|
11
|
+
* 泛型约束到定时器句柄型(`setTimeout`/`setInterval` 的回传值):本包 `"types": []` + 默认 DOM
|
|
12
|
+
* lib 下两者都是 `number`,Node 运行时实际回传 `Timeout` 对象——真身与编译期类型不一致正是
|
|
13
|
+
* `unref?.()` 需要可选调用的原因。约束此前是无约束 `<T>`,`unrefTimer(42)` / `unrefTimer(aPromise)`
|
|
14
|
+
* 这类明显打错调用点的用法会静默通过;收窄后这些误用编译期就报,而五个既有调用点(均传
|
|
15
|
+
* `setTimeout`/`setInterval` 的返回值)不受影响。
|
|
16
|
+
*/
|
|
17
|
+
type TimerLikeHandle = ReturnType<typeof setTimeout> | ReturnType<typeof setInterval>;
|
|
18
|
+
export declare function unrefTimer<T extends TimerLikeHandle>(t: T): T;
|
|
19
|
+
export {};
|
package/dist/workflow.d.ts
CHANGED
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
* [1617] 幽灵行家族的判别资产。
|
|
19
19
|
*/
|
|
20
20
|
/** 复合行键(`<runId> <taskId>`,fleet-bus fleetRunPublisher.childId)的尾段 = 引擎 taskId。
|
|
21
|
-
* 导出给壳侧 belt 半场复用(判据②③ 的行 id 归一)
|
|
22
|
-
*
|
|
21
|
+
* 导出给壳侧 belt 半场复用(判据②③ 的行 id 归一)。REF-CC-042(fleet2-04,P3 wave2):
|
|
22
|
+
* `fleetAgentPanelProjection.ts` 曾就地维护同语义私有副本(理由是「保持零依赖」,但该文件早已
|
|
23
|
+
* import 了 `engineAgentPanelStore.js`,前提本就不成立)——已改 import 本函数,单源。 */
|
|
23
24
|
export declare function rowIdTail(id: string): string;
|
|
24
25
|
/** core 1.356 BCE 合成 workflow-agent id 形:wa+16hex(判据①)。
|
|
25
26
|
* 真实 fleet 子行 id 是 `${runId} ${engineTaskId}` 复合形——必须取空白分隔尾段再匹配
|
package/dist/workflow.js
CHANGED
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
* [1617] 幽灵行家族的判别资产。
|
|
19
19
|
*/
|
|
20
20
|
/** 复合行键(`<runId> <taskId>`,fleet-bus fleetRunPublisher.childId)的尾段 = 引擎 taskId。
|
|
21
|
-
* 导出给壳侧 belt 半场复用(判据②③ 的行 id 归一)
|
|
22
|
-
*
|
|
21
|
+
* 导出给壳侧 belt 半场复用(判据②③ 的行 id 归一)。REF-CC-042(fleet2-04,P3 wave2):
|
|
22
|
+
* `fleetAgentPanelProjection.ts` 曾就地维护同语义私有副本(理由是「保持零依赖」,但该文件早已
|
|
23
|
+
* import 了 `engineAgentPanelStore.js`,前提本就不成立)——已改 import 本函数,单源。 */
|
|
23
24
|
export function rowIdTail(id) {
|
|
24
25
|
return id.split(/\s+/).pop() ?? id;
|
|
25
26
|
}
|
package/dist/workflowClient.d.ts
CHANGED
|
@@ -45,6 +45,13 @@ export interface LiveWorkflowConfig {
|
|
|
45
45
|
principal: string;
|
|
46
46
|
/** explicit workflow run id; when absent the source picks the first RUNNING run from list() (else the first). */
|
|
47
47
|
workflowId?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Test/host injection seam for the underlying HTTP transport (mirrors `EngineWireClientConfig.fetchImpl`
|
|
50
|
+
* on `makeEngineWireClient` — same purpose, forwarded verbatim). Absent ⇒ the SDK's real `fetch`. Lets a
|
|
51
|
+
* deterministic fake transport drive `noteDegrade`'s branches without a real socket (REF-CC-153 regression
|
|
52
|
+
* coverage).
|
|
53
|
+
*/
|
|
54
|
+
fetchImpl?: typeof fetch;
|
|
48
55
|
}
|
|
49
56
|
/** THE projector: SDK `WorkflowRun` (client.workflows.get) → the monitor's `WorkflowRunState`. Pure/total —
|
|
50
57
|
* tolerates absent/permissive fields and never throws (the graceful-degrade contract lives above, in the
|