dsh-ptc-plus 0.3.1 → 0.4.1
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 +66 -73
- package/README.md +66 -73
- 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 +30610 -722
- 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 +554 -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 +6 -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 +6 -4
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +15 -3
- 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 +9 -3
- package/docs/adr/0014-persist-cell-rewrite-policy.md +11 -5
- 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 +8 -6
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +17 -3
- 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 +82 -22
- package/docs/binding-review-placement-design.md +200 -0
- package/docs/capability-projection.md +1 -1
- package/docs/client-ui.md +96 -20
- package/docs/durability-design.md +61 -24
- package/docs/evaluation.md +78 -6
- package/docs/installation.md +41 -6
- package/docs/program-data-plane.md +6 -0
- package/docs/publishing.md +5 -3
- package/docs/runtime-reference.md +79 -25
- package/docs/semantic-validation.md +29 -0
- package/docs/stateful-binding-updates-proposal.md +755 -0
- package/docs/user-bindings.en.md +64 -0
- package/docs/user-bindings.md +64 -0
- package/docs/value-wire.md +3 -3
- package/docs/verification.md +57 -0
- package/index.js +374 -92
- package/internal/ast-traversal.js +5 -2
- 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 +391 -0
- package/internal/binding-update-policy.js +66 -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 +252 -242
- 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 -553
- 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 +84 -0
- package/internal/compiler-module-links.js +34 -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 +91 -25
- 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 +87 -0
- package/internal/dynamic-environment-runtime.js +362 -0
- package/internal/dynamic-native-calls.js +150 -0
- package/internal/dynamic-native-runtime.js +248 -0
- package/internal/dynamic-scope-analysis.js +90 -0
- package/internal/edit-transport-owner.js +28 -3
- package/internal/execution-seam-compat.js +193 -0
- package/internal/failure-reporting.js +118 -18
- package/internal/host-rpc.js +66 -0
- package/internal/isolated-worker.js +548 -0
- package/internal/kernel-child.js +139 -0
- package/internal/kernel-worker.js +911 -116
- 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 +321 -0
- package/internal/module-runtime-platform.js +19 -0
- package/internal/module-transform-contract.js +12 -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/recovery-tips.js +27 -15
- package/internal/rejected-cell-editor.js +13 -8
- package/internal/repl-convenience.js +2 -201
- package/internal/repl-memory-projection.js +81 -12
- package/internal/repl-observation-interest.js +70 -0
- package/internal/repl-rewrite-contract.js +21 -0
- package/internal/repl-scope-normalizer.js +2091 -0
- package/internal/repl-value-observer.js +114 -0
- package/internal/rpc-contract.js +52 -0
- package/internal/runtime-bridge-owner.js +172 -28
- package/internal/runtime-config.js +48 -51
- package/internal/runtime-contexts.js +82 -10
- package/internal/runtime-messages.js +111 -0
- package/internal/session-cell-executor.js +455 -91
- package/internal/session-journal-recovery.js +684 -0
- package/internal/session-journal-schema.js +106 -0
- package/internal/session-journal.js +237 -440
- package/internal/session-log-view.js +42 -9
- package/internal/session-runtime.js +325 -80
- package/internal/session-state.js +249 -40
- package/internal/source-position-map.js +211 -71
- package/internal/stateful-module-compiler.js +154 -0
- package/internal/stateful-module-runtime.js +303 -0
- package/internal/stateful-root-compiler.js +598 -0
- package/internal/stateful-root-runtime.js +340 -0
- package/internal/typert-codec-compat.js +28 -0
- package/internal/typescript-transform.js +29 -0
- package/internal/user-binding-authoring.js +70 -0
- package/internal/user-binding-console-worker.js +184 -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 +353 -0
- package/internal/value-wire-schema.js +28 -0
- package/internal/value-wire.js +29 -20
- package/internal/worker-client.js +57 -67
- package/internal/worker-environment.js +45 -0
- package/internal/worker-output-relay.js +29 -0
- package/internal/worker-shutdown.js +14 -0
- package/package.json +81 -11
- package/src/client-activity.js +109 -45
- 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
package/internal/value-wire.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
import { assertFields, isRecord } from './record-utils.js'
|
|
2
|
+
import {
|
|
3
|
+
VALUE_CODEC,
|
|
4
|
+
DEFAULT_VALUE_LIMITS,
|
|
5
|
+
VALUE_ENVELOPE_FIELDS as ENVELOPE_FIELDS,
|
|
6
|
+
VALUE_OBJECT_FIELDS as OBJECT_NODE_FIELDS,
|
|
7
|
+
VALUE_ARRAY_FIELDS as ARRAY_NODE_FIELDS,
|
|
8
|
+
VALUE_UNDEFINED_FIELDS as UNDEFINED_FIELDS,
|
|
9
|
+
VALUE_NUMBER_FIELDS as NUMBER_FIELDS,
|
|
10
|
+
VALUE_BIGINT_FIELDS as BIGINT_FIELDS,
|
|
11
|
+
VALUE_REFERENCE_FIELDS as REFERENCE_FIELDS,
|
|
12
|
+
} from './value-wire-schema.js'
|
|
2
13
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
export const DEFAULT_VALUE_LIMITS = Object.freeze({
|
|
6
|
-
maxNodes: 100_000,
|
|
7
|
-
maxEdges: 1_000_000,
|
|
8
|
-
maxArrayLength: 1_000_000,
|
|
9
|
-
maxBigIntDigits: 100_000,
|
|
10
|
-
maxStringBytes: 64 * 1024 * 1024,
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
const ENVELOPE_FIELDS = new Set(['codec', 'root', 'nodes'])
|
|
14
|
-
const OBJECT_NODE_FIELDS = new Set(['type', 'prototype', 'entries'])
|
|
15
|
-
const ARRAY_NODE_FIELDS = new Set(['type', 'length', 'entries'])
|
|
16
|
-
const UNDEFINED_FIELDS = new Set(['tag'])
|
|
17
|
-
const NUMBER_FIELDS = new Set(['tag', 'value'])
|
|
18
|
-
const BIGINT_FIELDS = new Set(['tag', 'value'])
|
|
19
|
-
const REFERENCE_FIELDS = new Set(['tag', 'index'])
|
|
14
|
+
export { VALUE_CODEC, DEFAULT_VALUE_LIMITS } from './value-wire-schema.js'
|
|
20
15
|
const IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/
|
|
21
16
|
|
|
22
17
|
function limitsOf(options = {}) {
|
|
@@ -338,7 +333,10 @@ function atomText(atom) {
|
|
|
338
333
|
/** Deterministic bounded TS-like presentation. It is never a decode format. */
|
|
339
334
|
export function renderValueWire(wire, options = {}) {
|
|
340
335
|
const limits = limitsOf(options)
|
|
341
|
-
|
|
336
|
+
return renderCanonicalValue(decodeCanonicalValue(wire, limits).wire, limits)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function renderCanonicalValue(normalized, limits) {
|
|
342
340
|
const references = new Array(normalized.nodes.length).fill(0)
|
|
343
341
|
const count = (atom) => {
|
|
344
342
|
if (isRecord(atom) && atom.tag === 'reference') references[atom.index] += 1
|
|
@@ -416,6 +414,17 @@ export function renderValueWire(wire, options = {}) {
|
|
|
416
414
|
* text. The untagged ranges overlap because a plain JSON root may itself be a string.
|
|
417
415
|
*/
|
|
418
416
|
export function projectValueWire(wire, options = {}) {
|
|
419
|
-
|
|
420
|
-
|
|
417
|
+
return prepareValueWire(wire, options).projectedValue
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/** Validate once when canonical storage and outer presentation are both required. */
|
|
421
|
+
export function prepareValueWire(wire, options = {}) {
|
|
422
|
+
const limits = limitsOf(options)
|
|
423
|
+
const canonical = decodeCanonicalValue(wire, limits)
|
|
424
|
+
return {
|
|
425
|
+
wire: canonical.wire,
|
|
426
|
+
projectedValue: isPlainJsonTree(canonical.value)
|
|
427
|
+
? canonical.value
|
|
428
|
+
: renderCanonicalValue(canonical.wire, limits),
|
|
429
|
+
}
|
|
421
430
|
}
|
|
@@ -1,65 +1,32 @@
|
|
|
1
1
|
import { mkdtemp, rm } from 'node:fs/promises'
|
|
2
2
|
import { tmpdir } from 'node:os'
|
|
3
3
|
import { isAbsolute, join } from 'node:path'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { messageOf, processExitDescription } from './failure-reporting.js'
|
|
5
|
+
import { IsolatedOwner } from './isolated-worker.js'
|
|
6
|
+
import { normalizeWorkerEnvironment } from './worker-environment.js'
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
['appdata', 'APPDATA'],
|
|
9
|
-
['comspec', 'ComSpec'],
|
|
10
|
-
['home', 'HOME'],
|
|
11
|
-
['homedrive', 'HOMEDRIVE'],
|
|
12
|
-
['homepath', 'HOMEPATH'],
|
|
13
|
-
['localappdata', 'LOCALAPPDATA'],
|
|
14
|
-
['path', 'PATH'],
|
|
15
|
-
['pathext', 'PATHEXT'],
|
|
16
|
-
['programdata', 'ProgramData'],
|
|
17
|
-
['programfiles', 'ProgramFiles'],
|
|
18
|
-
['programfiles(x86)', 'ProgramFiles(x86)'],
|
|
19
|
-
['systemdrive', 'SystemDrive'],
|
|
20
|
-
['systemroot', 'SystemRoot'],
|
|
21
|
-
['temp', 'TEMP'],
|
|
22
|
-
['tmp', 'TMP'],
|
|
23
|
-
['userprofile', 'USERPROFILE'],
|
|
24
|
-
['windir', 'windir'],
|
|
25
|
-
])
|
|
26
|
-
const HOST_ONLY_ENVIRONMENT_NAMES = new Set(['node_test_context', 'node_v8_coverage'])
|
|
8
|
+
export { normalizeWorkerEnvironment }
|
|
27
9
|
|
|
28
|
-
|
|
29
|
-
export function normalizeWorkerEnvironment(source, platform = process.platform) {
|
|
30
|
-
if (platform !== 'win32') {
|
|
31
|
-
return Object.fromEntries(Object.entries(source).filter(([name, value]) => (
|
|
32
|
-
value !== undefined && !HOST_ONLY_ENVIRONMENT_NAMES.has(name.toLowerCase())
|
|
33
|
-
)))
|
|
34
|
-
}
|
|
35
|
-
const normalized = new Map()
|
|
36
|
-
for (const [name, value] of Object.entries(source)) {
|
|
37
|
-
if (value === undefined) continue
|
|
38
|
-
const key = name.toLowerCase()
|
|
39
|
-
if (HOST_ONLY_ENVIRONMENT_NAMES.has(key)) continue
|
|
40
|
-
const canonicalName = WINDOWS_ENVIRONMENT_NAMES.get(key) ?? name
|
|
41
|
-
const current = normalized.get(key)
|
|
42
|
-
if (current === undefined || name === canonicalName) {
|
|
43
|
-
normalized.set(key, [canonicalName, value])
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return Object.fromEntries(normalized.values())
|
|
47
|
-
}
|
|
10
|
+
const KERNEL_HELPER = new URL('./kernel-child.js', import.meta.url)
|
|
48
11
|
|
|
49
12
|
/** Owns one session kernel's worker process, private port, and scratch directory. */
|
|
50
13
|
export class WorkerClient {
|
|
51
|
-
constructor({ workerUrl, cwd, onMessage, onFailure }) {
|
|
14
|
+
constructor({ workerUrl, cwd, onMessage, onFailure, compilerCache }) {
|
|
52
15
|
this.workerUrl = workerUrl
|
|
53
16
|
this.cwd = cwd
|
|
54
17
|
this.onMessage = onMessage
|
|
55
18
|
this.onFailure = onFailure
|
|
19
|
+
this.compilerCache = compilerCache
|
|
56
20
|
this.worker = undefined
|
|
57
21
|
this.workerLimit = undefined
|
|
58
22
|
this.workerReady = undefined
|
|
59
23
|
this.port = undefined
|
|
60
24
|
this.scratchReady = undefined
|
|
61
25
|
this.stderrTails = new WeakMap()
|
|
62
|
-
|
|
26
|
+
// One owner keeps every started kernel transport, including startup failures
|
|
27
|
+
// and closes that were refused, until its real exit is observed.
|
|
28
|
+
this.owner = new IsolatedOwner()
|
|
29
|
+
this.hostIds = new WeakMap()
|
|
63
30
|
this.disposed = false
|
|
64
31
|
}
|
|
65
32
|
|
|
@@ -101,19 +68,20 @@ export class WorkerClient {
|
|
|
101
68
|
const environment = normalizeWorkerEnvironment(process.env)
|
|
102
69
|
let worker
|
|
103
70
|
try {
|
|
104
|
-
|
|
71
|
+
const started = this.owner.start({
|
|
72
|
+
helper: KERNEL_HELPER,
|
|
73
|
+
entry: this.workerUrl,
|
|
74
|
+
workerData: { cwd: this.cwd, compilerCache: this.compilerCache?.() },
|
|
75
|
+
resourceLimits: { maxOldGenerationSizeMb: this.workerLimit },
|
|
105
76
|
env: {
|
|
106
77
|
...environment,
|
|
107
78
|
TEMP: scratchDirectory,
|
|
108
79
|
TMP: scratchDirectory,
|
|
109
80
|
TMPDIR: scratchDirectory,
|
|
110
81
|
},
|
|
111
|
-
execArgv: [],
|
|
112
|
-
workerData: this.cwd === undefined ? {} : { cwd: this.cwd },
|
|
113
|
-
resourceLimits: { maxOldGenerationSizeMb: this.workerLimit },
|
|
114
|
-
stdout: true,
|
|
115
|
-
stderr: true,
|
|
116
82
|
})
|
|
83
|
+
worker = started.transport
|
|
84
|
+
this.hostIds.set(worker, started.id)
|
|
117
85
|
} catch (error) {
|
|
118
86
|
this.workerLimit = undefined
|
|
119
87
|
throw error
|
|
@@ -129,15 +97,23 @@ export class WorkerClient {
|
|
|
129
97
|
})
|
|
130
98
|
this.stderrTails.set(worker, stderrTail)
|
|
131
99
|
worker.on('error', error => this.fail(worker, `worker error: ${messageOf(error)}`))
|
|
132
|
-
worker.on('exit', code
|
|
100
|
+
worker.on('exit', (code, signal) => {
|
|
101
|
+
this.fail(worker, `worker exited with ${processExitDescription(code, signal)}`)
|
|
102
|
+
})
|
|
133
103
|
this.worker = worker
|
|
134
104
|
this.workerReady = new Promise((resolve, reject) => {
|
|
135
|
-
const onError = error =>
|
|
136
|
-
const onExit = (code) => {
|
|
105
|
+
const onError = error => {
|
|
137
106
|
const detail = this.stderrDetail(worker)
|
|
107
|
+
reject(detail === undefined
|
|
108
|
+
? error
|
|
109
|
+
: new Error(`${messageOf(error)}; last stderr: ${detail}`, { cause: error }))
|
|
110
|
+
}
|
|
111
|
+
const onExit = (code, signal) => {
|
|
112
|
+
const detail = this.stderrDetail(worker)
|
|
113
|
+
const exit = processExitDescription(code, signal)
|
|
138
114
|
reject(new Error(detail === undefined
|
|
139
|
-
? `worker exited with
|
|
140
|
-
: `worker exited with
|
|
115
|
+
? `worker exited with ${exit} before opening its private channel`
|
|
116
|
+
: `worker exited with ${exit} before opening its private channel; last stderr: ${detail}`))
|
|
141
117
|
}
|
|
142
118
|
worker.once('error', onError)
|
|
143
119
|
worker.once('exit', onExit)
|
|
@@ -146,12 +122,16 @@ export class WorkerClient {
|
|
|
146
122
|
worker.removeListener('exit', onExit)
|
|
147
123
|
if (message?.type === 'startup-error' && typeof message.error === 'string') {
|
|
148
124
|
reject(new Error(message.error))
|
|
149
|
-
|
|
125
|
+
// The owner keeps a refused reclamation, so this must not surface as an
|
|
126
|
+
// unhandled rejection after the caller already handled the startup error.
|
|
127
|
+
void this.reset(worker).catch(() => {})
|
|
150
128
|
return
|
|
151
129
|
}
|
|
152
130
|
if (message?.type !== 'ready' || typeof message.port?.postMessage !== 'function') {
|
|
153
131
|
reject(new Error('kernel worker returned an invalid private channel'))
|
|
154
|
-
|
|
132
|
+
// The owner keeps a refused reclamation, so this must not surface as an
|
|
133
|
+
// unhandled rejection after the caller already handled the startup error.
|
|
134
|
+
void this.reset(worker).catch(() => {})
|
|
155
135
|
return
|
|
156
136
|
}
|
|
157
137
|
this.port = message.port
|
|
@@ -185,27 +165,37 @@ export class WorkerClient {
|
|
|
185
165
|
}
|
|
186
166
|
|
|
187
167
|
async reset(worker) {
|
|
168
|
+
const port = this.worker === worker ? this.port : undefined
|
|
188
169
|
if (this.worker === worker) {
|
|
189
170
|
this.worker = undefined
|
|
190
171
|
this.workerLimit = undefined
|
|
191
172
|
this.workerReady = undefined
|
|
192
|
-
this.port?.close()
|
|
193
173
|
this.port = undefined
|
|
194
174
|
}
|
|
195
|
-
|
|
196
|
-
this.
|
|
197
|
-
|
|
198
|
-
await termination
|
|
199
|
-
} finally {
|
|
200
|
-
this.terminations.delete(termination)
|
|
201
|
-
}
|
|
175
|
+
await this.owner.stop(this.hostIds.get(worker))
|
|
176
|
+
this.hostIds.delete(worker)
|
|
177
|
+
port?.close()
|
|
202
178
|
}
|
|
203
179
|
|
|
204
180
|
async dispose() {
|
|
205
181
|
this.disposed = true
|
|
206
182
|
const worker = this.worker
|
|
207
|
-
|
|
208
|
-
|
|
183
|
+
const port = this.port
|
|
184
|
+
this.worker = undefined
|
|
185
|
+
this.workerLimit = undefined
|
|
186
|
+
this.workerReady = undefined
|
|
187
|
+
this.port = undefined
|
|
188
|
+
if (worker !== undefined) this.hostIds.delete(worker)
|
|
189
|
+
const failures = []
|
|
190
|
+
try {
|
|
191
|
+
port?.close()
|
|
192
|
+
} catch (error) {
|
|
193
|
+
failures.push(error)
|
|
194
|
+
}
|
|
195
|
+
failures.push(...await this.owner.dispose())
|
|
196
|
+
if (failures.length > 0) {
|
|
197
|
+
throw new AggregateError(failures, 'ptc-plus kernel worker disposal failed')
|
|
198
|
+
}
|
|
209
199
|
if (this.scratchReady !== undefined) {
|
|
210
200
|
try {
|
|
211
201
|
const scratchDirectory = await this.scratchReady
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
/** Project the host environment once without losing Windows case variants. */
|
|
27
|
+
export function normalizeWorkerEnvironment(source, platform = process.platform) {
|
|
28
|
+
if (platform !== 'win32') {
|
|
29
|
+
return Object.fromEntries(Object.entries(source).filter(([name, value]) => (
|
|
30
|
+
value !== undefined && !HOST_ONLY_ENVIRONMENT_NAMES.has(name.toLowerCase())
|
|
31
|
+
)))
|
|
32
|
+
}
|
|
33
|
+
const normalized = new Map()
|
|
34
|
+
for (const [name, value] of Object.entries(source)) {
|
|
35
|
+
if (value === undefined) continue
|
|
36
|
+
const key = name.toLowerCase()
|
|
37
|
+
if (HOST_ONLY_ENVIRONMENT_NAMES.has(key)) continue
|
|
38
|
+
const canonicalName = WINDOWS_ENVIRONMENT_NAMES.get(key) ?? name
|
|
39
|
+
const current = normalized.get(key)
|
|
40
|
+
if (current === undefined || name === canonicalName) {
|
|
41
|
+
normalized.set(key, [canonicalName, value])
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return Object.fromEntries(normalized.values())
|
|
45
|
+
}
|
|
@@ -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,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.1",
|
|
4
4
|
"description": "A session-bound agent-native REPL for DeepSeek Harness PTC mode.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -12,13 +12,27 @@
|
|
|
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",
|
|
18
28
|
"assets/dsh-ptc-plus-banner-en.webp",
|
|
19
29
|
"assets/dsh-ptc-plus-banner-zh.webp",
|
|
30
|
+
"assets/ptc-plus-bindings-en.png",
|
|
31
|
+
"assets/ptc-plus-bindings-zh.png",
|
|
20
32
|
"assets/ptc-plus-repair-zh.png",
|
|
21
33
|
"assets/ptc-plus-repair-en.png",
|
|
34
|
+
"assets/ptc-plus-repl-workspace-en.png",
|
|
35
|
+
"assets/ptc-plus-repl-workspace-zh.png",
|
|
22
36
|
"assets/ptc-plus-settings-en.png",
|
|
23
37
|
"assets/ptc-plus-settings-zh.png",
|
|
24
38
|
"cordis.patch.yml",
|
|
@@ -34,28 +48,55 @@
|
|
|
34
48
|
},
|
|
35
49
|
"dependencies": {
|
|
36
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",
|
|
37
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",
|
|
38
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",
|
|
39
64
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
40
|
-
"
|
|
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"
|
|
41
74
|
},
|
|
42
75
|
"peerDependencies": {
|
|
76
|
+
"@deepseek-ai/dsh-atomic-write": "*",
|
|
77
|
+
"@deepseek-ai/dsh-home-paths": "*",
|
|
78
|
+
"@deepseek-ai/dsh-llm": "*",
|
|
43
79
|
"@deepseek-ai/dsh-settings": "*",
|
|
44
80
|
"@deepseek-ai/dsh-skill-filesystem": "*",
|
|
45
81
|
"@deepseek-ai/dsh-tool-cordis": "*",
|
|
46
|
-
"@deepseek-ai/dsh-tools": "*"
|
|
82
|
+
"@deepseek-ai/dsh-tools": "*",
|
|
83
|
+
"@deepseek-ai/dsh-typert-protocol": "*"
|
|
47
84
|
},
|
|
48
85
|
"scripts": {
|
|
49
|
-
"build": "node scripts/client-bundle.mjs build",
|
|
50
|
-
"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",
|
|
51
92
|
"prepack": "npm run build:check",
|
|
52
93
|
"hooks:install": "node scripts/review-findings.mjs install-hook",
|
|
53
94
|
"review:new": "node scripts/review-findings.mjs create",
|
|
54
95
|
"review:validate": "node scripts/review-findings.mjs validate",
|
|
55
96
|
"review:gate": "node scripts/review-findings.mjs gate",
|
|
56
97
|
"session:migrate": "node scripts/migrate-session-log.mjs",
|
|
57
|
-
"coverage": "node
|
|
58
|
-
"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
|
+
"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",
|
|
59
100
|
"check": "node scripts/review-findings.mjs check",
|
|
60
101
|
"test:expensive": "node scripts/expensive-headless-acceptance.mjs",
|
|
61
102
|
"test:ab": "node scripts/ab-headless-trajectories.mjs"
|
|
@@ -87,21 +128,50 @@
|
|
|
87
128
|
"react"
|
|
88
129
|
],
|
|
89
130
|
"inject": [
|
|
131
|
+
"@deepseek-ai/dsh-api-gateway",
|
|
132
|
+
"@deepseek-ai/dsh-api-remotes",
|
|
90
133
|
"@deepseek-ai/dsh-client-runtime",
|
|
91
134
|
"@deepseek-ai/dsh-client-locale",
|
|
92
135
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
93
136
|
"@deepseek-ai/dsh-client-ui-settings-plugins",
|
|
137
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
94
138
|
"@deepseek-ai/dsh-client-connection",
|
|
95
139
|
"@deepseek-ai/dsh-client-ui-primitives"
|
|
96
140
|
]
|
|
97
141
|
}
|
|
98
142
|
},
|
|
99
143
|
"devDependencies": {
|
|
100
|
-
"@deepseek-ai/dsh-
|
|
101
|
-
"@deepseek-ai/dsh-
|
|
102
|
-
"@deepseek-ai/dsh-
|
|
103
|
-
"@deepseek-ai/dsh-
|
|
144
|
+
"@deepseek-ai/dsh-agent-loop": "next",
|
|
145
|
+
"@deepseek-ai/dsh-api-gateway": "next",
|
|
146
|
+
"@deepseek-ai/dsh-api-remotes": "next",
|
|
147
|
+
"@deepseek-ai/dsh-atomic-write": "next",
|
|
148
|
+
"@deepseek-ai/dsh-client-locale": "next",
|
|
149
|
+
"@deepseek-ai/dsh-client-store": "next",
|
|
150
|
+
"@deepseek-ai/dsh-client-test-runtime": "next",
|
|
151
|
+
"@deepseek-ai/dsh-client-ui-conversation": "next",
|
|
152
|
+
"@deepseek-ai/dsh-client-ui-primitives": "next",
|
|
153
|
+
"@deepseek-ai/dsh-client-ui-renderer": "next",
|
|
154
|
+
"@deepseek-ai/dsh-client-ui-session": "next",
|
|
155
|
+
"@deepseek-ai/dsh-client-ui-slots": "next",
|
|
156
|
+
"@deepseek-ai/dsh-commands": "next",
|
|
157
|
+
"@deepseek-ai/dsh-home-paths": "next",
|
|
158
|
+
"@deepseek-ai/dsh-llm": "next",
|
|
159
|
+
"@deepseek-ai/dsh-session-persistence-jsonl": "next",
|
|
160
|
+
"@deepseek-ai/dsh-settings": "next",
|
|
161
|
+
"@deepseek-ai/dsh-skill-filesystem": "next",
|
|
162
|
+
"@deepseek-ai/dsh-tool-cordis": "next",
|
|
163
|
+
"@deepseek-ai/dsh-tools": "next",
|
|
164
|
+
"@deepseek-ai/dsh-typert-protocol": "next",
|
|
165
|
+
"@deepseek-ai/dsh-typert-registry": "next",
|
|
166
|
+
"@testing-library/react": "^16.3.3",
|
|
167
|
+
"c8": "^12.0.0",
|
|
168
|
+
"convert-source-map": "^2.0.0",
|
|
104
169
|
"esbuild": "0.28.2",
|
|
170
|
+
"jsdom": "^29.1.1",
|
|
171
|
+
"playwright": "^1.63.0",
|
|
172
|
+
"react": "^18.3.1",
|
|
173
|
+
"react-dom": "^18.3.1",
|
|
174
|
+
"vitest": "^5.0.0",
|
|
105
175
|
"yaml": "^2.9.0"
|
|
106
176
|
}
|
|
107
177
|
}
|