dsh-session-bridge 0.3.2-alpha.1 → 0.3.2-alpha.2
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 +18 -2
- package/README.zh.md +11 -0
- package/dsh.plugin.json +1 -1
- package/lib/index.js +33 -27
- package/package.json +1 -1
- package/scripts/check-dsh-compat.mjs +53 -1
- package/src/core.ts +12 -4
package/README.md
CHANGED
|
@@ -131,10 +131,13 @@ That checkout frequently lags the harness the plugin is loaded into, so a green
|
|
|
131
131
|
`build.sh` does **not** prove the plugin works on the running DSH — `build.sh`
|
|
132
132
|
warns when the two versions differ. Use `npm run check:compat` for that: it
|
|
133
133
|
type-checks `src/` against the `lib/types/*.d.ts` shipped inside the installed
|
|
134
|
-
DSH package,
|
|
134
|
+
DSH package, then reads the built `lib/index.js.map` to verify the
|
|
135
|
+
self-contained bundle actually inlined that same DSH version. (Type-checking
|
|
136
|
+
alone is not enough — a stale checkout type-checks green while the artifact
|
|
137
|
+
ships old DSH code.)
|
|
135
138
|
|
|
136
139
|
The GitHub Actions CI (`ci.yml`) instead resolves the `@deepseek-ai/dsh-*`
|
|
137
|
-
prereleases from the registry — pinned to the `0.1.6-alpha.
|
|
140
|
+
prereleases from the registry — pinned to the `0.1.6-alpha.2` line, which is
|
|
138
141
|
the DSH API surface this code targets — then runs `pnpm typecheck` and
|
|
139
142
|
`pnpm build:client` (the self-contained `tsdown` bundle). Bump that pin
|
|
140
143
|
together with the code when you migrate to a newer DSH API.
|
|
@@ -276,6 +279,19 @@ scripts/
|
|
|
276
279
|
build.sh type-check + link types against the DSH checkout
|
|
277
280
|
```
|
|
278
281
|
|
|
282
|
+
## Lifecycle and unloading
|
|
283
|
+
|
|
284
|
+
DSH ≥ 0.1.6 mounts and **unloads plugins at runtime** (Settings → Plugins, and
|
|
285
|
+
the injector's hot reload). This plugin unloads cleanly: it registers no
|
|
286
|
+
loader-level state, its tools are disposed with the plugin fiber, and the
|
|
287
|
+
monitor's timer is released through `ctx.effect` on unload.
|
|
288
|
+
|
|
289
|
+
One consequence of that ownership model: sessions created by
|
|
290
|
+
`session_bridge_create` are owned by the plugin fiber (the agent is created
|
|
291
|
+
under the plugin's context), so **unloading or reloading the plugin stops their
|
|
292
|
+
live agents**. The sessions themselves are persisted and show as offline; bring
|
|
293
|
+
one back with `session_bridge_resume`. Monitor watchdogs also stop on unload.
|
|
294
|
+
|
|
279
295
|
## License
|
|
280
296
|
|
|
281
297
|
MIT
|
package/README.zh.md
CHANGED
|
@@ -224,6 +224,17 @@ scripts/
|
|
|
224
224
|
build.sh 类型检查 + 链接 DSH checkout 类型
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
+
## 生命周期与卸载
|
|
228
|
+
|
|
229
|
+
DSH ≥ 0.1.6 支持**运行时挂载/卸载**插件(设置 → 插件页开关、注入器热重载)。
|
|
230
|
+
本插件可干净卸载:不注册 loader 级状态,工具随插件 fiber 一并释放,监控定时器
|
|
231
|
+
经 `ctx.effect` 在卸载时清理。
|
|
232
|
+
|
|
233
|
+
该所有权模型带来一个后果:`session_bridge_create` 创建的会话归插件 fiber 所有
|
|
234
|
+
(agent 在插件上下文下创建),因此**卸载/重载插件会停止这些会话的活动 agent**。
|
|
235
|
+
会话本身已持久化并显示为离线,可用 `session_bridge_resume` 重新上线;守护循环
|
|
236
|
+
同样在卸载时停止。
|
|
237
|
+
|
|
227
238
|
## License
|
|
228
239
|
|
|
229
240
|
MIT
|
package/dsh.plugin.json
CHANGED
package/lib/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { homedir } from "node:os";
|
|
|
4
4
|
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { appendFileSync, mkdirSync } from "node:fs";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-home-paths@0.1.6-alpha.
|
|
7
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-home-paths@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-home-paths/lib/index.js
|
|
8
8
|
/**
|
|
9
9
|
* Shared filesystem path helpers for DeepSeek Harness user data.
|
|
10
10
|
*
|
|
@@ -2200,7 +2200,7 @@ var Service = class Service {
|
|
|
2200
2200
|
}
|
|
2201
2201
|
};
|
|
2202
2202
|
//#endregion
|
|
2203
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-typert-protocol@0.1.6-alpha.
|
|
2203
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-typert-protocol@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-typert-protocol/lib/index.js
|
|
2204
2204
|
/** The one Remote failure class shared by owners, the Gateway, and consumers. */
|
|
2205
2205
|
/**
|
|
2206
2206
|
* One Remote call failure: a real Error carrying its stable code and typed
|
|
@@ -2345,7 +2345,7 @@ function validateName(subject, value) {
|
|
|
2345
2345
|
if (!isTypertRemoteSegment(value)) throw new TypeError(`typert-protocol: ${subject} must contain only RPC endpoint segment characters`);
|
|
2346
2346
|
}
|
|
2347
2347
|
//#endregion
|
|
2348
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-values@0.1.6-alpha.
|
|
2348
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-values@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-util-values/lib/index.js
|
|
2349
2349
|
/** Duplicate-install-safe JSON and immutable-value helpers. @module @deepseek-ai/dsh-util-values */
|
|
2350
2350
|
/**
|
|
2351
2351
|
* Mark an unreachable closed-union branch.
|
|
@@ -2557,7 +2557,7 @@ function deepFreeze(value) {
|
|
|
2557
2557
|
return value;
|
|
2558
2558
|
}
|
|
2559
2559
|
//#endregion
|
|
2560
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-crypto@0.1.6-alpha.
|
|
2560
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-crypto@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-util-crypto/lib/index.js
|
|
2561
2561
|
/**
|
|
2562
2562
|
* Random v4 UUID, minted from `crypto.getRandomValues`.
|
|
2563
2563
|
* @returns the UUID string.
|
|
@@ -2570,7 +2570,7 @@ function randomUUID$1() {
|
|
|
2570
2570
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
2571
2571
|
}
|
|
2572
2572
|
//#endregion
|
|
2573
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-brand@0.1.6-alpha.
|
|
2573
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-brand@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-brand/lib/index.js
|
|
2574
2574
|
/**
|
|
2575
2575
|
* Duplicate-install-safe nominal primitive helpers.
|
|
2576
2576
|
*
|
|
@@ -3187,11 +3187,11 @@ defineMethod("transform", [
|
|
|
3187
3187
|
"preserve"
|
|
3188
3188
|
], ({ inner }, isInner) => inner.toString(isInner));
|
|
3189
3189
|
//#endregion
|
|
3190
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-timeout@0.1.6-alpha.
|
|
3190
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-timeout@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-timeout/lib/index.js
|
|
3191
3191
|
/** Largest delay Node schedules without clamping it to one millisecond. */
|
|
3192
3192
|
const MAX_TIMER_DELAY_MS = 2147483647;
|
|
3193
3193
|
//#endregion
|
|
3194
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-llm@0.1.6-alpha.
|
|
3194
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-llm@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-llm/lib/index.js
|
|
3195
3195
|
/**
|
|
3196
3196
|
* Bound one `notice` summary to {@link CONTEXT_SUMMARY_MAX_CHARS}.
|
|
3197
3197
|
* @param summary - the producer's one-line account, of any length.
|
|
@@ -3957,7 +3957,8 @@ var LlmError = class extends HarnessError {
|
|
|
3957
3957
|
id: model.id,
|
|
3958
3958
|
...model.name === void 0 ? {} : { name: model.name },
|
|
3959
3959
|
...model.contextWindow === void 0 ? {} : { contextWindow: model.contextWindow },
|
|
3960
|
-
...model.maxTokens === void 0 ? {} : { maxTokens: model.maxTokens }
|
|
3960
|
+
...model.maxTokens === void 0 ? {} : { maxTokens: model.maxTokens },
|
|
3961
|
+
...model.inputModalities === void 0 ? {} : { inputModalities: [...model.inputModalities] }
|
|
3961
3962
|
});
|
|
3962
3963
|
}
|
|
3963
3964
|
return models;
|
|
@@ -9080,7 +9081,7 @@ function superRefine(fn, params) {
|
|
|
9080
9081
|
return /* @__PURE__ */ _superRefine(fn, params);
|
|
9081
9082
|
}
|
|
9082
9083
|
//#endregion
|
|
9083
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-storage@0.1.6-alpha.
|
|
9084
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-storage@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-storage/lib/index.js
|
|
9084
9085
|
/**
|
|
9085
9086
|
* Backend-facing vocabulary of the storage hub: a backend owns one medium
|
|
9086
9087
|
* (a file-tree root, a database file) and exposes operation groups over it.
|
|
@@ -9091,7 +9092,7 @@ function superRefine(fn, params) {
|
|
|
9091
9092
|
/** Allowed format for unit and table names: safe as a file name and as a SQL identifier segment without escaping. */
|
|
9092
9093
|
const UNIT_NAME_RE = /^[a-z][a-z0-9_]*$/;
|
|
9093
9094
|
//#endregion
|
|
9094
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-storage-domain@0.1.6-alpha.
|
|
9095
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-storage-domain@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+ds_5fa439225de576bdb2338dd42cd57e82/node_modules/@deepseek-ai/dsh-storage-domain/lib/index.js
|
|
9095
9096
|
/**
|
|
9096
9097
|
* Domain declaration vocabulary. A spec object is the single source of a
|
|
9097
9098
|
* domain's identity, layout, and record schemas: the owning package defines
|
|
@@ -9214,11 +9215,19 @@ Service.init;
|
|
|
9214
9215
|
*/
|
|
9215
9216
|
/**
|
|
9216
9217
|
* 兼容读取不同 dsh-session 版本上的会话事件:
|
|
9217
|
-
* - 旧版
|
|
9218
|
-
* -
|
|
9219
|
-
*
|
|
9220
|
-
*
|
|
9218
|
+
* - 旧版 \`Session\` 暴露 \`get events(): readonly SessionEvent[]\`;
|
|
9219
|
+
* - 新版将 \`get events\` 改为 \`snapshotEvents(fromSeq?, toSeqExclusive?)\` 方法——
|
|
9220
|
+
* \`.events\` 直接读取会得到 \`undefined\`,对 for...of 迭代即抛
|
|
9221
|
+
* \`events is not iterable\`。
|
|
9221
9222
|
* 两者都读不到(或 session 不存在)时回退为空数组,绝不抛迭代错误。
|
|
9223
|
+
*
|
|
9224
|
+
* 注意:dsh 0.1.6-alpha.1 起 \`snapshotEvents()\`(连同 \`eventAt()\` /
|
|
9225
|
+
* \`ownEvents()\`)已标记 @deprecated —— 官方策略是"现有逻辑可暂不迁移,但禁止
|
|
9226
|
+
* 新增调用";其替代不是同步读,而是(a)恢复后读取 Session 投影/派生状态,或
|
|
9227
|
+
* (b)按需异步分页读取历史窗口(见 dsh 决策
|
|
9228
|
+
* 2026-09-09-deprecate-synchronous-session-event-reads)。本函数的调用方
|
|
9229
|
+
* (foldMessages / segmentsSince / wait 基线)仍依赖完整同步快照,故按该决定暂缓
|
|
9230
|
+
* 迁移;将来官方补齐分页读后,只需改造这一个入口。
|
|
9222
9231
|
*/
|
|
9223
9232
|
function sessionEvents(session) {
|
|
9224
9233
|
const s = session;
|
|
@@ -10041,7 +10050,7 @@ var SessionMonitor = class {
|
|
|
10041
10050
|
}
|
|
10042
10051
|
};
|
|
10043
10052
|
//#endregion
|
|
10044
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-scope@0.1.6-alpha.
|
|
10053
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-scope@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+dsh-invaria_8802cbeca2a66ef97a5b4e663664f4cd/node_modules/@deepseek-ai/dsh-scope/lib/index.js
|
|
10045
10054
|
/**
|
|
10046
10055
|
* Shared insertion-ordered storage and effect ownership for scope-aware registries.
|
|
10047
10056
|
*
|
|
@@ -10320,7 +10329,7 @@ function scopeTarget(base, key) {
|
|
|
10320
10329
|
return carrier;
|
|
10321
10330
|
}
|
|
10322
10331
|
//#endregion
|
|
10323
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-sandbox@0.1.6-alpha.
|
|
10332
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-sandbox@0.1.6-alpha.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+dsh-llm@0_5328c6913d63e98a7878ca36cab93ca2/node_modules/@deepseek-ai/dsh-sandbox/lib/index.js
|
|
10324
10333
|
/**
|
|
10325
10334
|
* The escalation vocabulary and choreography shared by every sandbox-enforcing
|
|
10326
10335
|
* tool family (`@deepseek-ai/dsh-tool-bash`, `@deepseek-ai/dsh-tool-fs`): the
|
|
@@ -10371,21 +10380,18 @@ function validateEscalationArgs(sandboxPermissions, justification) {
|
|
|
10371
10380
|
if (justification !== void 0 && justification.trim().length === 0) throw new Error("invalid justification: expected a non-empty sentence");
|
|
10372
10381
|
}
|
|
10373
10382
|
/**
|
|
10374
|
-
* Resolve a sandbox
|
|
10375
|
-
*
|
|
10376
|
-
*
|
|
10377
|
-
*
|
|
10378
|
-
*
|
|
10379
|
-
* non-widening request, a missing approval service, an agent-less execution,
|
|
10380
|
-
* a rejection, a cancellation, an unanswerable ask) — the tool registry turns
|
|
10381
|
-
* the throw into the call's isError result, and nothing has run. A
|
|
10382
|
-
* non-widening request never prompts a human.
|
|
10383
|
+
* Resolve a sandbox permission request before execution. Repeating the call's
|
|
10384
|
+
* effective mode returns it without approval. A strictly wider mode requires
|
|
10385
|
+
* approval and applies only to this call. Narrower or unsupported targets,
|
|
10386
|
+
* missing approval services or agents for widening, and non-grant outcomes
|
|
10387
|
+
* throw before execution.
|
|
10383
10388
|
* @param request - the escalation to judge (see {@link EscalationRequest}).
|
|
10384
10389
|
* @param approval - the approval ingredients the tool holds (see {@link EscalationApproval}).
|
|
10385
10390
|
* @returns the granted mode, consumed by the one call that asked.
|
|
10386
10391
|
*/
|
|
10387
10392
|
async function approveEscalation(request, approval) {
|
|
10388
10393
|
const { requestedMode: mode, effectiveMode, justification, subject } = request;
|
|
10394
|
+
if (mode === effectiveMode) return effectiveMode;
|
|
10389
10395
|
if (!(WIDER_MODES[effectiveMode] ?? []).includes(mode)) throw new Error(`sandbox escalation to "${mode}" is not strictly wider than this call's current "${effectiveMode}" mode`);
|
|
10390
10396
|
if (approval.approver === void 0) throw new Error(`sandbox escalation to "${mode}" requires approval, but no approval service is composed`);
|
|
10391
10397
|
if (approval.agent === void 0) throw new Error(`sandbox escalation to "${mode}" requires approval, but the call has no agent to route it through`);
|
|
@@ -10405,7 +10411,7 @@ async function approveEscalation(request, approval) {
|
|
|
10405
10411
|
}
|
|
10406
10412
|
}
|
|
10407
10413
|
//#endregion
|
|
10408
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-tools@0.1.6-alpha.
|
|
10414
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-tools@0.1.6-alpha.2_e8d664b8446198a3dac4043bd11091d7/node_modules/@deepseek-ai/dsh-tools/lib/index.js
|
|
10409
10415
|
/**
|
|
10410
10416
|
* Enforced JSON Schema subset shared by tool outputs, generated PTC mode
|
|
10411
10417
|
* types, subagents, and workflows. The subset accepts any JSON root, an
|
|
@@ -14018,7 +14024,7 @@ function toolAbortedBeforeDispatchResult(prior) {
|
|
|
14018
14024
|
};
|
|
14019
14025
|
}
|
|
14020
14026
|
//#endregion
|
|
14021
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-agent@0.1.6-alpha.
|
|
14027
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-agent@0.1.6-alpha.2_44110910133b3cc261ea9dfdcaed39ee/node_modules/@deepseek-ai/dsh-agent/lib/index.js
|
|
14022
14028
|
/**
|
|
14023
14029
|
* Agent-scoped model selection shared by runtime entry points.
|
|
14024
14030
|
* @module @deepseek-ai/dsh-agent/model-selection
|
package/package.json
CHANGED
|
@@ -118,6 +118,44 @@ function dshVersionOf(scopeDir) {
|
|
|
118
118
|
return undefined
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Inspect the built tsdown bundle's source map for the DSH version it INLINED.
|
|
123
|
+
*
|
|
124
|
+
* `check:compat` type-checks src/ against the installed harness, but src/ is not
|
|
125
|
+
* what loads: lib/index.js is a self-contained bundle that inlines every
|
|
126
|
+
* @deepseek-ai/* import. A stale checkout therefore type-checks green while the
|
|
127
|
+
* artifact ships old DSH code (observed: checkout 0.1.5-alpha.2 / host
|
|
128
|
+
* 0.1.6-alpha.2). This reads the map's sources — a checkout path names the root
|
|
129
|
+
* whose package.json carries the version; a .pnpm path encodes it.
|
|
130
|
+
*
|
|
131
|
+
* @returns { versions: Set<string>, roots: Set<string> } or undefined when no map exists.
|
|
132
|
+
*/
|
|
133
|
+
function artifactProvenance() {
|
|
134
|
+
const mapPath = join(ROOT, 'lib', 'index.js.map')
|
|
135
|
+
if (!existsSync(mapPath)) return undefined
|
|
136
|
+
let map
|
|
137
|
+
try { map = JSON.parse(readFileSync(mapPath, 'utf8')) } catch { return undefined }
|
|
138
|
+
const versions = new Set()
|
|
139
|
+
const roots = new Set()
|
|
140
|
+
for (const source of Array.isArray(map.sources) ? map.sources : []) {
|
|
141
|
+
if (typeof source !== 'string') continue
|
|
142
|
+
// Source checkout: <root>/packages/... or <root>/vendor/... (relative to the map in lib/).
|
|
143
|
+
const checkout = source.match(/^(.*?)[/\\](?:packages|vendor)[/\\]/)
|
|
144
|
+
if (checkout !== null) { roots.add(resolve(ROOT, 'lib', checkout[1])); continue }
|
|
145
|
+
// Registry install: .../.pnpm/@deepseek-ai+<name>@<version>[_hash]/node_modules/...
|
|
146
|
+
const registry = source.match(/[\\/]\.pnpm[\\/]@deepseek-ai\+[a-z0-9-]+@([^\\/]+)[\\/]node_modules/)
|
|
147
|
+
if (registry !== null) {
|
|
148
|
+
const version = registry[1].replace(/_.*$/, '')
|
|
149
|
+
if (/^\d/.test(version)) versions.add(version)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
for (const root of roots) {
|
|
153
|
+
const manifest = readJson(join(root, 'package.json'))
|
|
154
|
+
if (typeof manifest?.version === 'string') versions.add(manifest.version)
|
|
155
|
+
}
|
|
156
|
+
return { versions, roots }
|
|
157
|
+
}
|
|
158
|
+
|
|
121
159
|
const dshVersion = dshVersionOf(scope) ?? '(unknown)'
|
|
122
160
|
|
|
123
161
|
// Every DSH package src/ imports, plus the plain `cordis` specifier that
|
|
@@ -170,4 +208,18 @@ if (failure !== undefined) {
|
|
|
170
208
|
const status = typeof failure.status === 'number' ? ' (tsc exit ' + failure.status + ')' : ''
|
|
171
209
|
fail('src/ does NOT type-check against installed dsh ' + dshVersion + status + ' — this is a real incompatibility with the running harness.')
|
|
172
210
|
}
|
|
173
|
-
console.log('check-dsh-compat: OK — src/ type-checks against installed dsh ' + dshVersion)
|
|
211
|
+
console.log('check-dsh-compat: OK — src/ type-checks against installed dsh ' + dshVersion)
|
|
212
|
+
|
|
213
|
+
const provenance = artifactProvenance()
|
|
214
|
+
if (provenance === undefined) {
|
|
215
|
+
console.log('check-dsh-compat: no lib/index.js.map — skipping bundle provenance check (run pnpm build:client to enable it)')
|
|
216
|
+
} else if (provenance.versions.size === 0) {
|
|
217
|
+
console.log('check-dsh-compat: bundle provenance not resolvable from the source map — skipped')
|
|
218
|
+
} else {
|
|
219
|
+
const inlined = [...provenance.versions].sort().join(', ')
|
|
220
|
+
console.log('check-dsh-compat: lib/index.js inlined DSH ' + inlined + ' (from ' + provenance.roots.size + ' checkout(s) / registry entries)')
|
|
221
|
+
if (dshVersion !== '(unknown)' && !(provenance.versions.size === 1 && provenance.versions.has(dshVersion))) {
|
|
222
|
+
fail('the built lib/index.js inlines DSH ' + inlined + ' but the installed harness is ' + dshVersion
|
|
223
|
+
+ ' — rebuild the bundle against the running harness (a stale checkout type-checks green while shipping old DSH code).')
|
|
224
|
+
}
|
|
225
|
+
}
|
package/src/core.ts
CHANGED
|
@@ -64,11 +64,19 @@ export interface BridgeFindItem {
|
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
66
|
* 兼容读取不同 dsh-session 版本上的会话事件:
|
|
67
|
-
* - 旧版
|
|
68
|
-
* -
|
|
69
|
-
*
|
|
70
|
-
*
|
|
67
|
+
* - 旧版 \`Session\` 暴露 \`get events(): readonly SessionEvent[]\`;
|
|
68
|
+
* - 新版将 \`get events\` 改为 \`snapshotEvents(fromSeq?, toSeqExclusive?)\` 方法——
|
|
69
|
+
* \`.events\` 直接读取会得到 \`undefined\`,对 for...of 迭代即抛
|
|
70
|
+
* \`events is not iterable\`。
|
|
71
71
|
* 两者都读不到(或 session 不存在)时回退为空数组,绝不抛迭代错误。
|
|
72
|
+
*
|
|
73
|
+
* 注意:dsh 0.1.6-alpha.1 起 \`snapshotEvents()\`(连同 \`eventAt()\` /
|
|
74
|
+
* \`ownEvents()\`)已标记 @deprecated —— 官方策略是"现有逻辑可暂不迁移,但禁止
|
|
75
|
+
* 新增调用";其替代不是同步读,而是(a)恢复后读取 Session 投影/派生状态,或
|
|
76
|
+
* (b)按需异步分页读取历史窗口(见 dsh 决策
|
|
77
|
+
* 2026-09-09-deprecate-synchronous-session-event-reads)。本函数的调用方
|
|
78
|
+
* (foldMessages / segmentsSince / wait 基线)仍依赖完整同步快照,故按该决定暂缓
|
|
79
|
+
* 迁移;将来官方补齐分页读后,只需改造这一个入口。
|
|
72
80
|
*/
|
|
73
81
|
export function sessionEvents(session: unknown): readonly SessionEvent[] {
|
|
74
82
|
const s = session as {
|