@deepseek-ai/dsh-session-projection-cache 0.1.2-alpha.5 → 0.1.3-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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/session/session-projection-cache/README.md
5
- README.md: 9fd9766d75ab3f9a460b2802ac59810839f21ae4
6
- README.zh.md: 98725d9ce76ab44821adf3d43e3807932cf6b675
5
+ README.md: ba90e838763787d28e5b6e278d868504fc672c5f
6
+ README.zh.md: 8b3fe4148d408af75194212e4787a7cdb9030507
package/README.md CHANGED
@@ -58,13 +58,13 @@ Three mandatory points always write: session creation persists the seed-derived
58
58
 
59
59
  ### Reading cached values
60
60
 
61
- `cachedSnapshot(meta, inheritedEventCount)` synchronously serves client values from the storage domain's in-memory tables with zero I/O. It accepts only an identity-matching record and version- and schema-matching keys, then returns a `{ asOfSeq, values }` cut at the lowest served-row watermark. An unseeded listing knows that its cut is zero; a seeded header-only listing does not know the numeric cut and must skip this fast path until an authoritative body read supplies it. `coldSnapshot(meta, inheritedEventCount, events)` accepts the exact cut with a complete ordered log, skips the checkpointed prefix while folding, and refreshes the record without reading persistence itself.
61
+ `cachedSnapshot(meta, inheritedEventCount)` synchronously serves client values from the storage domain's in-memory tables with zero I/O. It accepts only an identity-matching record and version- and schema-matching keys, then returns a `{ asOfSeq, values }` cut at the lowest served-row watermark. `cachedPredecessorTitle(meta, inheritedEventCount)` is the narrower listing-only exception: a structurally admitted predecessor record whose lifecycle matches may expose only a current-version-compatible `title` row. The title is a possibly stale fact from a durable prefix, not a fold seed; it carries the sentinel `asOfSeq: -1` because a cardinality-changing Session migration can invalidate the predecessor row's numeric sequence. All other predecessor rows remain unavailable. An unseeded listing knows that its cut is zero; a seeded header-only listing does not know the numeric cut and skips both fast paths until an authoritative body read supplies it. `coldSnapshot(meta, inheritedEventCount, events)` accepts the exact cut with a complete ordered log, skips the checkpointed prefix while folding, and refreshes the record without reading persistence itself.
62
62
 
63
63
  ### What the cache guarantees
64
64
 
65
- The log leads and the cache follows: a live checkpoint flushes the session's buffered events durably before the cache row lands, so a crash can leave the cache behind the log but never ahead of it. Reads and writes share the storage domain's coherent in-memory state; the per-unit write chain mutates memory only after durability. Each version-stamped record must match the live unit schema and complete lifecycle identity (`createdAt`, `cwd`, `isSeeded`, and `inheritedEventCount`), so a row initialized under one fork cut cannot seed another. The JSON backend stores each record at `<root>/session_projcache/sessions/<id>.json` in an owner-only directory tree.
65
+ The log leads and the cache follows: a live checkpoint flushes the session's buffered events durably before the cache row lands, so a crash can leave the cache behind the log but never ahead of it. Reads and writes share the storage domain's coherent in-memory state; the per-unit write chain mutates memory only after durability. Each version-stamped record must match the live unit schema and complete lifecycle identity (`formatVersion`, `createdAt`, `cwd`, `isSeeded`, and `inheritedEventCount`), so a row folded from another Session format generation or fork cut cannot seed the caller. The JSON backend stores each record at `<root>/session_projcache/sessions/<id>.json` in an owner-only directory tree.
66
66
 
67
- Upgrades never cost the boot or the listing: records stamped with a version in the spec's `compatibleVersions` stay readable (their absent lineage fields decode as the unseeded lineage — exact for unseeded sessions, while a seeded caller fails the identity match and refolds cold), and a stored record that still fails schema validation is moved aside as `<id>.json.bak.<stamp>` under the domain's `invalidRecords: 'backup-and-skip'` policy, logged with its cause, and rebuilt by the next checkpoint.
67
+ Upgrades never cost the boot or expose an unproven fold. Records stamped with a version in the spec's `compatibleVersions` remain structurally readable for a current checkpoint rewrite, but a missing or older `formatVersion` never matches a current Session and therefore cannot seed hydration. A lifecycle-matching predecessor title remains available only through the listing hint above because title text is invariant across the adjacent Session-format edges and its row still passes the current projection `stateVersion` and schema. Once the format matches, absent lineage fields decode as the unseeded lineage — exact for unseeded sessions, while a seeded caller fails the identity match and refolds cold. A stored record that still fails schema validation is moved aside as `<id>.json.bak.<stamp>` under the domain's `invalidRecords: 'backup-and-skip'` policy, logged with its cause, and rebuilt by the next checkpoint.
68
68
 
69
69
  -----
70
70
 
package/README.zh.md CHANGED
@@ -58,13 +58,13 @@ kind: "package-reference"
58
58
 
59
59
  ### 读取缓存值
60
60
 
61
- `cachedSnapshot(meta, inheritedEventCount)` 以零 I/O 从存储域的内存表同步提供客户端值。它只接受身份匹配的记录以及版本和 schema 均匹配的 key,再按所服务行的最低水位返回 `{ asOfSeq, values }` 切面。未 seeded 的列表知道切点为零;仅 header 的 seeded 列表不知道数字切点,必须跳过该快速路径,直到权威正文读取提供它。`coldSnapshot(meta, inheritedEventCount, events)` 接受精确切点与完整有序日志,在折叠时跳过已检查点化的前缀,并在自身不读取持久化层的情况下刷新记录。
61
+ `cachedSnapshot(meta, inheritedEventCount)` 以零 I/O 从存储域的内存表同步提供客户端值。它只接受身份匹配的记录以及版本和 schema 均匹配的 key,再按所服务行的最低水位返回 `{ asOfSeq, values }` 切面。`cachedPredecessorTitle(meta, inheritedEventCount)` 是更窄的列表专用例外:生命周期匹配且已通过结构准入的 predecessor record 只能公开与当前版本兼容的 `title` row。该 title 是 durable prefix 中可能过时的事实,而不是 fold seed;它携带 sentinel `asOfSeq: -1`,因为改变事件数量的 Session 迁移会使 predecessor row 的数字序号失效。其他 predecessor row 仍不可用。未 seeded 的列表知道切点为零;仅 header 的 seeded 列表不知道数字切点,因此两条快速路径都要跳过,直到权威正文读取提供它。`coldSnapshot(meta, inheritedEventCount, events)` 接受精确切点与完整有序日志,在折叠时跳过已检查点化的前缀,并在自身不读取持久化层的情况下刷新记录。
62
62
 
63
63
  ### 缓存保证什么
64
64
 
65
- 日志领先,缓存跟随:实时检查点先把会话的缓冲事件持久化,然后才保存缓存记录。因此崩溃可能让缓存落后于日志,但绝不会让缓存领先。读取和写入共享存储域内一致的内存状态;逐单元写入链只在持久化成功后修改内存。每个带版本戳的记录必须匹配实时单元 schema 与完整生命周期身份(`createdAt`、`cwd`、`isSeeded` 和 `inheritedEventCount`),因此在一个 fork 切点下初始化的行不能播种另一个切点。JSON 后端把每条记录存于仅所有者可访问的 `<root>/session_projcache/sessions/<id>.json` 目录树中。
65
+ 日志领先,缓存跟随:实时检查点先把会话的缓冲事件持久化,然后才保存缓存记录。因此崩溃可能让缓存落后于日志,但绝不会让缓存领先。读取和写入共享存储域内一致的内存状态;逐单元写入链只在持久化成功后修改内存。每个带版本戳的记录必须匹配实时单元 schema 与完整生命周期身份(`formatVersion`、`createdAt`、`cwd`、`isSeeded` 和 `inheritedEventCount`),因此从另一会话格式代或 fork 切点折叠出的行不能播种调用方。JSON 后端把每条记录存于仅所有者可访问的 `<root>/session_projcache/sessions/<id>.json` 目录树中。
66
66
 
67
- 升级绝不拖垮启动或列表:版本戳落在 spec `compatibleVersions` 集合内的记录保持可读(缺失的 lineage 字段解码为 unseeded lineage——对非 fork 会话精确无误,seeded 调用方则通不过身份比对、回落冷折叠),而仍然通不过 schema 校验的存量记录会按域的 `invalidRecords: 'backup-and-skip'` 策略移出为 `<id>.json.bak.<时间戳>`、连同原因写入日志,并由下一次检查点重建。
67
+ 升级绝不拖垮启动,也不会暴露未经证明的折叠结果。版本戳落在 spec `compatibleVersions` 集合内的记录仍可被结构化读取并等待当前检查点重写,但缺失或更旧的 `formatVersion` 绝不匹配当前 Session,因此不能作为 hydrate seed。生命周期匹配的 predecessor title 只能通过上述列表 hint 读取,因为 title 文本在相邻 Session format edge 之间保持不变,并且该 row 仍须通过当前 projection `stateVersion` 与 schema。格式匹配后,缺失的 lineage 字段解码为 unseeded lineage——对非 fork 会话精确无误,seeded 调用方则通不过身份比对、回落冷折叠。仍然通不过 schema 校验的存量记录会按域的 `invalidRecords: 'backup-and-skip'` 策略移出为 `<id>.json.bak.<时间戳>`、连同原因写入日志,并由下一次检查点重建。
68
68
 
69
69
  -----
70
70
 
package/lib/index.js CHANGED
@@ -38,14 +38,15 @@ const checkpointRow = z$1.object({
38
38
  * unrelated log. Reads validate this against the live header (listing) or
39
39
  * the stored header (cold read) before accepting any record.
40
40
  *
41
- * The lineage fields are optional because records admitted through
42
- * `compatibleVersions` predate them. The reader (`identityMatches`)
43
- * interprets their absence as the unseeded lineage exact for an unseeded
44
- * session, while a seeded expectation fails the match and the record is
45
- * discarded to a cold rebuild. Current-version writes always store both
41
+ * The format and lineage fields are optional because records admitted through
42
+ * `compatibleVersions` predate them. The reader (`identityMatches`) refuses an
43
+ * absent format generation because no current Session log can prove that
44
+ * record's fold semantics. It interprets absent lineage as unseeded only after
45
+ * the format generation matches. Current-version writes always store all three
46
46
  * fields.
47
47
  */
48
48
  const checkpointIdentity = z$1.object({
49
+ formatVersion: z$1.number().int().nonnegative().optional(),
49
50
  createdAt: z$1.number().int().nonnegative(),
50
51
  cwd: z$1.string().optional(),
51
52
  isSeeded: z$1.boolean().optional(),
@@ -67,15 +68,18 @@ const checkpointRecord = z$1.object({
67
68
  * open (cache semantics — a stale or unreadable cache costs a longer tail
68
69
  * replay, never a wrong value) while the rest of the domain stays usable,
69
70
  * instead of rejecting the whole medium. The `compatibleVersions` entries
70
- * are declared because those records differ from the current version only
71
- * by the absent optional lineage fields, so upgraded homes keep serving
72
- * their cached listing projections instead of dropping every title until
73
- * each session is reopened; the per-record version map lives in the
74
- * read-compat Agent Note
71
+ * keep structurally valid predecessor records available for a later current
72
+ * checkpoint rewrite. Records without `formatVersion` remain unusable as fold
73
+ * shortcuts because they cannot prove which Session event semantics produced
74
+ * their rows; the per-record version map and disposition live in the read-compat Agent Note
75
75
  * (.agents/notes/implemented/architecture/2026-09-02-projcache-cross-version-read-compat.md).
76
76
  * The per-row `ver` guard and the identity match still discard anything the
77
77
  * current fold semantics cannot vouch for.
78
78
  *
79
+ * A lifecycle-matching predecessor may still expose its version-compatible
80
+ * title through the cache service's listing-only hint; this never relaxes the
81
+ * format requirement for hydration or another fold shortcut.
82
+ *
79
83
  * `invalidRecords: 'backup-and-skip'`: a stored record that fails the schema
80
84
  * anyway is disposable derived data, so it must never cost the boot — the
81
85
  * domain layer moves the document aside as `<key>.json.bak.<stamp>`, logs
@@ -84,8 +88,13 @@ const checkpointRecord = z$1.object({
84
88
  */
85
89
  const projectionCacheDomainSpec = defineDomain({
86
90
  name: "session_projcache",
87
- version: 5,
88
- compatibleVersions: [3, 4],
91
+ version: 7,
92
+ compatibleVersions: [
93
+ 3,
94
+ 4,
95
+ 5,
96
+ 6
97
+ ],
89
98
  invalidRecords: "backup-and-skip",
90
99
  layout: "per-record",
91
100
  tables: { sessions: domainTable(checkpointRecord) }
@@ -109,6 +118,7 @@ const projectionCacheDomainSpec = defineDomain({
109
118
  * (.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md).
110
119
  * @module @deepseek-ai/dsh-session-projection-cache
111
120
  */
121
+ const PREDECESSOR_TITLE_KEY = "title";
112
122
  const Config = z.object({
113
123
  writeEveryEvents: z.natural().min(1).required(),
114
124
  writeIntervalMs: z.natural().min(1).required()
@@ -178,16 +188,46 @@ var SessionProjectionCache = class extends Service {
178
188
  cachedSnapshot(meta, inheritedEventCount, keys) {
179
189
  const record = this.recordFor(meta.id, identityOf(meta, inheritedEventCount));
180
190
  if (record === void 0) return void 0;
191
+ return this.viewRecord(record, keys);
192
+ }
193
+ /**
194
+ * Read only a predecessor checkpoint's title as a zero-I/O listing hint.
195
+ *
196
+ * The authoritative Session header supplies the lifecycle identity. A cache
197
+ * checkpoint can lag that log but cannot lead it because writes flush the
198
+ * log first, so a matching predecessor title is a genuine (possibly stale)
199
+ * fact from this Session. The registry still requires the current title
200
+ * projection's row version and schema. No other predecessor projection is
201
+ * exposed: format normalization can change their current meaning, and the
202
+ * strict {@link cachedSnapshot} / hydration paths continue to reject them.
203
+ * @param meta - authoritative listed Session header.
204
+ * @param inheritedEventCount - exact inherited cut completing the lifecycle identity.
205
+ * @returns a title-only checkpoint view with `asOfSeq: -1`, or `undefined`
206
+ * when the record is current, newer, unrelated, missing, or incompatible
207
+ * with the title unit. The sentinel avoids reusing a sequence that a
208
+ * cardinality-changing Session migration may have remapped.
209
+ */
210
+ cachedPredecessorTitle(meta, inheritedEventCount) {
211
+ const expected = identityOf(meta, inheritedEventCount);
212
+ const record = this.requireTable().get(meta.id);
213
+ if (record === void 0 || !predecessorIdentityMatches(record.identity, expected)) return void 0;
214
+ const title = this.viewRecord(record, [PREDECESSOR_TITLE_KEY]);
215
+ return title === void 0 ? void 0 : {
216
+ ...title,
217
+ asOfSeq: -1
218
+ };
219
+ }
220
+ /** View selected wire rows and bind them to their lowest served watermark. */
221
+ viewRecord(record, keys) {
181
222
  const values = this.ctx.sessionProjections.viewCheckpoint(record.rows, keys);
182
223
  const servedKeys = Object.keys(values);
183
224
  if (servedKeys.length === 0) return void 0;
184
- let asOfSeq;
185
- for (const key of servedKeys) {
225
+ const firstKey = servedKeys[0];
226
+ let asOfSeq = record.rows[firstKey].seq;
227
+ for (const key of servedKeys.slice(1)) {
186
228
  const row = record.rows[key];
187
- if (row !== void 0 && (asOfSeq === void 0 || row.seq < asOfSeq)) asOfSeq = row.seq;
229
+ if (row.seq < asOfSeq) asOfSeq = row.seq;
188
230
  }
189
- /* v8 ignore next -- A nonempty checkpoint view contains a stored row for every returned key. */
190
- if (asOfSeq === void 0) return void 0;
191
231
  return {
192
232
  asOfSeq,
193
233
  values
@@ -322,6 +362,7 @@ function identityOf(header, inheritedEventCount) {
322
362
  const cut = SessionLogOffset(inheritedEventCount);
323
363
  if (!header.isSeeded && cut !== 0) throw new Error("unseeded projection-cache identity inherited event count must be 0");
324
364
  return {
365
+ formatVersion: header.version,
325
366
  createdAt: header.createdAt,
326
367
  ...header.cwd === void 0 ? {} : { cwd: header.cwd },
327
368
  isSeeded: header.isSeeded,
@@ -330,12 +371,20 @@ function identityOf(header, inheritedEventCount) {
330
371
  }
331
372
  /**
332
373
  * Whether a stored record's bound identity names the caller's lifecycle.
333
- * Absent lineage fields (records admitted via `compatibleVersions` predate
334
- * them) read as the unseeded lineage: exact for an unseeded caller, and a
335
- * seeded caller's expectation then fails the match, discarding the record to
336
- * a cold rebuild.
374
+ * An absent format generation cannot prove the fold semantics and never
375
+ * matches. Once the format matches, absent lineage fields (records admitted
376
+ * via `compatibleVersions` predate them) read as the unseeded lineage: exact
377
+ * for an unseeded caller, while a seeded caller fails the match.
337
378
  */
338
379
  function identityMatches(stored, expected) {
380
+ return stored.formatVersion === expected.formatVersion && lifecycleIdentityMatches(stored, expected);
381
+ }
382
+ /** Match one predecessor cache record to the authoritative listed lifecycle. */
383
+ function predecessorIdentityMatches(stored, expected) {
384
+ return (stored.formatVersion === void 0 || stored.formatVersion < expected.formatVersion) && lifecycleIdentityMatches(stored, expected);
385
+ }
386
+ /** Match the format-independent fields that distinguish one Session lifecycle. */
387
+ function lifecycleIdentityMatches(stored, expected) {
339
388
  return stored.createdAt === expected.createdAt && stored.cwd === expected.cwd && (stored.isSeeded ?? false) === expected.isSeeded && (stored.inheritedEventCount ?? 0) === expected.inheritedEventCount;
340
389
  }
341
390
  //#endregion
@@ -88,6 +88,26 @@ export declare class SessionProjectionCache extends Service {
88
88
  * `undefined` when no usable row exists for this lifecycle.
89
89
  */
90
90
  cachedSnapshot(meta: SessionHeader, inheritedEventCount: SessionLogOffset, keys?: readonly Extract<keyof SessionProjectionMap, string>[]): ProjectionSnapshot | undefined;
91
+ /**
92
+ * Read only a predecessor checkpoint's title as a zero-I/O listing hint.
93
+ *
94
+ * The authoritative Session header supplies the lifecycle identity. A cache
95
+ * checkpoint can lag that log but cannot lead it because writes flush the
96
+ * log first, so a matching predecessor title is a genuine (possibly stale)
97
+ * fact from this Session. The registry still requires the current title
98
+ * projection's row version and schema. No other predecessor projection is
99
+ * exposed: format normalization can change their current meaning, and the
100
+ * strict {@link cachedSnapshot} / hydration paths continue to reject them.
101
+ * @param meta - authoritative listed Session header.
102
+ * @param inheritedEventCount - exact inherited cut completing the lifecycle identity.
103
+ * @returns a title-only checkpoint view with `asOfSeq: -1`, or `undefined`
104
+ * when the record is current, newer, unrelated, missing, or incompatible
105
+ * with the title unit. The sentinel avoids reusing a sequence that a
106
+ * cardinality-changing Session migration may have remapped.
107
+ */
108
+ cachedPredecessorTitle(meta: SessionHeader, inheritedEventCount: SessionLogOffset): ProjectionSnapshot | undefined;
109
+ /** View selected wire rows and bind them to their lowest served watermark. */
110
+ private viewRecord;
91
111
  /**
92
112
  * Hydrate projection cells for an already-prepared Session without another
93
113
  * persistence read. The cache seeds matching rows; the supplied exact log
@@ -34,14 +34,15 @@ export declare const checkpointRow: z.ZodObject<{
34
34
  * unrelated log. Reads validate this against the live header (listing) or
35
35
  * the stored header (cold read) before accepting any record.
36
36
  *
37
- * The lineage fields are optional because records admitted through
38
- * `compatibleVersions` predate them. The reader (`identityMatches`)
39
- * interprets their absence as the unseeded lineage exact for an unseeded
40
- * session, while a seeded expectation fails the match and the record is
41
- * discarded to a cold rebuild. Current-version writes always store both
37
+ * The format and lineage fields are optional because records admitted through
38
+ * `compatibleVersions` predate them. The reader (`identityMatches`) refuses an
39
+ * absent format generation because no current Session log can prove that
40
+ * record's fold semantics. It interprets absent lineage as unseeded only after
41
+ * the format generation matches. Current-version writes always store all three
42
42
  * fields.
43
43
  */
44
44
  export declare const checkpointIdentity: z.ZodObject<{
45
+ formatVersion: z.ZodOptional<z.ZodNumber>;
45
46
  createdAt: z.ZodNumber;
46
47
  cwd: z.ZodOptional<z.ZodString>;
47
48
  isSeeded: z.ZodOptional<z.ZodBoolean>;
@@ -57,6 +58,7 @@ export type CheckpointIdentity = z.infer<typeof checkpointIdentity>;
57
58
  */
58
59
  export declare const checkpointRecord: z.ZodObject<{
59
60
  identity: z.ZodObject<{
61
+ formatVersion: z.ZodOptional<z.ZodNumber>;
60
62
  createdAt: z.ZodNumber;
61
63
  cwd: z.ZodOptional<z.ZodString>;
62
64
  isSeeded: z.ZodOptional<z.ZodBoolean>;
@@ -76,15 +78,18 @@ export type CheckpointRecord = z.infer<typeof checkpointRecord>;
76
78
  * open (cache semantics — a stale or unreadable cache costs a longer tail
77
79
  * replay, never a wrong value) while the rest of the domain stays usable,
78
80
  * instead of rejecting the whole medium. The `compatibleVersions` entries
79
- * are declared because those records differ from the current version only
80
- * by the absent optional lineage fields, so upgraded homes keep serving
81
- * their cached listing projections instead of dropping every title until
82
- * each session is reopened; the per-record version map lives in the
83
- * read-compat Agent Note
81
+ * keep structurally valid predecessor records available for a later current
82
+ * checkpoint rewrite. Records without `formatVersion` remain unusable as fold
83
+ * shortcuts because they cannot prove which Session event semantics produced
84
+ * their rows; the per-record version map and disposition live in the read-compat Agent Note
84
85
  * (.agents/notes/implemented/architecture/2026-09-02-projcache-cross-version-read-compat.md).
85
86
  * The per-row `ver` guard and the identity match still discard anything the
86
87
  * current fold semantics cannot vouch for.
87
88
  *
89
+ * A lifecycle-matching predecessor may still expose its version-compatible
90
+ * title through the cache service's listing-only hint; this never relaxes the
91
+ * format requirement for hydration or another fold shortcut.
92
+ *
88
93
  * `invalidRecords: 'backup-and-skip'`: a stored record that fails the schema
89
94
  * anyway is disposable derived data, so it must never cost the boot — the
90
95
  * domain layer moves the document aside as `<key>.json.bak.<stamp>`, logs
@@ -101,6 +106,7 @@ export declare const projectionCacheDomainSpec: {
101
106
  sessions: import("@deepseek-ai/dsh-storage-domain").DomainTableSpec<SessionId, {
102
107
  identity: {
103
108
  createdAt: number;
109
+ formatVersion?: number | undefined;
104
110
  cwd?: string | undefined;
105
111
  isSeeded?: boolean | undefined;
106
112
  inheritedEventCount?: SessionLogOffset | undefined;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-session-projection-cache",
3
3
  "description": "Persisted projection cache (ctx.sessionProjectionCache): durable per-session checkpoint records on the session_projcache storage domain (per-record layout), throttled write-behind, and the cached listing read",
4
- "version": "0.1.2-alpha.5",
4
+ "version": "0.1.3-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -28,21 +28,21 @@
28
28
  "license": "MIT",
29
29
  "dependencies": {
30
30
  "zod": "^4.4.3",
31
- "@deepseek-ai/dsh-util-values": "^0.1.2-alpha.5",
31
+ "@deepseek-ai/dsh-util-values": "^0.1.3-alpha.2",
32
32
  "@deepseek-ai/schemastery": "^3.18.2"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@deepseek-ai/cordis": "^4.0.2",
36
- "@deepseek-ai/dsh-session": "^0.1.2-alpha.5",
37
- "@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.5",
38
- "@deepseek-ai/dsh-storage-domain": "^0.1.2-alpha.5"
36
+ "@deepseek-ai/dsh-session-projection": "^0.1.3-alpha.2",
37
+ "@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
38
+ "@deepseek-ai/dsh-storage-domain": "^0.1.3-alpha.2"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@deepseek-ai/cordis": "^4.0.2",
42
- "@deepseek-ai/dsh-session": "^0.1.2-alpha.5",
43
- "@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.5",
44
- "@deepseek-ai/dsh-storage": "^0.1.2-alpha.5",
45
- "@deepseek-ai/dsh-storage-json": "^0.1.2-alpha.5",
46
- "@deepseek-ai/dsh-storage-domain": "^0.1.2-alpha.5"
42
+ "@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
43
+ "@deepseek-ai/dsh-session-projection": "^0.1.3-alpha.2",
44
+ "@deepseek-ai/dsh-storage": "^0.1.3-alpha.2",
45
+ "@deepseek-ai/dsh-storage-domain": "^0.1.3-alpha.2",
46
+ "@deepseek-ai/dsh-storage-json": "^0.1.3-alpha.2"
47
47
  }
48
48
  }