@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
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Renamed from **`@sema-agent/wire-cc-adapter`** (0.1.x, deprecated — see *Migra
|
|
|
23
23
|
|
|
24
24
|
## Scope
|
|
25
25
|
|
|
26
|
-
**Version:** 0.
|
|
26
|
+
**Version:** 0.13.0
|
|
27
27
|
|
|
28
28
|
- **Today** — the adapter seam, the whole `adapt()` pipeline (all 14 A-layer arms plus the
|
|
29
29
|
B/D/E tool-card layers), the notification/caps/model families, the adapter kernel (stream driver
|
|
@@ -203,6 +203,13 @@ npm test # = node scripts/run-client-core-all-gates.mjs — runs every suite b
|
|
|
203
203
|
absent) does not short-circuit the ones after it, and the runner prints the three-part verdict
|
|
204
204
|
itself (FAILED names + skipped names + arithmetic reconciliation). All-SKIP reports exit 3, never 0.
|
|
205
205
|
|
|
206
|
+
The suite set is a **name-equality gate**, not a lower bound: the runner cross-checks what it finds
|
|
207
|
+
on disk against `scripts/gates-manifest.json` in both directions. A registered suite that is missing
|
|
208
|
+
is red (a guard was deleted or renamed); a suite on disk that is not registered is red (whoever
|
|
209
|
+
added it skipped the registration). Adding a guard is therefore three actions in one commit — the
|
|
210
|
+
`run-*-test.mjs` file, its row in `gates-manifest.json`, and its row in the table below (the
|
|
211
|
+
public-surface guard checks that last one).
|
|
212
|
+
|
|
206
213
|
| Suite | What it guards |
|
|
207
214
|
|---|---|
|
|
208
215
|
| `scripts/run-client-core-pure-test.mjs` | Consumer-view behaviour of every moved-in module; segment floors (B1–B8 + C) that only move up |
|
|
@@ -218,7 +225,13 @@ itself (FAILED names + skipped names + arithmetic reconciliation). All-SKIP repo
|
|
|
218
225
|
| `scripts/run-fleet-view-keys-test.mjs` | The fleet projection views, **both directions**: `FleetTaskView`/`FleetWorkflowView` ⇄ their key lists (compile-pinned) ⇄ what a maximal/minimal row really projects, plus a wire-key coverage ledger (every `FleetTaskRow` key is either projected or carries a written reason why not) and a drift ledger against the shell's render contract. A one-directional assignability check is blind to optional keys — which is how `startedAt` was silently dropped |
|
|
219
226
|
| `scripts/run-usage-verbatim-channel-test.mjs` | The two complementary usage disciplines (core 3.0.0 metering semantics): the CC `ModelUsage` mirror stays pure (five pinned keys, `totalInputTokens` has no seat), while the sema-owned channel forwards the engine `turn_end.usage` object **verbatim** (six keys, incl. `totalInputTokens`) via `last_turn_usage.engineUsage` / `handle.latestEngineUsage` — honest absence on pre-3.0.0 engines, no fabricated zeros |
|
|
220
227
|
| `scripts/run-plan-review-decide-verify-test.mjs` | `decidePlanReview`'s post-decide honesty ([2315]/[2316], engine RB-471 family): a 2xx from the decide endpoint is **not** a terminal — the wire re-pulls the task status and words the outcome by the real shape (still-locked / legal new gate / genuinely left park / unverified), never claiming success it hasn't earned. Driven against a real fake-engine HTTP server through the shipped dist |
|
|
221
|
-
| `scripts/run-
|
|
228
|
+
| `scripts/run-shell-gate-durable-allow-test.mjs` | #110: the durable approval leg for **shell** gates. The tool_end HOLD/REJECT predicate must cover Bash the same way park detection already does (otherwise the park poison frame `Operation aborted` hits the transcript, `endedCalls` swallows the real replayed result, and the user who pressed Yes watches a command that really ran be reported as aborted); a replayed, already-decided park must resume reading the stream instead of being reported as a failed turn; `lastEventId` must track numeric `seq` too. Mutation-proven: each of the three fixes reverted turns the gate red |
|
|
229
|
+
| `scripts/run-public-surface-test.mjs` | The outward promises: the npm export surface baseline (an **exact set**, both directions — a new export that never entered the baseline is one nobody watched leave, and deleting it later would not be red), the peer floor witness, and this README's claims |
|
|
230
|
+
| `scripts/run-client-core-message-branching-test.mjs` | §B8 (branching on error **text**) and §B10 (truthiness standing in for existence when the value can be `0`). AST + type-checker census over `src/`, a named ALLOW list carrying owner and expiry, a known-site floor, and two fixed corpora with a known verdict judged by the same classifier on every run |
|
|
231
|
+
| `scripts/run-client-core-failloud-test.mjs` | §C1/§C2: an empty `catch` with no comment anywhere inside it, a pure-swallow `catch` nobody reasoned about, and `void <write>` that really returns a Promise with no `.catch`. The exemption instrument is a comment saying why *this* failure may die; the documented-swallow count is a ratchet that only goes down |
|
|
232
|
+
| `scripts/run-client-core-typeshape-test.mjs` | Type discipline as a guard rather than a build side effect: the set of enabled strict knobs (one silently switched off is red), `tsc --noEmit`, and export-surface ratchets for inline anonymous shapes (≥3 members), `unknown` leaving the surface, and bare `unknown` returns — zero slack in either direction |
|
|
233
|
+
| `scripts/run-client-core-singleton-test.mjs` | Module-level singletons ⇄ `docs/refactor/p1-scan/singleton-manifest.json`, **both directions**: an unregistered singleton is red (registering it forces someone to answer "what if this got duplicated"), a stale entry is red, and the `dupRisk: high` count only goes down |
|
|
234
|
+
| `scripts/run-abortable-sleep-test.mjs` | The shared `abortableSleep(ms, signal)` leaf (consumed by `workflowClient.ts` and `agentSession/backgroundView.ts`'s poll backoff): normal timeout resolution, immediate wake-up on `abort` mid-wait, `clearTimeout` really firing on that path, and a post-resolve late abort staying a no-op |
|
|
222
235
|
|
|
223
236
|
Each suite carries a floor that only moves up — a refactor that stops executing a group of
|
|
224
237
|
assertions is a failure, not a quieter pass. Guards anchor on the **installed artefact's content**
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* abortableSleep.ts — REF-CC-147(域词表-17)+ REF-CC-149(域词表-21)裁定的落地面:P2 裁决
|
|
3
|
+
* (docs/refactor/P2-LEDGER-DRAFT.md「I族」)明确 D 族(8 处轮询/重试/看门狗循环)不收编成通用
|
|
4
|
+
* poller——循环体裁/终止量/节拍语义/失败后是否继续/abort 归属/谁持有状态六个维度互不兼容,
|
|
5
|
+
* 统一后正确性核心会消失在配置参数里。**只抽两个低层原语**,这是其中之一(另一个是
|
|
6
|
+
* unrefTimer/TimersPort 接线,见 host.ts):统一「怎么安全地睡一觉」,不统一「该睡多久/睡完
|
|
7
|
+
* 干什么」——退避曲线、终止预算这些策略维度仍各自留在调用点。
|
|
8
|
+
*
|
|
9
|
+
* 原实现 = agentSession/backgroundView.ts 的私有 `sleep()`(D 族六处循环里唯一做对「dispose
|
|
10
|
+
* 必须唤醒在飞的等待」这条不变量的一处,P1 lexicon 镜头点名「全仓最佳形」)。workflowClient.ts
|
|
11
|
+
* 的 `sleep()` 此前是裸 `new Promise(r => setTimeout(r, ms))`——不感知 abort:dispose() 只置位
|
|
12
|
+
* `disposed`/abort 掉 AbortController,但正在等待的这一轮 sleep 不会被唤醒,后果两条:
|
|
13
|
+
* ① consume() 循环在 dispose 后最多还会多跑一轮(sleep 到期才重新检查 `!disposed` 退出);
|
|
14
|
+
* ② 那个未被清理的 setTimeout 在 Node 上继续维持事件循环存活,把 headless `-p` 车道的进程退出
|
|
15
|
+
* 拖慢最多一个退避周期(当前三处退避常量的最大值,见 workflowClient.ts 的 *_BACKOFF_MS)。
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* abort 感知的 sleep:到点正常 resolve;`signal` 在等待期间被 abort 时立即 resolve 并清掉
|
|
19
|
+
* 定时器——不留悬挂 timer 拖住宿主进程。调用方的循环在下一轮入口自会读到 `signal.aborted`
|
|
20
|
+
* 并退出,本函数只负责「别让等待本身变成一个新的悬挂句柄」,不负责终止判断。
|
|
21
|
+
*
|
|
22
|
+
* 入口先查 `signal.aborted`(wave1 回炉修:此前只在等待期间监听 'abort' 事件——若 signal
|
|
23
|
+
* 在**调用前**就已 aborted,事件早已派发完毕,`addEventListener('abort', …)` 上的 listener
|
|
24
|
+
* 永不触发,函数会退化成裸 `setTimeout` 照睡满整个 `ms` 并留一个未清的句柄,这正是本文件要
|
|
25
|
+
* 消灭的那个病,只是窗口从「sleep 期间 abort」挪到了「abort 后才进 sleep」。可达路径见
|
|
26
|
+
* workflowClient.ts 的 527→529→530:dispose 掐在一次 GET 在飞时,catch 会原样返回上一轮的
|
|
27
|
+
* `degraded=true`,回到 consume() 循环拿到的正是一个已 aborted 的 signal。
|
|
28
|
+
*/
|
|
29
|
+
export declare function abortableSleep(ms: number, signal: AbortSignal): Promise<void>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* abortableSleep.ts — REF-CC-147(域词表-17)+ REF-CC-149(域词表-21)裁定的落地面:P2 裁决
|
|
3
|
+
* (docs/refactor/P2-LEDGER-DRAFT.md「I族」)明确 D 族(8 处轮询/重试/看门狗循环)不收编成通用
|
|
4
|
+
* poller——循环体裁/终止量/节拍语义/失败后是否继续/abort 归属/谁持有状态六个维度互不兼容,
|
|
5
|
+
* 统一后正确性核心会消失在配置参数里。**只抽两个低层原语**,这是其中之一(另一个是
|
|
6
|
+
* unrefTimer/TimersPort 接线,见 host.ts):统一「怎么安全地睡一觉」,不统一「该睡多久/睡完
|
|
7
|
+
* 干什么」——退避曲线、终止预算这些策略维度仍各自留在调用点。
|
|
8
|
+
*
|
|
9
|
+
* 原实现 = agentSession/backgroundView.ts 的私有 `sleep()`(D 族六处循环里唯一做对「dispose
|
|
10
|
+
* 必须唤醒在飞的等待」这条不变量的一处,P1 lexicon 镜头点名「全仓最佳形」)。workflowClient.ts
|
|
11
|
+
* 的 `sleep()` 此前是裸 `new Promise(r => setTimeout(r, ms))`——不感知 abort:dispose() 只置位
|
|
12
|
+
* `disposed`/abort 掉 AbortController,但正在等待的这一轮 sleep 不会被唤醒,后果两条:
|
|
13
|
+
* ① consume() 循环在 dispose 后最多还会多跑一轮(sleep 到期才重新检查 `!disposed` 退出);
|
|
14
|
+
* ② 那个未被清理的 setTimeout 在 Node 上继续维持事件循环存活,把 headless `-p` 车道的进程退出
|
|
15
|
+
* 拖慢最多一个退避周期(当前三处退避常量的最大值,见 workflowClient.ts 的 *_BACKOFF_MS)。
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* abort 感知的 sleep:到点正常 resolve;`signal` 在等待期间被 abort 时立即 resolve 并清掉
|
|
19
|
+
* 定时器——不留悬挂 timer 拖住宿主进程。调用方的循环在下一轮入口自会读到 `signal.aborted`
|
|
20
|
+
* 并退出,本函数只负责「别让等待本身变成一个新的悬挂句柄」,不负责终止判断。
|
|
21
|
+
*
|
|
22
|
+
* 入口先查 `signal.aborted`(wave1 回炉修:此前只在等待期间监听 'abort' 事件——若 signal
|
|
23
|
+
* 在**调用前**就已 aborted,事件早已派发完毕,`addEventListener('abort', …)` 上的 listener
|
|
24
|
+
* 永不触发,函数会退化成裸 `setTimeout` 照睡满整个 `ms` 并留一个未清的句柄,这正是本文件要
|
|
25
|
+
* 消灭的那个病,只是窗口从「sleep 期间 abort」挪到了「abort 后才进 sleep」。可达路径见
|
|
26
|
+
* workflowClient.ts 的 527→529→530:dispose 掐在一次 GET 在飞时,catch 会原样返回上一轮的
|
|
27
|
+
* `degraded=true`,回到 consume() 循环拿到的正是一个已 aborted 的 signal。
|
|
28
|
+
*/
|
|
29
|
+
export function abortableSleep(ms, signal) {
|
|
30
|
+
if (signal.aborted)
|
|
31
|
+
return Promise.resolve();
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
const timer = setTimeout(() => {
|
|
34
|
+
signal.removeEventListener('abort', onAbort);
|
|
35
|
+
resolve();
|
|
36
|
+
}, ms);
|
|
37
|
+
const onAbort = () => {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
resolve();
|
|
40
|
+
};
|
|
41
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapt/arms.ts — 15 条帧臂的**注册表**(A 族拆分 REF-CC-SPLIT-01 的臂表化半场)。
|
|
3
|
+
*
|
|
4
|
+
* 拆分前这是驱动壳里一个 600 行的 `switch (m.type)`。改成注册表之后:
|
|
5
|
+
* · 每条臂是一个具名 generator,`break` 变 `return`(语义逐条对位,`default:` 空臂 = 表里查不到);
|
|
6
|
+
* · 臂拿不到驱动壳的局部变量 —— 它要什么状态,必须写在自己的 deps 类型里。
|
|
7
|
+
*
|
|
8
|
+
* 🔴 表用 `Map` 而不是普通对象(codex verdict 3):对象表被 `{type:'__proto__'}` /
|
|
9
|
+
* `{type:'toString'}` 这种帧一命中就是原型污染(wire 帧是 UNTRUSTED 的开集)。
|
|
10
|
+
*
|
|
11
|
+
* 🔴 **两级 deps 是判别力本身,不是洁癖**(矩阵 §3.5):
|
|
12
|
+
* `ProjectionArmFn` 只吃 `{ctx, idOf}` —— 于是「这几条臂碰不到任何适配器状态」这件事从
|
|
13
|
+
* 注释里的断言变成**编译期事实**。全量注入(一个大 deps 喂所有臂)会让封闭性声明失去判别力,
|
|
14
|
+
* 那正是 A 族 codex 复审里 5/11 那次翻车的根因。
|
|
15
|
+
*
|
|
16
|
+
* 🔴 **7 组由输入帧顺序耦合的臂对**(codex verdict 3 的清单;源码级无顺序耦合 —— 每帧单键分发 +
|
|
17
|
+
* return,但**帧到达顺序**会改判别结果)。逐条点名在下面各臂的注释里,标记 `⟨帧序耦合 N/7⟩`:
|
|
18
|
+
* 1. assistant(开卡)→ task_progress(FIFO 猜父只认**已开**的卡)
|
|
19
|
+
* 2. assistant(Workflow 卡)→ task_progress(判据③ 认 seenWorkflowToolCallIds)
|
|
20
|
+
* 3. assistant(开卡)→ tool_end_result(没开过的卡,tool_end 直接丢)
|
|
21
|
+
* 4. task_progress(首 tick)→ tool_end_result(关卡 settle 只结**已发布**的行)
|
|
22
|
+
* 5. task_progress(首 tick,fire Start)→ task_notification(if-started 门)
|
|
23
|
+
* 6. retry_status(挂旗)→ 任一主 lane 内容帧(恢复即清)
|
|
24
|
+
* 7. turn_usage(endEmitted)→ result(`!endEmitted` 门决定 end 度量发不发第二遍)
|
|
25
|
+
*/
|
|
26
|
+
import type { AdapterContext, AdapterOutput } from '../seam.js';
|
|
27
|
+
import { type Frame, type IdOf } from './ids.js';
|
|
28
|
+
import type { AdapterInstanceLedger } from './instanceLedger.js';
|
|
29
|
+
import type { PanelTaskLedger } from './panelTasks.js';
|
|
30
|
+
import type { TextStream } from './textStream.js';
|
|
31
|
+
import type { ToolCardLedger } from './toolCards.js';
|
|
32
|
+
import type { TurnFlags } from './turnFlags.js';
|
|
33
|
+
/** 纯投影臂的 deps —— **零适配器状态**(类型即证明)。 */
|
|
34
|
+
export interface ProjectionArmDeps {
|
|
35
|
+
readonly ctx: AdapterContext;
|
|
36
|
+
readonly idOf: IdOf;
|
|
37
|
+
}
|
|
38
|
+
/** 有状态臂的 deps —— 矩阵 §3.5 收窄成的六件,不多给。 */
|
|
39
|
+
export interface ArmDeps extends ProjectionArmDeps {
|
|
40
|
+
readonly text: TextStream;
|
|
41
|
+
readonly cards: ToolCardLedger;
|
|
42
|
+
readonly panel: PanelTaskLedger;
|
|
43
|
+
readonly flags: TurnFlags;
|
|
44
|
+
readonly inst: AdapterInstanceLedger;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 只碰 `{ctx, idOf}` 的臂。`ProjectionArmFn` 可赋给 `ArmFn`(入参逆变),所以两级可以放同一张表,
|
|
48
|
+
* 而**声明成哪一级**就是那条臂的封闭性声明 —— 想碰状态就得改签名,改签名就在 diff 里显形。
|
|
49
|
+
* ⚠️ 判别力边界说清楚:它证明的是「碰不到 M1/M2/M3/M6/inst 五个**适配器状态**模块」,
|
|
50
|
+
* 不是「零副作用」—— `workflow_complete` 就是个例子,它写 notifications.ts 的 **module 台账**。
|
|
51
|
+
*/
|
|
52
|
+
export type ProjectionArmFn = (m: Frame, deps: ProjectionArmDeps) => Generator<AdapterOutput>;
|
|
53
|
+
export type ArmFn = (m: Frame, deps: ArmDeps) => Generator<AdapterOutput>;
|
|
54
|
+
/**
|
|
55
|
+
* 帧类型 → 臂。**Map 而不是对象字面量**:`{type:'__proto__'}` 这种 UNTRUSTED 帧命中对象表
|
|
56
|
+
* 就是原型污染(codex verdict 3)。表里查不到 = 拆分前 `switch` 的 `default:` 空臂,行为同。
|
|
57
|
+
*/
|
|
58
|
+
export declare const ARMS: ReadonlyMap<string, ArmFn>;
|