dsh-ptc-plus 0.4.1 → 0.4.3

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.
Files changed (103) hide show
  1. package/README.en.md +164 -78
  2. package/README.md +165 -79
  3. package/assets/dsh-ptc-plus-banner-en.webp +0 -0
  4. package/assets/dsh-ptc-plus-banner-zh.webp +0 -0
  5. package/assets/ptc-plus-icon.svg +5 -0
  6. package/client.js +854 -336
  7. package/compiler-core.cjs +161 -157
  8. package/compiler-core.cjs.map +3 -3
  9. package/docs/README.md +4 -1
  10. package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +8 -7
  11. package/docs/adr/0008-define-agent-operating-contract.md +2 -2
  12. package/docs/adr/0010-session-log-derived-recovery-tips.md +7 -0
  13. package/docs/adr/0016-archive-resolved-review-findings.md +3 -3
  14. package/docs/adr/0019-plugin-settings-and-kill-switch.md +3 -3
  15. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -0
  16. package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +14 -3
  17. package/docs/adr/0023-global-user-bindings.md +7 -7
  18. package/docs/adr/0025-use-versioned-logical-binding-identities.md +3 -3
  19. package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +23 -7
  20. package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +9 -5
  21. package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +26 -6
  22. package/docs/adr/0031-close-semantic-obligations-by-owner.md +29 -0
  23. package/docs/adr/README.md +4 -4
  24. package/docs/architecture.md +15 -10
  25. package/docs/binding-review-placement-design.md +1 -1
  26. package/docs/client-ui.md +9 -5
  27. package/docs/durability-design.md +12 -9
  28. package/docs/installation.md +27 -9
  29. package/docs/runtime-reference.md +23 -12
  30. package/docs/semantic-validation.md +7 -3
  31. package/docs/stateful-binding-updates-proposal.md +8 -4
  32. package/docs/user-bindings.en.md +10 -7
  33. package/docs/user-bindings.md +9 -6
  34. package/docs/value-wire.md +1 -1
  35. package/docs/verification-optimization-work.md +41 -0
  36. package/docs/verification.md +53 -2
  37. package/index.js +39 -34
  38. package/internal/async-local-storage-intrinsics.js +43 -0
  39. package/internal/binding-declaration-contract.js +8 -0
  40. package/internal/binding-source-analysis.js +381 -64
  41. package/internal/binding-update-policy.js +7 -1
  42. package/internal/callable-source-facts.js +37 -1
  43. package/internal/cell-analysis.js +85 -17
  44. package/internal/compiler-intrinsics.js +9 -43
  45. package/internal/compiler-module-links.js +7 -4
  46. package/internal/config-spec.js +1 -1
  47. package/internal/cordis-tools-owner.js +20 -10
  48. package/internal/dynamic-environment-integration.js +8 -4
  49. package/internal/dynamic-environment-runtime.js +24 -3
  50. package/internal/dynamic-native-calls.js +4 -1
  51. package/internal/dynamic-native-runtime.js +15 -1
  52. package/internal/edit-transport-owner.js +80 -20
  53. package/internal/execution-seam-compat.js +192 -30
  54. package/internal/failure-reporting.js +38 -30
  55. package/internal/isolated-worker.js +17 -10
  56. package/internal/kernel-worker.js +645 -393
  57. package/internal/message-sources.js +14 -0
  58. package/internal/module-compilation.js +7 -5
  59. package/internal/module-transform-contract.js +32 -2
  60. package/internal/record-utils.js +24 -15
  61. package/internal/repl-memory-projection.js +10 -0
  62. package/internal/repl-scope-normalizer.js +72 -35
  63. package/internal/repl-value-observer.js +145 -46
  64. package/internal/runtime-config.js +62 -2
  65. package/internal/runtime-intrinsics.js +104 -0
  66. package/internal/runtime-messages.js +6 -4
  67. package/internal/session-cell-executor.js +26 -2
  68. package/internal/session-journal-recovery.js +267 -67
  69. package/internal/session-journal-schema.js +30 -13
  70. package/internal/session-journal.js +485 -44
  71. package/internal/session-log-view.js +5 -4
  72. package/internal/session-runtime.js +46 -21
  73. package/internal/session-state.js +7 -29
  74. package/internal/settings-compat.js +66 -1
  75. package/internal/source-position-map.js +38 -0
  76. package/internal/stateful-root-compiler.js +3 -1
  77. package/internal/typescript-transform.js +4 -2
  78. package/internal/user-binding-console-worker.js +115 -41
  79. package/internal/user-binding-draft-projection.js +3 -2
  80. package/internal/user-bindings-owner.js +2 -1
  81. package/internal/user-bindings.js +16 -3
  82. package/internal/validated-parse-repair.js +6 -2
  83. package/internal/value-wire.js +189 -94
  84. package/internal/worker-client.js +99 -8
  85. package/internal/worker-cwd-virtualization.js +82 -54
  86. package/internal/worker-environment.js +20 -0
  87. package/internal/worker-output-capture.js +187 -0
  88. package/internal/worker-output-fence.js +26 -0
  89. package/internal/worker-realm-surfaces.js +197 -0
  90. package/internal/worker-repl-realm.js +140 -0
  91. package/package.json +37 -4
  92. package/src/client-activity.js +12 -2
  93. package/src/client-authoring-view.js +121 -62
  94. package/src/client-console.js +4 -2
  95. package/src/client-copy.js +4 -2
  96. package/src/client-feature-gates.js +7 -9
  97. package/src/client-host-compat.js +104 -27
  98. package/src/client-repl-view.js +3 -1
  99. package/src/client-styles.js +12 -1
  100. package/src/client-tool-view.js +3 -1
  101. package/src/client-transport.js +2 -2
  102. package/src/client-workbench.js +4 -3
  103. package/src/client.js +56 -17
@@ -0,0 +1,197 @@
1
+ import { runtimeIntrinsics as internal } from './runtime-intrinsics.js'
2
+
3
+ const { Error, TypeError, includes, objectFreeze,
4
+ objectGetOwnPropertyDescriptor, objectHasOwn, toString, Reflect: privateReflect } = internal
5
+
6
+ export const WORKER_REALM_MUTATION = objectFreeze({
7
+ STABLE: 'stable-native-divergence',
8
+ TEMPORARY: 'temporary-compiler-name',
9
+ PROGRAM: 'per-cell-program-binding',
10
+ USER: 'user-declaration-binding',
11
+ RESTORE: 'restoration-only',
12
+ })
13
+
14
+ const MUTATION_CLASSES = objectFreeze([
15
+ WORKER_REALM_MUTATION.STABLE,
16
+ WORKER_REALM_MUTATION.TEMPORARY,
17
+ WORKER_REALM_MUTATION.PROGRAM,
18
+ WORKER_REALM_MUTATION.USER,
19
+ WORKER_REALM_MUTATION.RESTORE,
20
+ ])
21
+
22
+ export const PROCESS_CONTROL_ERROR_CODE = 'ERR_PTC_PROCESS_CONTROL'
23
+ export const WORKER_REALM_SURFACE_CONTRACT = objectFreeze([
24
+ objectFreeze({
25
+ surface: 'console',
26
+ owner: 'internal/kernel-worker.js and internal/user-binding-console-worker.js',
27
+ classification: WORKER_REALM_MUTATION.STABLE,
28
+ contract: 'native Console methods; output enters the per-cell log budget',
29
+ reference: 'plain Node worker console methods',
30
+ verification: 'console-methods',
31
+ }),
32
+ objectFreeze({
33
+ surface: 'process.stdout.write/process.stderr.write',
34
+ owner: 'internal/kernel-worker.js',
35
+ classification: WORKER_REALM_MUTATION.STABLE,
36
+ contract: 'captured per cell as writable own methods; direct descriptor output remains covered by the helper transport',
37
+ reference: 'plain Node worker stream descriptors',
38
+ verification: 'stream-descriptors',
39
+ }),
40
+ objectFreeze({
41
+ surface: 'process.cwd',
42
+ owner: 'internal/worker-cwd-virtualization.js',
43
+ classification: WORKER_REALM_MUTATION.STABLE,
44
+ contract: 'recorded cwd; immutable and non-configurable when a session cwd exists',
45
+ reference: 'plain Node worker process descriptor',
46
+ verification: 'cwd-descriptor',
47
+ }),
48
+ objectFreeze({
49
+ surface: 'cwd-projected Node builtins',
50
+ owner: 'internal/worker-cwd-virtualization.js',
51
+ classification: WORKER_REALM_MUTATION.STABLE,
52
+ contract: 'relative fs, path, and child-process calls use the recorded cwd while retaining callable descriptors',
53
+ reference: 'plain Node worker fs, fs/promises, path, and child_process callable descriptors',
54
+ verification: 'cwd-projected-builtins',
55
+ }),
56
+ objectFreeze({
57
+ surface: 'process.exit/abort/kill/chdir',
58
+ owner: 'internal/worker-realm-surfaces.js',
59
+ classification: WORKER_REALM_MUTATION.STABLE,
60
+ contract: `immutable lifecycle guards; failures use ${PROCESS_CONTROL_ERROR_CODE}`,
61
+ reference: 'plain Node worker process descriptors',
62
+ verification: 'process-controls',
63
+ }),
64
+ objectFreeze({
65
+ surface: 'fd 1/2 and inherited child output',
66
+ owner: 'internal/worker-client.js and internal/worker-output-capture.js',
67
+ classification: 'transport-boundary',
68
+ contract: 'captured in the acknowledged per-cell dual-stream fence window; out-of-round output resets the worker',
69
+ reference: 'helper stdout/stderr transport contract in ADR 0027',
70
+ verification: 'descriptor-output',
71
+ }),
72
+ objectFreeze({
73
+ surface: 'cell module metadata',
74
+ owner: 'internal/session-cell-executor.js and internal/kernel-worker.js and internal/user-binding-console-worker.js',
75
+ classification: WORKER_REALM_MUTATION.STABLE,
76
+ contract: 'current cells expose import.meta url/filename/dirname; require subset exists without ambient CommonJS wrapper globals',
77
+ reference: 'plain Node worker CommonJS surface and the session module parent',
78
+ verification: 'module-surface',
79
+ }),
80
+ objectFreeze({
81
+ surface: 'private AsyncLocalStorage receiver methods',
82
+ owner: 'internal/async-local-storage-intrinsics.js',
83
+ classification: WORKER_REALM_MUTATION.STABLE,
84
+ contract: 'immutable captured getStore, enterWith, and run methods on plugin-private receivers',
85
+ reference: 'the corresponding native AsyncLocalStorage methods bound to a fresh receiver',
86
+ verification: 'private-async-local-storage',
87
+ }),
88
+ objectFreeze({
89
+ surface: 'AsyncLocalStorage.prototype.run',
90
+ owner: 'internal/async-local-storage-intrinsics.js',
91
+ classification: WORKER_REALM_MUTATION.TEMPORARY,
92
+ contract: 'native at rest; synchronously replaced only during private REPL bootstrap',
93
+ reference: 'plain Node worker AsyncLocalStorage descriptors',
94
+ verification: 'async-local-storage',
95
+ }),
96
+ ])
97
+
98
+ function assertMutation(classification, surface) {
99
+ if (!includes(MUTATION_CLASSES, classification)) {
100
+ throw new TypeError(`unknown worker realm mutation classification: ${classification}`)
101
+ }
102
+ if (classification !== WORKER_REALM_MUTATION.STABLE) return
103
+ let registered = false
104
+ for (let index = 0; index < WORKER_REALM_SURFACE_CONTRACT.length; index += 1) {
105
+ const entry = WORKER_REALM_SURFACE_CONTRACT[index]
106
+ if (entry.surface === surface && entry.classification === classification) registered = true
107
+ }
108
+ if (!registered) {
109
+ throw new TypeError(`stable worker realm mutation requires a matching registered classification: ${surface}`)
110
+ }
111
+ }
112
+
113
+ /** The only supported write boundary for worker globals, process surfaces and native prototypes. */
114
+ export function defineWorkerRealmProperty(classification, surface, owner, property, descriptor) {
115
+ assertMutation(classification, surface)
116
+ if (!privateReflect.defineProperty(owner, property, descriptor)) {
117
+ throw new TypeError(`worker realm property ${toString(property)} could not be defined`)
118
+ }
119
+ return owner
120
+ }
121
+
122
+ export function assignWorkerRealmProperty(classification, surface, owner, property, value) {
123
+ assertMutation(classification, surface)
124
+ if (!privateReflect.set(owner, property, value)) {
125
+ throw new TypeError(`worker realm property ${toString(property)} could not be assigned`)
126
+ }
127
+ return value
128
+ }
129
+
130
+ export function deleteWorkerRealmProperty(classification, surface, owner, property) {
131
+ assertMutation(classification, surface)
132
+ return privateReflect.deleteProperty(owner, property)
133
+ }
134
+
135
+ function codedError(code, message) {
136
+ const error = new Error(message)
137
+ privateReflect.defineProperty(error, 'code', {
138
+ configurable: true,
139
+ enumerable: true,
140
+ writable: true,
141
+ value: code,
142
+ })
143
+ return error
144
+ }
145
+
146
+ export function installProjectedProcessCwd(processObject, cwd) {
147
+ defineWorkerRealmProperty(WORKER_REALM_MUTATION.STABLE, 'process.cwd', processObject, 'cwd', {
148
+ configurable: false,
149
+ enumerable: true,
150
+ writable: false,
151
+ value: () => cwd,
152
+ })
153
+ }
154
+
155
+ export function installProcessControlGuards(processObject, properties) {
156
+ for (let index = 0; index < properties.length; index += 1) {
157
+ const property = properties[index]
158
+ const descriptor = objectGetOwnPropertyDescriptor(processObject, property)
159
+ defineWorkerRealmProperty(
160
+ WORKER_REALM_MUTATION.STABLE,
161
+ 'process.exit/abort/kill/chdir',
162
+ processObject,
163
+ property,
164
+ {
165
+ configurable: false,
166
+ enumerable: descriptor?.enumerable ?? true,
167
+ writable: false,
168
+ value: () => {
169
+ throw codedError(PROCESS_CONTROL_ERROR_CODE, `process.${property} is forbidden inside the REPL kernel`)
170
+ },
171
+ },
172
+ )
173
+ }
174
+ }
175
+
176
+ /** Stable facts consumed by the conformance test and runtime documentation. */
177
+ export function workerRealmSurfaceFacts(processObject) {
178
+ const descriptor = (owner, name) => {
179
+ const value = objectGetOwnPropertyDescriptor(owner, name)
180
+ return value === undefined ? undefined : {
181
+ configurable: value.configurable,
182
+ enumerable: value.enumerable,
183
+ writable: value.writable,
184
+ own: true,
185
+ }
186
+ }
187
+ const controls = []
188
+ for (const name of ['exit', 'abort', 'kill', 'chdir']) controls.push([name, descriptor(processObject, name)])
189
+ return {
190
+ cwd: descriptor(processObject, 'cwd'),
191
+ controls,
192
+ stdoutWrite: descriptor(processObject.stdout, 'write'),
193
+ stderrWrite: descriptor(processObject.stderr, 'write'),
194
+ stdoutWriteOwn: objectHasOwn(processObject.stdout, 'write'),
195
+ stderrWriteOwn: objectHasOwn(processObject.stderr, 'write'),
196
+ }
197
+ }
@@ -0,0 +1,140 @@
1
+ import { createContext, runInContext, runInThisContext } from 'node:vm'
2
+ import { types } from 'node:util'
3
+ import { protectNextAsyncLocalStorageRun } from './async-local-storage-intrinsics.js'
4
+ import {
5
+ WORKER_REALM_MUTATION,
6
+ defineWorkerRealmProperty,
7
+ deleteWorkerRealmProperty,
8
+ } from './worker-realm-surfaces.js'
9
+
10
+ export const WORKER_REPL_OPTIONS = Object.freeze({ useGlobal: true })
11
+ const NativeMap = Map
12
+ const ownKeys = Reflect.ownKeys
13
+ const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
14
+ const createObject = Object.create
15
+ const hasOwn = Object.hasOwn
16
+ const sameValue = Object.is
17
+ const isMap = types.isMap
18
+ const mapSet = Function.prototype.call.bind(Map.prototype.set)
19
+ const mapHas = Function.prototype.call.bind(Map.prototype.has)
20
+ const mapForEach = Function.prototype.call.bind(Map.prototype.forEach)
21
+ const DESCRIPTOR_FIELDS = ['configurable', 'enumerable', 'writable', 'value', 'get', 'set']
22
+
23
+ /** Snapshot the native worker surface before Node installs REPL conveniences. */
24
+ export function captureWorkerReplGlobals(globalObject = globalThis) {
25
+ const baseline = new NativeMap()
26
+ const keys = ownKeys(globalObject)
27
+ for (let index = 0; index < keys.length; index += 1) {
28
+ mapSet(baseline, keys[index], getOwnPropertyDescriptor(globalObject, keys[index]))
29
+ }
30
+ return baseline
31
+ }
32
+
33
+ function descriptorsEqual(left, right) {
34
+ const field = (descriptor, name) => descriptor !== undefined && hasOwn(descriptor, name)
35
+ ? descriptor[name] : undefined
36
+ return left !== undefined && right !== undefined
37
+ && field(left, 'configurable') === field(right, 'configurable')
38
+ && field(left, 'enumerable') === field(right, 'enumerable')
39
+ && field(left, 'writable') === field(right, 'writable')
40
+ && sameValue(field(left, 'value'), field(right, 'value'))
41
+ && field(left, 'get') === field(right, 'get')
42
+ && field(left, 'set') === field(right, 'set')
43
+ }
44
+
45
+ function detachedDescriptor(descriptor) {
46
+ const detached = createObject(null)
47
+ for (let index = 0; index < DESCRIPTOR_FIELDS.length; index += 1) {
48
+ const name = DESCRIPTOR_FIELDS[index]
49
+ if (hasOwn(descriptor, name)) detached[name] = descriptor[name]
50
+ }
51
+ return detached
52
+ }
53
+
54
+ /** Remove Node's REPL-only module shortcuts and restore changed native globals. */
55
+ export function restoreWorkerReplGlobals(baseline, globalObject = globalThis) {
56
+ if (!isMap(baseline)) throw new TypeError('worker REPL global baseline must be a Map')
57
+ const keys = ownKeys(globalObject)
58
+ for (let index = 0; index < keys.length; index += 1) {
59
+ const key = keys[index]
60
+ if (typeof key === 'string' && !mapHas(baseline, key)
61
+ && !deleteWorkerRealmProperty(WORKER_REALM_MUTATION.RESTORE, undefined, globalObject, key)) {
62
+ throw new Error(`worker REPL added a non-configurable global ${String(key)}`)
63
+ }
64
+ }
65
+ mapForEach(baseline, (descriptor, key) => {
66
+ if (!descriptorsEqual(getOwnPropertyDescriptor(globalObject, key), descriptor)) {
67
+ defineWorkerRealmProperty(
68
+ WORKER_REALM_MUTATION.RESTORE, undefined, globalObject, key, detachedDescriptor(descriptor),
69
+ )
70
+ }
71
+ })
72
+ return globalObject
73
+ }
74
+
75
+ /** A dedicated worker is the native realm shared by its REPL and Node modules. */
76
+ export function workerReplContext(server) {
77
+ if (server.context !== globalThis) {
78
+ throw new Error('worker REPL did not use its native global realm')
79
+ }
80
+ return server.context
81
+ }
82
+
83
+ let replAsyncContextProtected = false
84
+
85
+ /** Newer Node REPLs own an AsyncLocalStorage instance whose public prototype
86
+ * remains user-mutable. Give only that platform instance its native operations
87
+ * before the first user evaluation. */
88
+ export function protectWorkerReplAsyncContext(server) {
89
+ if (replAsyncContextProtected) return
90
+ let callbackError
91
+ const scope = protectNextAsyncLocalStorageRun(() => {
92
+ server.eval('void 0\n', server.context, 'ptc-plus-repl-bootstrap', error => { callbackError = error })
93
+ })
94
+ if (callbackError !== null && callbackError !== undefined) throw callbackError
95
+ replAsyncContextProtected = true
96
+ return scope !== undefined
97
+ }
98
+
99
+ export function runInWorkerReplRealm(source, options) {
100
+ return runInThisContext(source, options)
101
+ }
102
+
103
+ /** Control promises stay outside the user-mutable worker realm. */
104
+ export function createWorkerControlPromise() {
105
+ return runInContext('Promise', createContext())
106
+ }
107
+
108
+ /** PTC owns settlement; the REPL's legacy domain would run Node bookkeeping
109
+ * through user-mutable prototypes in the shared worker realm. */
110
+ export function disableWorkerReplDomain(domain) {
111
+ domain.enter = () => domain
112
+ domain.exit = () => domain
113
+ return domain
114
+ }
115
+
116
+ /** Newer REPLs format errors before the eval callback unless an owned
117
+ * evaluation consumes the original thrown value through handleError. */
118
+ export function createWorkerReplErrorHandler(evaluationScope, settle) {
119
+ return error => {
120
+ const finish = evaluationScope.getStore()
121
+ if (finish === undefined) return 'unhandled'
122
+ settle(finish, error)
123
+ return 'ignore'
124
+ }
125
+ }
126
+
127
+ /** Older REPLs can bypass handleError. Keep their process-level fallback
128
+ * directly testable without requiring a version-specific uncaught event. */
129
+ export function createWorkerUncaughtExceptionHandler(evaluationScope, listenerOwner = process) {
130
+ const handleUncaughtException = error => {
131
+ const finish = evaluationScope.getStore()
132
+ if (finish !== undefined) {
133
+ finish(true, error)
134
+ return
135
+ }
136
+ listenerOwner.removeListener('uncaughtException', handleUncaughtException)
137
+ throw error
138
+ }
139
+ return handleUncaughtException
140
+ }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "dsh-ptc-plus",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
+ "icon": "assets/ptc-plus-icon.svg",
4
5
  "description": "A session-bound agent-native REPL for DeepSeek Harness PTC mode.",
5
6
  "type": "module",
6
7
  "main": "./index.js",
@@ -25,6 +26,7 @@
25
26
  "src",
26
27
  "internal",
27
28
  "docs",
29
+ "assets/ptc-plus-icon.svg",
28
30
  "assets/dsh-ptc-plus-banner-en.webp",
29
31
  "assets/dsh-ptc-plus-banner-zh.webp",
30
32
  "assets/ptc-plus-bindings-en.png",
@@ -61,7 +63,7 @@
61
63
  "@codemirror/language": "^6.12.4",
62
64
  "@codemirror/state": "^6.7.4",
63
65
  "@codemirror/view": "^6.43.11",
64
- "@deepseek-ai/schemastery": "^3.18.1",
66
+ "@deepseek-ai/schemastery": "^3.18.3",
65
67
  "@jridgewell/trace-mapping": "^0.3.31",
66
68
  "@lezer/highlight": "^1.2.3",
67
69
  "acorn": "^8.15.0",
@@ -87,16 +89,24 @@
87
89
  "build:check": "node scripts/client-bundle.mjs check && node scripts/compiler-bundle.mjs check",
88
90
  "test:client": "vitest run --config scripts/client-test.config.mjs",
89
91
  "test:semantics": "node --test --test-concurrency=1 test/semantic-test262.test.js test/semantic-dialect.test.js test/semantic-boundaries.test.js",
92
+ "semantic:check": "node scripts/semantic-obligations.mjs",
90
93
  "test:client:web": "node scripts/client-web-smoke.mjs",
91
94
  "test:client:layout": "node scripts/client-binding-layout.mjs",
92
95
  "prepack": "npm run build:check",
93
96
  "hooks:install": "node scripts/review-findings.mjs install-hook",
94
97
  "review:new": "node scripts/review-findings.mjs create",
98
+ "review:plan:new": "node scripts/review-findings.mjs plan-create",
99
+ "review:plan": "node scripts/review-findings.mjs plan",
100
+ "review:status": "node scripts/review-findings.mjs status",
101
+ "review:lane": "node scripts/review-findings.mjs lane-verdict",
102
+ "review:finalize": "node scripts/review-findings.mjs finalize",
103
+ "review:clear": "node scripts/review-findings.mjs review-clear",
95
104
  "review:validate": "node scripts/review-findings.mjs validate",
96
105
  "review:gate": "node scripts/review-findings.mjs gate",
97
106
  "session:migrate": "node scripts/migrate-session-log.mjs",
98
107
  "coverage": "node scripts/coverage.mjs",
99
- "verify": "npm run review:validate && npm run build:check && node --check index.js && node --check internal/kernel-worker.js && node --check scripts/migrate-session-log.mjs && node --check scripts/expensive-headless-acceptance.mjs && node --check scripts/ab-headless-trajectories.mjs && npm run test:client && npm run coverage",
108
+ "coverage:focus": "node scripts/coverage.mjs --focus",
109
+ "verify": "npm run review:validate && npm run semantic:check && npm run build:check && node --check index.js && node --check internal/kernel-worker.js && node --check scripts/migrate-session-log.mjs && node --check scripts/expensive-headless-acceptance.mjs && node --check scripts/ab-headless-trajectories.mjs && npm run test:client && npm run coverage",
100
110
  "check": "node scripts/review-findings.mjs check",
101
111
  "test:expensive": "node scripts/expensive-headless-acceptance.mjs",
102
112
  "test:ab": "node scripts/ab-headless-trajectories.mjs"
@@ -156,6 +166,8 @@
156
166
  "@deepseek-ai/dsh-commands": "next",
157
167
  "@deepseek-ai/dsh-home-paths": "next",
158
168
  "@deepseek-ai/dsh-llm": "next",
169
+ "@deepseek-ai/dsh-session-format-catalog": "next",
170
+ "@deepseek-ai/dsh-session-format-v0-to-v1": "next",
159
171
  "@deepseek-ai/dsh-session-persistence-jsonl": "next",
160
172
  "@deepseek-ai/dsh-settings": "next",
161
173
  "@deepseek-ai/dsh-skill-filesystem": "next",
@@ -163,15 +175,36 @@
163
175
  "@deepseek-ai/dsh-tools": "next",
164
176
  "@deepseek-ai/dsh-typert-protocol": "next",
165
177
  "@deepseek-ai/dsh-typert-registry": "next",
178
+ "@deepseek-ai/dsh-util-workspace-path": "next",
179
+ "@shikijs/langs": "^4.3.1",
166
180
  "@testing-library/react": "^16.3.3",
181
+ "anser": "^2.3.5",
167
182
  "c8": "^12.0.0",
183
+ "clsx": "^2.0.0",
168
184
  "convert-source-map": "^2.0.0",
185
+ "diff": "^9.0.0",
169
186
  "esbuild": "0.28.2",
187
+ "immer": "^10.1.1",
170
188
  "jsdom": "^29.1.1",
189
+ "katex": "^0.16.47",
190
+ "mdast-util-from-markdown": "^2.0.3",
191
+ "mdast-util-gfm": "^3.1.0",
192
+ "mdast-util-math": "^3.0.0",
193
+ "micromark-core-commonmark": "^2.0.3",
194
+ "micromark-extension-gfm": "^3.0.0",
195
+ "micromark-extension-math": "^3.1.0",
196
+ "micromark-factory-space": "^2.0.1",
197
+ "micromark-util-character": "^2.1.1",
198
+ "micromark-util-classify-character": "^2.0.1",
199
+ "micromark-util-sanitize-uri": "^2.0.1",
200
+ "micromark-util-symbol": "^2.0.1",
171
201
  "playwright": "^1.63.0",
172
202
  "react": "^18.3.1",
173
203
  "react-dom": "^18.3.1",
204
+ "shiki": "^4.3.1",
205
+ "simple-icons": "16.31.0",
174
206
  "vitest": "^5.0.0",
175
- "yaml": "^2.9.0"
207
+ "yaml": "^2.9.0",
208
+ "zustand": "~4.4.7"
176
209
  }
177
210
  }
@@ -3,6 +3,7 @@ import {
3
3
  STATUSES as JOURNAL_STATUSES,
4
4
  BINDING_MODES,
5
5
  JOURNAL_FIELDS,
6
+ LANGUAGE_SEMANTICS_JOURNAL_FIELDS,
6
7
  PER_NAME_JOURNAL_FIELDS,
7
8
  LANGUAGE_SEMANTICS_JOURNAL_VERSION,
8
9
  WHOLE_ENTRY_JOURNAL_FIELDS,
@@ -33,6 +34,7 @@ import {
33
34
  USER_BINDINGS_REUSE_POLICIES,
34
35
  } from '../internal/session-journal-schema.js'
35
36
  import { normalizeLanguageSemantics } from '../internal/language-semantics.js'
37
+ import { normalizeModuleTransform } from '../internal/module-transform-contract.js'
36
38
  import {
37
39
  VALUE_CODEC,
38
40
  DEFAULT_VALUE_LIMITS,
@@ -103,7 +105,7 @@ function isLine(value) {
103
105
  }
104
106
 
105
107
  function isSafeSequence(value) {
106
- return Number.isSafeInteger(value) && value >= 0
108
+ return Number.isSafeInteger(value) && value >= 0 && !Object.is(value, -0)
107
109
  }
108
110
 
109
111
  function isValidPosition(value) {
@@ -185,6 +187,7 @@ function isValidValueWire(value) {
185
187
  nodeCount: value.nodes.length,
186
188
  discovered: new Set(),
187
189
  edges: 0,
190
+ arraySlots: 0,
188
191
  textBytes: 0,
189
192
  }
190
193
  if (!isValidValueAtom(value.root, state)) return false
@@ -194,6 +197,8 @@ function isValidValueWire(value) {
194
197
  if (!hasExactOrderedFields(node, VALUE_ARRAY_FIELDS)
195
198
  || !Number.isSafeInteger(node.length) || node.length < 0 || node.length > MAX_ARRAY_LENGTH
196
199
  || !Array.isArray(node.entries)) return false
200
+ state.arraySlots += node.length
201
+ if (state.arraySlots > MAX_ARRAY_LENGTH) return false
197
202
  let previous = -1
198
203
  for (const entry of node.entries) {
199
204
  if (!Array.isArray(entry) || entry.length !== 2 || !Number.isSafeInteger(entry[0])
@@ -292,7 +297,8 @@ function isReadableJournalUnchecked(value) {
292
297
  : value.version === 4 ? RELATIONLESS_JOURNAL_FIELDS
293
298
  : value.version === 5 ? FINGERPRINT_REUSE_JOURNAL_FIELDS
294
299
  : value.version < PER_NAME_USER_BINDINGS_JOURNAL_VERSION ? WHOLE_ENTRY_JOURNAL_FIELDS
295
- : value.version < LANGUAGE_SEMANTICS_JOURNAL_VERSION ? PER_NAME_JOURNAL_FIELDS : JOURNAL_FIELDS
300
+ : value.version < LANGUAGE_SEMANTICS_JOURNAL_VERSION ? PER_NAME_JOURNAL_FIELDS
301
+ : value.version === LANGUAGE_SEMANTICS_JOURNAL_VERSION ? LANGUAGE_SEMANTICS_JOURNAL_FIELDS : JOURNAL_FIELDS
296
302
  const required = predecessor
297
303
  ? ['version', 'bindingMode', 'status', 'calls', 'operations', 'diagnostics']
298
304
  : ['version', 'bindingPolicy', 'rewritePolicy', 'moduleSemantics', 'status', 'calls', 'operations', 'diagnostics']
@@ -307,6 +313,10 @@ function isReadableJournalUnchecked(value) {
307
313
  required.push('languageSemantics')
308
314
  normalizeLanguageSemantics(value.languageSemantics)
309
315
  }
316
+ if (value.version > LANGUAGE_SEMANTICS_JOURNAL_VERSION) {
317
+ required.push('moduleTransform')
318
+ normalizeModuleTransform(value.moduleTransform, value.languageSemantics)
319
+ }
310
320
  if (!hasClosedFields(value, fields, required)
311
321
  || (predecessor && !BINDING_MODES.has(value.bindingMode))
312
322
  || (value.version >= 4 && !isValidBindingPolicy(value.bindingPolicy))