dsh-ptc-plus 0.3.2 → 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 +65 -78
- package/README.md +65 -78
- 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 +30596 -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 +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 +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 +73 -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 +25 -10
- package/docs/evaluation.md +78 -6
- package/docs/installation.md +41 -6
- package/docs/publishing.md +5 -3
- package/docs/runtime-reference.md +72 -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 +369 -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 +240 -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 +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 +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 +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 +27 -2
- 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 +904 -120
- 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 -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 +114 -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-messages.js +111 -0
- package/internal/session-cell-executor.js +401 -87
- package/internal/session-journal-recovery.js +684 -0
- package/internal/session-journal-schema.js +106 -0
- package/internal/session-journal.js +184 -654
- package/internal/session-log-view.js +42 -9
- package/internal/session-runtime.js +256 -95
- package/internal/session-state.js +247 -71
- 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 +75 -7
- package/src/client-activity.js +88 -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
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { constants, createContext, Script } from 'node:vm'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { workerData } from 'node:worker_threads'
|
|
5
|
+
import { deserialize } from 'node:v8'
|
|
6
|
+
import { copyCompilerData } from './compiler-data.js'
|
|
7
|
+
import { PreflightError } from './cell-analysis-contract.js'
|
|
8
|
+
import { ModuleRewriteError } from './cell-error.js'
|
|
9
|
+
import { installCompilerPlatform } from './compiler-platform.js'
|
|
10
|
+
import { compilerDescriptors } from './compiler-descriptors.js'
|
|
11
|
+
|
|
12
|
+
export { PreflightError } from './cell-analysis-contract.js'
|
|
13
|
+
|
|
14
|
+
const bundleUrl = new URL('../compiler-core.cjs', import.meta.url)
|
|
15
|
+
const filename = fileURLToPath(bundleUrl)
|
|
16
|
+
const directory = fileURLToPath(new URL('./', bundleUrl))
|
|
17
|
+
const compilerSource = readFileSync(bundleUrl, 'utf8')
|
|
18
|
+
const NativeScript = Script
|
|
19
|
+
const nativeCreateContext = createContext
|
|
20
|
+
const dontContextify = constants.DONT_CONTEXTIFY
|
|
21
|
+
const runInContext = Script.prototype.runInContext
|
|
22
|
+
const createCachedData = Script.prototype.createCachedData
|
|
23
|
+
const NativeUint8Array = Uint8Array
|
|
24
|
+
const apply = Reflect.apply
|
|
25
|
+
const hasInstance = Function.prototype[Symbol.hasInstance]
|
|
26
|
+
const nativeErrors = { Error, SyntaxError, TypeError, RangeError, ReferenceError,
|
|
27
|
+
EvalError, URIError, ModuleRewriteError, PreflightError }
|
|
28
|
+
const define = compilerDescriptors.defineProperty
|
|
29
|
+
const keys = Object.keys
|
|
30
|
+
let compiler
|
|
31
|
+
let compilerScript
|
|
32
|
+
const coverageEnabled = Boolean(process.env.NODE_V8_COVERAGE)
|
|
33
|
+
const bytecodeFile = process.env.DSH_PTC_COMPILER_BYTECODE
|
|
34
|
+
let workerCache = bytecodeFile ? deserialize(readFileSync(bytecodeFile)) : undefined
|
|
35
|
+
if (workerCache?.source !== compilerSource) workerCache = undefined
|
|
36
|
+
// Bytecode contains no compiler realm or program state. Match the complete
|
|
37
|
+
// source: V8's cache validation alone does not prove source text equality.
|
|
38
|
+
let cachedData = workerData?.compilerCache?.source === compilerSource
|
|
39
|
+
? new NativeUint8Array(workerData.compilerCache.data) : undefined
|
|
40
|
+
// Keep the snapshot private before source code can inspect workerData.
|
|
41
|
+
if (workerData !== null && typeof workerData === 'object') delete workerData.compilerCache
|
|
42
|
+
|
|
43
|
+
/** Reuse compiled compiler code across fresh workers, never their realm state. */
|
|
44
|
+
export function compilerWorkerCache() {
|
|
45
|
+
if (compilerScript === undefined) return undefined
|
|
46
|
+
// Instrumented compiler instances neither produce nor consume bytecode.
|
|
47
|
+
// Coverage's runner supplies a snapshot from its uninstrumented preparation.
|
|
48
|
+
if (workerCache === undefined && coverageEnabled) return undefined
|
|
49
|
+
workerCache ??= { source: compilerSource, data: apply(createCachedData, compilerScript, []) }
|
|
50
|
+
return { source: workerCache.source, data: new NativeUint8Array(workerCache.data) }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Service errors are rehomed here before execution-realm translation. */
|
|
54
|
+
export const isCompilerSyntaxError = error => apply(hasInstance, nativeErrors.SyntaxError, [error])
|
|
55
|
+
|
|
56
|
+
function compilerEntry() {
|
|
57
|
+
if (compiler !== undefined) return compiler
|
|
58
|
+
// Workers can execute host-prepared cells without compiling dynamic source.
|
|
59
|
+
// Capture source and platform before user code, but parse only on first use.
|
|
60
|
+
compilerScript = new NativeScript(compilerSource, { __proto__: null, filename, displayErrors: false,
|
|
61
|
+
cachedData: coverageEnabled ? undefined : cachedData })
|
|
62
|
+
cachedData = undefined
|
|
63
|
+
const context = nativeCreateContext(dontContextify)
|
|
64
|
+
define(context, '__compilerBaseUrl', { value: import.meta.url })
|
|
65
|
+
define(context, '__filename', { value: filename })
|
|
66
|
+
define(context, '__dirname', { value: directory })
|
|
67
|
+
installCompilerPlatform(context)
|
|
68
|
+
apply(runInContext, compilerScript, [context, { __proto__: null, displayErrors: false }])
|
|
69
|
+
compiler = context.module.exports.compile
|
|
70
|
+
return compiler
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function compile(operation, args, originalSource) {
|
|
74
|
+
const result = compilerEntry()(operation, args, originalSource)
|
|
75
|
+
if (result.error !== undefined) {
|
|
76
|
+
const { kind, message, properties } = result.error
|
|
77
|
+
const ErrorClass = nativeErrors[kind] ?? nativeErrors.Error
|
|
78
|
+
const error = ErrorClass === PreflightError
|
|
79
|
+
? new PreflightError(message, undefined, copyCompilerData(properties.span?.value)) : new ErrorClass(message)
|
|
80
|
+
const names = keys(properties)
|
|
81
|
+
for (let index = 0; index < names.length; index++) {
|
|
82
|
+
const name = names[index]
|
|
83
|
+
const property = properties[name]
|
|
84
|
+
if (name === 'stack' || !('value' in property)) continue
|
|
85
|
+
define(error, name, { ...property, value: copyCompilerData(property.value) })
|
|
86
|
+
}
|
|
87
|
+
throw error
|
|
88
|
+
}
|
|
89
|
+
return copyCompilerData(result.value)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const prepareProgram = (source, options) => compile('prepareProgram', [source, options])
|
|
93
|
+
export const prepareConsoleProgram = (source, options) => compile('prepareConsoleProgram', [source, options])
|
|
94
|
+
export const classifyDurability = (source, known, options) => compile('classifyDurability', [source, known, options])
|
|
95
|
+
export const compileModuleSource = (source, options) => compile('compileStatefulModule', [source, options])
|
|
96
|
+
export const detectModuleSourceFormat = (source, options) => compile('detectModuleSourceFormat', [source, options])
|
|
97
|
+
export const attachNamespaceSource = (source, attributes, reference, regions) =>
|
|
98
|
+
compile('attachModuleNamespace', [source, attributes, reference, regions])
|
|
99
|
+
export const linkCommonJsEvidenceSource = (source, prefix) => compile('linkCommonJsEvidenceSource', [source, prefix])
|
|
100
|
+
export const identifier = (value, subject, reserved) => compile('identifier', [value, subject, reserved])
|
|
101
|
+
export const exportedSymbols = (source, transform) => compile('exportedSymbols', [source, transform])
|
|
102
|
+
export const sourceDurability = (source, transform) => compile('sourceDurability', [source, transform])
|
|
103
|
+
export const hashText = (source, encoding, format) => compile('hashText', [source, encoding, format])
|
|
104
|
+
export const deflateText = source => compile('deflateText', [source])
|
|
105
|
+
export const inflateText = (source, maxOutputBytes) => compile('inflateText', [source, maxOutputBytes])
|
|
106
|
+
export const createCallableSourceCatalog = (buffers, ranges) => compile('createCallableSourceCatalog', [buffers, ranges])
|
|
107
|
+
export function compileDynamicSource(source, { resolveOriginalSource, ...options } = {}) {
|
|
108
|
+
return compile('compileDynamicEnvironmentSource', [source, options], resolveOriginalSource)
|
|
109
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { copyCompilerData } from './compiler-data.js'
|
|
2
|
+
|
|
3
|
+
/** Cache source-derived metadata within one compiler generation. Input and
|
|
4
|
+
* output data stay private; callers receive fresh collections on every read. */
|
|
5
|
+
export function createCompilerSourceCache(compute, { maxEntries = 64, maxCharacters = 512 * 1024 } = {}) {
|
|
6
|
+
const entries = new Map()
|
|
7
|
+
let characters = 0
|
|
8
|
+
return (source, transform) => {
|
|
9
|
+
// Unsupported inputs retain the owner's original validation and errors.
|
|
10
|
+
if (typeof source !== 'string' || transform !== undefined && typeof transform !== 'string') {
|
|
11
|
+
return compute(source, transform)
|
|
12
|
+
}
|
|
13
|
+
const key = JSON.stringify([source, transform])
|
|
14
|
+
const cached = entries.get(key)
|
|
15
|
+
if (cached !== undefined) {
|
|
16
|
+
entries.delete(key)
|
|
17
|
+
entries.set(key, cached)
|
|
18
|
+
return copyCompilerData(cached.value)
|
|
19
|
+
}
|
|
20
|
+
const value = compute(source, transform)
|
|
21
|
+
if (maxEntries > 0 && key.length <= maxCharacters) {
|
|
22
|
+
while (entries.size >= maxEntries || characters + key.length > maxCharacters) {
|
|
23
|
+
const oldest = entries.keys().next().value
|
|
24
|
+
entries.delete(oldest)
|
|
25
|
+
characters -= oldest.length
|
|
26
|
+
}
|
|
27
|
+
entries.set(key, { value })
|
|
28
|
+
characters += key.length
|
|
29
|
+
}
|
|
30
|
+
return copyCompilerData(value)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createSourceMapBuilder } from './source-position-map.js'
|
|
2
|
+
|
|
3
|
+
const WIDTH = 6
|
|
4
|
+
const BLOCK_SIZE = 4096
|
|
5
|
+
const TEXT = 0, COPY = 1, MAPPED = 2, JOIN = 3, REGION = 4
|
|
6
|
+
|
|
7
|
+
/** A numeric piece graph owns output without one object per copied token. */
|
|
8
|
+
export function createSourcePieces(source) {
|
|
9
|
+
const blocks = []
|
|
10
|
+
const strings = []
|
|
11
|
+
const regionFacts = []
|
|
12
|
+
const stringIds = new Map()
|
|
13
|
+
let count = 0
|
|
14
|
+
const get = (id, field) => blocks[Math.floor(id / BLOCK_SIZE)][id % BLOCK_SIZE * WIDTH + field]
|
|
15
|
+
const put = (size, kind, left, right = 0, start = 0, end = 0) => {
|
|
16
|
+
if (count % BLOCK_SIZE === 0) blocks.push(new Uint32Array(BLOCK_SIZE * WIDTH))
|
|
17
|
+
const id = count++
|
|
18
|
+
blocks.at(-1).set([size, kind, left, right, start, end], id % BLOCK_SIZE * WIDTH)
|
|
19
|
+
return id
|
|
20
|
+
}
|
|
21
|
+
const stringId = value => {
|
|
22
|
+
let id = stringIds.get(value)
|
|
23
|
+
if (id === undefined) { id = strings.length; strings.push(value); stringIds.set(value, id) }
|
|
24
|
+
return id
|
|
25
|
+
}
|
|
26
|
+
const length = id => get(id, 0)
|
|
27
|
+
const text = value => put(value.length, TEXT, stringId(value))
|
|
28
|
+
const original = (start, end) => put(end - start, COPY, start, end)
|
|
29
|
+
const mapped = (value, node) => put(value.length, MAPPED, stringId(value), 0, node.start, node.end)
|
|
30
|
+
const region = (piece, fact) => {
|
|
31
|
+
const index = regionFacts.length
|
|
32
|
+
regionFacts.push(fact)
|
|
33
|
+
return put(length(piece), REGION, piece, index)
|
|
34
|
+
}
|
|
35
|
+
const empty = text('')
|
|
36
|
+
const pair = (left, right) => {
|
|
37
|
+
if (length(left) === 0) return right
|
|
38
|
+
if (length(right) === 0) return left
|
|
39
|
+
if (get(left, 1) === COPY && get(right, 1) === COPY && get(left, 3) === get(right, 2)) {
|
|
40
|
+
return original(get(left, 2), get(right, 3))
|
|
41
|
+
}
|
|
42
|
+
return put(length(left) + length(right), JOIN, left, right)
|
|
43
|
+
}
|
|
44
|
+
const join = parts => {
|
|
45
|
+
const combine = (start, end) => end <= start ? empty : end === start + 1 ? parts[start]
|
|
46
|
+
: pair(combine(start, (start + end) >>> 1), combine((start + end) >>> 1, end))
|
|
47
|
+
return combine(0, parts.length)
|
|
48
|
+
}
|
|
49
|
+
const slice = (id, start, end = length(id)) => {
|
|
50
|
+
const size = length(id)
|
|
51
|
+
if (start === 0 && end === size) return id
|
|
52
|
+
const kind = get(id, 1), left = get(id, 2), right = get(id, 3)
|
|
53
|
+
if (kind === REGION) return slice(left, start, end)
|
|
54
|
+
if (kind === JOIN) {
|
|
55
|
+
const split = length(left)
|
|
56
|
+
if (end <= split) return slice(left, start, end)
|
|
57
|
+
if (start >= split) return slice(right, start - split, end - split)
|
|
58
|
+
return pair(slice(left, start), slice(right, 0, end - split))
|
|
59
|
+
}
|
|
60
|
+
if (kind === COPY) return original(left + start, left + end)
|
|
61
|
+
const value = strings[left].slice(start, end)
|
|
62
|
+
if (kind === TEXT) return text(value)
|
|
63
|
+
const from = get(id, 4), to = get(id, 5), linear = to - from === size
|
|
64
|
+
return mapped(value, { start: from + (linear ? start : 0), end: linear ? from + end : to })
|
|
65
|
+
}
|
|
66
|
+
const emit = id => {
|
|
67
|
+
const chunks = []
|
|
68
|
+
let pending = []
|
|
69
|
+
const mappings = createSourceMapBuilder()
|
|
70
|
+
const regions = []
|
|
71
|
+
let offset = 0
|
|
72
|
+
const visit = id => {
|
|
73
|
+
const size = length(id)
|
|
74
|
+
if (size === 0) return
|
|
75
|
+
const kind = get(id, 1), left = get(id, 2), right = get(id, 3)
|
|
76
|
+
if (kind === JOIN) { visit(left); visit(right); return }
|
|
77
|
+
if (kind === REGION) {
|
|
78
|
+
regions.push({ ...regionFacts[right], start: offset, end: offset + size })
|
|
79
|
+
visit(left)
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
pending.push(kind === COPY ? source.slice(left, right) : strings[left])
|
|
83
|
+
if (pending.length === BLOCK_SIZE) { chunks.push(pending.join('')); pending = [] }
|
|
84
|
+
if (kind !== TEXT) mappings.push({ generatedStart: offset, generatedEnd: offset + size,
|
|
85
|
+
originalStart: kind === COPY ? left : get(id, 4), originalEnd: kind === COPY ? right : get(id, 5) })
|
|
86
|
+
offset += size
|
|
87
|
+
}
|
|
88
|
+
visit(id)
|
|
89
|
+
chunks.push(pending.join(''))
|
|
90
|
+
return { text: chunks.join(''), mappings: mappings.finish(), regions }
|
|
91
|
+
}
|
|
92
|
+
return { text, original, mapped, join, slice, emit, length, region }
|
|
93
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import traverseModule, { NodePath } from '@babel/traverse'
|
|
2
|
+
import { types as t } from '@babel/core'
|
|
3
|
+
|
|
4
|
+
const traverse = traverseModule.default ?? traverseModule
|
|
5
|
+
const SOURCE_CONTEXT = Object.freeze({ opts: Object.freeze({ noScope: true }) })
|
|
6
|
+
|
|
7
|
+
class SourceScope {
|
|
8
|
+
constructor(id, nodeId, parentId) { this.id = id; this.nodeId = nodeId; this.parentId = parentId }
|
|
9
|
+
get path() { return this.index.get(this.block) }
|
|
10
|
+
getFunctionParent() {
|
|
11
|
+
for (let scope = this; scope; scope = scope.parent) {
|
|
12
|
+
if (t.isFunction(scope.block) || t.isStaticBlock(scope.block)) return scope
|
|
13
|
+
}
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
getProgramParent() {
|
|
17
|
+
let scope = this
|
|
18
|
+
while (scope.parent) scope = scope.parent
|
|
19
|
+
return scope
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function sourcePath(node, parentPath, container, key, listKey = null, scope = null) {
|
|
24
|
+
const path = new NodePath(undefined, parentPath?.node ?? container)
|
|
25
|
+
path.parentPath = parentPath
|
|
26
|
+
path.container = container
|
|
27
|
+
path.key = key
|
|
28
|
+
path.listKey = listKey
|
|
29
|
+
path.node = node
|
|
30
|
+
path.type = node.type
|
|
31
|
+
path.setContext(SOURCE_CONTEXT)
|
|
32
|
+
path.scope = scope
|
|
33
|
+
return path
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Visit source facts with Babel's syntax predicates, retaining only ancestry.
|
|
37
|
+
* These paths do not enter Babel's whole-tree path/scope caches. Mutating
|
|
38
|
+
* transforms use separately bounded work trees instead. */
|
|
39
|
+
export function visitSource(tree, visitor) {
|
|
40
|
+
const handlers = traverse.visitors.explode({ ...visitor, noScope: true })
|
|
41
|
+
const callbacks = new Map()
|
|
42
|
+
let stopped = false
|
|
43
|
+
const visit = (parentPath, container, key, listKey) => {
|
|
44
|
+
const node = container[key]
|
|
45
|
+
if (node === null || node === undefined) return
|
|
46
|
+
const path = sourcePath(node, parentPath, container, key, listKey)
|
|
47
|
+
let selected = callbacks.get(node.type)
|
|
48
|
+
if (selected === undefined) {
|
|
49
|
+
selected = { enter: [...handlers.enter ?? [], ...handlers[node.type]?.enter ?? []],
|
|
50
|
+
exit: [...handlers[node.type]?.exit ?? [], ...handlers.exit ?? []] }
|
|
51
|
+
callbacks.set(node.type, selected)
|
|
52
|
+
}
|
|
53
|
+
for (const handler of selected.enter) {
|
|
54
|
+
handler(path)
|
|
55
|
+
if (path.shouldStop) { stopped = true; return }
|
|
56
|
+
if (path.shouldSkip) return
|
|
57
|
+
}
|
|
58
|
+
for (const field of t.VISITOR_KEYS[node.type] ?? []) {
|
|
59
|
+
if (path.skipKeys?.[field]) continue
|
|
60
|
+
const child = node[field]
|
|
61
|
+
if (Array.isArray(child)) {
|
|
62
|
+
for (let index = 0; index < child.length && !stopped; index++) visit(path, child, index, field)
|
|
63
|
+
} else if (!stopped) visit(path, node, field, null)
|
|
64
|
+
}
|
|
65
|
+
for (const handler of selected.exit) {
|
|
66
|
+
handler(path)
|
|
67
|
+
if (path.shouldStop) { stopped = true; return }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (tree.type === 'File') visit(null, tree, 'program', null)
|
|
71
|
+
else visit(null, { root: tree }, 'root', null)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Compact ancestry survives a work tree; NodePaths are materialized on demand. */
|
|
75
|
+
export function indexSource(tree) {
|
|
76
|
+
const ids = new WeakMap()
|
|
77
|
+
const nodes = [], parentIds = [], keys = [], lists = [], scopeIds = []
|
|
78
|
+
const scopes = []
|
|
79
|
+
const visit = (node, parentId, key, listKey) => {
|
|
80
|
+
if (node === null || node === undefined) return
|
|
81
|
+
const parent = parentId === undefined ? tree : nodes[parentId]
|
|
82
|
+
const id = nodes.length
|
|
83
|
+
ids.set(node, id)
|
|
84
|
+
nodes.push(node)
|
|
85
|
+
parentIds.push(parentId ?? -1)
|
|
86
|
+
keys.push(key)
|
|
87
|
+
lists.push(listKey)
|
|
88
|
+
let parentScope = parentId === undefined ? -1 : scopeIds[parentId]
|
|
89
|
+
if (parentId !== undefined && (key === 'key' || listKey === 'decorators') && t.isMethod(parent)
|
|
90
|
+
|| parentId !== undefined && key === 'discriminant' && t.isSwitchStatement(parent)) {
|
|
91
|
+
parentScope = scopes[parentScope]?.parentId ?? -1
|
|
92
|
+
}
|
|
93
|
+
let scopeId = parentScope
|
|
94
|
+
if (t.isScope(node, parent)) {
|
|
95
|
+
scopeId = scopes.length
|
|
96
|
+
scopes.push(new SourceScope(scopeId, id, parentScope))
|
|
97
|
+
}
|
|
98
|
+
scopeIds.push(scopeId)
|
|
99
|
+
for (const field of t.VISITOR_KEYS[node.type] ?? []) {
|
|
100
|
+
const child = node[field]
|
|
101
|
+
if (Array.isArray(child)) {
|
|
102
|
+
for (let index = 0; index < child.length; index++) visit(child[index], id, index, field)
|
|
103
|
+
} else visit(child, id, field, null)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
visit(tree.type === 'File' ? tree.program : tree, undefined, tree.type === 'File' ? 'program' : 'root', null)
|
|
107
|
+
const parents = Int32Array.from(parentIds)
|
|
108
|
+
const nodeScopes = Int32Array.from(scopeIds)
|
|
109
|
+
const get = node => {
|
|
110
|
+
let id = ids.get(node)
|
|
111
|
+
if (id === undefined) return undefined
|
|
112
|
+
const ancestors = []
|
|
113
|
+
while (id >= 0) { ancestors.push(id); id = parents[id] }
|
|
114
|
+
let path = null
|
|
115
|
+
for (let index = ancestors.length - 1; index >= 0; index--) {
|
|
116
|
+
id = ancestors[index]
|
|
117
|
+
const node = nodes[id]
|
|
118
|
+
const container = lists[id] === null ? path?.node ?? tree : path.node[lists[id]]
|
|
119
|
+
path = sourcePath(node, path, container, keys[id], lists[id], scopes[nodeScopes[id]])
|
|
120
|
+
}
|
|
121
|
+
return path
|
|
122
|
+
}
|
|
123
|
+
const index = { get, ids, nodes, scopes, scopeFor: node => scopes[nodeScopes[ids.get(node)]],
|
|
124
|
+
parentFor: node => nodes[parents[ids.get(node)]] ?? tree,
|
|
125
|
+
}
|
|
126
|
+
for (const scope of scopes) {
|
|
127
|
+
scope.block = nodes[scope.nodeId]
|
|
128
|
+
scope.parent = scopes[scope.parentId] ?? null
|
|
129
|
+
scope.index = index
|
|
130
|
+
}
|
|
131
|
+
return index
|
|
132
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** One construction contract for compiler-owned storage in every emitted realm. */
|
|
2
|
+
export const compilerStorageSource = `(object, WeakMap, WeakSet, symbol, promise, reflect, arrayConstructor, functionPrototype) => {
|
|
3
|
+
const define = object.defineProperty, defineProperties = object.defineProperties, setPrototype = object.setPrototypeOf;
|
|
4
|
+
const uncurry = functionPrototype.bind.bind(functionPrototype.call);
|
|
5
|
+
const descriptor = (value,writable=false,configurable=false) => {
|
|
6
|
+
const result=object.create(null);result.value=value;result.writable=writable;result.configurable=configurable;return result;
|
|
7
|
+
};
|
|
8
|
+
if(symbol.dispose===void 0)define(symbol,'dispose',descriptor(symbol.for('nodejs.dispose')));
|
|
9
|
+
if(symbol.asyncDispose===void 0)define(symbol,'asyncDispose',descriptor(symbol.for('nodejs.asyncDispose')));
|
|
10
|
+
const mapMethods = object.create(null), setMethods = object.create(null);
|
|
11
|
+
for (const name of ['get','set','has','delete']) mapMethods[name] = descriptor(WeakMap.prototype[name]);
|
|
12
|
+
for (const name of ['has','add','delete']) setMethods[name] = descriptor(WeakSet.prototype[name]);
|
|
13
|
+
const values = uncurry(arrayConstructor.prototype.values);
|
|
14
|
+
const arrayMethods = object.create(null);
|
|
15
|
+
for (const name of ['push','pop','unshift']) arrayMethods[name] = descriptor(arrayConstructor.prototype[name]);
|
|
16
|
+
const apply = reflect.apply;
|
|
17
|
+
for (const name of ['concat','splice']) {
|
|
18
|
+
const operation = arrayConstructor.prototype[name];
|
|
19
|
+
arrayMethods[name] = descriptor(function(...args){return array(apply(operation,this,args))});
|
|
20
|
+
}
|
|
21
|
+
const next = uncurry(object.getPrototypeOf(values([])).next);
|
|
22
|
+
const description = uncurry(object.getOwnPropertyDescriptor(symbol.prototype,'description').get);
|
|
23
|
+
const then = uncurry(promise.prototype.then);
|
|
24
|
+
function array(value){
|
|
25
|
+
setPrototype(value,null);
|
|
26
|
+
defineProperties(value,arrayMethods);
|
|
27
|
+
define(value,'constructor',descriptor(void 0,true,true));
|
|
28
|
+
define(value,symbol.iterator,descriptor(function(){
|
|
29
|
+
const iterator=values(value);
|
|
30
|
+
setPrototype(iterator,null);
|
|
31
|
+
define(iterator,'next',descriptor(function(){return next(iterator)}));
|
|
32
|
+
return iterator;
|
|
33
|
+
},false,true));
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
functionCall:functionPrototype.call,functionApply:functionPrototype.apply,functionBind:functionPrototype.bind,
|
|
38
|
+
promiseThen:promise.prototype.then,
|
|
39
|
+
record(value){return setPrototype(value,null)},
|
|
40
|
+
observeOwnedPromise(value,fulfilled,rejected){
|
|
41
|
+
setPrototype(value,null);
|
|
42
|
+
then(value,result=>{try{fulfilled(result)}catch(error){rejected(error)}},rejected);
|
|
43
|
+
},
|
|
44
|
+
async awaitValue(value,fulfilled,rejected){
|
|
45
|
+
let result;
|
|
46
|
+
try{result=await value}catch(error){if(rejected)return await rejected(error);throw error}
|
|
47
|
+
return await fulfilled(result);
|
|
48
|
+
},
|
|
49
|
+
weakMapStore(){return defineProperties(new WeakMap(),mapMethods)},
|
|
50
|
+
weakSetStore(){return defineProperties(new WeakSet(),setMethods)},
|
|
51
|
+
symbolDescription:description,
|
|
52
|
+
array
|
|
53
|
+
};
|
|
54
|
+
}`
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto'
|
|
2
|
+
import { deflateRawSync, inflateRawSync } from 'node:zlib'
|
|
3
|
+
|
|
4
|
+
/** Exact source facts cross the compiler boundary as strings, never buffers. */
|
|
5
|
+
export function hashText(source, encoding = 'utf8', format = 'base64') {
|
|
6
|
+
return createHash('sha256').update(source, encoding).digest(format)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function deflateText(source) {
|
|
10
|
+
return deflateRawSync(Buffer.from(source, 'utf16le')).toString('base64')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function inflateText(encoded, maxOutputBytes) {
|
|
14
|
+
return inflateRawSync(Buffer.from(encoded, 'base64'), { maxOutputLength: maxOutputBytes }).toString('utf16le')
|
|
15
|
+
}
|
package/internal/config-spec.js
CHANGED
|
@@ -5,12 +5,21 @@ export const MAX_TIMER_DELAY_MS = 2_147_483_647
|
|
|
5
5
|
export const SETTINGS_NAMESPACE = 'ptc-plus'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Shared field definitions for the Host schema and settings card. `label` and
|
|
9
9
|
* `description` are the canonical Host schema copy; `labelEn` and
|
|
10
10
|
* `descriptionEn` carry the English settings-card copy. A field's description
|
|
11
11
|
* exists in both locales or in neither.
|
|
12
12
|
*/
|
|
13
13
|
export const CONFIG_FIELDS = Object.freeze([
|
|
14
|
+
{
|
|
15
|
+
key: 'legacyBindingSettings',
|
|
16
|
+
type: 'boolean',
|
|
17
|
+
default: false,
|
|
18
|
+
label: '旧绑定设置迁移状态',
|
|
19
|
+
labelEn: 'Legacy binding settings migration state',
|
|
20
|
+
description: '',
|
|
21
|
+
descriptionEn: '',
|
|
22
|
+
},
|
|
14
23
|
{
|
|
15
24
|
key: 'enabled',
|
|
16
25
|
type: 'boolean',
|
|
@@ -29,6 +38,24 @@ export const CONFIG_FIELDS = Object.freeze([
|
|
|
29
38
|
description: '开启时使用增强工具卡片;关闭后使用 DSH 原生工具卡片。',
|
|
30
39
|
descriptionEn: 'Uses enhanced tool cards when enabled and DSH native tool cards when disabled.',
|
|
31
40
|
},
|
|
41
|
+
{
|
|
42
|
+
key: 'replViewEnabled',
|
|
43
|
+
type: 'boolean',
|
|
44
|
+
default: true,
|
|
45
|
+
label: '显示 REPL 页签',
|
|
46
|
+
labelEn: 'Show REPL tab',
|
|
47
|
+
description: '在 PTC 会话中显示 REPL 工作台;隐藏后仍可从设置管理全局绑定。',
|
|
48
|
+
descriptionEn: 'Shows the REPL workspace in PTC sessions. Global bindings remain manageable in Settings.',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
key: 'bindingAuthorButtonVisible',
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
default: true,
|
|
54
|
+
label: '显示 PTC Plus 快捷入口',
|
|
55
|
+
labelEn: 'Show the PTC Plus shortcut',
|
|
56
|
+
description: '在输入框旁显示 PTC Plus 快捷入口:查看和启停全局绑定、编写新绑定,并直接打开插件设置窗口;隐藏后仍可使用 /binding 命令。',
|
|
57
|
+
descriptionEn: 'Shows the PTC Plus shortcut beside the composer: global binding access and toggles, authoring, and direct access to the plugin settings dialog. Hiding it keeps /binding commands available.',
|
|
58
|
+
},
|
|
32
59
|
{
|
|
33
60
|
key: 'autoDescribeRunCode',
|
|
34
61
|
type: 'boolean',
|
|
@@ -38,6 +65,16 @@ export const CONFIG_FIELDS = Object.freeze([
|
|
|
38
65
|
description: '允许 run_code 缺少外层 description;关闭后恢复 DSH 校验。模型请求和原始调用参数保持不变。',
|
|
39
66
|
descriptionEn: 'Allows run_code to omit its outer description; disabling restores DSH validation. Model requests and original call arguments remain unchanged.',
|
|
40
67
|
},
|
|
68
|
+
{
|
|
69
|
+
key: 'bindingUpdates',
|
|
70
|
+
type: 'enum',
|
|
71
|
+
options: Object.freeze(['stateful', 'protected']),
|
|
72
|
+
default: 'stateful',
|
|
73
|
+
label: '允许重声明和覆盖',
|
|
74
|
+
labelEn: 'Allow redeclarations and overrides',
|
|
75
|
+
description: '同一作用域的声明和赋值可更新变量、函数、类及导入。关闭后检测跨 cell 重声明,并保护新建的 const 和 import;静态 import/export 始终可用。',
|
|
76
|
+
descriptionEn: 'Declarations and assignments update variables, functions, classes and imports in the same scope. Disabling detects cross-cell redeclarations and protects newly created const and import bindings; static import/export remains available.',
|
|
77
|
+
},
|
|
41
78
|
{
|
|
42
79
|
key: 'canonicalizeToolCalls',
|
|
43
80
|
type: 'boolean',
|
|
@@ -56,6 +93,15 @@ export const CONFIG_FIELDS = Object.freeze([
|
|
|
56
93
|
description: '开启后,PTC agent 可使用官方 Cordis 工具、配套指引和开发 Skill;关闭后移除这些能力。Cordis 工具以 DSH 进程权限运行。',
|
|
57
94
|
descriptionEn: 'When enabled, PTC agents can use the official Cordis tools, guidance, and development Skill; disabling removes them. Cordis tools run with the DSH process permissions.',
|
|
58
95
|
},
|
|
96
|
+
{
|
|
97
|
+
key: 'userBindingsEnabled',
|
|
98
|
+
type: 'boolean',
|
|
99
|
+
default: false,
|
|
100
|
+
label: '启用全局用户 Binding',
|
|
101
|
+
labelEn: 'Enable Global User Bindings',
|
|
102
|
+
description: '管理 TypeScript helper,并将已启用条目作为跨会话的默认 REPL 绑定。',
|
|
103
|
+
descriptionEn: 'Manages TypeScript helpers and loads enabled entries as default REPL bindings across sessions.',
|
|
104
|
+
},
|
|
59
105
|
{
|
|
60
106
|
key: 'looseTopLevelRedeclarations',
|
|
61
107
|
type: 'boolean',
|
|
@@ -68,7 +114,7 @@ export const CONFIG_FIELDS = Object.freeze([
|
|
|
68
114
|
{
|
|
69
115
|
key: 'looseTopLevelFunctionClassRedeclarations',
|
|
70
116
|
type: 'boolean',
|
|
71
|
-
default:
|
|
117
|
+
default: true,
|
|
72
118
|
label: '允许顶层函数/类重声明',
|
|
73
119
|
labelEn: 'Allow top-level function/class redeclarations',
|
|
74
120
|
description: '允许顶层 function 或 class 声明替换已有的可写 binding;不可写或保留 binding 仍会在执行前被拒绝。',
|
|
@@ -125,10 +171,10 @@ export const CONFIG_FIELDS = Object.freeze([
|
|
|
125
171
|
default: 60_000,
|
|
126
172
|
min: 1,
|
|
127
173
|
max: Number.MAX_SAFE_INTEGER,
|
|
128
|
-
label: '单 cell
|
|
129
|
-
labelEn: '
|
|
130
|
-
description: '
|
|
131
|
-
descriptionEn: '
|
|
174
|
+
label: '单 cell 事件循环活跃时间上限 (ms)',
|
|
175
|
+
labelEn: 'Event-loop active time limit per cell (ms)',
|
|
176
|
+
description: '包含同步阻塞等待,不等同于 CPU 用时;超限时丢弃当前 cell 并重置 worker。',
|
|
177
|
+
descriptionEn: 'Includes synchronous blocking, not just CPU use; exceeding the limit discards the cell and resets the worker.',
|
|
132
178
|
},
|
|
133
179
|
{
|
|
134
180
|
key: 'maxWallMs',
|
|
@@ -242,34 +288,46 @@ export const CONFIG_FIELDS = Object.freeze([
|
|
|
242
288
|
},
|
|
243
289
|
])
|
|
244
290
|
|
|
245
|
-
/**
|
|
291
|
+
/** Purpose-based presentation groups are independent of Host schema field order. */
|
|
246
292
|
export const CONFIG_GROUPS = Object.freeze([
|
|
247
293
|
{
|
|
248
|
-
key: '
|
|
249
|
-
label: '
|
|
250
|
-
labelEn: '
|
|
251
|
-
fields: Object.freeze(['enabled'
|
|
294
|
+
key: 'switch',
|
|
295
|
+
label: '插件开关',
|
|
296
|
+
labelEn: 'Plugin switch',
|
|
297
|
+
fields: Object.freeze(['enabled']),
|
|
252
298
|
},
|
|
253
299
|
{
|
|
254
|
-
key: '
|
|
255
|
-
label: '
|
|
256
|
-
labelEn: '
|
|
257
|
-
fields: Object.freeze(['
|
|
300
|
+
key: 'calls',
|
|
301
|
+
label: '调用容错',
|
|
302
|
+
labelEn: 'Tool call tolerance',
|
|
303
|
+
fields: Object.freeze(['autoDescribeRunCode', 'canonicalizeToolCalls']),
|
|
258
304
|
},
|
|
259
305
|
{
|
|
260
|
-
key: '
|
|
261
|
-
label: '
|
|
262
|
-
labelEn: '
|
|
306
|
+
key: 'syntax',
|
|
307
|
+
label: 'REPL 语法',
|
|
308
|
+
labelEn: 'REPL syntax',
|
|
263
309
|
fields: Object.freeze([
|
|
264
|
-
'
|
|
265
|
-
'looseTopLevelFunctionClassRedeclarations',
|
|
266
|
-
'autoRewriteImports',
|
|
267
|
-
'autoStripExports',
|
|
268
|
-
'autoSplitRedeclarations',
|
|
269
|
-
'durableReplay',
|
|
270
|
-
'tipsEnabled',
|
|
310
|
+
'bindingUpdates',
|
|
271
311
|
]),
|
|
272
312
|
},
|
|
313
|
+
{
|
|
314
|
+
key: 'recovery',
|
|
315
|
+
label: '状态与恢复',
|
|
316
|
+
labelEn: 'State and recovery',
|
|
317
|
+
fields: Object.freeze(['durableReplay', 'tipsEnabled', 'tipCooldownMessages', 'tipEscalationFailures']),
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
key: 'extensions',
|
|
321
|
+
label: '工具扩展',
|
|
322
|
+
labelEn: 'Tool extensions',
|
|
323
|
+
fields: Object.freeze(['userBindingsEnabled', 'cordisToolsEnabled']),
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
key: 'interface',
|
|
327
|
+
label: '界面显示',
|
|
328
|
+
labelEn: 'Interface display',
|
|
329
|
+
fields: Object.freeze(['enhancedToolView', 'replViewEnabled', 'bindingAuthorButtonVisible']),
|
|
330
|
+
},
|
|
273
331
|
{
|
|
274
332
|
key: 'limits',
|
|
275
333
|
label: '资源限制',
|
|
@@ -284,8 +342,6 @@ export const CONFIG_GROUPS = Object.freeze([
|
|
|
284
342
|
'maxValueEdges',
|
|
285
343
|
'maxValueArrayLength',
|
|
286
344
|
'maxValueBigIntDigits',
|
|
287
|
-
'tipCooldownMessages',
|
|
288
|
-
'tipEscalationFailures',
|
|
289
345
|
]),
|
|
290
346
|
},
|
|
291
347
|
])
|