@forgeax/engine-remote 0.0.0-dev.8d955ade1c79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +269 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/__tests__/cli-defaults.unit.test.d.ts +2 -0
  5. package/dist/__tests__/cli-defaults.unit.test.d.ts.map +1 -0
  6. package/dist/__tests__/console.unit.test.d.ts +2 -0
  7. package/dist/__tests__/console.unit.test.d.ts.map +1 -0
  8. package/dist/__tests__/errors.unit.test.d.ts +2 -0
  9. package/dist/__tests__/errors.unit.test.d.ts.map +1 -0
  10. package/dist/__tests__/execute-browser-safe.unit.test.d.ts +2 -0
  11. package/dist/__tests__/execute-browser-safe.unit.test.d.ts.map +1 -0
  12. package/dist/__tests__/execute-profiler-root.browser.test.d.ts +2 -0
  13. package/dist/__tests__/execute-profiler-root.browser.test.d.ts.map +1 -0
  14. package/dist/__tests__/execute.async.test.d.ts +2 -0
  15. package/dist/__tests__/execute.async.test.d.ts.map +1 -0
  16. package/dist/__tests__/execution-report-root.unit.test.d.ts +2 -0
  17. package/dist/__tests__/execution-report-root.unit.test.d.ts.map +1 -0
  18. package/dist/__tests__/introspect-profiler.unit.test.d.ts +2 -0
  19. package/dist/__tests__/introspect-profiler.unit.test.d.ts.map +1 -0
  20. package/dist/__tests__/method-roster-profiler.test.d.ts +2 -0
  21. package/dist/__tests__/method-roster-profiler.test.d.ts.map +1 -0
  22. package/dist/__tests__/rhi-capture-remote.integration.test.d.ts +2 -0
  23. package/dist/__tests__/rhi-capture-remote.integration.test.d.ts.map +1 -0
  24. package/dist/__tests__/server.unit.test.d.ts +2 -0
  25. package/dist/__tests__/server.unit.test.d.ts.map +1 -0
  26. package/dist/__tests__/simulation-inspect.integration.test.d.ts +2 -0
  27. package/dist/__tests__/simulation-inspect.integration.test.d.ts.map +1 -0
  28. package/dist/cli.d.ts +15 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.mjs +336 -0
  31. package/dist/cli.mjs.map +1 -0
  32. package/dist/defineSubcommand.d.ts +40 -0
  33. package/dist/defineSubcommand.d.ts.map +1 -0
  34. package/dist/error-messages.d.ts +3 -0
  35. package/dist/error-messages.d.ts.map +1 -0
  36. package/dist/errors.d.ts +82 -0
  37. package/dist/errors.d.ts.map +1 -0
  38. package/dist/errors.mjs +37 -0
  39. package/dist/errors.mjs.map +1 -0
  40. package/dist/execute.d.ts +32 -0
  41. package/dist/execute.d.ts.map +1 -0
  42. package/dist/execute.mjs +95 -0
  43. package/dist/execute.mjs.map +1 -0
  44. package/dist/index.d.ts +2 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.mjs +30 -0
  47. package/dist/index.mjs.map +1 -0
  48. package/dist/introspect.d.ts +23 -0
  49. package/dist/introspect.d.ts.map +1 -0
  50. package/dist/introspect.mjs +170 -0
  51. package/dist/introspect.mjs.map +1 -0
  52. package/dist/server.d.ts +35 -0
  53. package/dist/server.d.ts.map +1 -0
  54. package/dist/server.mjs +435 -0
  55. package/dist/server.mjs.map +1 -0
  56. package/package.json +81 -0
  57. package/src/__tests__/cli-defaults.unit.test.ts +69 -0
  58. package/src/__tests__/console.unit.test.ts +679 -0
  59. package/src/__tests__/errors.unit.test.ts +88 -0
  60. package/src/__tests__/execute-browser-safe.unit.test.ts +43 -0
  61. package/src/__tests__/execute-profiler-root.browser.test.ts +41 -0
  62. package/src/__tests__/execute.async.test.ts +373 -0
  63. package/src/__tests__/execution-report-root.unit.test.ts +38 -0
  64. package/src/__tests__/introspect-profiler.unit.test.ts +55 -0
  65. package/src/__tests__/method-roster-profiler.test.ts +80 -0
  66. package/src/__tests__/rhi-capture-remote.integration.test.ts +58 -0
  67. package/src/__tests__/server.unit.test.ts +613 -0
  68. package/src/__tests__/simulation-inspect.integration.test.ts +67 -0
  69. package/src/__tests__/vm-async-eval-verify.mjs +149 -0
  70. package/src/cli.ts +333 -0
  71. package/src/defineSubcommand.ts +169 -0
  72. package/src/error-messages.ts +9 -0
  73. package/src/errors.ts +143 -0
  74. package/src/execute.ts +155 -0
  75. package/src/index.ts +20 -0
  76. package/src/introspect.ts +218 -0
  77. package/src/server.ts +285 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/defineSubcommand.ts","../src/cli.ts"],"names":[],"mappings":"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","file":"cli.mjs","sourcesContent":["// @forgeax/engine-remote/src/defineSubcommand - sade utils.js form (~94-line\n// flat-dictionary + section primitive) DSL for the `forgeax-engine-console`\n// CLI help renderer. Plan-strategy D-4 + D-7 lock-in:\n//\n// - Single file, package-internal (NOT in package.json#exports).\n// `cli.ts` is the sole consumer; tsup inlines it into dist/cli.mjs.\n// - 94-line ceiling is a pattern target, not a hard cap; we trade a few\n// extra lines for explicit JSDoc that AI users read at edit time.\n// - Three render layers driven by `path` slicing:\n// path = [] -> top-level help\n// path = ['inspect'] -> subcommand help\n// path = ['inspect', 'entities'] -> sub-target help\n// - List-width pin: `maxLen + GAP=4` padding (R-4 mitigation; snapshot\n// test packages/console/src/__tests__/cli-help.test.ts guards drift).\n//\n// charter: proposition 1 (progressive disclosure — `path` is the navigator,\n// not a hidden config) + proposition 3 (machine-readable spec >>> hand-rolled\n// strings) + proposition 4 (explicit failure — render is total: any unknown\n// path returns the closest valid layer rather than throwing).\n\nconst GAP = 4;\n\n/** Single option entry: `--with <Name>`, `--port <number>` ... */\nexport interface OptionSpec {\n readonly flag: string;\n readonly description: string;\n readonly multiple?: boolean;\n readonly defaultValue?: string;\n}\n\n/** Single example block: usage line + free description. */\nexport interface ExampleSpec {\n readonly usage: string;\n readonly description?: string;\n}\n\n/** Subcommand spec — recursive (subcommands map to nested specs). */\nexport interface SubcommandSpec {\n readonly name: string;\n readonly description: string;\n readonly options?: ReadonlyArray<OptionSpec>;\n readonly subcommands?: ReadonlyArray<SubcommandSpec>;\n readonly examples?: ReadonlyArray<ExampleSpec>;\n readonly extraNotes?: ReadonlyArray<string>;\n}\n\n/**\n * Single-input wrapping helper: turns a sade-style descriptor into a\n * SubcommandSpec POD. Today the function is a near-identity (the spec is\n * already structurally a POD), but the wrapper preserves a single intercept\n * point for future validation (charter proposition 4: explicit failure on\n * malformed input — we can throw here rather than silently render garbage).\n */\nexport function defineSubcommand(spec: SubcommandSpec): SubcommandSpec {\n if (typeof spec.name !== 'string' || spec.name.length === 0) {\n throw new Error('defineSubcommand: spec.name must be a non-empty string');\n }\n return spec;\n}\n\n/**\n * Look up the descendant spec at `path`. Returns the closest matching\n * ancestor when the path is partially unknown so renderHelp degrades to the\n * deepest valid layer rather than throwing (charter proposition 4 explicit\n * failure: a wrong path is recoverable; a thrown render is not).\n */\nfunction resolvePath(\n root: SubcommandSpec,\n path: readonly string[],\n): { readonly spec: SubcommandSpec; readonly path: readonly string[] } {\n let current = root;\n const consumed: string[] = [];\n for (const segment of path) {\n const next = current.subcommands?.find((s) => s.name === segment);\n if (next === undefined) break;\n current = next;\n consumed.push(segment);\n }\n return { spec: current, path: consumed };\n}\n\n/**\n * Render a single section with `key` left-padded to `maxLen + GAP` columns.\n * `items` carries `[label, body]` pairs; both halves are flat strings.\n *\n * Skips emission entirely when `items` is empty so the rendered help body\n * has no orphan section headers (UX nit: AI users grep section headers as\n * anchors — emitting a header followed by nothing fools the grep).\n */\nfunction section(title: string, items: ReadonlyArray<readonly [string, string]>): string[] {\n if (items.length === 0) return [];\n let maxLen = 0;\n for (const [label] of items) {\n if (label.length > maxLen) maxLen = label.length;\n }\n const lines: string[] = [];\n lines.push(`${title}:`);\n for (const [label, body] of items) {\n const pad = ' '.repeat(maxLen + GAP - label.length);\n lines.push(` ${label}${pad}${body}`);\n }\n lines.push('');\n return lines;\n}\n\n/**\n * Render the help body for `path` against `root`. Always returns a non-empty\n * string ending in a single newline so callers can pipe to stdout without\n * post-processing.\n *\n * Layer 1 (root): title + Usage + Sub-commands + Options + extraNotes\n * Layer 2 (subcommand): title + Usage + Sub-targets (if any) + Options + Examples + extraNotes\n * Layer 3 (sub-target): title + Usage + Options + Examples + extraNotes\n */\nexport function renderHelp(root: SubcommandSpec, path: readonly string[]): string {\n const { spec, path: consumed } = resolvePath(root, path);\n const fullPath = [root.name, ...consumed].join(' ');\n const out: string[] = [];\n out.push(`${fullPath} - ${spec.description}`);\n out.push('');\n\n // Usage line — synthesised from `path` + the leaf's surface.\n const usagePieces: string[] = [fullPath];\n if (spec.subcommands && spec.subcommands.length > 0) {\n usagePieces.push('<subcommand>');\n } else {\n // Leaf nodes use a generic <args> token; concrete shape lives in\n // `examples` so the help body stays declarative rather than guessed.\n usagePieces.push('[options]');\n }\n out.push('Usage:');\n out.push(` ${usagePieces.join(' ')}`);\n out.push('');\n\n if (spec.subcommands && spec.subcommands.length > 0) {\n out.push(\n ...section(\n consumed.length === 0 ? 'Sub-commands' : 'Sub-targets',\n spec.subcommands.map((s) => [s.name, s.description] as const),\n ),\n );\n }\n\n if (spec.options && spec.options.length > 0) {\n out.push(\n ...section(\n 'Options',\n spec.options.map((o) => [o.flag, o.description] as const),\n ),\n );\n }\n\n if (spec.examples && spec.examples.length > 0) {\n const exampleItems: Array<readonly [string, string]> = spec.examples.map(\n (e) => [e.usage, e.description ?? ''] as const,\n );\n out.push(...section('Examples', exampleItems));\n }\n\n if (spec.extraNotes && spec.extraNotes.length > 0) {\n out.push('Notes:');\n for (const note of spec.extraNotes) {\n out.push(` ${note}`);\n }\n out.push('');\n }\n\n return `${out.join('\\n').trimEnd()}\\n`;\n}\n","#!/usr/bin/env node\n// @forgeax/engine-remote/src/cli - forgeax CLI binary entry (feat-20260517 D-3\n// + D-4: inspect-subcommand removed; only built-in `script` / `eval`\n// remain. M2 w8: plugin discovery (discoverPlugins) deleted alongside\n// routing layer removal. defaultConnect SSOT lives in\n// `@forgeax/engine-types/inspector-client` and is re-exported here\n// for the legacy import surface).\n//\n// Two-subcommand built-in dispatch:\n// - forgeax-engine-remote script <file>\n// - forgeax-engine-remote eval <inline-script>\n//\n// WebSocket client (D-3 / w18): the in-cli ~80-line `defaultConnect`\n// implementation was extracted to `@forgeax/engine-types/inspector-client`\n// so the engine-remote base CLI and the engine-ecs `cli-ecs` plugin bin\n// (M3) share one client recipe. The Result-form `eval(script)` /\n// `dispose()` surface replaces the legacy `request(method,params)` /\n// `close()` shape that lived inside cli.ts.\n//\n// Argparse via stdlib `node:util.parseArgs` (no commander / sade / cac\n// dep). Help body is produced by the package-internal `defineSubcommand`\n// DSL (plan-strategy D-4 + D-7).\n\nimport { readFile, realpath } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\nimport type { RemoteError as RemoteErrorShape } from '@forgeax/engine-types';\nimport {\n type ConnectFn,\n defaultConnect,\n INSPECTOR_DEFAULT_HOST,\n INSPECTOR_DEFAULT_PORT,\n type InspectorClient,\n} from '@forgeax/engine-types/inspector-client';\nimport { defineSubcommand, renderHelp, type SubcommandSpec } from './defineSubcommand';\n\nexport type { ConnectFn, InspectorClient };\nexport { defaultConnect };\n\n// w8: LEGACY_INSPECT_TARGETS removed alongside plugin discovery deletion.\n// ─── Subcommand spec tree (sade utils.js form) ───────────────────────────────\n\nexport const FORGEAX_CLI_SPEC: SubcommandSpec = defineSubcommand({\n name: 'forgeax-engine-remote',\n description: 'remote eval CLI - drive a running forgeax engine via JSON-RPC over WS',\n options: [\n {\n flag: '--port <n>',\n description: `Inspector WebSocket port (default ${INSPECTOR_DEFAULT_PORT}; monitor uses 5731)`,\n },\n { flag: '--host <s>', description: `Host name (default ${INSPECTOR_DEFAULT_HOST})` },\n { flag: '--help, -h', description: 'Show this help and exit 0' },\n ],\n subcommands: [\n defineSubcommand({\n name: 'script',\n description: 'eval a script file against the live world/renderer/assets',\n options: [{ flag: '--help, -h', description: 'Show this help and exit 0' }],\n examples: [\n {\n usage: 'forgeax-engine-remote script ./inspect.mjs',\n description: 'eval a local script file',\n },\n ],\n }),\n defineSubcommand({\n name: 'eval',\n description: 'evaluate an inline expression against the world',\n options: [{ flag: '--help, -h', description: 'Show this help and exit 0' }],\n examples: [\n {\n usage: 'forgeax-engine-remote eval \"world.inspect().entityCount\"',\n description: 'inline read of world.inspect()',\n },\n ],\n }),\n ],\n extraNotes: [\n 'eval is full read/write access to the live world/renderer/assets/debugAdapter; the only security boundary is whether the host started the server.',\n 'Plugin discovery via PATH-prefix removed in M2 (routing layer deletion).',\n 'See also: packages/remote/README.md (eval API, live roots, security model) + AI User Charter.',\n 'Simulation inspection is read-only through eval; restore and replay are not Remote or CLI actions.',\n ],\n});\n\n// w8: Plugin discovery (discoverPlugins) removed alongside routing layer deletion.\n// renderTopLevelHelp no longer takes plugins — only built-in commands displayed.\n\nfunction renderTopLevelHelp(): string {\n const lines: string[] = [];\n lines.push(`${FORGEAX_CLI_SPEC.name} - ${FORGEAX_CLI_SPEC.description}`);\n lines.push('');\n lines.push('Usage:');\n lines.push(` ${FORGEAX_CLI_SPEC.name} <subcommand> [args]`);\n lines.push('');\n\n lines.push('Built-in commands:');\n const builtIns = FORGEAX_CLI_SPEC.subcommands ?? [];\n const builtInWidth = builtIns.reduce((m, s) => Math.max(m, s.name.length), 0);\n for (const s of builtIns) {\n const pad = ' '.repeat(builtInWidth - s.name.length + 4);\n lines.push(` ${s.name}${pad}${s.description}`);\n }\n lines.push('');\n\n if (FORGEAX_CLI_SPEC.options && FORGEAX_CLI_SPEC.options.length > 0) {\n lines.push('Options:');\n const optWidth = FORGEAX_CLI_SPEC.options.reduce((m, o) => Math.max(m, o.flag.length), 0);\n for (const o of FORGEAX_CLI_SPEC.options) {\n const pad = ' '.repeat(optWidth - o.flag.length + 4);\n lines.push(` ${o.flag}${pad}${o.description}`);\n }\n lines.push('');\n }\n\n if (FORGEAX_CLI_SPEC.extraNotes && FORGEAX_CLI_SPEC.extraNotes.length > 0) {\n lines.push('Notes:');\n for (const note of FORGEAX_CLI_SPEC.extraNotes) {\n lines.push(` ${note}`);\n }\n lines.push('');\n }\n\n return `${lines.join('\\n').trimEnd()}\\n`;\n}\n\n// w8: renderConsoleStartupFailed (plugin-discovery error rendering) removed.\n// For unknown subcommands, a simple stderr fallback is used inline.\n\n// --- Dispatch (test-injectable) ---\n\nexport interface DispatchOptions {\n readonly argv: readonly string[];\n readonly stdoutWrite: (line: string) => void;\n readonly stderrWrite: (line: string) => void;\n readonly connect: ConnectFn;\n readonly fileReader?: (path: string) => Promise<string>;\n}\n\nconst defaultFileReader = async (path: string): Promise<string> => {\n return await readFile(path, 'utf8');\n};\n\nexport async function dispatch(opts: DispatchOptions): Promise<number> {\n const { argv, stdoutWrite, stderrWrite, connect } = opts;\n const fileReader = opts.fileReader ?? defaultFileReader;\n const [, , subcommand, ...rest] = argv;\n\n if (subcommand === undefined || subcommand === '--help' || subcommand === '-h') {\n stdoutWrite(renderTopLevelHelp());\n return 0;\n }\n\n let port = INSPECTOR_DEFAULT_PORT;\n let host = INSPECTOR_DEFAULT_HOST;\n const filteredRest: string[] = [];\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i];\n if (arg === '--port') {\n const next = rest[i + 1];\n if (typeof next === 'string') {\n const parsed = Number(next);\n if (!Number.isNaN(parsed) && parsed > 0) {\n port = parsed;\n i++;\n continue;\n }\n }\n }\n if (arg === '--host') {\n const next = rest[i + 1];\n if (typeof next === 'string') {\n host = next;\n i++;\n continue;\n }\n }\n if (typeof arg === 'string') filteredRest.push(arg);\n }\n\n switch (subcommand) {\n case 'script':\n return runScript(filteredRest, {\n stdoutWrite,\n stderrWrite,\n connect,\n port,\n host,\n fileReader,\n });\n case 'eval':\n return runEval(filteredRest, { stdoutWrite, stderrWrite, connect, port, host });\n default: {\n // CLI argument error (not a RemoteErrorCode — that closed union is the\n // wire/eval failure vocabulary, not a usage-error channel). Plain\n // usage message mirrors the script/eval missing-arg errors above.\n stderrWrite(\n `forgeax: unknown subcommand '${subcommand}'\\n expected: subcommand is one of: script, eval\\n hint: run 'forgeax-engine-remote --help' for usage\\n detail: '${subcommand}' is not a built-in subcommand (plugin discovery removed in M2)\\n`,\n );\n return 1;\n }\n }\n}\n\ninterface RunCtx {\n readonly stdoutWrite: (line: string) => void;\n readonly stderrWrite: (line: string) => void;\n readonly connect: ConnectFn;\n readonly port: number;\n readonly host: string;\n}\n\ninterface RunScriptCtx extends RunCtx {\n readonly fileReader: (path: string) => Promise<string>;\n}\n\nfunction inspectorErrorToStderr(e: RemoteErrorShape): string {\n return [`forgeax: ${e.code}`, ` expected: ${e.expected}`, ` hint: ${e.hint}`].join('\\n');\n}\n\nasync function runScript(rest: string[], ctx: RunScriptCtx): Promise<number> {\n const [file] = rest;\n if (file === '--help' || file === '-h') {\n ctx.stdoutWrite(renderHelp(FORGEAX_CLI_SPEC, ['script']));\n return 0;\n }\n if (typeof file !== 'string') {\n ctx.stderrWrite(\n [\n 'forgeax: script requires a <file> positional argument',\n ' expected: forgeax-engine-remote script <path-to-js-file>',\n \" hint: e.g. 'forgeax-engine-remote script ./inspect.mjs'\",\n ].join('\\n'),\n );\n return 1;\n }\n let body: string;\n try {\n body = await ctx.fileReader(file);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n ctx.stderrWrite(\n [\n `forgeax: script file unreadable: ${file}`,\n ' expected: file exists and is readable',\n ` hint: check path; underlying error: ${message}`,\n ].join('\\n'),\n );\n return 1;\n }\n return invokeExecute(body, ctx);\n}\n\nasync function runEval(rest: string[], ctx: RunCtx): Promise<number> {\n const [script] = rest;\n if (script === '--help' || script === '-h') {\n ctx.stdoutWrite(renderHelp(FORGEAX_CLI_SPEC, ['eval']));\n return 0;\n }\n if (typeof script !== 'string') {\n ctx.stderrWrite(\n [\n 'forgeax: eval requires an inline <script> positional argument',\n ' expected: forgeax-engine-remote eval \"<expression>\"',\n ' hint: e.g. \\'forgeax-engine-remote eval \"world.inspect().entityCount\"\\'',\n ].join('\\n'),\n );\n return 1;\n }\n return invokeExecute(script, ctx);\n}\n\nasync function invokeExecute(script: string, ctx: RunCtx): Promise<number> {\n const url = `ws://${ctx.host}:${ctx.port}/inspector`;\n const connectResult = await ctx.connect(url);\n if (!connectResult.ok) {\n ctx.stderrWrite(inspectorErrorToStderr(connectResult.error));\n return 1;\n }\n const client = connectResult.value;\n try {\n const result = await client.eval(script);\n ctx.stdoutWrite(typeof result === 'string' ? result : JSON.stringify(result, null, 2));\n return 0;\n } catch (e) {\n if (isRemoteError(e)) {\n ctx.stderrWrite(inspectorErrorToStderr(e));\n return 1;\n }\n const message = e instanceof Error ? e.message : String(e);\n ctx.stderrWrite(\n [\n 'forgeax: execute failed',\n ' expected: server-side execute() resolves Result.ok',\n ` hint: underlying: ${message}`,\n ].join('\\n'),\n );\n return 1;\n } finally {\n await client.dispose();\n }\n}\n\nfunction isRemoteError(e: unknown): e is RemoteErrorShape {\n return (\n typeof e === 'object' &&\n e !== null &&\n typeof (e as { code?: unknown }).code === 'string' &&\n typeof (e as { expected?: unknown }).expected === 'string' &&\n typeof (e as { hint?: unknown }).hint === 'string'\n );\n}\n\n// ─── Bin entry — only runs when this module is the process entry ────────────\n\nconst isBinEntry = await (async () => {\n const argv1 = process.argv[1];\n if (typeof argv1 !== 'string') return false;\n const argv1Real = await realpath(argv1).catch(() => argv1);\n const selfReal = await realpath(fileURLToPath(import.meta.url)).catch(() =>\n fileURLToPath(import.meta.url),\n );\n return argv1Real === selfReal;\n})();\n\nif (isBinEntry) {\n const exitCode = await dispatch({\n argv: process.argv,\n stdoutWrite: (line: string) => process.stdout.write(`${line}\\n`),\n stderrWrite: (line: string) => process.stderr.write(`${line}\\n`),\n connect: defaultConnect,\n });\n process.exit(exitCode);\n}\n"]}
@@ -0,0 +1,40 @@
1
+ /** Single option entry: `--with <Name>`, `--port <number>` ... */
2
+ export interface OptionSpec {
3
+ readonly flag: string;
4
+ readonly description: string;
5
+ readonly multiple?: boolean;
6
+ readonly defaultValue?: string;
7
+ }
8
+ /** Single example block: usage line + free description. */
9
+ export interface ExampleSpec {
10
+ readonly usage: string;
11
+ readonly description?: string;
12
+ }
13
+ /** Subcommand spec — recursive (subcommands map to nested specs). */
14
+ export interface SubcommandSpec {
15
+ readonly name: string;
16
+ readonly description: string;
17
+ readonly options?: ReadonlyArray<OptionSpec>;
18
+ readonly subcommands?: ReadonlyArray<SubcommandSpec>;
19
+ readonly examples?: ReadonlyArray<ExampleSpec>;
20
+ readonly extraNotes?: ReadonlyArray<string>;
21
+ }
22
+ /**
23
+ * Single-input wrapping helper: turns a sade-style descriptor into a
24
+ * SubcommandSpec POD. Today the function is a near-identity (the spec is
25
+ * already structurally a POD), but the wrapper preserves a single intercept
26
+ * point for future validation (charter proposition 4: explicit failure on
27
+ * malformed input — we can throw here rather than silently render garbage).
28
+ */
29
+ export declare function defineSubcommand(spec: SubcommandSpec): SubcommandSpec;
30
+ /**
31
+ * Render the help body for `path` against `root`. Always returns a non-empty
32
+ * string ending in a single newline so callers can pipe to stdout without
33
+ * post-processing.
34
+ *
35
+ * Layer 1 (root): title + Usage + Sub-commands + Options + extraNotes
36
+ * Layer 2 (subcommand): title + Usage + Sub-targets (if any) + Options + Examples + extraNotes
37
+ * Layer 3 (sub-target): title + Usage + Options + Examples + extraNotes
38
+ */
39
+ export declare function renderHelp(root: SubcommandSpec, path: readonly string[]): string;
40
+ //# sourceMappingURL=defineSubcommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineSubcommand.d.ts","sourceRoot":"","sources":["../src/defineSubcommand.ts"],"names":[],"mappings":"AAsBA,kEAAkE;AAClE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAC7C,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC7C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc,CAKrE;AA+CD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAsDhF"}
@@ -0,0 +1,3 @@
1
+ import type { RemoteErrorCode } from './errors';
2
+ export declare const REMOTE_ERROR_MESSAGES: Readonly<Record<RemoteErrorCode, string>>;
3
+ //# sourceMappingURL=error-messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-messages.d.ts","sourceRoot":"","sources":["../src/error-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAM3E,CAAC"}
@@ -0,0 +1,82 @@
1
+ import type { RemoteErrorCode, RemoteErrorDetail, RemoteError as RemoteErrorShape } from '@forgeax/engine-types';
2
+ export type { RemoteErrorCode };
3
+ /**
4
+ * Structured remote error. Four core fields plus bounded detail, mirroring `@forgeax/engine-rhi`
5
+ * `RhiError` (charter proposition 5 consistent abstraction; AGENTS.md
6
+ * "Errors are structured"). The class `implements RemoteErrorShape`
7
+ * (the structural interface re-exported from `@forgeax/engine-types`) so the type
8
+ * SSOT and the runtime class cannot drift.
9
+ *
10
+ * - `.code` closed union member (L1 key signal; switch-able).
11
+ * - `.expected` expected-state description (L2 detail; ai-user-charter
12
+ * proposition 4 requires expected-state copy).
13
+ * - `.hint` actionable recovery guidance (L2 detail; charter
14
+ * proposition 3 machine-readable hint > prose).
15
+ * - `.message` auto-composed `[RemoteError <code>] expected: <expected>;
16
+ * hint: <hint>` so human stack traces still surface the
17
+ * triple. AI users prefer property access (charter
18
+ * proposition 4: no string parsing).
19
+ *
20
+ * Per-code `.expected` + `.hint` templates (requirements §10.2 SSOT):
21
+ *
22
+ * | code | `.expected` | `.hint` |
23
+ * |:--|:--|:--|
24
+ * | `'script-syntax-error'` | `'script body is valid JavaScript'` | `'check syntax position in errMessage; fix and resubmit'` |
25
+ * | `'script-runtime-error'` | `'script executes without throwing'` | `'inspect error; verify symbol availability; eval has full access to world/renderer/assets'` |
26
+ * | `'server-startup-failed'` | `'server starts successfully on requested port'` | `'check if port is already in use (default 5732); pass different port; or kill existing process holding the port'` |
27
+ * | `'server-not-running'` | `'server is reachable at ws://localhost:<port>'` | `'start the demo first; verify app.remote is wired; pass --port to override default 5732'` |
28
+ * | `'eval-result-not-serializable'` | `'eval result is JSON-serializable'` | `'return a JSON-safe value; BigInt and cyclic objects are unsupported over JSON-RPC'` |
29
+ *
30
+ * JSON-RPC 2.0 transport contract: `toJSON()` returns the structured plain
31
+ * object carried verbatim via `error.data` on the WebSocket envelope. The
32
+ * JSON-RPC server-error `.code` numeric segment -32001 ~ -32005 maps 1:1
33
+ * to the 5 members
34
+ * at the dispatch layer.
35
+ *
36
+ * @example AI-user exhaustive switch on the 5 remote-domain alternatives (no default fallback)
37
+ * ```ts
38
+ * import { RemoteError, type RemoteErrorCode } from '@forgeax/engine-remote';
39
+ *
40
+ * function recover(code: RemoteErrorCode): string {
41
+ * switch (code) {
42
+ * case 'script-syntax-error': return 'fix script body syntax and resubmit';
43
+ * case 'script-runtime-error': return 'inspect stack trace; verify symbol availability';
44
+ * case 'server-startup-failed': return 'pick a different port or free port 5732';
45
+ * case 'server-not-running': return 'start demo dev or wire app.remote';
46
+ * case 'eval-result-not-serializable': return 'return a JSON-safe eval result';
47
+ * }
48
+ * }
49
+ * ```
50
+ */
51
+ export declare class RemoteError extends Error implements RemoteErrorShape {
52
+ readonly code: RemoteErrorCode;
53
+ readonly expected: string;
54
+ readonly hint: string;
55
+ readonly detail?: RemoteErrorDetail;
56
+ constructor(args: {
57
+ code: RemoteErrorCode;
58
+ expected: string;
59
+ hint: string;
60
+ detail?: RemoteErrorDetail;
61
+ });
62
+ toJSON(): {
63
+ readonly code: RemoteErrorCode;
64
+ readonly expected: string;
65
+ readonly hint: string;
66
+ readonly message: string;
67
+ readonly detail?: RemoteErrorDetail;
68
+ };
69
+ }
70
+ /**
71
+ * SSOT mapping `RemoteErrorCode` -> JSON-RPC `error.code` numeric segment
72
+ * (feat-20260629-inspector-two-layer-model D-5). The 5 remote P0
73
+ * members occupy the closed segment `-32001..-32005`.
74
+ *
75
+ * `server.ts` consumes this map at the JSON-RPC envelope edge so the wire
76
+ * always carries the lock-in numeric and a future drift in either direction
77
+ * raises a TypeScript completeness error (the `Record<RemoteErrorCode,
78
+ * number>` type guard requires every closed-union member to have a
79
+ * numeric).
80
+ */
81
+ export declare const REMOTE_ERROR_CODE_TO_JSONRPC: Readonly<Record<RemoteErrorCode, number>>;
82
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,WAAW,IAAI,gBAAgB,EAChC,MAAM,uBAAuB,CAAC;AAM/B,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,qBAAa,WAAY,SAAQ,KAAM,YAAW,gBAAgB;IAChE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;gBAExB,IAAI,EAAE;QAChB,IAAI,EAAE,eAAe,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,iBAAiB,CAAC;KAC5B;IAWD,MAAM,IAAI;QACR,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;QAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;KACrC;CASF;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAMlF,CAAC"}
@@ -0,0 +1,37 @@
1
+ // src/errors.ts
2
+ var RemoteError = class extends Error {
3
+ code;
4
+ expected;
5
+ hint;
6
+ detail;
7
+ constructor(args) {
8
+ super(`[RemoteError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);
9
+ this.name = "RemoteError";
10
+ this.code = args.code;
11
+ this.expected = args.expected;
12
+ this.hint = args.hint;
13
+ if (args.detail !== void 0) {
14
+ this.detail = args.detail;
15
+ }
16
+ }
17
+ toJSON() {
18
+ const json = {
19
+ code: this.code,
20
+ expected: this.expected,
21
+ hint: this.hint,
22
+ message: this.message
23
+ };
24
+ return this.detail === void 0 ? json : { ...json, detail: this.detail };
25
+ }
26
+ };
27
+ var REMOTE_ERROR_CODE_TO_JSONRPC = {
28
+ "script-syntax-error": -32001,
29
+ "script-runtime-error": -32002,
30
+ "server-startup-failed": -32003,
31
+ "server-not-running": -32004,
32
+ "eval-result-not-serializable": -32005
33
+ };
34
+
35
+ export { REMOTE_ERROR_CODE_TO_JSONRPC, RemoteError };
36
+ //# sourceMappingURL=errors.mjs.map
37
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts"],"names":[],"mappings":";AAsFO,IAAM,WAAA,GAAN,cAA0B,KAAA,CAAkC;AAAA,EACxD,IAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EAET,YAAY,IAAA,EAKT;AACD,IAAA,KAAA,CAAM,CAAA,aAAA,EAAgB,KAAK,IAAI,CAAA,YAAA,EAAe,KAAK,QAAQ,CAAA,QAAA,EAAW,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA;AACjF,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAW;AAC7B,MAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAA,GAME;AACA,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAS,IAAA,CAAK;AAAA,KAChB;AACA,IAAA,OAAO,IAAA,CAAK,WAAW,MAAA,GAAY,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO;AAAA,EAC3E;AACF;AAaO,IAAM,4BAAA,GAA0E;AAAA,EACrF,qBAAA,EAAuB,MAAA;AAAA,EACvB,sBAAA,EAAwB,MAAA;AAAA,EACxB,uBAAA,EAAyB,MAAA;AAAA,EACzB,oBAAA,EAAsB,MAAA;AAAA,EACtB,8BAAA,EAAgC;AAClC","file":"errors.mjs","sourcesContent":["// @forgeax/engine-remote/src/errors - RemoteError runtime class + re-export of\n// the closed `RemoteErrorCode` union; 5 members (feat-20260629-inspector-two-layer-model D-5).\n//\n// SSOT split: the **type alias** `RemoteErrorCode`\n// + **structural interface** `RemoteError` live in `@forgeax/engine-types`\n// (parallel to the existing `ShaderErrorCode` placement). This file owns\n// the **runtime class** (`extends Error` + `toJSON()`) only; the class\n// `implements` the type-side interface so the two sides cannot drift\n// (architecture-principles #1 SSOT).\n//\n// Shape (mirrors @forgeax/engine-rhi/src/errors.ts RhiError 4-field surface for\n// charter proposition 5 consistent abstraction):\n// - `RemoteErrorCode` = closed union 5 members (re-exported from types).\n// tsc strict-mode guards exhaustive switch completeness (charter\n// proposition 4); AI users consume via `switch (err.code) { case '...': ... }`\n// with NO default branch.\n// - `RemoteError` class extends Error with three readonly fields .code /\n// .expected / .hint (AGENTS.md \"Errors are structured\"). The constructor\n// auto-composes a human-readable .message (`[RemoteError <code>]\n// expected: <expected>; hint: <hint>`). The class implements the\n// `RemoteError` interface from `@forgeax/engine-types` so callers may\n// alternately type against the structural shape.\n// - `toJSON()` opts into JSON.stringify serialisation so the JSON-RPC 2.0\n// `error.data` payload carries .code / .expected / .hint / .message\n// verbatim through the WebSocket transport.\n\nimport type {\n RemoteErrorCode,\n RemoteErrorDetail,\n RemoteError as RemoteErrorShape,\n} from '@forgeax/engine-types';\n\n// Re-export the type-side alias verbatim so existing\n// `import { type RemoteErrorCode } from '@forgeax/engine-remote'` call sites\n// keep working (charter proposition 1 progressive disclosure — single\n// entry point for AI users).\nexport type { RemoteErrorCode };\n\n/**\n * Structured remote error. Four core fields plus bounded detail, mirroring `@forgeax/engine-rhi`\n * `RhiError` (charter proposition 5 consistent abstraction; AGENTS.md\n * \"Errors are structured\"). The class `implements RemoteErrorShape`\n * (the structural interface re-exported from `@forgeax/engine-types`) so the type\n * SSOT and the runtime class cannot drift.\n *\n * - `.code` closed union member (L1 key signal; switch-able).\n * - `.expected` expected-state description (L2 detail; ai-user-charter\n * proposition 4 requires expected-state copy).\n * - `.hint` actionable recovery guidance (L2 detail; charter\n * proposition 3 machine-readable hint > prose).\n * - `.message` auto-composed `[RemoteError <code>] expected: <expected>;\n * hint: <hint>` so human stack traces still surface the\n * triple. AI users prefer property access (charter\n * proposition 4: no string parsing).\n *\n * Per-code `.expected` + `.hint` templates (requirements §10.2 SSOT):\n *\n * | code | `.expected` | `.hint` |\n * |:--|:--|:--|\n * | `'script-syntax-error'` | `'script body is valid JavaScript'` | `'check syntax position in errMessage; fix and resubmit'` |\n * | `'script-runtime-error'` | `'script executes without throwing'` | `'inspect error; verify symbol availability; eval has full access to world/renderer/assets'` |\n * | `'server-startup-failed'` | `'server starts successfully on requested port'` | `'check if port is already in use (default 5732); pass different port; or kill existing process holding the port'` |\n * | `'server-not-running'` | `'server is reachable at ws://localhost:<port>'` | `'start the demo first; verify app.remote is wired; pass --port to override default 5732'` |\n * | `'eval-result-not-serializable'` | `'eval result is JSON-serializable'` | `'return a JSON-safe value; BigInt and cyclic objects are unsupported over JSON-RPC'` |\n *\n * JSON-RPC 2.0 transport contract: `toJSON()` returns the structured plain\n * object carried verbatim via `error.data` on the WebSocket envelope. The\n * JSON-RPC server-error `.code` numeric segment -32001 ~ -32005 maps 1:1\n * to the 5 members\n * at the dispatch layer.\n *\n * @example AI-user exhaustive switch on the 5 remote-domain alternatives (no default fallback)\n * ```ts\n * import { RemoteError, type RemoteErrorCode } from '@forgeax/engine-remote';\n *\n * function recover(code: RemoteErrorCode): string {\n * switch (code) {\n * case 'script-syntax-error': return 'fix script body syntax and resubmit';\n * case 'script-runtime-error': return 'inspect stack trace; verify symbol availability';\n * case 'server-startup-failed': return 'pick a different port or free port 5732';\n * case 'server-not-running': return 'start demo dev or wire app.remote';\n * case 'eval-result-not-serializable': return 'return a JSON-safe eval result';\n * }\n * }\n * ```\n */\nexport class RemoteError extends Error implements RemoteErrorShape {\n readonly code: RemoteErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: RemoteErrorDetail;\n\n constructor(args: {\n code: RemoteErrorCode;\n expected: string;\n hint: string;\n detail?: RemoteErrorDetail;\n }) {\n super(`[RemoteError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);\n this.name = 'RemoteError';\n this.code = args.code;\n this.expected = args.expected;\n this.hint = args.hint;\n if (args.detail !== undefined) {\n this.detail = args.detail;\n }\n }\n\n toJSON(): {\n readonly code: RemoteErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly message: string;\n readonly detail?: RemoteErrorDetail;\n } {\n const json = {\n code: this.code,\n expected: this.expected,\n hint: this.hint,\n message: this.message,\n };\n return this.detail === undefined ? json : { ...json, detail: this.detail };\n }\n}\n\n/**\n * SSOT mapping `RemoteErrorCode` -> JSON-RPC `error.code` numeric segment\n * (feat-20260629-inspector-two-layer-model D-5). The 5 remote P0\n * members occupy the closed segment `-32001..-32005`.\n *\n * `server.ts` consumes this map at the JSON-RPC envelope edge so the wire\n * always carries the lock-in numeric and a future drift in either direction\n * raises a TypeScript completeness error (the `Record<RemoteErrorCode,\n * number>` type guard requires every closed-union member to have a\n * numeric).\n */\nexport const REMOTE_ERROR_CODE_TO_JSONRPC: Readonly<Record<RemoteErrorCode, number>> = {\n 'script-syntax-error': -32001,\n 'script-runtime-error': -32002,\n 'server-startup-failed': -32003,\n 'server-not-running': -32004,\n 'eval-result-not-serializable': -32005,\n};\n"]}
@@ -0,0 +1,32 @@
1
+ import { RemoteError } from './errors';
2
+ export type ExecuteContext = {
3
+ readonly world: unknown;
4
+ readonly renderer: unknown;
5
+ readonly assets: unknown;
6
+ readonly rhiCapture?: unknown;
7
+ readonly simulation?: unknown;
8
+ readonly profiler?: unknown;
9
+ readonly execution?: unknown;
10
+ readonly importModule?: (specifier: string) => Promise<unknown>;
11
+ };
12
+ export type ExecuteResult = {
13
+ ok: true;
14
+ value: unknown;
15
+ } | {
16
+ ok: false;
17
+ error: RemoteError;
18
+ };
19
+ /**
20
+ * Evaluate a JavaScript script against the host engine context.
21
+ *
22
+ * Route B (D-1): host-realm compilation via the AsyncFunction constructor with
23
+ * injected _import. The script is the body of an async function; a lone
24
+ * expression is auto-returned, and top-level `await` / `return` are legal.
25
+ * - _import is available as a parameter for dynamic ESM imports.
26
+ * - rhiCapture is available as a 4th eval-scope root for the RHI capture
27
+ * capability (plan-strategy D-4).
28
+ * - No sandbox — full access reads and writes.
29
+ * - No timeout — host realm eval cannot be interrupted (see R6).
30
+ */
31
+ export declare function executeScript(script: string, ctx: ExecuteContext): Promise<ExecuteResult>;
32
+ //# sourceMappingURL=execute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAoCA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACjE,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AA0C7F;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CA+C/F"}
@@ -0,0 +1,95 @@
1
+ // src/errors.ts
2
+ var RemoteError = class extends Error {
3
+ code;
4
+ expected;
5
+ hint;
6
+ detail;
7
+ constructor(args) {
8
+ super(`[RemoteError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);
9
+ this.name = "RemoteError";
10
+ this.code = args.code;
11
+ this.expected = args.expected;
12
+ this.hint = args.hint;
13
+ if (args.detail !== void 0) {
14
+ this.detail = args.detail;
15
+ }
16
+ }
17
+ toJSON() {
18
+ const json = {
19
+ code: this.code,
20
+ expected: this.expected,
21
+ hint: this.hint,
22
+ message: this.message
23
+ };
24
+ return this.detail === void 0 ? json : { ...json, detail: this.detail };
25
+ }
26
+ };
27
+
28
+ // src/execute.ts
29
+ var AsyncFunction = Object.getPrototypeOf(async () => {
30
+ }).constructor;
31
+ var _import = async (specifier) => import(specifier);
32
+ function compile(script) {
33
+ const params = [
34
+ "world",
35
+ "renderer",
36
+ "assets",
37
+ "rhiCapture",
38
+ "simulation",
39
+ "profiler",
40
+ "execution",
41
+ "_import"
42
+ ];
43
+ try {
44
+ const expr = script.replace(/[\s;]+$/, "");
45
+ return new AsyncFunction(...params, `return (${expr}
46
+ )`);
47
+ } catch (e) {
48
+ if (!(e instanceof SyntaxError)) throw e;
49
+ return new AsyncFunction(...params, script);
50
+ }
51
+ }
52
+ async function executeScript(script, ctx) {
53
+ try {
54
+ const fn = compile(script);
55
+ const value = await fn(
56
+ ctx.world,
57
+ ctx.renderer,
58
+ ctx.assets,
59
+ ctx.rhiCapture,
60
+ ctx.simulation,
61
+ ctx.profiler,
62
+ ctx.execution,
63
+ ctx.importModule ?? _import
64
+ );
65
+ return { ok: true, value };
66
+ } catch (e) {
67
+ if (e instanceof RemoteError) {
68
+ return { ok: false, error: e };
69
+ }
70
+ if (e instanceof SyntaxError) {
71
+ const msg = e.message;
72
+ return {
73
+ ok: false,
74
+ error: new RemoteError({
75
+ code: "script-syntax-error",
76
+ expected: "script body is valid JavaScript",
77
+ hint: `check syntax near: ${msg}; fix and resubmit`
78
+ })
79
+ };
80
+ }
81
+ const rawMessage = e instanceof Error ? e.message : String(e);
82
+ return {
83
+ ok: false,
84
+ error: new RemoteError({
85
+ code: "script-runtime-error",
86
+ expected: "script executes without throwing",
87
+ hint: `inspect error; verify symbol availability; eval has full access to world/renderer/assets (errMessage: ${rawMessage})`
88
+ })
89
+ };
90
+ }
91
+ }
92
+
93
+ export { executeScript };
94
+ //# sourceMappingURL=execute.mjs.map
95
+ //# sourceMappingURL=execute.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/execute.ts"],"names":[],"mappings":"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","file":"execute.mjs","sourcesContent":["// @forgeax/engine-remote/src/errors - RemoteError runtime class + re-export of\n// the closed `RemoteErrorCode` union; 5 members (feat-20260629-inspector-two-layer-model D-5).\n//\n// SSOT split: the **type alias** `RemoteErrorCode`\n// + **structural interface** `RemoteError` live in `@forgeax/engine-types`\n// (parallel to the existing `ShaderErrorCode` placement). This file owns\n// the **runtime class** (`extends Error` + `toJSON()`) only; the class\n// `implements` the type-side interface so the two sides cannot drift\n// (architecture-principles #1 SSOT).\n//\n// Shape (mirrors @forgeax/engine-rhi/src/errors.ts RhiError 4-field surface for\n// charter proposition 5 consistent abstraction):\n// - `RemoteErrorCode` = closed union 5 members (re-exported from types).\n// tsc strict-mode guards exhaustive switch completeness (charter\n// proposition 4); AI users consume via `switch (err.code) { case '...': ... }`\n// with NO default branch.\n// - `RemoteError` class extends Error with three readonly fields .code /\n// .expected / .hint (AGENTS.md \"Errors are structured\"). The constructor\n// auto-composes a human-readable .message (`[RemoteError <code>]\n// expected: <expected>; hint: <hint>`). The class implements the\n// `RemoteError` interface from `@forgeax/engine-types` so callers may\n// alternately type against the structural shape.\n// - `toJSON()` opts into JSON.stringify serialisation so the JSON-RPC 2.0\n// `error.data` payload carries .code / .expected / .hint / .message\n// verbatim through the WebSocket transport.\n\nimport type {\n RemoteErrorCode,\n RemoteErrorDetail,\n RemoteError as RemoteErrorShape,\n} from '@forgeax/engine-types';\n\n// Re-export the type-side alias verbatim so existing\n// `import { type RemoteErrorCode } from '@forgeax/engine-remote'` call sites\n// keep working (charter proposition 1 progressive disclosure — single\n// entry point for AI users).\nexport type { RemoteErrorCode };\n\n/**\n * Structured remote error. Four core fields plus bounded detail, mirroring `@forgeax/engine-rhi`\n * `RhiError` (charter proposition 5 consistent abstraction; AGENTS.md\n * \"Errors are structured\"). The class `implements RemoteErrorShape`\n * (the structural interface re-exported from `@forgeax/engine-types`) so the type\n * SSOT and the runtime class cannot drift.\n *\n * - `.code` closed union member (L1 key signal; switch-able).\n * - `.expected` expected-state description (L2 detail; ai-user-charter\n * proposition 4 requires expected-state copy).\n * - `.hint` actionable recovery guidance (L2 detail; charter\n * proposition 3 machine-readable hint > prose).\n * - `.message` auto-composed `[RemoteError <code>] expected: <expected>;\n * hint: <hint>` so human stack traces still surface the\n * triple. AI users prefer property access (charter\n * proposition 4: no string parsing).\n *\n * Per-code `.expected` + `.hint` templates (requirements §10.2 SSOT):\n *\n * | code | `.expected` | `.hint` |\n * |:--|:--|:--|\n * | `'script-syntax-error'` | `'script body is valid JavaScript'` | `'check syntax position in errMessage; fix and resubmit'` |\n * | `'script-runtime-error'` | `'script executes without throwing'` | `'inspect error; verify symbol availability; eval has full access to world/renderer/assets'` |\n * | `'server-startup-failed'` | `'server starts successfully on requested port'` | `'check if port is already in use (default 5732); pass different port; or kill existing process holding the port'` |\n * | `'server-not-running'` | `'server is reachable at ws://localhost:<port>'` | `'start the demo first; verify app.remote is wired; pass --port to override default 5732'` |\n * | `'eval-result-not-serializable'` | `'eval result is JSON-serializable'` | `'return a JSON-safe value; BigInt and cyclic objects are unsupported over JSON-RPC'` |\n *\n * JSON-RPC 2.0 transport contract: `toJSON()` returns the structured plain\n * object carried verbatim via `error.data` on the WebSocket envelope. The\n * JSON-RPC server-error `.code` numeric segment -32001 ~ -32005 maps 1:1\n * to the 5 members\n * at the dispatch layer.\n *\n * @example AI-user exhaustive switch on the 5 remote-domain alternatives (no default fallback)\n * ```ts\n * import { RemoteError, type RemoteErrorCode } from '@forgeax/engine-remote';\n *\n * function recover(code: RemoteErrorCode): string {\n * switch (code) {\n * case 'script-syntax-error': return 'fix script body syntax and resubmit';\n * case 'script-runtime-error': return 'inspect stack trace; verify symbol availability';\n * case 'server-startup-failed': return 'pick a different port or free port 5732';\n * case 'server-not-running': return 'start demo dev or wire app.remote';\n * case 'eval-result-not-serializable': return 'return a JSON-safe eval result';\n * }\n * }\n * ```\n */\nexport class RemoteError extends Error implements RemoteErrorShape {\n readonly code: RemoteErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: RemoteErrorDetail;\n\n constructor(args: {\n code: RemoteErrorCode;\n expected: string;\n hint: string;\n detail?: RemoteErrorDetail;\n }) {\n super(`[RemoteError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);\n this.name = 'RemoteError';\n this.code = args.code;\n this.expected = args.expected;\n this.hint = args.hint;\n if (args.detail !== undefined) {\n this.detail = args.detail;\n }\n }\n\n toJSON(): {\n readonly code: RemoteErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly message: string;\n readonly detail?: RemoteErrorDetail;\n } {\n const json = {\n code: this.code,\n expected: this.expected,\n hint: this.hint,\n message: this.message,\n };\n return this.detail === undefined ? json : { ...json, detail: this.detail };\n }\n}\n\n/**\n * SSOT mapping `RemoteErrorCode` -> JSON-RPC `error.code` numeric segment\n * (feat-20260629-inspector-two-layer-model D-5). The 5 remote P0\n * members occupy the closed segment `-32001..-32005`.\n *\n * `server.ts` consumes this map at the JSON-RPC envelope edge so the wire\n * always carries the lock-in numeric and a future drift in either direction\n * raises a TypeScript completeness error (the `Record<RemoteErrorCode,\n * number>` type guard requires every closed-union member to have a\n * numeric).\n */\nexport const REMOTE_ERROR_CODE_TO_JSONRPC: Readonly<Record<RemoteErrorCode, number>> = {\n 'script-syntax-error': -32001,\n 'script-runtime-error': -32002,\n 'server-startup-failed': -32003,\n 'server-not-running': -32004,\n 'eval-result-not-serializable': -32005,\n};\n","// @forgeax/engine-remote/src/execute — async host-realm eval.\n//\n// D-1 route B (2026-06-29): vm.runInContext does not honor\n// importModuleDynamically for Script execution. Host realm compilation via\n// the AsyncFunction constructor resolves `await import` naturally, as long\n// as the import function from the calling module scope is injected.\n//\n// CONTRACT (the one an AI user holds): the script IS the body of an async\n// function with `world` / `renderer` / `assets` / `rhiCapture` / `simulation` / `_import`\n// in scope. So all of these Just Work, un-wrapped:\n// - a bare expression: `renderer.backend` -> auto-returned\n// - top-level await: `await _import('engine-module')`\n// - top-level return: `return world.inspect().entityCount`\n// - multi-statement + return: `const m = await _import(...); return m.x`\n// (the historical `(async () => { ... })()` IIFE form still works too — its\n// returned Promise is awaited.)\n//\n// Implementation (mirrors a REPL, two construction-time-checked attempts):\n// 1. expression mode: compile `return (<script>)` — auto-returns a lone\n// expression (incl. an await-expression), preserving last-expression value.\n// 2. on SyntaxError from (1)'s CONSTRUCTION: statement mode — compile\n// `<script>` as the async body directly, legalizing top-level return +\n// await + arbitrary statements.\n// Only a construction-time SyntaxError advances attempt 1 -> 2, so user code is\n// compiled once and executed at most once (no double side effects). We never use\n// `eval`: indirect eval ran the body as a global program, which is precisely\n// what banned top-level return/await and produced the doc-vs-reality gap.\n//\n// try/catch maps errors:\n// SyntaxError (both attempts fail to compile) -> 'script-syntax-error'\n// RemoteError (re-thrown) -> verbatim\n// anything else -> 'script-runtime-error'\n//\n// The sandbox is dismantled — eval is full-access, no wrapReadOnly.\n// Timeout is removed (route B has no interrupt mechanism; see R6).\n\nimport { RemoteError } from './errors';\n\n// AsyncFunction constructor (not a global binding). An async body is what\n// legalizes top-level `await` AND top-level `return` simultaneously.\nconst AsyncFunction = Object.getPrototypeOf(async () => {}).constructor as FunctionConstructor;\n\nexport type ExecuteContext = {\n readonly world: unknown;\n readonly renderer: unknown;\n readonly assets: unknown;\n readonly rhiCapture?: unknown;\n readonly simulation?: unknown;\n readonly profiler?: unknown;\n readonly execution?: unknown;\n readonly importModule?: (specifier: string) => Promise<unknown>;\n};\n\nexport type ExecuteResult = { ok: true; value: unknown } | { ok: false; error: RemoteError };\n\n// Capture import at module load time. This is the host realm's dynamic\n// import() — when injected into new Function, it resolves module\n// specifiers relative to the module that called executeScript. The remote\n// package stays package-neutral: a host may inject a capability projection\n// through ExecuteContext.importModule, but the transport does not own any\n// engine package vocabulary.\nconst _import = async (specifier: string): Promise<unknown> => import(specifier);\n\n// Compile the script as an async function body. Tries expression mode first\n// (auto-return a lone expression), falling back to statement mode on a\n// construction-time SyntaxError. Returns the compiled fn, or throws the\n// statement-mode SyntaxError if BOTH modes fail to parse.\nfunction compile(script: string): FunctionConstructor['prototype'] {\n const params = [\n 'world',\n 'renderer',\n 'assets',\n 'rhiCapture',\n 'simulation',\n 'profiler',\n 'execution',\n '_import',\n ] as const;\n try {\n // Expression mode: `return (<expr>)` auto-returns a lone expression\n // (including an await-expression), preserving last-expression-value.\n // Trailing semicolons/whitespace are trimmed so `renderer.backend;`\n // still returns its value (the old indirect-eval completion-value\n // behavior) instead of parsing as a statement that returns undefined.\n const expr = script.replace(/[\\s;]+$/, '');\n return new AsyncFunction(...params, `return (${expr}\\n)`);\n } catch (e) {\n if (!(e instanceof SyntaxError)) throw e;\n // Statement mode: the script IS the async body — legalizes top-level\n // return + await + arbitrary statements. If this also fails to parse,\n // its SyntaxError is the authoritative one to surface.\n return new AsyncFunction(...params, script);\n }\n}\n\n/**\n * Evaluate a JavaScript script against the host engine context.\n *\n * Route B (D-1): host-realm compilation via the AsyncFunction constructor with\n * injected _import. The script is the body of an async function; a lone\n * expression is auto-returned, and top-level `await` / `return` are legal.\n * - _import is available as a parameter for dynamic ESM imports.\n * - rhiCapture is available as a 4th eval-scope root for the RHI capture\n * capability (plan-strategy D-4).\n * - No sandbox — full access reads and writes.\n * - No timeout — host realm eval cannot be interrupted (see R6).\n */\nexport async function executeScript(script: string, ctx: ExecuteContext): Promise<ExecuteResult> {\n try {\n const fn = compile(script);\n // AsyncFunction always returns a Promise; await resolves the value and\n // surfaces any runtime throw into this catch.\n const value: unknown = await fn(\n ctx.world,\n ctx.renderer,\n ctx.assets,\n ctx.rhiCapture,\n ctx.simulation,\n ctx.profiler,\n ctx.execution,\n ctx.importModule ?? _import,\n );\n\n return { ok: true, value };\n } catch (e) {\n // 1. RemoteError re-thrown from within the script surfaces verbatim.\n if (e instanceof RemoteError) {\n return { ok: false, error: e };\n }\n\n // 2. SyntaxError: both compile() attempts failed to parse the script.\n if (e instanceof SyntaxError) {\n const msg = e.message;\n return {\n ok: false,\n error: new RemoteError({\n code: 'script-syntax-error',\n expected: 'script body is valid JavaScript',\n hint: `check syntax near: ${msg}; fix and resubmit`,\n }),\n };\n }\n\n // 3. Runtime error (throws during function execution).\n const rawMessage = e instanceof Error ? e.message : String(e);\n return {\n ok: false,\n error: new RemoteError({\n code: 'script-runtime-error',\n expected: 'script executes without throwing',\n hint: `inspect error; verify symbol availability; eval has full access to world/renderer/assets (errMessage: ${rawMessage})`,\n }),\n };\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export { RemoteError, type RemoteErrorCode } from './errors';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.mjs ADDED
@@ -0,0 +1,30 @@
1
+ // src/errors.ts
2
+ var RemoteError = class extends Error {
3
+ code;
4
+ expected;
5
+ hint;
6
+ detail;
7
+ constructor(args) {
8
+ super(`[RemoteError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);
9
+ this.name = "RemoteError";
10
+ this.code = args.code;
11
+ this.expected = args.expected;
12
+ this.hint = args.hint;
13
+ if (args.detail !== void 0) {
14
+ this.detail = args.detail;
15
+ }
16
+ }
17
+ toJSON() {
18
+ const json = {
19
+ code: this.code,
20
+ expected: this.expected,
21
+ hint: this.hint,
22
+ message: this.message
23
+ };
24
+ return this.detail === void 0 ? json : { ...json, detail: this.detail };
25
+ }
26
+ };
27
+
28
+ export { RemoteError };
29
+ //# sourceMappingURL=index.mjs.map
30
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts"],"names":[],"mappings":";AAsFO,IAAM,WAAA,GAAN,cAA0B,KAAA,CAAkC;AAAA,EACxD,IAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EAET,YAAY,IAAA,EAKT;AACD,IAAA,KAAA,CAAM,CAAA,aAAA,EAAgB,KAAK,IAAI,CAAA,YAAA,EAAe,KAAK,QAAQ,CAAA,QAAA,EAAW,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA;AACjF,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAW;AAC7B,MAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAA,GAME;AACA,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAS,IAAA,CAAK;AAAA,KAChB;AACA,IAAA,OAAO,IAAA,CAAK,WAAW,MAAA,GAAY,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO;AAAA,EAC3E;AACF","file":"index.mjs","sourcesContent":["// @forgeax/engine-remote/src/errors - RemoteError runtime class + re-export of\n// the closed `RemoteErrorCode` union; 5 members (feat-20260629-inspector-two-layer-model D-5).\n//\n// SSOT split: the **type alias** `RemoteErrorCode`\n// + **structural interface** `RemoteError` live in `@forgeax/engine-types`\n// (parallel to the existing `ShaderErrorCode` placement). This file owns\n// the **runtime class** (`extends Error` + `toJSON()`) only; the class\n// `implements` the type-side interface so the two sides cannot drift\n// (architecture-principles #1 SSOT).\n//\n// Shape (mirrors @forgeax/engine-rhi/src/errors.ts RhiError 4-field surface for\n// charter proposition 5 consistent abstraction):\n// - `RemoteErrorCode` = closed union 5 members (re-exported from types).\n// tsc strict-mode guards exhaustive switch completeness (charter\n// proposition 4); AI users consume via `switch (err.code) { case '...': ... }`\n// with NO default branch.\n// - `RemoteError` class extends Error with three readonly fields .code /\n// .expected / .hint (AGENTS.md \"Errors are structured\"). The constructor\n// auto-composes a human-readable .message (`[RemoteError <code>]\n// expected: <expected>; hint: <hint>`). The class implements the\n// `RemoteError` interface from `@forgeax/engine-types` so callers may\n// alternately type against the structural shape.\n// - `toJSON()` opts into JSON.stringify serialisation so the JSON-RPC 2.0\n// `error.data` payload carries .code / .expected / .hint / .message\n// verbatim through the WebSocket transport.\n\nimport type {\n RemoteErrorCode,\n RemoteErrorDetail,\n RemoteError as RemoteErrorShape,\n} from '@forgeax/engine-types';\n\n// Re-export the type-side alias verbatim so existing\n// `import { type RemoteErrorCode } from '@forgeax/engine-remote'` call sites\n// keep working (charter proposition 1 progressive disclosure — single\n// entry point for AI users).\nexport type { RemoteErrorCode };\n\n/**\n * Structured remote error. Four core fields plus bounded detail, mirroring `@forgeax/engine-rhi`\n * `RhiError` (charter proposition 5 consistent abstraction; AGENTS.md\n * \"Errors are structured\"). The class `implements RemoteErrorShape`\n * (the structural interface re-exported from `@forgeax/engine-types`) so the type\n * SSOT and the runtime class cannot drift.\n *\n * - `.code` closed union member (L1 key signal; switch-able).\n * - `.expected` expected-state description (L2 detail; ai-user-charter\n * proposition 4 requires expected-state copy).\n * - `.hint` actionable recovery guidance (L2 detail; charter\n * proposition 3 machine-readable hint > prose).\n * - `.message` auto-composed `[RemoteError <code>] expected: <expected>;\n * hint: <hint>` so human stack traces still surface the\n * triple. AI users prefer property access (charter\n * proposition 4: no string parsing).\n *\n * Per-code `.expected` + `.hint` templates (requirements §10.2 SSOT):\n *\n * | code | `.expected` | `.hint` |\n * |:--|:--|:--|\n * | `'script-syntax-error'` | `'script body is valid JavaScript'` | `'check syntax position in errMessage; fix and resubmit'` |\n * | `'script-runtime-error'` | `'script executes without throwing'` | `'inspect error; verify symbol availability; eval has full access to world/renderer/assets'` |\n * | `'server-startup-failed'` | `'server starts successfully on requested port'` | `'check if port is already in use (default 5732); pass different port; or kill existing process holding the port'` |\n * | `'server-not-running'` | `'server is reachable at ws://localhost:<port>'` | `'start the demo first; verify app.remote is wired; pass --port to override default 5732'` |\n * | `'eval-result-not-serializable'` | `'eval result is JSON-serializable'` | `'return a JSON-safe value; BigInt and cyclic objects are unsupported over JSON-RPC'` |\n *\n * JSON-RPC 2.0 transport contract: `toJSON()` returns the structured plain\n * object carried verbatim via `error.data` on the WebSocket envelope. The\n * JSON-RPC server-error `.code` numeric segment -32001 ~ -32005 maps 1:1\n * to the 5 members\n * at the dispatch layer.\n *\n * @example AI-user exhaustive switch on the 5 remote-domain alternatives (no default fallback)\n * ```ts\n * import { RemoteError, type RemoteErrorCode } from '@forgeax/engine-remote';\n *\n * function recover(code: RemoteErrorCode): string {\n * switch (code) {\n * case 'script-syntax-error': return 'fix script body syntax and resubmit';\n * case 'script-runtime-error': return 'inspect stack trace; verify symbol availability';\n * case 'server-startup-failed': return 'pick a different port or free port 5732';\n * case 'server-not-running': return 'start demo dev or wire app.remote';\n * case 'eval-result-not-serializable': return 'return a JSON-safe eval result';\n * }\n * }\n * ```\n */\nexport class RemoteError extends Error implements RemoteErrorShape {\n readonly code: RemoteErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: RemoteErrorDetail;\n\n constructor(args: {\n code: RemoteErrorCode;\n expected: string;\n hint: string;\n detail?: RemoteErrorDetail;\n }) {\n super(`[RemoteError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);\n this.name = 'RemoteError';\n this.code = args.code;\n this.expected = args.expected;\n this.hint = args.hint;\n if (args.detail !== undefined) {\n this.detail = args.detail;\n }\n }\n\n toJSON(): {\n readonly code: RemoteErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly message: string;\n readonly detail?: RemoteErrorDetail;\n } {\n const json = {\n code: this.code,\n expected: this.expected,\n hint: this.hint,\n message: this.message,\n };\n return this.detail === undefined ? json : { ...json, detail: this.detail };\n }\n}\n\n/**\n * SSOT mapping `RemoteErrorCode` -> JSON-RPC `error.code` numeric segment\n * (feat-20260629-inspector-two-layer-model D-5). The 5 remote P0\n * members occupy the closed segment `-32001..-32005`.\n *\n * `server.ts` consumes this map at the JSON-RPC envelope edge so the wire\n * always carries the lock-in numeric and a future drift in either direction\n * raises a TypeScript completeness error (the `Record<RemoteErrorCode,\n * number>` type guard requires every closed-union member to have a\n * numeric).\n */\nexport const REMOTE_ERROR_CODE_TO_JSONRPC: Readonly<Record<RemoteErrorCode, number>> = {\n 'script-syntax-error': -32001,\n 'script-runtime-error': -32002,\n 'server-startup-failed': -32003,\n 'server-not-running': -32004,\n 'eval-result-not-serializable': -32005,\n};\n"]}
@@ -0,0 +1,23 @@
1
+ export interface ComponentIntrospectionDescriptor {
2
+ readonly name: string;
3
+ readonly schema: Readonly<Record<string, string>>;
4
+ readonly fields: Readonly<Record<string, unknown>>;
5
+ readonly meta: Readonly<Record<string, unknown>>;
6
+ }
7
+ export interface RemoteRootValues {
8
+ readonly world: unknown;
9
+ readonly renderer: unknown;
10
+ readonly assets: unknown;
11
+ readonly rhiCapture?: unknown;
12
+ readonly profiler?: unknown;
13
+ readonly execution?: unknown;
14
+ /** Read-only World-owned simulation summary; no restore/replay operation. */
15
+ readonly simulation?: unknown;
16
+ readonly introspection?: readonly ComponentIntrospectionDescriptor[];
17
+ }
18
+ export declare function isProfilerRoot(value: unknown): boolean;
19
+ export declare function isExecutionRoot(value: unknown): value is {
20
+ report(): unknown;
21
+ };
22
+ export declare function buildIntrospectDoc(host: string, port: number, roots: RemoteRootValues): unknown;
23
+ //# sourceMappingURL=introspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../src/introspect.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,gCAAgC,EAAE,CAAC;CACtE;AAcD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CActD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI;IAAE,MAAM,IAAI,OAAO,CAAA;CAAE,CAM9E;AA0GD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAuD/F"}