dsh-ptc-plus 0.3.2 → 0.4.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.
Files changed (206) hide show
  1. package/README.en.md +63 -80
  2. package/README.md +63 -80
  3. package/assets/ptc-plus-bindings-en.png +0 -0
  4. package/assets/ptc-plus-bindings-zh.png +0 -0
  5. package/assets/ptc-plus-repair-en.png +0 -0
  6. package/assets/ptc-plus-repair-zh.png +0 -0
  7. package/assets/ptc-plus-repl-workspace-en.png +0 -0
  8. package/assets/ptc-plus-repl-workspace-zh.png +0 -0
  9. package/assets/ptc-plus-settings-en.png +0 -0
  10. package/assets/ptc-plus-settings-zh.png +0 -0
  11. package/client.js +30827 -742
  12. package/compiler-amaro.cjs +5 -0
  13. package/compiler-amaro.cjs.map +6 -0
  14. package/compiler-asset-124f80c1bba92ff5fe79cfec6e8ad518f476de4a42514cae3919538887f510e8.txt +1 -0
  15. package/compiler-assets.json +3 -0
  16. package/compiler-core.cjs +556 -0
  17. package/compiler-core.cjs.map +6 -0
  18. package/compiler-platform.cjs +2 -0
  19. package/compiler-platform.cjs.map +6 -0
  20. package/compiler-typescript.cjs +388 -0
  21. package/compiler-typescript.cjs.map +6 -0
  22. package/docs/README.md +7 -0
  23. package/docs/adr/0004-declare-program-bindings-at-the-host.md +1 -1
  24. package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +5 -3
  25. package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +1 -1
  26. package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -0
  27. package/docs/adr/0010-session-log-derived-recovery-tips.md +59 -5
  28. package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +1 -1
  29. package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +3 -1
  30. package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +3 -1
  31. package/docs/adr/0014-persist-cell-rewrite-policy.md +6 -2
  32. package/docs/adr/0015-preserve-source-positions-through-rewrites.md +1 -1
  33. package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
  34. package/docs/adr/0017-track-the-latest-dsh-public-surface.md +49 -0
  35. package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +3 -3
  36. package/docs/adr/0019-plugin-settings-and-kill-switch.md +5 -3
  37. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
  38. package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +12 -0
  39. package/docs/adr/0023-global-user-bindings.md +104 -0
  40. package/docs/adr/0024-repl-console-observation.md +33 -0
  41. package/docs/adr/0025-use-versioned-logical-binding-identities.md +119 -0
  42. package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +21 -0
  43. package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +37 -0
  44. package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +103 -0
  45. package/docs/adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md +27 -0
  46. package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +27 -0
  47. package/docs/architecture.md +77 -21
  48. package/docs/binding-review-placement-design.md +200 -0
  49. package/docs/capability-projection.md +1 -1
  50. package/docs/client-ui.md +95 -19
  51. package/docs/durability-design.md +28 -10
  52. package/docs/evaluation.md +78 -6
  53. package/docs/installation.md +41 -6
  54. package/docs/publishing.md +5 -3
  55. package/docs/runtime-reference.md +76 -25
  56. package/docs/semantic-validation.md +29 -0
  57. package/docs/stateful-binding-updates-proposal.md +759 -0
  58. package/docs/user-bindings.en.md +66 -0
  59. package/docs/user-bindings.md +66 -0
  60. package/docs/value-wire.md +3 -3
  61. package/docs/verification-optimization-work.md +41 -0
  62. package/docs/verification.md +71 -0
  63. package/index.js +369 -92
  64. package/internal/ast-traversal.js +5 -2
  65. package/internal/async-local-storage-intrinsics.js +38 -0
  66. package/internal/binding-declaration-contract.js +8 -0
  67. package/internal/binding-descriptors.js +1 -0
  68. package/internal/binding-pattern-traversal.js +25 -0
  69. package/internal/binding-pattern.js +26 -29
  70. package/internal/binding-source-analysis.js +708 -0
  71. package/internal/binding-update-policy.js +72 -0
  72. package/internal/bounded-worker-round.js +56 -0
  73. package/internal/callable-definition-environment.js +42 -0
  74. package/internal/callable-source-catalog.js +129 -0
  75. package/internal/callable-source-encoding.js +47 -0
  76. package/internal/callable-source-facts.js +459 -0
  77. package/internal/callable-source-format.js +2 -0
  78. package/internal/callable-source-lowering.js +123 -0
  79. package/internal/cell-analysis-contract.js +25 -0
  80. package/internal/cell-analysis.js +253 -290
  81. package/internal/cell-completion.js +15 -0
  82. package/internal/cell-error.js +7 -0
  83. package/internal/cell-parser.js +66 -0
  84. package/internal/cell-rewriter.js +3 -677
  85. package/internal/commonjs-export-evidence.js +63 -0
  86. package/internal/commonjs-source-evidence.js +72 -0
  87. package/internal/compiler-amaro.cjs +2 -0
  88. package/internal/compiler-compression.js +12 -0
  89. package/internal/compiler-data.js +58 -0
  90. package/internal/compiler-descriptors.js +54 -0
  91. package/internal/compiler-dynamic-cache.js +48 -0
  92. package/internal/compiler-entry.js +35 -0
  93. package/internal/compiler-generated-names.js +17 -0
  94. package/internal/compiler-intrinsics.js +50 -0
  95. package/internal/compiler-module-links.js +37 -0
  96. package/internal/compiler-operations.js +61 -0
  97. package/internal/compiler-platform-factory.js +84 -0
  98. package/internal/compiler-platform.js +136 -0
  99. package/internal/compiler-record-roles.js +53 -0
  100. package/internal/compiler-region-output.js +259 -0
  101. package/internal/compiler-resource-lowering.js +103 -0
  102. package/internal/compiler-scope-facts.js +115 -0
  103. package/internal/compiler-service.js +109 -0
  104. package/internal/compiler-source-cache.js +32 -0
  105. package/internal/compiler-source-pieces.js +93 -0
  106. package/internal/compiler-source-regions.js +132 -0
  107. package/internal/compiler-storage-source.js +54 -0
  108. package/internal/compiler-text.js +15 -0
  109. package/internal/compiler-typescript.cjs +2 -0
  110. package/internal/config-spec.js +83 -27
  111. package/internal/cordis-tools-owner.js +130 -21
  112. package/internal/diagnostic.js +27 -1
  113. package/internal/direct-surface-owner.js +76 -23
  114. package/internal/dynamic-binding-evidence.js +16 -0
  115. package/internal/dynamic-environment-compiler.js +779 -0
  116. package/internal/dynamic-environment-integration.js +91 -0
  117. package/internal/dynamic-environment-runtime.js +383 -0
  118. package/internal/dynamic-native-calls.js +153 -0
  119. package/internal/dynamic-native-runtime.js +262 -0
  120. package/internal/dynamic-scope-analysis.js +90 -0
  121. package/internal/edit-transport-owner.js +27 -2
  122. package/internal/execution-seam-compat.js +193 -0
  123. package/internal/failure-reporting.js +136 -28
  124. package/internal/host-rpc.js +66 -0
  125. package/internal/isolated-worker.js +555 -0
  126. package/internal/kernel-child.js +139 -0
  127. package/internal/kernel-worker.js +1179 -233
  128. package/internal/language-semantics.js +14 -0
  129. package/internal/legacy-binding-catalog.js +48 -0
  130. package/internal/legacy-cell-analysis.js +600 -0
  131. package/internal/legacy-cell-parser.js +50 -0
  132. package/internal/legacy-cell-rewriter.js +631 -0
  133. package/internal/legacy-repl-convenience.js +291 -0
  134. package/internal/managed-module-operations.js +170 -0
  135. package/internal/module-compilation.js +322 -0
  136. package/internal/module-runtime-platform.js +19 -0
  137. package/internal/module-transform-contract.js +42 -0
  138. package/internal/native-await-declarations.js +68 -0
  139. package/internal/native-root-compilation.js +54 -0
  140. package/internal/native-root-dynamic.js +67 -0
  141. package/internal/record-utils.js +24 -15
  142. package/internal/recovery-tips.js +27 -15
  143. package/internal/rejected-cell-editor.js +13 -8
  144. package/internal/repl-convenience.js +2 -289
  145. package/internal/repl-memory-projection.js +81 -12
  146. package/internal/repl-observation-interest.js +70 -0
  147. package/internal/repl-rewrite-contract.js +6 -0
  148. package/internal/repl-scope-normalizer.js +2091 -0
  149. package/internal/repl-value-observer.js +117 -0
  150. package/internal/rpc-contract.js +52 -0
  151. package/internal/runtime-bridge-owner.js +172 -28
  152. package/internal/runtime-config.js +48 -52
  153. package/internal/runtime-contexts.js +82 -10
  154. package/internal/runtime-intrinsics.js +101 -0
  155. package/internal/runtime-messages.js +111 -0
  156. package/internal/session-cell-executor.js +402 -87
  157. package/internal/session-journal-recovery.js +684 -0
  158. package/internal/session-journal-schema.js +123 -0
  159. package/internal/session-journal.js +199 -654
  160. package/internal/session-log-view.js +42 -9
  161. package/internal/session-runtime.js +257 -95
  162. package/internal/session-state.js +247 -71
  163. package/internal/source-position-map.js +230 -71
  164. package/internal/stateful-module-compiler.js +154 -0
  165. package/internal/stateful-module-runtime.js +303 -0
  166. package/internal/stateful-root-compiler.js +600 -0
  167. package/internal/stateful-root-runtime.js +340 -0
  168. package/internal/typert-codec-compat.js +28 -0
  169. package/internal/typescript-transform.js +31 -0
  170. package/internal/user-binding-authoring.js +70 -0
  171. package/internal/user-binding-console-worker.js +244 -0
  172. package/internal/user-binding-console.js +148 -0
  173. package/internal/user-binding-draft-projection.js +335 -0
  174. package/internal/user-binding-model-context.js +31 -0
  175. package/internal/user-binding-runner.js +56 -0
  176. package/internal/user-bindings-owner.js +1065 -0
  177. package/internal/user-bindings-store.js +293 -0
  178. package/internal/user-bindings.js +361 -0
  179. package/internal/value-wire-schema.js +28 -0
  180. package/internal/value-wire.js +130 -91
  181. package/internal/worker-client.js +57 -67
  182. package/internal/worker-cwd-virtualization.js +80 -53
  183. package/internal/worker-environment.js +65 -0
  184. package/internal/worker-output-relay.js +29 -0
  185. package/internal/worker-repl-realm.js +134 -0
  186. package/internal/worker-shutdown.js +14 -0
  187. package/package.json +76 -7
  188. package/src/client-activity.js +95 -53
  189. package/src/client-authoring-view.js +580 -0
  190. package/src/client-binding-review.js +230 -0
  191. package/src/client-bindings-data.js +29 -0
  192. package/src/client-catalog.js +127 -0
  193. package/src/client-code-editor.js +84 -0
  194. package/src/client-console.js +112 -0
  195. package/src/client-copy.js +370 -0
  196. package/src/client-feature-gates.js +62 -0
  197. package/src/client-host-compat.js +150 -0
  198. package/src/client-indicator-view.js +267 -0
  199. package/src/client-repl-view.js +292 -0
  200. package/src/client-rpc.js +20 -0
  201. package/src/client-settings-view.js +221 -0
  202. package/src/client-styles.js +106 -0
  203. package/src/client-tool-view.js +108 -0
  204. package/src/client-transport.js +159 -0
  205. package/src/client-workbench.js +521 -0
  206. package/src/client.js +233 -615
@@ -1,5 +1,10 @@
1
1
  import { isAbsolute, parse, resolve, sep } from 'node:path'
2
2
  import { promisify } from 'node:util'
3
+ import { runtimeIntrinsics as internal } from './runtime-intrinsics.js'
4
+
5
+ const { Reflect: privateReflect, appendArray, bufferConcat, bufferIsBuffer, bufferToString,
6
+ copyArray, isArray, regexpTest } = internal
7
+ const TRAILING_SEPARATOR = /[\\/]$/
3
8
 
4
9
  const FILE_SYSTEM_PATH_ARGUMENTS = Object.freeze({
5
10
  access: [0], accessSync: [0], appendFile: [0], appendFileSync: [0],
@@ -34,7 +39,7 @@ const CHILD_PROCESS_PROJECTED_PROPERTIES = Object.freeze({
34
39
  function wrapBuiltinCallable(original, projectArguments, projectedProperties = []) {
35
40
  const wrapped = {
36
41
  invoke(...args) {
37
- return Reflect.apply(original, this, projectArguments(args))
42
+ return privateReflect.apply(original, this, projectArguments(args))
38
43
  },
39
44
  }.invoke
40
45
  const descriptors = Object.getOwnPropertyDescriptors(original)
@@ -59,80 +64,101 @@ function wrapBuiltin(owner, name, projectArguments, projectedProperties) {
59
64
  owner[name] = wrapBuiltinCallable(original, projectArguments, projectedProperties)
60
65
  }
61
66
 
67
+ export function projectChildProcessArguments(name, args, sessionCwd) {
68
+ const sessionChildOptions = options => (
69
+ options === null || typeof options !== 'object' || options.cwd !== undefined
70
+ ? options
71
+ : { ...options, cwd: sessionCwd }
72
+ )
73
+ const withDefaultOptions = (index) => {
74
+ const next = copyArray(args)
75
+ next[index] = sessionChildOptions(next[index]) ?? { cwd: sessionCwd }
76
+ return next
77
+ }
78
+ const insertDefaultOptions = (index) => {
79
+ const next = copyArray(args, 0, index)
80
+ appendArray(next, { cwd: sessionCwd })
81
+ return copyArray(args, index, args.length, next)
82
+ }
83
+ if (name === 'exec' || name === 'execSync') {
84
+ const next = copyArray(args)
85
+ if (typeof next[1] === 'function') return insertDefaultOptions(1)
86
+ else next[1] = sessionChildOptions(next[1]) ?? { cwd: sessionCwd }
87
+ return next
88
+ }
89
+ if (name === 'execFile' || name === 'execFileSync') {
90
+ if (args.length === 1 || typeof args[1] === 'function') {
91
+ return insertDefaultOptions(1)
92
+ }
93
+ if (typeof args[2] === 'function') {
94
+ if (args[1] !== undefined && !isArray(args[1])) return withDefaultOptions(1)
95
+ return insertDefaultOptions(2)
96
+ }
97
+ if (args[1] !== undefined && !isArray(args[1])) return withDefaultOptions(1)
98
+ return withDefaultOptions(2)
99
+ }
100
+ return args.length === 1 || (args[1] !== undefined && !isArray(args[1]))
101
+ ? withDefaultOptions(1)
102
+ : withDefaultOptions(2)
103
+ }
104
+
62
105
  /** Install one session's cwd projection into Node builtins loaded by the worker. */
63
- export function installWorkerCwdVirtualization(sessionCwd, originalRequire) {
64
- if (sessionCwd === undefined) return
106
+ export function installWorkerCwdVirtualization(sessionCwd, originalRequire, markVolatile) {
107
+ if (sessionCwd === undefined) {
108
+ const nativeCwd = process.cwd
109
+ process.cwd = () => {
110
+ markVolatile('process.cwd')
111
+ return privateReflect.apply(nativeCwd, process, [])
112
+ }
113
+ return
114
+ }
65
115
  const nativeResolve = resolve
66
- const bufferPrefix = Buffer.from(sessionCwd + (/[\\/]$/.test(sessionCwd) ? '' : sep))
116
+ const bufferPrefix = Buffer.from(sessionCwd + (regexpTest(TRAILING_SEPARATOR, sessionCwd) ? '' : sep))
67
117
  const sessionPath = (value) => {
68
118
  if (typeof value === 'string') return isAbsolute(value) ? value : nativeResolve(sessionCwd, value)
69
- if (Buffer.isBuffer(value)) {
70
- const absolute = isAbsolute(String.fromCharCode(...value.subarray(0, 3)))
71
- return absolute ? value : Buffer.concat([bufferPrefix, value])
119
+ if (bufferIsBuffer(value)) {
120
+ const absolute = isAbsolute(bufferToString(value, 'utf8', 0, 3))
121
+ return absolute ? value : bufferConcat([bufferPrefix, value])
72
122
  }
73
123
  return value
74
124
  }
75
125
  const sessionPathPrefix = (value) => {
76
126
  if (typeof value !== 'string' || isAbsolute(value) || parse(value).root !== '') return sessionPath(value)
77
- return sessionCwd + (/[\\/]$/.test(sessionCwd) ? '' : sep) + value
127
+ return sessionCwd + (regexpTest(TRAILING_SEPARATOR, sessionCwd) ? '' : sep) + value
78
128
  }
79
129
  const projectPaths = (args, indices) => {
80
- const next = [...args]
81
- for (const index of indices) next[index] = sessionPath(next[index])
130
+ const next = copyArray(args)
131
+ for (let offset = 0; offset < indices.length; offset += 1) {
132
+ const index = indices[offset]
133
+ next[index] = sessionPath(next[index])
134
+ }
82
135
  return next
83
136
  }
84
137
  const projectPrefix = (args) => {
85
- const next = [...args]
138
+ const next = copyArray(args)
86
139
  next[0] = sessionPathPrefix(next[0])
87
140
  return next
88
141
  }
89
- const sessionChildOptions = options => (
90
- options === null || typeof options !== 'object' || options.cwd !== undefined
91
- ? options
92
- : { ...options, cwd: sessionCwd }
93
- )
94
- const withDefaultOptions = (args, index) => {
95
- const next = [...args]
96
- next[index] = sessionChildOptions(next[index]) ?? { cwd: sessionCwd }
97
- return next
98
- }
99
- const childProcessOptions = (name, args) => {
100
- if (name === 'exec' || name === 'execSync') {
101
- const next = [...args]
102
- if (typeof next[1] === 'function') next.splice(1, 0, { cwd: sessionCwd })
103
- else next[1] = sessionChildOptions(next[1]) ?? { cwd: sessionCwd }
104
- return next
105
- }
106
- if (name === 'execFile' || name === 'execFileSync') {
107
- if (args.length === 1 || typeof args[1] === 'function') {
108
- const next = [...args]
109
- next.splice(1, 0, { cwd: sessionCwd })
110
- return next
111
- }
112
- if (typeof args[2] === 'function') {
113
- if (args[1] !== undefined && !Array.isArray(args[1])) return withDefaultOptions(args, 1)
114
- const next = [...args]
115
- next.splice(2, 0, { cwd: sessionCwd })
116
- return next
117
- }
118
- if (args[1] !== undefined && !Array.isArray(args[1])) return withDefaultOptions(args, 1)
119
- return withDefaultOptions(args, 2)
120
- }
121
- return args.length === 1 || (args[1] !== undefined && !Array.isArray(args[1]))
122
- ? withDefaultOptions(args, 1)
123
- : withDefaultOptions(args, 2)
124
- }
125
142
  const sessionGlobOptions = (args) => {
126
- const next = [...args]
127
- if (typeof next[1] === 'function') next.splice(1, 0, { cwd: sessionCwd })
128
- else if (next[1] === undefined) next[1] = { cwd: sessionCwd }
143
+ if (typeof args[1] === 'function') {
144
+ const next = copyArray(args, 0, 1)
145
+ appendArray(next, { cwd: sessionCwd })
146
+ return copyArray(args, 1, args.length, next)
147
+ }
148
+ const next = copyArray(args)
149
+ if (next[1] === undefined) next[1] = { cwd: sessionCwd }
129
150
  else if (next[1] !== null && typeof next[1] === 'object' && next[1].cwd === undefined) {
130
151
  next[1] = { ...next[1], cwd: sessionCwd }
131
152
  }
132
153
  return next
133
154
  }
134
155
 
135
- process.cwd = () => sessionCwd
156
+ Object.defineProperty(process, 'cwd', {
157
+ configurable: false,
158
+ enumerable: true,
159
+ writable: false,
160
+ value: () => sessionCwd,
161
+ })
136
162
  const fs = originalRequire('node:fs')
137
163
  const path = originalRequire('node:path')
138
164
  for (const [name, indices] of Object.entries(FILE_SYSTEM_PATH_ARGUMENTS)) {
@@ -147,9 +173,10 @@ export function installWorkerCwdVirtualization(sessionCwd, originalRequire) {
147
173
  wrapBuiltin(fs, name, sessionGlobOptions)
148
174
  wrapBuiltin(fs.promises, name, sessionGlobOptions)
149
175
  }
150
- wrapBuiltin(path, 'resolve', args => [sessionCwd, ...args])
176
+ wrapBuiltin(path, 'resolve', args => copyArray(args, 0, args.length, [sessionCwd]))
151
177
  const childProcess = originalRequire('node:child_process')
152
178
  for (const name of ['exec', 'execFile', 'execFileSync', 'execSync', 'fork', 'spawn', 'spawnSync']) {
153
- wrapBuiltin(childProcess, name, args => childProcessOptions(name, args), CHILD_PROCESS_PROJECTED_PROPERTIES[name])
179
+ wrapBuiltin(childProcess, name,
180
+ args => projectChildProcessArguments(name, args, sessionCwd), CHILD_PROCESS_PROJECTED_PROPERTIES[name])
154
181
  }
155
182
  }
@@ -0,0 +1,65 @@
1
+ const WINDOWS_ENVIRONMENT_NAMES = new Map([
2
+ ['appdata', 'APPDATA'],
3
+ ['comspec', 'ComSpec'],
4
+ ['home', 'HOME'],
5
+ ['homedrive', 'HOMEDRIVE'],
6
+ ['homepath', 'HOMEPATH'],
7
+ ['localappdata', 'LOCALAPPDATA'],
8
+ ['path', 'PATH'],
9
+ ['pathext', 'PATHEXT'],
10
+ ['programdata', 'ProgramData'],
11
+ ['programfiles', 'ProgramFiles'],
12
+ ['programfiles(x86)', 'ProgramFiles(x86)'],
13
+ ['systemdrive', 'SystemDrive'],
14
+ ['systemroot', 'SystemRoot'],
15
+ ['temp', 'TEMP'],
16
+ ['tmp', 'TMP'],
17
+ ['userprofile', 'USERPROFILE'],
18
+ ['windir', 'windir'],
19
+ ])
20
+ export const HOST_ONLY_ENVIRONMENT_NAMES = new Set([
21
+ 'node_test_context',
22
+ 'node_v8_coverage',
23
+ 'dsh_ptc_compiler_bytecode',
24
+ ])
25
+
26
+ /** Detect whether the Host executable needs Electron's Node startup mode. */
27
+ export function isElectronHost(versions = process.versions) {
28
+ return typeof versions?.electron === 'string'
29
+ }
30
+
31
+ /** Overlay only the helper process environment needed to boot an Electron executable as Node. */
32
+ export function helperProcessEnvironment(source, platform = process.platform, electronHost = isElectronHost()) {
33
+ if (!electronHost) return source
34
+ const environment = { ...(source ?? process.env) }
35
+ if (platform === 'win32') {
36
+ for (const name of Object.keys(environment)) {
37
+ if (name !== 'ELECTRON_RUN_AS_NODE' && name.toLowerCase() === 'electron_run_as_node') {
38
+ delete environment[name]
39
+ }
40
+ }
41
+ }
42
+ environment.ELECTRON_RUN_AS_NODE = '1'
43
+ return environment
44
+ }
45
+
46
+ /** Project the host environment once without losing Windows case variants. */
47
+ export function normalizeWorkerEnvironment(source, platform = process.platform) {
48
+ if (platform !== 'win32') {
49
+ return Object.fromEntries(Object.entries(source).filter(([name, value]) => (
50
+ value !== undefined && !HOST_ONLY_ENVIRONMENT_NAMES.has(name.toLowerCase())
51
+ )))
52
+ }
53
+ const normalized = new Map()
54
+ for (const [name, value] of Object.entries(source)) {
55
+ if (value === undefined) continue
56
+ const key = name.toLowerCase()
57
+ if (HOST_ONLY_ENVIRONMENT_NAMES.has(key)) continue
58
+ const canonicalName = WINDOWS_ENVIRONMENT_NAMES.get(key) ?? name
59
+ const current = normalized.get(key)
60
+ if (current === undefined || name === canonicalName) {
61
+ normalized.set(key, [canonicalName, value])
62
+ }
63
+ }
64
+ return Object.fromEntries(normalized.values())
65
+ }
@@ -0,0 +1,29 @@
1
+ /** Forward one worker output stream while honoring destination backpressure. */
2
+ export function relayWorkerOutput(source, destination) {
3
+ if (source === null || source === undefined) return Promise.resolve()
4
+ return new Promise((resolve, reject) => {
5
+ let ended = false
6
+ let pending = 0
7
+ let settled = false
8
+ let failure
9
+ const finish = error => {
10
+ if (error !== undefined) failure ??= error
11
+ if (settled || (!ended && failure === undefined) || pending > 0) return
12
+ settled = true
13
+ if (failure === undefined) resolve()
14
+ else reject(failure)
15
+ }
16
+ source.on('data', chunk => {
17
+ source.pause()
18
+ pending += 1
19
+ destination.write(chunk, error => {
20
+ pending -= 1
21
+ if (error !== null && error !== undefined) { finish(error); return }
22
+ if (failure === undefined) source.resume()
23
+ finish()
24
+ })
25
+ })
26
+ source.once('end', () => { ended = true; finish() })
27
+ source.once('error', error => { ended = true; finish(error) })
28
+ })
29
+ }
@@ -0,0 +1,134 @@
1
+ import { createContext, runInContext, runInThisContext } from 'node:vm'
2
+ import { types } from 'node:util'
3
+ import { protectNextAsyncLocalStorageRun } from './async-local-storage-intrinsics.js'
4
+
5
+ export const WORKER_REPL_OPTIONS = Object.freeze({ useGlobal: true })
6
+ const NativeMap = Map
7
+ const ownKeys = Reflect.ownKeys
8
+ const deleteProperty = Reflect.deleteProperty
9
+ const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
10
+ const defineProperty = Object.defineProperty
11
+ const createObject = Object.create
12
+ const hasOwn = Object.hasOwn
13
+ const sameValue = Object.is
14
+ const isMap = types.isMap
15
+ const mapSet = Function.prototype.call.bind(Map.prototype.set)
16
+ const mapHas = Function.prototype.call.bind(Map.prototype.has)
17
+ const mapForEach = Function.prototype.call.bind(Map.prototype.forEach)
18
+ const DESCRIPTOR_FIELDS = ['configurable', 'enumerable', 'writable', 'value', 'get', 'set']
19
+
20
+ /** Snapshot the native worker surface before Node installs REPL conveniences. */
21
+ export function captureWorkerReplGlobals(globalObject = globalThis) {
22
+ const baseline = new NativeMap()
23
+ const keys = ownKeys(globalObject)
24
+ for (let index = 0; index < keys.length; index += 1) {
25
+ mapSet(baseline, keys[index], getOwnPropertyDescriptor(globalObject, keys[index]))
26
+ }
27
+ return baseline
28
+ }
29
+
30
+ function descriptorsEqual(left, right) {
31
+ const field = (descriptor, name) => descriptor !== undefined && hasOwn(descriptor, name)
32
+ ? descriptor[name] : undefined
33
+ return left !== undefined && right !== undefined
34
+ && field(left, 'configurable') === field(right, 'configurable')
35
+ && field(left, 'enumerable') === field(right, 'enumerable')
36
+ && field(left, 'writable') === field(right, 'writable')
37
+ && sameValue(field(left, 'value'), field(right, 'value'))
38
+ && field(left, 'get') === field(right, 'get')
39
+ && field(left, 'set') === field(right, 'set')
40
+ }
41
+
42
+ function detachedDescriptor(descriptor) {
43
+ const detached = createObject(null)
44
+ for (let index = 0; index < DESCRIPTOR_FIELDS.length; index += 1) {
45
+ const name = DESCRIPTOR_FIELDS[index]
46
+ if (hasOwn(descriptor, name)) detached[name] = descriptor[name]
47
+ }
48
+ return detached
49
+ }
50
+
51
+ /** Remove Node's REPL-only module shortcuts and restore changed native globals. */
52
+ export function restoreWorkerReplGlobals(baseline, globalObject = globalThis) {
53
+ if (!isMap(baseline)) throw new TypeError('worker REPL global baseline must be a Map')
54
+ const keys = ownKeys(globalObject)
55
+ for (let index = 0; index < keys.length; index += 1) {
56
+ const key = keys[index]
57
+ if (typeof key === 'string' && !mapHas(baseline, key) && !deleteProperty(globalObject, key)) {
58
+ throw new Error(`worker REPL added a non-configurable global ${String(key)}`)
59
+ }
60
+ }
61
+ mapForEach(baseline, (descriptor, key) => {
62
+ if (!descriptorsEqual(getOwnPropertyDescriptor(globalObject, key), descriptor)) {
63
+ defineProperty(globalObject, key, detachedDescriptor(descriptor))
64
+ }
65
+ })
66
+ return globalObject
67
+ }
68
+
69
+ /** A dedicated worker is the native realm shared by its REPL and Node modules. */
70
+ export function workerReplContext(server) {
71
+ if (server.context !== globalThis) {
72
+ throw new Error('worker REPL did not use its native global realm')
73
+ }
74
+ return server.context
75
+ }
76
+
77
+ let replAsyncContextProtected = false
78
+
79
+ /** Newer Node REPLs own an AsyncLocalStorage instance whose public prototype
80
+ * remains user-mutable. Give only that platform instance its native operations
81
+ * before the first user evaluation. */
82
+ export function protectWorkerReplAsyncContext(server) {
83
+ if (replAsyncContextProtected) return
84
+ let callbackError
85
+ const scope = protectNextAsyncLocalStorageRun(() => {
86
+ server.eval('void 0\n', server.context, 'ptc-plus-repl-bootstrap', error => { callbackError = error })
87
+ })
88
+ if (callbackError !== null && callbackError !== undefined) throw callbackError
89
+ replAsyncContextProtected = true
90
+ return scope !== undefined
91
+ }
92
+
93
+ export function runInWorkerReplRealm(source, options) {
94
+ return runInThisContext(source, options)
95
+ }
96
+
97
+ /** Control promises stay outside the user-mutable worker realm. */
98
+ export function createWorkerControlPromise() {
99
+ return runInContext('Promise', createContext())
100
+ }
101
+
102
+ /** PTC owns settlement; the REPL's legacy domain would run Node bookkeeping
103
+ * through user-mutable prototypes in the shared worker realm. */
104
+ export function disableWorkerReplDomain(domain) {
105
+ domain.enter = () => domain
106
+ domain.exit = () => domain
107
+ return domain
108
+ }
109
+
110
+ /** Newer REPLs format errors before the eval callback unless an owned
111
+ * evaluation consumes the original thrown value through handleError. */
112
+ export function createWorkerReplErrorHandler(evaluationScope, settle) {
113
+ return error => {
114
+ const finish = evaluationScope.getStore()
115
+ if (finish === undefined) return 'unhandled'
116
+ settle(finish, error)
117
+ return 'ignore'
118
+ }
119
+ }
120
+
121
+ /** Older REPLs can bypass handleError. Keep their process-level fallback
122
+ * directly testable without requiring a version-specific uncaught event. */
123
+ export function createWorkerUncaughtExceptionHandler(evaluationScope, listenerOwner = process) {
124
+ const handleUncaughtException = error => {
125
+ const finish = evaluationScope.getStore()
126
+ if (finish !== undefined) {
127
+ finish(true, error)
128
+ return
129
+ }
130
+ listenerOwner.removeListener('uncaughtException', handleUncaughtException)
131
+ throw error
132
+ }
133
+ return handleUncaughtException
134
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shutdown protocol shared by the plugin's worker entries.
3
+ *
4
+ * Each worker entry releases the machinery it owns when it receives the request
5
+ * and reports that release with the acknowledgement. The release, the real exit
6
+ * and the kill bound belong to the helper process boundary in
7
+ * isolated-worker.js; these two constants are the only part the worker entries
8
+ * themselves need.
9
+ */
10
+
11
+ /** Request that asks one worker to release everything it owns and stop. */
12
+ export const WORKER_SHUTDOWN_REQUEST = 'shutdown'
13
+ /** Reply a worker posts after releasing its own machinery, before it exits. */
14
+ export const WORKER_SHUTDOWN_ACKNOWLEDGEMENT = 'shutdown-released'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-ptc-plus",
3
- "version": "0.3.2",
3
+ "version": "0.4.2",
4
4
  "description": "A session-bound agent-native REPL for DeepSeek Harness PTC mode.",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -12,6 +12,16 @@
12
12
  "files": [
13
13
  "index.js",
14
14
  "client.js",
15
+ "compiler-core.cjs",
16
+ "compiler-core.cjs.map",
17
+ "compiler-platform.cjs",
18
+ "compiler-platform.cjs.map",
19
+ "compiler-typescript.cjs",
20
+ "compiler-typescript.cjs.map",
21
+ "compiler-amaro.cjs",
22
+ "compiler-amaro.cjs.map",
23
+ "compiler-assets.json",
24
+ "compiler-asset-*.txt",
15
25
  "src",
16
26
  "internal",
17
27
  "docs",
@@ -21,6 +31,8 @@
21
31
  "assets/ptc-plus-bindings-zh.png",
22
32
  "assets/ptc-plus-repair-zh.png",
23
33
  "assets/ptc-plus-repair-en.png",
34
+ "assets/ptc-plus-repl-workspace-en.png",
35
+ "assets/ptc-plus-repl-workspace-zh.png",
24
36
  "assets/ptc-plus-settings-en.png",
25
37
  "assets/ptc-plus-settings-zh.png",
26
38
  "cordis.patch.yml",
@@ -36,28 +48,56 @@
36
48
  },
37
49
  "dependencies": {
38
50
  "@babel/code-frame": "^7.29.7",
51
+ "@babel/core": "^7.29.7",
52
+ "@babel/generator": "^7.29.8",
53
+ "@babel/helper-create-class-features-plugin": "^7.29.7",
39
54
  "@babel/parser": "^7.29.0",
55
+ "@babel/plugin-proposal-decorators": "^7.29.7",
56
+ "@babel/plugin-transform-explicit-resource-management": "^7.29.7",
57
+ "@babel/plugin-transform-optional-chaining": "^7.29.7",
58
+ "@babel/plugin-transform-typescript": "^7.29.7",
40
59
  "@babel/traverse": "^7.29.0",
60
+ "@codemirror/lang-javascript": "^6.2.5",
61
+ "@codemirror/language": "^6.12.4",
62
+ "@codemirror/state": "^6.7.4",
63
+ "@codemirror/view": "^6.43.11",
41
64
  "@deepseek-ai/schemastery": "^3.18.1",
42
- "acorn": "^8.15.0"
65
+ "@jridgewell/trace-mapping": "^0.3.31",
66
+ "@lezer/highlight": "^1.2.3",
67
+ "acorn": "^8.15.0",
68
+ "amaro": "1.1.11",
69
+ "codemirror": "^6.0.2",
70
+ "fflate": "^0.8.3",
71
+ "pathe": "^2.0.3",
72
+ "tslib": "^2.8.1",
73
+ "typescript": "^6.0.3"
43
74
  },
44
75
  "peerDependencies": {
76
+ "@deepseek-ai/dsh-atomic-write": "*",
77
+ "@deepseek-ai/dsh-home-paths": "*",
78
+ "@deepseek-ai/dsh-llm": "*",
45
79
  "@deepseek-ai/dsh-settings": "*",
46
80
  "@deepseek-ai/dsh-skill-filesystem": "*",
47
81
  "@deepseek-ai/dsh-tool-cordis": "*",
48
- "@deepseek-ai/dsh-tools": "*"
82
+ "@deepseek-ai/dsh-tools": "*",
83
+ "@deepseek-ai/dsh-typert-protocol": "*"
49
84
  },
50
85
  "scripts": {
51
- "build": "node scripts/client-bundle.mjs build",
52
- "build:check": "node scripts/client-bundle.mjs check",
86
+ "build": "node scripts/client-bundle.mjs build && node scripts/compiler-bundle.mjs build",
87
+ "build:check": "node scripts/client-bundle.mjs check && node scripts/compiler-bundle.mjs check",
88
+ "test:client": "vitest run --config scripts/client-test.config.mjs",
89
+ "test:semantics": "node --test --test-concurrency=1 test/semantic-test262.test.js test/semantic-dialect.test.js test/semantic-boundaries.test.js",
90
+ "test:client:web": "node scripts/client-web-smoke.mjs",
91
+ "test:client:layout": "node scripts/client-binding-layout.mjs",
53
92
  "prepack": "npm run build:check",
54
93
  "hooks:install": "node scripts/review-findings.mjs install-hook",
55
94
  "review:new": "node scripts/review-findings.mjs create",
56
95
  "review:validate": "node scripts/review-findings.mjs validate",
57
96
  "review:gate": "node scripts/review-findings.mjs gate",
58
97
  "session:migrate": "node scripts/migrate-session-log.mjs",
59
- "coverage": "node --test --experimental-test-module-mocks --experimental-test-coverage --test-concurrency=1 --test-coverage-include=\"index.js\" --test-coverage-include=\"internal/*.js\" --test-coverage-lines=100 --test-coverage-branches=95 --test-coverage-functions=100 \"test/*.test.js\"",
60
- "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 coverage",
98
+ "coverage": "node scripts/coverage.mjs",
99
+ "coverage:focus": "node scripts/coverage.mjs --focus",
100
+ "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",
61
101
  "check": "node scripts/review-findings.mjs check",
62
102
  "test:expensive": "node scripts/expensive-headless-acceptance.mjs",
63
103
  "test:ab": "node scripts/ab-headless-trajectories.mjs"
@@ -89,21 +129,50 @@
89
129
  "react"
90
130
  ],
91
131
  "inject": [
132
+ "@deepseek-ai/dsh-api-gateway",
133
+ "@deepseek-ai/dsh-api-remotes",
92
134
  "@deepseek-ai/dsh-client-runtime",
93
135
  "@deepseek-ai/dsh-client-locale",
94
136
  "@deepseek-ai/dsh-client-ui-settings",
95
137
  "@deepseek-ai/dsh-client-ui-settings-plugins",
138
+ "@deepseek-ai/dsh-client-ui-conversation",
96
139
  "@deepseek-ai/dsh-client-connection",
97
140
  "@deepseek-ai/dsh-client-ui-primitives"
98
141
  ]
99
142
  }
100
143
  },
101
144
  "devDependencies": {
145
+ "@deepseek-ai/dsh-agent-loop": "next",
146
+ "@deepseek-ai/dsh-api-gateway": "next",
147
+ "@deepseek-ai/dsh-api-remotes": "next",
148
+ "@deepseek-ai/dsh-atomic-write": "next",
149
+ "@deepseek-ai/dsh-client-locale": "next",
150
+ "@deepseek-ai/dsh-client-store": "next",
151
+ "@deepseek-ai/dsh-client-test-runtime": "next",
152
+ "@deepseek-ai/dsh-client-ui-conversation": "next",
153
+ "@deepseek-ai/dsh-client-ui-primitives": "next",
154
+ "@deepseek-ai/dsh-client-ui-renderer": "next",
155
+ "@deepseek-ai/dsh-client-ui-session": "next",
156
+ "@deepseek-ai/dsh-client-ui-slots": "next",
157
+ "@deepseek-ai/dsh-commands": "next",
158
+ "@deepseek-ai/dsh-home-paths": "next",
159
+ "@deepseek-ai/dsh-llm": "next",
160
+ "@deepseek-ai/dsh-session-persistence-jsonl": "next",
102
161
  "@deepseek-ai/dsh-settings": "next",
103
162
  "@deepseek-ai/dsh-skill-filesystem": "next",
104
163
  "@deepseek-ai/dsh-tool-cordis": "next",
105
164
  "@deepseek-ai/dsh-tools": "next",
165
+ "@deepseek-ai/dsh-typert-protocol": "next",
166
+ "@deepseek-ai/dsh-typert-registry": "next",
167
+ "@testing-library/react": "^16.3.3",
168
+ "c8": "^12.0.0",
169
+ "convert-source-map": "^2.0.0",
106
170
  "esbuild": "0.28.2",
171
+ "jsdom": "^29.1.1",
172
+ "playwright": "^1.63.0",
173
+ "react": "^18.3.1",
174
+ "react-dom": "^18.3.1",
175
+ "vitest": "^5.0.0",
107
176
  "yaml": "^2.9.0"
108
177
  }
109
178
  }