@vmz/vmz 0.0.2 → 0.0.3

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 (65) hide show
  1. package/README.md +13 -9
  2. package/dist/application-cmd.d.ts +1 -2
  3. package/dist/application-cmd.js +9 -10
  4. package/dist/bundler-adapter.d.ts +2 -3
  5. package/dist/bundler-adapter.js +2 -3
  6. package/dist/cli.d.ts +10 -2
  7. package/dist/cli.js +119 -15
  8. package/dist/dev-session.d.ts +2 -2
  9. package/dist/dev-session.js +3 -3
  10. package/dist/document-build.js +1 -2
  11. package/dist/document-check.d.ts +1 -1
  12. package/dist/document-check.js +4 -4
  13. package/dist/document-cmd.d.ts +1 -2
  14. package/dist/document-cmd.js +2 -3
  15. package/dist/document-designs.js +1 -1
  16. package/dist/document-enrich.js +2 -3
  17. package/dist/document-evidence.d.ts +4 -4
  18. package/dist/document-evidence.js +20 -12
  19. package/dist/document-integrate.d.ts +0 -1
  20. package/dist/document-integrate.js +0 -1
  21. package/dist/document-interactive.d.ts +11 -11
  22. package/dist/document-interactive.js +12 -13
  23. package/dist/document-locale.d.ts +1 -1
  24. package/dist/document-locale.js +1 -1
  25. package/dist/document-markdown.d.ts +1 -2
  26. package/dist/document-markdown.js +13 -7
  27. package/dist/document-scan.d.ts +4 -4
  28. package/dist/document-scan.js +4 -4
  29. package/dist/document-schema.d.ts +28 -29
  30. package/dist/document-schema.js +28 -29
  31. package/dist/explain-cmd.js +3 -3
  32. package/dist/index.d.ts +340 -789
  33. package/dist/index.js +91 -80
  34. package/dist/invocation.d.ts +91 -0
  35. package/dist/invocation.js +190 -0
  36. package/dist/locale-check.d.ts +3 -3
  37. package/dist/locale-check.js +5 -6
  38. package/dist/locale-cmd.js +6 -7
  39. package/dist/locale-delivery.d.ts +38 -38
  40. package/dist/locale-delivery.js +39 -40
  41. package/dist/locale-router.d.ts +39 -40
  42. package/dist/locale-router.js +39 -40
  43. package/dist/locale-runtime.d.ts +39 -39
  44. package/dist/locale-runtime.js +44 -45
  45. package/dist/locale-schema.d.ts +1 -2
  46. package/dist/locale-schema.js +1 -2
  47. package/dist/locale-tooling.d.ts +13 -13
  48. package/dist/locale-tooling.js +14 -15
  49. package/dist/log.d.ts +1 -1
  50. package/dist/log.js +1 -1
  51. package/dist/packages.d.ts +1 -2
  52. package/dist/packages.js +1 -2
  53. package/dist/plugin-host.d.ts +1 -2
  54. package/dist/plugin-host.js +2 -3
  55. package/dist/refactor-cmd.d.ts +1 -1
  56. package/dist/refactor-cmd.js +6 -6
  57. package/dist/resolve-native-cli.d.ts +14 -0
  58. package/dist/resolve-native-cli.js +84 -0
  59. package/dist/resolve.d.ts +1 -2
  60. package/dist/resolve.js +1 -2
  61. package/dist/test-cmd.d.ts +2 -2
  62. package/dist/test-cmd.js +37 -17
  63. package/dist/watch-diff.d.ts +1 -1
  64. package/dist/watch-diff.js +1 -1
  65. package/package.json +31 -16
package/README.md CHANGED
@@ -28,21 +28,25 @@ toolchains.
28
28
 
29
29
  ## One tool, several views of the same program
30
30
 
31
- | Workflow | The question it should answer |
32
- |---|---|
33
- | Development | What changed, and which application regions are affected? |
34
- | Checking | Which state, route, server, or lifetime boundary cannot be proven? |
35
- | Building | What belongs in browser, SSR, resume, and server output? |
36
- | Testing | Did the application behave correctly and avoid unrelated work? |
37
- | Documents | Are project documents connected, localized, and deployable? |
31
+ | Workflow | The question it should answer |
32
+ |-------------|--------------------------------------------------------------------|
33
+ | Development | What changed, and which application regions are affected? |
34
+ | Checking | Which state, route, server, or lifetime boundary cannot be proven? |
35
+ | Building | What belongs in browser, SSR, resume, and server output? |
36
+ | Testing | Did the application behave correctly and avoid unrelated work? |
37
+ | Documents | Are project documents connected, localized, and deployable? |
38
38
 
39
39
  ### Designed for the npm world
40
40
 
41
- VMZ does not ask users to abandon JavaScript packaging. Node remains the npm, plugin, development-server, and orchestration host. A long-lived N-API bridge connects that ecosystem to Rust and oxc without reducing semantic analysis to a sequence of tiny file transforms.
41
+ VMZ does not ask users to abandon JavaScript packaging. Node remains the npm, plugin, development-server, and
42
+ orchestration host. A long-lived N-API bridge connects that ecosystem to Rust and oxc without reducing semantic analysis
43
+ to a sequence of tiny file transforms.
42
44
 
43
45
  ### More than pass or fail
44
46
 
45
- The interesting future of the CLI is explanation. A useful compiler should expose the source span, graph edge, owner, deployment boundary, and fallback reason behind a decision. That is a better developer experience than adding more colored output to an opaque build. 🧭
47
+ The interesting future of the CLI is explanation. A useful compiler should expose the source span, graph edge, owner,
48
+ deployment boundary, and fallback reason behind a decision. That is a better developer experience than adding more
49
+ colored output to an opaque build. 🧭
46
50
 
47
51
  ## License
48
52
 
@@ -1,6 +1,5 @@
1
1
  /**
2
- * `vmz application` — Application Collection / Mount (M0–M5).
3
- * Design: `规划设计/vmz/22`
2
+ * `vmz application` — Application Collection / Mount .
4
3
  */
5
4
  /**
6
5
  * @param {string[]} argv
@@ -1,7 +1,6 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * `vmz application` — Application Collection / Mount (M0–M5).
4
- * Design: `规划设计/vmz/22`
3
+ * `vmz application` — Application Collection / Mount .
5
4
  */
6
5
  import { existsSync, readFileSync, writeFileSync } from 'node:fs';
7
6
  import path from 'node:path';
@@ -42,18 +41,18 @@ export async function cmdApplication(argv) {
42
41
  return 1;
43
42
  }
44
43
  function printHelp() {
45
- console.log(`vmz application — Application Collection / Mount (M0–M5)
44
+ console.log(`vmz application — Application Collection / Mount
46
45
 
47
46
  Usage:
48
47
  vmz application check [host] Validate descriptors + applications.config.json5
49
48
  vmz application list [host] List resolved ApplicationIds / collections / mounts
50
49
  vmz application schemas Print frozen protocol catalog JSON
51
- vmz application relocatable [pkg] M1: ApplicationBase / non_relocatable_url proof
52
- vmz application relocate <manifest.json> M1: apply ApplicationBase to relocation manifest
53
- vmz application artifacts [host] M2: ApplicationArtifact + MountTable boundary
54
- vmz application isolation [host] M3: isolation namespaces + failure containment
55
- vmz application composition [host] M4: catalog consumption + cross-app Link hrefs
56
- vmz application dev [host] M5: sessions / affected / proxy / mounted tests / deploy
50
+ vmz application relocatable [pkg] ApplicationBase / non_relocatable_url proof
51
+ vmz application relocate <manifest.json> apply ApplicationBase to relocation manifest
52
+ vmz application artifacts [host] ApplicationArtifact + MountTable boundary
53
+ vmz application isolation [host] isolation namespaces + failure containment
54
+ vmz application composition [host] catalog consumption + cross-app Link hrefs
55
+ vmz application dev [host] sessions / affected / proxy / mounted tests / deploy
57
56
 
58
57
  Options:
59
58
  --json [file] Emit report JSON to stdout or file
@@ -125,7 +124,7 @@ function emitJson(args, json, printHuman) {
125
124
  }
126
125
  function cmdSchemas() {
127
126
  const native = loadNative();
128
- console.log(native.queryApplicationProtocolCatalog());
127
+ console.log(native.queryApplicationProtocolCatalog);
129
128
  return 0;
130
129
  }
131
130
  /**
@@ -1,7 +1,6 @@
1
1
  /**
2
- * Bundler adapter (N4) — consumes Deployment IR; does not invent VMZ semantics.
2
+ * Bundler adapter (session) — consumes Deployment IR; does not invent VMZ semantics.
3
3
  *
4
- * Design: `规划设计/vmz/14` — VPG/Deployment IR → bundler executes pack/minify/assets.
5
4
  * Vite/Rolldown may call these helpers; they must not reverse the arrow.
6
5
  */
7
6
  /**
@@ -54,7 +53,7 @@ export declare function createVitePluginVmzAdapter(options?: {}): {
54
53
  configResolved(): void;
55
54
  };
56
55
  /**
57
- * Thin Rolldown plugin factory (N4.2) — same contract as Vite adapter: read Deployment IR only.
56
+ * Thin Rolldown plugin factory (deployment) — same contract as Vite adapter: read Deployment IR only.
58
57
  * @param {{ outDir?: string, root?: string }} [options]
59
58
  */
60
59
  export declare function createRolldownPluginVmzAdapter(options?: {}): {
@@ -1,8 +1,7 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * Bundler adapter (N4) — consumes Deployment IR; does not invent VMZ semantics.
3
+ * Bundler adapter (session) — consumes Deployment IR; does not invent VMZ semantics.
4
4
  *
5
- * Design: `规划设计/vmz/14` — VPG/Deployment IR → bundler executes pack/minify/assets.
6
5
  * Vite/Rolldown may call these helpers; they must not reverse the arrow.
7
6
  */
8
7
  import { existsSync, readFileSync } from 'node:fs';
@@ -90,7 +89,7 @@ export function createVitePluginVmzAdapter(options = {}) {
90
89
  };
91
90
  }
92
91
  /**
93
- * Thin Rolldown plugin factory (N4.2) — same contract as Vite adapter: read Deployment IR only.
92
+ * Thin Rolldown plugin factory (deployment) — same contract as Vite adapter: read Deployment IR only.
94
93
  * @param {{ outDir?: string, root?: string }} [options]
95
94
  */
96
95
  export function createRolldownPluginVmzAdapter(options = {}) {
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Node CLI command implementations (N2).
2
+ * Node CLI command implementations .
3
3
  */
4
4
  /**
5
5
  * @param {string[]} argv
@@ -7,9 +7,17 @@
7
7
  export declare function parseArgs(argv: any): {
8
8
  _: any[];
9
9
  };
10
+ export declare function printGlobalHelp(): void;
11
+ export declare function printProjectHelp(): void;
12
+ /** @deprecated use printProjectHelp / printGlobalHelp */
10
13
  export declare function printHelp(): void;
11
14
  /**
12
15
  * @param {string[]} argv
16
+ * @param {{
17
+ * cwd?: string,
18
+ * thisPackageRoot?: string,
19
+ * reexec?: (bin: string, argv: string[]) => Promise<number>,
20
+ * }} [opts]
13
21
  * @returns {Promise<number>}
14
22
  */
15
- export declare function runCli(argv: any): Promise<any>;
23
+ export declare function runCli(argv: any, opts?: {}): Promise<any>;
package/dist/cli.js CHANGED
@@ -1,12 +1,13 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * Node CLI command implementations (N2).
3
+ * Node CLI command implementations .
4
4
  */
5
5
  import { spawn } from 'node:child_process';
6
- import { existsSync } from 'node:fs';
6
+ import { copyFileSync, existsSync } from 'node:fs';
7
7
  import path from 'node:path';
8
- import { HOST_PROTOCOL, createWorkspace, getProtocolVersions } from './index.js';
8
+ import { HOST_PROTOCOL, createWorkspace, getProtocolVersions, resolveCoreRuntimeDist } from './index.js';
9
9
  import { createDevSession } from './dev-session.js';
10
+ import { gateGlobalProjectCommand, getInvocationContext, isGlobalAllowedCommand } from './invocation.js';
10
11
  import { log } from './log.js';
11
12
  import { readPackageMeta, resolveWorkspaceDirs } from './resolve.js';
12
13
  import { cmdTest } from './test-cmd.js';
@@ -16,6 +17,7 @@ import { cmdLocale } from './locale-cmd.js';
16
17
  import { cmdApplication } from './application-cmd.js';
17
18
  import { cmdRefactor } from './refactor-cmd.js';
18
19
  import { cmdExplain } from './explain-cmd.js';
20
+ import { resolveNativeVmzCli } from './resolve-native-cli.js';
19
21
  /**
20
22
  * @param {string[]} argv
21
23
  */
@@ -61,21 +63,48 @@ export function parseArgs(argv) {
61
63
  }
62
64
  return out;
63
65
  }
64
- export function printHelp() {
65
- console.log(`vmz — Node toolchain host (N-API workspace)
66
+ export function printGlobalHelp() {
67
+ console.log(`vmz — global mode (scaffold only)
68
+
69
+ developer monorepo source (packages/runtimes/vmz) — full CLI
70
+ project app node_modules/@vmz/vmz (or vmz) — full CLI
71
+ global npm/pnpm -g — only new/init/help/version
72
+
73
+ You are in global mode. Pin \`@vmz/vmz\` in the app so check/build/lsp
74
+ use a traceable project install.
66
75
 
67
76
  Usage:
77
+ vmz new|init <dir> Scaffold (native CLI; Node only gates + forwards)
78
+ vmz version Show host + native protocol versions
79
+ vmz help Show this help
80
+
81
+ Project commands:
82
+ pnpm add -D @vmz/vmz
83
+ pnpm exec vmz check
84
+ # or: vmz new my-app && cd my-app && pnpm install
85
+
86
+ If a project \`node_modules/@vmz/vmz\` (or \`vmz\`) exists, a global
87
+ \`vmz <cmd>\` re-execs that bin.
88
+ `);
89
+ }
90
+ export function printProjectHelp() {
91
+ console.log(`vmz — Node toolchain host (project / developer mode)
92
+
93
+ Usage:
94
+ vmz new|init <dir> Scaffold a minimal app (native CLI)
68
95
  vmz check [path] Check project via Workspace
69
96
  vmz build [path] [options] Build project via Workspace
70
97
  vmz serve [path] [options] Serve dist (optional --build)
71
98
  vmz dev [path] [options] Long-lived rebuild session (no CLI spawn)
72
99
  vmz format [path] [--check] Format .vmz via N-API (oxc codegen)
73
100
  vmz lint [path] [--deny-warnings] Lint (= check) via N-API
74
- vmz test [path] [options] Native test discover / report (T0+)
75
- vmz document|docs <cmd> Project /documents domain (D0: check)
76
- vmz application <cmd> Application Collection / Mount (M0–M5)
77
- vmz refactor <cmd> DX rename plans / apply (X1)
101
+ vmz test [path] [options] Native test discover / report
102
+ vmz document|docs <cmd> Project /documents domain
103
+ vmz application <cmd> Application Collection / Mount
104
+ vmz refactor <cmd> DX rename plans / apply
78
105
  vmz explain [style] <target> DX causal explain (style Theme chain)
106
+ vmz lsp [root] [--out-dir] Language server (stdio; native CLI)
107
+ vmz mcp [root] [--out-dir] MCP server (stdio; native CLI)
79
108
  vmz version Show host + native protocol versions
80
109
  vmz help Show this help
81
110
 
@@ -99,21 +128,51 @@ Options:
99
128
  --strict Strict document locale/PageKey coverage (document check)
100
129
  `);
101
130
  }
131
+ /** @deprecated use printProjectHelp / printGlobalHelp */
132
+ export function printHelp() {
133
+ printProjectHelp();
134
+ }
102
135
  /**
103
136
  * @param {string[]} argv
137
+ * @param {{
138
+ * cwd?: string,
139
+ * thisPackageRoot?: string,
140
+ * reexec?: (bin: string, argv: string[]) => Promise<number>,
141
+ * }} [opts]
104
142
  * @returns {Promise<number>}
105
143
  */
106
- export async function runCli(argv) {
144
+ export async function runCli(argv, opts = {}) {
107
145
  const [cmd, ...rest] = argv;
146
+ const inv = getInvocationContext({
147
+ cwd: opts.cwd,
148
+ thisPackageRoot: opts.thisPackageRoot,
149
+ });
108
150
  if (!cmd || cmd === 'help' || cmd === '-h' || cmd === '--help') {
109
- printHelp();
151
+ if (inv.mode === 'global')
152
+ printGlobalHelp();
153
+ else
154
+ printProjectHelp();
110
155
  return 0;
111
156
  }
112
157
  if (cmd === 'version' || cmd === '-V' || cmd === '--version') {
113
158
  return cmdVersion();
114
159
  }
160
+ if (!isGlobalAllowedCommand(cmd)) {
161
+ const gated = await gateGlobalProjectCommand({
162
+ argv,
163
+ cwd: opts.cwd,
164
+ thisPackageRoot: opts.thisPackageRoot,
165
+ reexec: opts.reexec,
166
+ logError: (msg) => log.error(msg),
167
+ });
168
+ if (gated.action === 'exit')
169
+ return gated.code;
170
+ }
115
171
  const args = parseArgs(rest);
116
172
  switch (cmd) {
173
+ case 'new':
174
+ case 'init':
175
+ return cmdNativeForward(cmd, rest);
117
176
  case 'check':
118
177
  return cmdCheck(args);
119
178
  case 'build':
@@ -142,12 +201,49 @@ export async function runCli(argv) {
142
201
  return cmdRefactor(rest);
143
202
  case 'explain':
144
203
  return cmdExplain(rest);
204
+ case 'lsp':
205
+ return cmdNativeForward('lsp', rest);
206
+ case 'mcp':
207
+ return cmdNativeForward('mcp', rest);
145
208
  default:
146
209
  log.error(`unknown command \`${cmd}\``);
147
- printHelp();
210
+ if (inv.mode === 'global')
211
+ printGlobalHelp();
212
+ else
213
+ printProjectHelp();
148
214
  return 1;
149
215
  }
150
216
  }
217
+ /**
218
+ * Forward to the single native `vmz` binary (vmz-tools).
219
+ * Scaffold / stdio servers live in Rust — Node only gates + re-execs.
220
+ *
221
+ * @param {'new' | 'init' | 'lsp' | 'mcp'} sub
222
+ * @param {string[]} argv
223
+ * @returns {Promise<number>}
224
+ */
225
+ function cmdNativeForward(sub, argv) {
226
+ const bin = resolveNativeVmzCli();
227
+ if (!bin) {
228
+ log.error('native `vmz` CLI not found (vmz-tools).');
229
+ log.error('Build: cargo build -p vmz-tools');
230
+ log.error('Or set VMZ_NATIVE to the absolute path of that binary.');
231
+ return Promise.resolve(1);
232
+ }
233
+ return new Promise((resolve) => {
234
+ const child = spawn(bin, [sub, ...argv], { stdio: 'inherit' });
235
+ child.on('error', (err) => {
236
+ log.error(`failed to spawn ${bin}: ${err.message}`);
237
+ resolve(1);
238
+ });
239
+ child.on('exit', (code, signal) => {
240
+ if (signal)
241
+ resolve(1);
242
+ else
243
+ resolve(code ?? 1);
244
+ });
245
+ });
246
+ }
151
247
  function cmdVersion() {
152
248
  const native = getProtocolVersions();
153
249
  console.log(`vmz host ${HOST_PROTOCOL}`);
@@ -182,7 +278,7 @@ function cmdCheck(args) {
182
278
  * @param {import('./index.js').Workspace} ws
183
279
  * @param {string} project
184
280
  * @param {string} outDir
185
- * @param {() => Promise<number> | number} fn
281
+ * @param { => Promise<number> | number} fn
186
282
  */
187
283
  async function runWithPlugins(ws, project, outDir, fn) {
188
284
  const { loadVmzConfig, applyPlugins } = await import('./plugin-host.js');
@@ -244,8 +340,16 @@ async function cmdServe(args) {
244
340
  });
245
341
  const hostJs = path.join(outDir, 'vmz-serve-host.mjs');
246
342
  if (!existsSync(hostJs)) {
247
- log.error(`missing ${hostJs} run \`vmz build\` first (or pass --build)`);
248
- return 1;
343
+ const coreDist = resolveCoreRuntimeDist();
344
+ const src = coreDist ? path.join(coreDist, 'serve-host.mjs') : null;
345
+ if (src && existsSync(src)) {
346
+ copyFileSync(src, hostJs);
347
+ log.info(`materialized ${hostJs} from @vmz/core (release builds omit it)`);
348
+ }
349
+ else {
350
+ log.error(`missing ${hostJs} — run \`vmz build\` (without --release) or ensure @vmz/core is installed`);
351
+ return 1;
352
+ }
249
353
  }
250
354
  const host = typeof args.host === 'string' ? args.host : '127.0.0.1';
251
355
  const port = Number(args.port ?? 5173);
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Long-lived Node dev session (N2/N4).
2
+ * Long-lived Node dev session (/session).
3
3
  *
4
4
  * Rebuilds go through the N-API `Workspace` — never spawn `cargo` / `vmz-tools`.
5
- * N4: only dirty leaves are marked; Workspace emits affected deployment units.
5
+ * session: only dirty leaves are marked; Workspace emits affected deployment units.
6
6
  */
7
7
  /**
8
8
  * @typedef {object} DevSessionOptions
@@ -1,9 +1,9 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * Long-lived Node dev session (N2/N4).
3
+ * Long-lived Node dev session (/session).
4
4
  *
5
5
  * Rebuilds go through the N-API `Workspace` — never spawn `cargo` / `vmz-tools`.
6
- * N4: only dirty leaves are marked; Workspace emits affected deployment units.
6
+ * session: only dirty leaves are marked; Workspace emits affected deployment units.
7
7
  */
8
8
  import { spawn } from 'node:child_process';
9
9
  import { existsSync } from 'node:fs';
@@ -65,7 +65,7 @@ export function createDevSession(options) {
65
65
  throw new Error(`vmz dev: missing src/ under ${project}`);
66
66
  }
67
67
  log.info('initial build (N-API workspace, full)…');
68
- // Empty dirty → full project build (N4).
68
+ // Empty dirty → full project build (session).
69
69
  const initial = rebuild();
70
70
  if (!printReport(initial, 'build')) {
71
71
  throw new Error('vmz dev: initial build failed');
@@ -1,7 +1,6 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * Document D1 Static + D3 Interactive artifacts.
4
- * Design: 规划设计/vmz/19 §5–6 · D1/D3
3
+ * Document Static + Interactive artifacts.
5
4
  */
6
5
  import fs from 'node:fs';
7
6
  import path from 'node:path';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Build DocumentManifest + run D0 / --strict checks.
2
+ * Build DocumentManifest + run / --strict checks.
3
3
  */
4
4
  /**
5
5
  * Resolve project documents root.
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * Build DocumentManifest + run D0 / --strict checks.
3
+ * Build DocumentManifest + run / --strict checks.
4
4
  */
5
5
  import fs from 'node:fs';
6
6
  import path from 'node:path';
@@ -44,7 +44,7 @@ export function loadDocumentsConfig(documentsRoot) {
44
44
  return { config: null, diagnostics, configPath: null };
45
45
  }
46
46
  /**
47
- * D0: only declaration objects — no arbitrary hooks.
47
+ *: only declaration objects — no arbitrary hooks.
48
48
  * @param {string} raw
49
49
  * @param {string} filename
50
50
  */
@@ -88,7 +88,7 @@ export function checkDocuments(opts) {
88
88
  diagnostics.push({
89
89
  code: DIAG.CONFIG_MISSING,
90
90
  severity: strict ? 'error' : 'warning',
91
- message: 'documents.config.json|ts missing; D0 requires defaultLocale + locales for strict coverage checks',
91
+ message: 'documents.config.json|ts missing; strict mode requires defaultLocale + locales for strict coverage checks',
92
92
  path: documentsRoot,
93
93
  });
94
94
  }
@@ -175,7 +175,7 @@ export function checkDocuments(opts) {
175
175
  });
176
176
  }
177
177
  }
178
- // D0: no silent whole-page fallback by default
178
+ // no silent whole-page fallback by default
179
179
  if (config && config.fallback === true) {
180
180
  diagnostics.push({
181
181
  code: DIAG.FALLBACK_SILENT,
@@ -1,6 +1,5 @@
1
1
  /**
2
- * `vmz document` / `vmz docs` CLI (D0 check · D1 build).
3
- * Design: 规划设计/vmz/19 §1 · §8
2
+ * `vmz document` / `vmz docs` CLI .
4
3
  */
5
4
  /**
6
5
  * @param {string[]} argv
@@ -1,7 +1,6 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * `vmz document` / `vmz docs` CLI (D0 check · D1 build).
4
- * Design: 规划设计/vmz/19 §1 · §8
3
+ * `vmz document` / `vmz docs` CLI .
5
4
  */
6
5
  import fs from 'node:fs';
7
6
  import path from 'node:path';
@@ -14,7 +13,7 @@ import { createWorkspace } from './index.js';
14
13
  import { log } from './log.js';
15
14
  import { parseArgs } from './cli.js';
16
15
  function printDocumentHelp() {
17
- console.log(`vmz document — project /documents domain (D0–D3)
16
+ console.log(`vmz document — project /documents domain
18
17
 
19
18
  Usage:
20
19
  vmz document check [project] Check locale tree + links/anchors + fence/API evidence
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * Document D1 — wire project `/designs` into static document assets.
3
+ * Document — wire project `/designs` into static document assets.
4
4
  * Prefer compiled `vmz-designs.css` / `vmz.css`; else emit a minimal token CSS.
5
5
  */
6
6
  import fs from 'node:fs';
@@ -1,7 +1,6 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * Document D1 — enrich manifest with routes, anchors, nav; diagnose links.
4
- * Design: 规划设计/vmz/19 §5–6
3
+ * Document — enrich manifest with routes, anchors, nav; diagnose links.
5
4
  */
6
5
  import fs from 'node:fs';
7
6
  import path from 'node:path';
@@ -115,7 +114,7 @@ export function enrichDocumentContent(manifest, ctx) {
115
114
  if (!href || href.startsWith('mailto:') || href.startsWith('http://') || href.startsWith('https://')) {
116
115
  continue;
117
116
  }
118
- // D2 API refs are resolved by evidence, not as page links.
117
+ // API refs are resolved by evidence, not as page links.
119
118
  if (href.startsWith('vmz-api:') || href.startsWith('api:')) {
120
119
  continue;
121
120
  }
@@ -30,10 +30,10 @@ export declare function resolveApiSymbol(index: any, query: any): {
30
30
  /**
31
31
  * @param {import('./document-schema.js').DocumentManifest} manifest
32
32
  * @param {{
33
- * analyzeMarkdown: Function,
34
- * projectRoot: string,
35
- * createWorkspace?: Function,
36
- * ensureProgramGraph?: boolean,
33
+ * analyzeMarkdown: Function,
34
+ * projectRoot: string,
35
+ * createWorkspace?: Function,
36
+ * ensureProgramGraph?: boolean,
37
37
  * }} ctx
38
38
  */
39
39
  export declare function enrichDocumentEvidence(manifest: any, ctx: any): Promise<{
@@ -1,7 +1,6 @@
1
1
  // @ts-nocheck
2
2
  /**
3
- * Document D2 Evidence — fence check + API refs from Program Graph.
4
- * Design: 规划设计/vmz/19 §4 · §8 D2
3
+ * Document Evidence — fence check + API refs from Program Graph.
5
4
  *
6
5
  * Not a Doc IR: filesystem/manifest projection + Workspace/Program Graph queries.
7
6
  */
@@ -117,10 +116,10 @@ export function resolveApiSymbol(index, query) {
117
116
  /**
118
117
  * @param {import('./document-schema.js').DocumentManifest} manifest
119
118
  * @param {{
120
- * analyzeMarkdown: Function,
121
- * projectRoot: string,
122
- * createWorkspace?: Function,
123
- * ensureProgramGraph?: boolean,
119
+ * analyzeMarkdown: Function,
120
+ * projectRoot: string,
121
+ * createWorkspace?: Function,
122
+ * ensureProgramGraph?: boolean,
124
123
  * }} ctx
125
124
  */
126
125
  export async function enrichDocumentEvidence(manifest, ctx) {
@@ -424,22 +423,31 @@ function checkScriptFence({ fence, meta, sourcePath, page }) {
424
423
  diagnostics.push({
425
424
  code: DIAG.FENCE_CHECK,
426
425
  severity: 'error',
427
- message: `${meta.lang} fence parse produced empty SourceFile`,
426
+ message: `${meta.lang} fence parse produced no SourceFile`,
428
427
  path: `${sourcePath}:${fence.lineStart}`,
429
428
  });
430
- return { record: { status: 'failed' }, diagnostics };
429
+ return { record: { status: 'failed', detail: 'parse' }, diagnostics };
431
430
  }
432
- return { record: { status: 'ok', detail: 'syntax' }, diagnostics };
431
+ return { record: { status: 'ok' }, diagnostics };
433
432
  }
434
433
  catch (e) {
434
+ const msg = e instanceof Error ? e.message : String(e);
435
+ if (/Cannot find module ['\"]typescript['\"]/i.test(msg) || e?.code === 'MODULE_NOT_FOUND') {
436
+ diagnostics.push({
437
+ code: DIAG.FENCE_CHECK,
438
+ severity: 'error',
439
+ message: 'TS/JS fence check needs `typescript` (optional peer of `@vmz/vmz`). Install: pnpm add -D typescript',
440
+ path: `${sourcePath}:${fence.lineStart}`,
441
+ });
442
+ return { record: { status: 'failed', detail: 'missing-typescript' }, diagnostics };
443
+ }
435
444
  diagnostics.push({
436
445
  code: DIAG.FENCE_CHECK,
437
446
  severity: 'error',
438
- message: `${meta.lang} fence check unavailable: ${e.message || e}`,
447
+ message: `${meta.lang} fence check failed: ${msg}`,
439
448
  path: `${sourcePath}:${fence.lineStart}`,
440
- pageKey: page?.identity?.pageKey,
441
449
  });
442
- return { record: { status: 'failed', detail: 'engine' }, diagnostics };
450
+ return { record: { status: 'failed', detail: 'exception' }, diagnostics };
443
451
  }
444
452
  }
445
453
  function walkFiles(dir, fn) {
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Integrated DocumentMount — build /documents into the host app dist so
3
3
  * routeBase (e.g. /d) is served as static HTML next to SSR pages.
4
- * Design: 规划设计/vmz/19 · Integrated DocumentMount (same project, no separate package).
5
4
  */
6
5
  /**
7
6
  * @param {string} projectRoot
@@ -2,7 +2,6 @@
2
2
  /**
3
3
  * Integrated DocumentMount — build /documents into the host app dist so
4
4
  * routeBase (e.g. /d) is served as static HTML next to SSR pages.
5
- * Design: 规划设计/vmz/19 · Integrated DocumentMount (same project, no separate package).
6
5
  */
7
6
  import fs from 'node:fs';
8
7
  import path from 'node:path';
@@ -5,10 +5,10 @@
5
5
  export declare function htmlToSearchText(html: any): string;
6
6
  /**
7
7
  * @param {{
8
- * manifest: any,
9
- * enriched: { byId: Map<string, any> },
10
- * evidence: any,
11
- * version?: string | null,
8
+ * manifest: any,
9
+ * enriched: { byId: Map<string, any> },
10
+ * evidence: any,
11
+ * version?: string | null,
12
12
  * }} opts
13
13
  */
14
14
  export declare function buildDocumentSearch(opts: any): {
@@ -20,9 +20,9 @@ export declare function buildDocumentSearch(opts: any): {
20
20
  /**
21
21
  * Island-only resume plan for document surfaces.
22
22
  * @param {{
23
- * evidence: any,
24
- * searchHref?: string,
25
- * fenceBodies?: Map<string, string>,
23
+ * evidence: any,
24
+ * searchHref?: string,
25
+ * fenceBodies?: Map<string, string>,
26
26
  * }} opts
27
27
  */
28
28
  export declare function buildDocumentIslands(opts: any): {
@@ -57,10 +57,10 @@ export declare function collectFenceBodies(analyzedByPageId: any, pages: any): M
57
57
  /**
58
58
  * Render SSR island shells (no script — resume later).
59
59
  * @param {{
60
- * islands: any,
61
- * searchIndexHref: string,
62
- * pageKey: string,
63
- * locale: string,
60
+ * islands: any,
61
+ * searchIndexHref: string,
62
+ * pageKey: string,
63
+ * locale: string,
64
64
  * }} opts
65
65
  */
66
66
  export declare function renderIslandShellsHtml(opts: any): {