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.
- package/README.en.md +63 -80
- package/README.md +63 -80
- package/assets/ptc-plus-bindings-en.png +0 -0
- package/assets/ptc-plus-bindings-zh.png +0 -0
- package/assets/ptc-plus-repair-en.png +0 -0
- package/assets/ptc-plus-repair-zh.png +0 -0
- package/assets/ptc-plus-repl-workspace-en.png +0 -0
- package/assets/ptc-plus-repl-workspace-zh.png +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.js +30827 -742
- package/compiler-amaro.cjs +5 -0
- package/compiler-amaro.cjs.map +6 -0
- package/compiler-asset-124f80c1bba92ff5fe79cfec6e8ad518f476de4a42514cae3919538887f510e8.txt +1 -0
- package/compiler-assets.json +3 -0
- package/compiler-core.cjs +556 -0
- package/compiler-core.cjs.map +6 -0
- package/compiler-platform.cjs +2 -0
- package/compiler-platform.cjs.map +6 -0
- package/compiler-typescript.cjs +388 -0
- package/compiler-typescript.cjs.map +6 -0
- package/docs/README.md +7 -0
- package/docs/adr/0004-declare-program-bindings-at-the-host.md +1 -1
- package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +5 -3
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +1 -1
- package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -0
- package/docs/adr/0010-session-log-derived-recovery-tips.md +59 -5
- package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +1 -1
- package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +3 -1
- package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +3 -1
- package/docs/adr/0014-persist-cell-rewrite-policy.md +6 -2
- package/docs/adr/0015-preserve-source-positions-through-rewrites.md +1 -1
- package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +49 -0
- package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +3 -3
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +5 -3
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +12 -0
- package/docs/adr/0023-global-user-bindings.md +104 -0
- package/docs/adr/0024-repl-console-observation.md +33 -0
- package/docs/adr/0025-use-versioned-logical-binding-identities.md +119 -0
- package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +21 -0
- package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +37 -0
- package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +103 -0
- package/docs/adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md +27 -0
- package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +27 -0
- package/docs/architecture.md +77 -21
- package/docs/binding-review-placement-design.md +200 -0
- package/docs/capability-projection.md +1 -1
- package/docs/client-ui.md +95 -19
- package/docs/durability-design.md +28 -10
- package/docs/evaluation.md +78 -6
- package/docs/installation.md +41 -6
- package/docs/publishing.md +5 -3
- package/docs/runtime-reference.md +76 -25
- package/docs/semantic-validation.md +29 -0
- package/docs/stateful-binding-updates-proposal.md +759 -0
- package/docs/user-bindings.en.md +66 -0
- package/docs/user-bindings.md +66 -0
- package/docs/value-wire.md +3 -3
- package/docs/verification-optimization-work.md +41 -0
- package/docs/verification.md +71 -0
- package/index.js +369 -92
- package/internal/ast-traversal.js +5 -2
- package/internal/async-local-storage-intrinsics.js +38 -0
- package/internal/binding-declaration-contract.js +8 -0
- package/internal/binding-descriptors.js +1 -0
- package/internal/binding-pattern-traversal.js +25 -0
- package/internal/binding-pattern.js +26 -29
- package/internal/binding-source-analysis.js +708 -0
- package/internal/binding-update-policy.js +72 -0
- package/internal/bounded-worker-round.js +56 -0
- package/internal/callable-definition-environment.js +42 -0
- package/internal/callable-source-catalog.js +129 -0
- package/internal/callable-source-encoding.js +47 -0
- package/internal/callable-source-facts.js +459 -0
- package/internal/callable-source-format.js +2 -0
- package/internal/callable-source-lowering.js +123 -0
- package/internal/cell-analysis-contract.js +25 -0
- package/internal/cell-analysis.js +253 -290
- package/internal/cell-completion.js +15 -0
- package/internal/cell-error.js +7 -0
- package/internal/cell-parser.js +66 -0
- package/internal/cell-rewriter.js +3 -677
- package/internal/commonjs-export-evidence.js +63 -0
- package/internal/commonjs-source-evidence.js +72 -0
- package/internal/compiler-amaro.cjs +2 -0
- package/internal/compiler-compression.js +12 -0
- package/internal/compiler-data.js +58 -0
- package/internal/compiler-descriptors.js +54 -0
- package/internal/compiler-dynamic-cache.js +48 -0
- package/internal/compiler-entry.js +35 -0
- package/internal/compiler-generated-names.js +17 -0
- package/internal/compiler-intrinsics.js +50 -0
- package/internal/compiler-module-links.js +37 -0
- package/internal/compiler-operations.js +61 -0
- package/internal/compiler-platform-factory.js +84 -0
- package/internal/compiler-platform.js +136 -0
- package/internal/compiler-record-roles.js +53 -0
- package/internal/compiler-region-output.js +259 -0
- package/internal/compiler-resource-lowering.js +103 -0
- package/internal/compiler-scope-facts.js +115 -0
- package/internal/compiler-service.js +109 -0
- package/internal/compiler-source-cache.js +32 -0
- package/internal/compiler-source-pieces.js +93 -0
- package/internal/compiler-source-regions.js +132 -0
- package/internal/compiler-storage-source.js +54 -0
- package/internal/compiler-text.js +15 -0
- package/internal/compiler-typescript.cjs +2 -0
- package/internal/config-spec.js +83 -27
- package/internal/cordis-tools-owner.js +130 -21
- package/internal/diagnostic.js +27 -1
- package/internal/direct-surface-owner.js +76 -23
- package/internal/dynamic-binding-evidence.js +16 -0
- package/internal/dynamic-environment-compiler.js +779 -0
- package/internal/dynamic-environment-integration.js +91 -0
- package/internal/dynamic-environment-runtime.js +383 -0
- package/internal/dynamic-native-calls.js +153 -0
- package/internal/dynamic-native-runtime.js +262 -0
- package/internal/dynamic-scope-analysis.js +90 -0
- package/internal/edit-transport-owner.js +27 -2
- package/internal/execution-seam-compat.js +193 -0
- package/internal/failure-reporting.js +136 -28
- package/internal/host-rpc.js +66 -0
- package/internal/isolated-worker.js +555 -0
- package/internal/kernel-child.js +139 -0
- package/internal/kernel-worker.js +1179 -233
- package/internal/language-semantics.js +14 -0
- package/internal/legacy-binding-catalog.js +48 -0
- package/internal/legacy-cell-analysis.js +600 -0
- package/internal/legacy-cell-parser.js +50 -0
- package/internal/legacy-cell-rewriter.js +631 -0
- package/internal/legacy-repl-convenience.js +291 -0
- package/internal/managed-module-operations.js +170 -0
- package/internal/module-compilation.js +322 -0
- package/internal/module-runtime-platform.js +19 -0
- package/internal/module-transform-contract.js +42 -0
- package/internal/native-await-declarations.js +68 -0
- package/internal/native-root-compilation.js +54 -0
- package/internal/native-root-dynamic.js +67 -0
- package/internal/record-utils.js +24 -15
- package/internal/recovery-tips.js +27 -15
- package/internal/rejected-cell-editor.js +13 -8
- package/internal/repl-convenience.js +2 -289
- package/internal/repl-memory-projection.js +81 -12
- package/internal/repl-observation-interest.js +70 -0
- package/internal/repl-rewrite-contract.js +6 -0
- package/internal/repl-scope-normalizer.js +2091 -0
- package/internal/repl-value-observer.js +117 -0
- package/internal/rpc-contract.js +52 -0
- package/internal/runtime-bridge-owner.js +172 -28
- package/internal/runtime-config.js +48 -52
- package/internal/runtime-contexts.js +82 -10
- package/internal/runtime-intrinsics.js +101 -0
- package/internal/runtime-messages.js +111 -0
- package/internal/session-cell-executor.js +402 -87
- package/internal/session-journal-recovery.js +684 -0
- package/internal/session-journal-schema.js +123 -0
- package/internal/session-journal.js +199 -654
- package/internal/session-log-view.js +42 -9
- package/internal/session-runtime.js +257 -95
- package/internal/session-state.js +247 -71
- package/internal/source-position-map.js +230 -71
- package/internal/stateful-module-compiler.js +154 -0
- package/internal/stateful-module-runtime.js +303 -0
- package/internal/stateful-root-compiler.js +600 -0
- package/internal/stateful-root-runtime.js +340 -0
- package/internal/typert-codec-compat.js +28 -0
- package/internal/typescript-transform.js +31 -0
- package/internal/user-binding-authoring.js +70 -0
- package/internal/user-binding-console-worker.js +244 -0
- package/internal/user-binding-console.js +148 -0
- package/internal/user-binding-draft-projection.js +335 -0
- package/internal/user-binding-model-context.js +31 -0
- package/internal/user-binding-runner.js +56 -0
- package/internal/user-bindings-owner.js +1065 -0
- package/internal/user-bindings-store.js +293 -0
- package/internal/user-bindings.js +361 -0
- package/internal/value-wire-schema.js +28 -0
- package/internal/value-wire.js +130 -91
- package/internal/worker-client.js +57 -67
- package/internal/worker-cwd-virtualization.js +80 -53
- package/internal/worker-environment.js +65 -0
- package/internal/worker-output-relay.js +29 -0
- package/internal/worker-repl-realm.js +134 -0
- package/internal/worker-shutdown.js +14 -0
- package/package.json +76 -7
- package/src/client-activity.js +95 -53
- package/src/client-authoring-view.js +580 -0
- package/src/client-binding-review.js +230 -0
- package/src/client-bindings-data.js +29 -0
- package/src/client-catalog.js +127 -0
- package/src/client-code-editor.js +84 -0
- package/src/client-console.js +112 -0
- package/src/client-copy.js +370 -0
- package/src/client-feature-gates.js +62 -0
- package/src/client-host-compat.js +150 -0
- package/src/client-indicator-view.js +267 -0
- package/src/client-repl-view.js +292 -0
- package/src/client-rpc.js +20 -0
- package/src/client-settings-view.js +221 -0
- package/src/client-styles.js +106 -0
- package/src/client-tool-view.js +108 -0
- package/src/client-transport.js +159 -0
- package/src/client-workbench.js +521 -0
- 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
|
|
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)
|
|
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 + (
|
|
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 (
|
|
70
|
-
const absolute = isAbsolute(
|
|
71
|
-
return absolute ? 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 + (
|
|
127
|
+
return sessionCwd + (regexpTest(TRAILING_SEPARATOR, sessionCwd) ? '' : sep) + value
|
|
78
128
|
}
|
|
79
129
|
const projectPaths = (args, indices) => {
|
|
80
|
-
const next =
|
|
81
|
-
for (
|
|
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 =
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
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 =>
|
|
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,
|
|
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
|
+
"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
|
-
"
|
|
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
|
|
60
|
-
"
|
|
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
|
}
|