@vistagenic/vista 0.3.5 → 0.3.8

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 (74) hide show
  1. package/bin/flashpack-agent-playground.mjs +134 -0
  2. package/bin/flashpack-boot.mjs +504 -0
  3. package/bin/flashpack-ssr-loader.mjs +42 -0
  4. package/bin/flashpack-ssr.mjs +81 -0
  5. package/bin/flashpack-vendor.mjs +97 -0
  6. package/bin/vista.js +56 -42
  7. package/dist/ai/providers/base.js +7 -1
  8. package/dist/bin/build-rsc.js +16 -0
  9. package/dist/bin/build.js +17 -11
  10. package/dist/bin/deploy.js +7 -0
  11. package/dist/bin/dev-client-runtime.d.ts +6 -0
  12. package/dist/bin/dev-client-runtime.js +99 -0
  13. package/dist/bin/dev-error-overlay-snippet.js +79 -21
  14. package/dist/bin/dev-error-overlay-snippet.ts +840 -0
  15. package/dist/bin/devtools-indicator-snippet.js +29 -13
  16. package/dist/bin/file-scanner.js +7 -24
  17. package/dist/bin/generate.js +94 -2
  18. package/dist/bin/webpack.config.js +3 -1
  19. package/dist/build/rsc/compiler.d.ts +14 -0
  20. package/dist/build/rsc/compiler.js +66 -6
  21. package/dist/build/rsc/server-manifest.js +5 -4
  22. package/dist/config.d.ts +5 -0
  23. package/dist/config.js +15 -1
  24. package/dist/deploy/adapters/render.js +2 -2
  25. package/dist/deploy/index.d.ts +1 -0
  26. package/dist/deploy/index.js +3 -0
  27. package/dist/deploy/runtime-pack.js +22 -1
  28. package/dist/deploy/utils.js +16 -6
  29. package/dist/flashpack/command.d.ts +1 -0
  30. package/dist/flashpack/command.js +42 -76
  31. package/dist/flashpack/runtime.d.ts +12 -0
  32. package/dist/flashpack/runtime.js +124 -22
  33. package/dist/metadata/generate.d.ts +1 -0
  34. package/dist/metadata/generate.js +117 -21
  35. package/dist/metadata/index.d.ts +5 -0
  36. package/dist/metadata/index.js +15 -1
  37. package/dist/metadata/json-ld.d.ts +15 -0
  38. package/dist/metadata/json-ld.js +19 -0
  39. package/dist/metadata/merge.d.ts +17 -0
  40. package/dist/metadata/merge.js +161 -0
  41. package/dist/metadata/routes.d.ts +66 -0
  42. package/dist/metadata/routes.js +143 -0
  43. package/dist/metadata/types.d.ts +1 -1
  44. package/dist/metadata/types.js +3 -1
  45. package/dist/og/image-response.d.ts +38 -0
  46. package/dist/og/image-response.js +88 -0
  47. package/dist/og/index.d.ts +2 -0
  48. package/dist/og/index.js +5 -0
  49. package/dist/rust/index.d.ts +13 -0
  50. package/dist/rust/index.js +132 -0
  51. package/dist/server/engine.js +13 -3
  52. package/dist/server/logger.js +2 -1
  53. package/dist/server/project-alias-resolver.d.ts +7 -0
  54. package/dist/server/project-alias-resolver.js +70 -0
  55. package/dist/server/rsc-engine.js +93 -16
  56. package/dist/server/static-generator.js +4 -3
  57. package/dist/server/typed-api-runtime.js +92 -0
  58. package/dist/theme/index.d.ts +1 -0
  59. package/dist/theme/index.js +3 -1
  60. package/dist/theme/react-server.d.ts +4 -2
  61. package/dist/theme/react-server.js +5 -3
  62. package/dist/theme/theme-toggle.d.ts +5 -0
  63. package/dist/theme/theme-toggle.js +39 -0
  64. package/docs/ai.md +69 -0
  65. package/docs/app.md +30 -0
  66. package/docs/cli.md +29 -0
  67. package/docs/index.md +18 -0
  68. package/docs/rag.md +54 -0
  69. package/native/win32-x64/flashpack-cli.exe +0 -0
  70. package/package.json +196 -178
  71. package/skills/README.md +9 -0
  72. package/skills/vista-agent/SKILL.md +28 -0
  73. package/skills/vista-dev-loop/SKILL.md +25 -0
  74. package/skills/vista-rag/SKILL.md +26 -0
@@ -0,0 +1,81 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createRequire, register } from 'node:module';
4
+ import { pathToFileURL } from 'node:url';
5
+
6
+ function readArg(name) {
7
+ const index = process.argv.indexOf(name);
8
+ if (index === -1 || index + 1 >= process.argv.length) return '';
9
+ return process.argv[index + 1];
10
+ }
11
+
12
+ const cwd = path.resolve(readArg('--cwd') || process.cwd());
13
+ const requestPath = readArg('--path') || '/';
14
+ const modulesDir = path.join(cwd, '.flash', 'dev', 'modules');
15
+ const shimsDir = path.join(cwd, '.flash', 'dev', 'ssr');
16
+
17
+ const registered = register(new URL('./flashpack-ssr-loader.mjs', import.meta.url), {
18
+ parentURL: import.meta.url,
19
+ data: { modulesDir, shimsDir },
20
+ });
21
+ if (registered && typeof registered.then === 'function') {
22
+ await registered;
23
+ }
24
+
25
+ function moduleFile(relativePath) {
26
+ const file = path.join(modulesDir, ...relativePath.split('/'));
27
+ return fs.existsSync(file) ? file : null;
28
+ }
29
+
30
+ const appRequire = createRequire(path.join(cwd, 'package.json'));
31
+ const { createElement } = appRequire('react');
32
+ const { renderToReadableStream } = appRequire('react-dom/server');
33
+
34
+ const rootFile = moduleFile('app/root.tsx.js') || moduleFile('app/root.jsx.js');
35
+ if (!rootFile) {
36
+ throw new Error('flashpack ssr: app/root was not compiled');
37
+ }
38
+
39
+ const pathname = requestPath.replace(/\/$/, '') || '/';
40
+ let pageFile = null;
41
+ let pageProps = {};
42
+ let layoutFile = null;
43
+
44
+ if (pathname === '/docs' || pathname.startsWith('/docs/')) {
45
+ layoutFile = moduleFile('app/docs/layout.tsx.js');
46
+ if (pathname === '/docs') {
47
+ pageFile = moduleFile('app/docs/page.tsx.js');
48
+ } else {
49
+ pageFile = moduleFile('app/docs/[...slug]/page.tsx.js');
50
+ pageProps = { params: { slug: pathname.split('/').filter(Boolean).slice(1) } };
51
+ }
52
+ }
53
+
54
+ if (!pageFile) {
55
+ pageFile =
56
+ moduleFile('app/index.tsx.js') ||
57
+ moduleFile('app/index.jsx.js') ||
58
+ moduleFile('app/page.tsx.js') ||
59
+ moduleFile('app/page.jsx.js');
60
+ }
61
+
62
+ if (!pageFile) {
63
+ throw new Error(`flashpack ssr: no page module for ${pathname}`);
64
+ }
65
+
66
+ const rootMod = await import(pathToFileURL(rootFile).href);
67
+ const pageMod = await import(pathToFileURL(pageFile).href);
68
+ const Root = rootMod.default;
69
+ const Page = pageMod.default;
70
+ let page = createElement(Page, pageProps);
71
+ if (page && typeof page.then === 'function') {
72
+ page = await page;
73
+ }
74
+ if (layoutFile) {
75
+ const layoutMod = await import(pathToFileURL(layoutFile).href);
76
+ page = createElement(layoutMod.default, { children: page });
77
+ }
78
+
79
+ const stream = await renderToReadableStream(createElement(Root, { children: page }));
80
+ await stream.allReady;
81
+ process.stdout.write(await new Response(stream).text());
@@ -0,0 +1,97 @@
1
+ import { createRequire } from 'node:module';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+
5
+ const cwd = path.resolve(process.argv[2] || '');
6
+ const spec = process.argv[3] || '';
7
+ const outfile = path.resolve(process.argv[4] || '');
8
+
9
+ function loadEsbuild() {
10
+ const bases = [cwd, path.resolve(cwd, '../..'), path.resolve(cwd, '../../..')];
11
+ for (const base of bases) {
12
+ try {
13
+ return createRequire(path.join(base, 'package.json'))('esbuild');
14
+ } catch {
15
+ // try the next root
16
+ }
17
+ }
18
+ const pnpm = path.resolve(cwd, '../../node_modules/.pnpm');
19
+ if (!fs.existsSync(pnpm)) {
20
+ throw new Error('esbuild is not installed');
21
+ }
22
+ const versions = fs.readdirSync(pnpm).filter((name) => name.startsWith('esbuild@')).sort();
23
+ const version = versions.at(-1);
24
+ if (!version) throw new Error('esbuild is not installed');
25
+ return createRequire(path.join(pnpm, version, 'node_modules', 'esbuild', 'package.json'))('esbuild');
26
+ }
27
+
28
+ function namedExports(specifier) {
29
+ try {
30
+ const loaded = createRequire(path.join(cwd, 'package.json'))(specifier);
31
+ const source = loaded && (typeof loaded === 'object' || typeof loaded === 'function') ? loaded : {};
32
+ return Object.keys(source).filter(
33
+ (name) => name !== 'default' && name !== '__esModule' && /^[A-Za-z_$][\w$]*$/.test(name)
34
+ );
35
+ } catch {
36
+ return [];
37
+ }
38
+ }
39
+
40
+ const reactGlobals = {
41
+ react: '__VISTA_REACT__',
42
+ 'react-dom': '__VISTA_REACT_DOM__',
43
+ 'react-dom/client': '__VISTA_REACT_DOM_CLIENT__',
44
+ 'react/jsx-runtime': '__VISTA_JSX__',
45
+ 'react/jsx-dev-runtime': '__VISTA_JSX_DEV__',
46
+ };
47
+
48
+ function writeReactShim(specifier, file) {
49
+ const globalName = reactGlobals[specifier];
50
+ const lines = namedExports(specifier).map(
51
+ (name) => `export const ${name} = ns[${JSON.stringify(name)}];`
52
+ );
53
+ fs.writeFileSync(
54
+ file,
55
+ `const ns = window[${JSON.stringify(globalName)}];\n${lines.join('\n')}\nexport default ns;\n`
56
+ );
57
+ }
58
+
59
+ const esbuild = loadEsbuild();
60
+ if (reactGlobals[spec]) {
61
+ fs.mkdirSync(path.dirname(outfile), { recursive: true });
62
+ writeReactShim(spec, outfile);
63
+ process.exit(0);
64
+ }
65
+ const exportLines = namedExports(spec).map(
66
+ (name) => `export const ${name} = namespace[${JSON.stringify(name)}];`
67
+ );
68
+ fs.mkdirSync(path.dirname(outfile), { recursive: true });
69
+ await esbuild.build({
70
+ absWorkingDir: cwd,
71
+ stdin: {
72
+ contents: `import * as namespace from ${JSON.stringify(spec)};\n${exportLines.join('\n')}\nexport default namespace.default ?? namespace;\n`,
73
+ resolveDir: cwd,
74
+ sourcefile: 'flashpack-vendor.js',
75
+ },
76
+ bundle: true,
77
+ format: 'esm',
78
+ platform: 'browser',
79
+ target: ['es2022'],
80
+ outfile,
81
+ logLevel: 'silent',
82
+ define: {
83
+ 'process.env.NODE_ENV': '"development"',
84
+ },
85
+ mainFields: ['browser', 'module', 'main'],
86
+ plugins: [
87
+ {
88
+ name: 'vista-shared-react',
89
+ setup(build) {
90
+ build.onResolve({ filter: /^react($|\/)|^react-dom($|\/)/ }, (args) => {
91
+ if (!Object.prototype.hasOwnProperty.call(reactGlobals, args.path)) return null;
92
+ return { path: `/_flashpack/mod/${args.path}`, external: true };
93
+ });
94
+ },
95
+ },
96
+ ],
97
+ });
package/bin/vista.js CHANGED
@@ -86,11 +86,23 @@ if (
86
86
  process.exit(1);
87
87
  }
88
88
 
89
+ function readPackageEngine(cwd) {
90
+ try {
91
+ const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));
92
+ const vista = pkg && pkg.vista;
93
+ const raw = typeof vista === 'string' ? vista : vista && vista.engine;
94
+ return normalizeEngineVariant(raw);
95
+ } catch {
96
+ return null;
97
+ }
98
+ }
99
+
89
100
  const envEngineVariant = normalizeEngineVariant(
90
101
  process.env.VISTA_ENGINE_VARIANT ||
91
102
  process.env.VISTA_ENGINE ||
92
103
  (process.env.VISTA_FLASHPACK === 'true' ? 'flashpack' : '')
93
104
  );
105
+ const packageEngineVariant = readPackageEngine(process.cwd());
94
106
 
95
107
  let configEngineVariant = null;
96
108
  try {
@@ -108,7 +120,7 @@ try {
108
120
  }
109
121
 
110
122
  const forcedByFlag = explicitEngineVariant || (explicitFlashpack ? 'flashpack' : null) || (explicitDefaultEngine ? 'default' : null);
111
- const engineVariant = forcedByFlag || envEngineVariant || configEngineVariant || 'default';
123
+ const engineVariant = forcedByFlag || envEngineVariant || packageEngineVariant || configEngineVariant || 'default';
112
124
  process.env.VISTA_ENGINE = engineVariant;
113
125
  process.env.VISTA_ENGINE_VARIANT = engineVariant;
114
126
  process.env.VISTA_FLASHPACK = engineVariant === 'flashpack' ? 'true' : 'false';
@@ -117,21 +129,7 @@ process.env.VISTA_FLASHPACK = engineVariant === 'flashpack' ? 'true' : 'false';
117
129
  const { markStartTime } = require('../dist/server/logger');
118
130
  markStartTime();
119
131
 
120
- if (command === 'dev') {
121
- forceRuntimeEnv('development');
122
- console.log(`[vista] Engine: ${process.env.VISTA_ENGINE}`);
123
- const useFlashpack = process.env.VISTA_ENGINE === 'flashpack';
124
- if (useFlashpack) {
125
- const { runFlashpackEngineCommand } = require('../dist/flashpack/command');
126
- runFlashpackEngineCommand('dev', {
127
- cwd: process.cwd(),
128
- port: process.env.PORT || 3003,
129
- }).catch((err) => {
130
- console.error('Flashpack dev failed:', err);
131
- process.exit(1);
132
- });
133
- return;
134
- }
132
+ function startFlightDev() {
135
133
  const { buildRSC } = require('../dist/bin/build-rsc');
136
134
  const { startRSCServer } = require('../dist/server/rsc-engine');
137
135
 
@@ -146,25 +144,26 @@ if (command === 'dev') {
146
144
  console.error('RSC Build failed:', err);
147
145
  process.exit(1);
148
146
  });
149
- } else if (command === 'build') {
150
- forceRuntimeEnv('production');
151
- console.log(`[vista] Engine: ${process.env.VISTA_ENGINE}`);
152
- const useFlashpack = process.env.VISTA_ENGINE === 'flashpack';
153
- if (useFlashpack) {
147
+ }
148
+
149
+ if (command === 'dev') {
150
+ forceRuntimeEnv('development');
151
+ if (process.env.VISTA_ENGINE === 'flashpack') {
154
152
  const { runFlashpackEngineCommand } = require('../dist/flashpack/command');
155
- runFlashpackEngineCommand('build', {
153
+ runFlashpackEngineCommand('dev', {
156
154
  cwd: process.cwd(),
157
- })
158
- .then(() => {
159
- console.log('');
160
- console.log('Production build complete!');
161
- })
162
- .catch((err) => {
163
- console.error('Flashpack build failed:', err);
164
- process.exit(1);
165
- });
155
+ action: 'run',
156
+ port: process.env.PORT || 3003,
157
+ }).catch((err) => {
158
+ console.error('Flashpack dev failed:', err);
159
+ process.exit(1);
160
+ });
166
161
  return;
167
162
  }
163
+ startFlightDev();
164
+ } else if (command === 'build') {
165
+ forceRuntimeEnv('production');
166
+ console.log(`[vista] Engine: ${process.env.VISTA_ENGINE}`);
168
167
  const { buildRSC } = require('../dist/bin/build-rsc');
169
168
 
170
169
  buildRSC(false)
@@ -176,20 +175,32 @@ if (command === 'dev') {
176
175
  console.error('RSC Build failed:', err);
177
176
  process.exit(1);
178
177
  });
179
- } else if (command === 'start') {
180
- forceRuntimeEnv('production');
181
- console.log(`[vista] Engine: ${process.env.VISTA_ENGINE}`);
182
- if (process.env.VISTA_ENGINE === 'flashpack') {
183
- const { runFlashpackEngineCommand } = require('../dist/flashpack/command');
184
- runFlashpackEngineCommand('start', {
178
+ } else if (command === 'bind') {
179
+ const rust = require('../dist/rust');
180
+ const route = getFlagValue('--route') || '(shop)/products/[id]';
181
+ const folders = route.split('/').filter((part) => part.length > 0);
182
+ console.log(`[vista] rust native=${rust.nativeBindingsLoaded()}`);
183
+ for (const folder of folders) {
184
+ const classified = rust.classifyAppSegment(folder);
185
+ console.log(`[vista] ${folder} -> ${classified.kind} (${classified.segment})`);
186
+ }
187
+ console.log(`[vista] pattern ${rust.routePattern(folders)}`);
188
+ console.log(`[vista] error ${rust.encodeVistaErrorCode('ROUTE_MISSING')}`);
189
+ console.log(`[vista] taskless ${rust.tasklessSteps(true).join(' -> ')}`);
190
+ if (engineVariant === 'flashpack') {
191
+ const { prepareFlashpackRuntime } = require('../dist/flashpack/runtime');
192
+ const prepared = prepareFlashpackRuntime({
185
193
  cwd: process.cwd(),
186
- port: process.env.PORT || 3003,
187
- }).catch((err) => {
188
- console.error('Flashpack start failed:', err);
189
- process.exit(1);
194
+ phase: 'build',
195
+ mode: 'production',
196
+ allowFallback: true,
190
197
  });
191
- return;
198
+ console.log(`[vista] flashpack crates bound=${prepared.rustPipelineUsed}`);
199
+ if (!prepared.rustPipelineUsed) process.exit(1);
192
200
  }
201
+ } else if (command === 'start') {
202
+ forceRuntimeEnv('production');
203
+ console.log(`[vista] Engine: ${process.env.VISTA_ENGINE}`);
193
204
  const standaloneServerPath = path.join(process.cwd(), '.vista', 'standalone', 'server.js');
194
205
  if (fs.existsSync(standaloneServerPath)) {
195
206
  const standalone = require(standaloneServerPath);
@@ -216,6 +227,7 @@ if (command === 'dev') {
216
227
  console.log(' start Start production server');
217
228
  console.log(' deploy Build and deploy to a hosting platform');
218
229
  console.log(' g Generate typed API scaffolds (api-init, router, procedure)');
230
+ console.log(' bind Classify a route and, with --flashpack, bind the Rust crates');
219
231
  console.log('');
220
232
  console.log('Options:');
221
233
  console.log(' --engine <default|flashpack> Select engine variant');
@@ -230,5 +242,7 @@ if (command === 'dev') {
230
242
  console.log(' vista dev --flashpack # Start dev server with Flashpack mode');
231
243
  console.log(' vista build # Production Flight RSC/SSR build');
232
244
  console.log(' vista g api-init # Generate typed API starter files');
245
+ console.log(' vista bind --route "(shop)/products/[id]"');
246
+ console.log(' vista bind --flashpack');
233
247
  console.log('');
234
248
  }
@@ -75,11 +75,17 @@ function resolveModel(model, options = {}) {
75
75
  baseURL: options.baseURL || process.env.GROQ_BASE_URL || 'https://api.groq.com/openai/v1',
76
76
  apiKey: options.apiKey || process.env.GROQ_API_KEY || '',
77
77
  });
78
+ case 'openrouter':
79
+ return (0, openai_1.createOpenAIModel)({
80
+ ...modelOptions,
81
+ baseURL: options.baseURL || process.env.OPENROUTER_BASE_URL || 'https://openrouter.ai/api/v1',
82
+ apiKey: options.apiKey || process.env.OPENROUTER_API_KEY || '',
83
+ });
78
84
  case 'mock':
79
85
  return (0, mock_1.createMockModel)({
80
86
  modelName,
81
87
  });
82
88
  default:
83
- throw new Error(`Unsupported model provider "${provider}". Supported providers: openai, anthropic, gemini, ollama, nvidia, groq, mock.`);
89
+ throw new Error(`Unsupported model provider "${provider}". Supported providers: openai, anthropic, gemini, ollama, nvidia, groq, openrouter, mock.`);
84
90
  }
85
91
  }
@@ -23,6 +23,7 @@ const server_manifest_1 = require("../build/rsc/server-manifest");
23
23
  const file_scanner_1 = require("./file-scanner");
24
24
  const config_1 = require("../config");
25
25
  const constants_1 = require("../constants");
26
+ const runtime_1 = require("../flashpack/runtime");
26
27
  const structure_validator_1 = require("../server/structure-validator");
27
28
  const static_generator_1 = require("../server/static-generator");
28
29
  const structure_log_1 = require("../server/structure-log");
@@ -383,6 +384,21 @@ async function buildRSC(watch = false) {
383
384
  }
384
385
  if (_debug)
385
386
  console.log(`[vista:build] Engine variant: ${engineVariant}`);
387
+ if (engineVariant === 'flashpack') {
388
+ const prepared = (0, runtime_1.prepareFlashpackRuntime)({
389
+ cwd,
390
+ phase: watch ? 'dev' : 'build',
391
+ mode: watch ? 'development' : 'production',
392
+ allowFallback: process.env.VISTA_FLASHPACK_STRICT !== 'true',
393
+ });
394
+ if (!prepared.rustPipelineUsed) {
395
+ const message = '[vista] Flashpack crates were not bound. Run `vista bind --flashpack` after the Rust CLI is available.';
396
+ if (process.env.VISTA_FLASHPACK_STRICT === 'true') {
397
+ throw new Error(message);
398
+ }
399
+ console.warn(message);
400
+ }
401
+ }
386
402
  if (structureConfig.enabled) {
387
403
  const result = (0, structure_validator_1.validateAppStructure)({ cwd });
388
404
  (0, structure_log_1.logValidationResult)(result, structureConfig.logLevel);
package/dist/bin/build.js CHANGED
@@ -44,19 +44,25 @@ function runPostCSS(cwd, vistaDir) {
44
44
  }
45
45
  }
46
46
  }
47
+ function urlSegmentForNode(node) {
48
+ if (!node.segment)
49
+ return null;
50
+ if (node.kind === 'group' || node.kind === 'parallel' || node.kind === 'interception') {
51
+ return null;
52
+ }
53
+ if (node.kind === 'dynamic')
54
+ return `:${node.segment}`;
55
+ if (node.kind === 'catch-all')
56
+ return `:${node.segment}*`;
57
+ if (node.kind === 'optional-catch-all')
58
+ return `:${node.segment}*?`;
59
+ return node.segment;
60
+ }
47
61
  function collectRouteArtifactEntries(node, segments = [], entries = []) {
48
62
  const nextSegments = [...segments];
49
- if (node.segment) {
50
- if (node.kind === 'dynamic') {
51
- nextSegments.push(`:${node.segment}`);
52
- }
53
- else if (node.kind === 'catch-all') {
54
- nextSegments.push(`:${node.segment}*`);
55
- }
56
- else if (node.kind !== 'group') {
57
- nextSegments.push(node.segment);
58
- }
59
- }
63
+ const urlPiece = urlSegmentForNode(node);
64
+ if (urlPiece)
65
+ nextSegments.push(urlPiece);
60
66
  if (node.indexPath) {
61
67
  const pattern = nextSegments.length === 0 ? '/' : `/${nextSegments.join('/')}`;
62
68
  const type = pattern.includes('*')
@@ -26,6 +26,7 @@ function printHelp() {
26
26
  console.log('');
27
27
  console.log('Options:');
28
28
  console.log(' --target <auto|render|vercel|cloudflare|netlify|docker>');
29
+ console.log(' --output <standalone|static|hybrid>');
29
30
  console.log(' --prod Production deploy (default)');
30
31
  console.log(' --preview Preview/staging deploy');
31
32
  console.log(' --dry-run Build + emit + validate only');
@@ -64,6 +65,11 @@ async function runDeployCommand(flags, options = {}) {
64
65
  (options.error ?? console.error)(`[vista:deploy] Unsupported target "${target}". Use one of: ${(0, deploy_1.listKnownTargets)().join(', ')}`);
65
66
  return 1;
66
67
  }
68
+ const output = getFlagValue(flags, '--output');
69
+ if (output && !['standalone', 'static', 'hybrid'].includes(output)) {
70
+ (options.error ?? console.error)(`[vista:deploy] Unsupported output "${output}". Use one of: standalone, static, hybrid`);
71
+ return 1;
72
+ }
67
73
  const cwd = options.cwd ?? process.cwd();
68
74
  const dryRun = flags.includes('--dry-run');
69
75
  const skipBuild = flags.includes('--skip-build');
@@ -78,6 +84,7 @@ async function runDeployCommand(flags, options = {}) {
78
84
  const result = await (0, deploy_1.runDeploy)({
79
85
  cwd,
80
86
  target,
87
+ output: output,
81
88
  dryRun,
82
89
  skipBuild,
83
90
  prod,
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The same development client the default engine injects:
3
+ * devtools indicator, error overlay, and runtime error reporting.
4
+ * Flashpack serves this file instead of keeping a second error UI.
5
+ */
6
+ export declare function getSharedDevClientSource(bootSessionId: string): string;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSharedDevClientSource = getSharedDevClientSource;
4
+ const dev_error_overlay_snippet_1 = require("./dev-error-overlay-snippet");
5
+ const devtools_indicator_snippet_1 = require("./devtools-indicator-snippet");
6
+ /**
7
+ * The same development client the default engine injects:
8
+ * devtools indicator, error overlay, and runtime error reporting.
9
+ * Flashpack serves this file instead of keeping a second error UI.
10
+ */
11
+ function getSharedDevClientSource(bootSessionId) {
12
+ return `${(0, devtools_indicator_snippet_1.getDevToolsIndicatorBootstrapSource)(bootSessionId)}
13
+ ${(0, dev_error_overlay_snippet_1.getDevErrorOverlayBootstrapSource)()}
14
+ ${sharedRuntimeReporterSource()}
15
+ `;
16
+ }
17
+ function sharedRuntimeReporterSource() {
18
+ return `
19
+ function buildRuntimeMessage(title, error) {
20
+ var value = error;
21
+ var text = '';
22
+ if (value && typeof value === 'object') {
23
+ if (typeof value.message === 'string' && value.message.trim().length > 0) {
24
+ text = value.message;
25
+ }
26
+ if (typeof value.stack === 'string' && value.stack.trim().length > 0) {
27
+ text = text ? text + '\\n\\n' + value.stack : value.stack;
28
+ }
29
+ if (!text && typeof value.toString === 'function') {
30
+ var asString = String(value);
31
+ if (asString && asString !== '[object Object]') text = asString;
32
+ }
33
+ } else if (typeof error === 'string') {
34
+ text = error;
35
+ } else if (error != null) {
36
+ text = String(error);
37
+ }
38
+ if (!text || text === 'undefined' || text === 'null') {
39
+ text = 'Unknown runtime error (no message or stack from the browser).';
40
+ }
41
+ if (text.indexOf(title) === 0) return text;
42
+ return title + '\\n\\n' + text;
43
+ }
44
+
45
+ function revealBootHold() {
46
+ try {
47
+ document.documentElement.setAttribute('data-vista-ready', '');
48
+ } catch (err) {}
49
+ }
50
+
51
+ function reportDevRuntimeError(title, error) {
52
+ if (typeof window === 'undefined') return;
53
+ revealBootHold();
54
+ var indicator = window.__VISTA_DEVTOOLS_INDICATOR__;
55
+ var overlay = window.__VISTA_DEV_ERROR_OVERLAY__;
56
+ var message = buildRuntimeMessage(title, error);
57
+ if (indicator && typeof indicator.setError === 'function') {
58
+ try {
59
+ if (typeof indicator.ensureAttached === 'function') indicator.ensureAttached();
60
+ } catch (err) {}
61
+ indicator.setError(title, 1);
62
+ }
63
+ // Always open the overlay for hard runtime failures — capture/minimize alone
64
+ // leaves a white page when boot never finished painting.
65
+ if (overlay && typeof overlay.show === 'function') {
66
+ overlay.show([message]);
67
+ } else if (overlay && typeof overlay.capture === 'function') {
68
+ overlay.capture([message]);
69
+ }
70
+ if (typeof fetch === 'function') {
71
+ fetch('/_flashpack/client-error', {
72
+ method: 'POST',
73
+ headers: { 'content-type': 'application/json' },
74
+ body: JSON.stringify({ title: title, message: message }),
75
+ }).catch(function () {});
76
+ }
77
+ }
78
+
79
+ if (typeof window !== 'undefined') {
80
+ window.addEventListener('error', function (event) {
81
+ reportDevRuntimeError('Runtime Error', event.error || event.message || 'Script error');
82
+ });
83
+ window.addEventListener('unhandledrejection', function (event) {
84
+ reportDevRuntimeError('Unhandled Promise Rejection', event.reason);
85
+ });
86
+ var nativeConsoleError = console.error.bind(console);
87
+ console.error = function () {
88
+ nativeConsoleError.apply(console, arguments);
89
+ var text = Array.prototype.map.call(arguments, function (item) {
90
+ return item && item.stack ? item.stack : String(item);
91
+ }).join('\\n');
92
+ if (/data-cursor-ref/.test(text)) return;
93
+ if (/Hydration|Uncaught|TypeError|ReferenceError/.test(text)) {
94
+ reportDevRuntimeError('Runtime Error', text);
95
+ }
96
+ };
97
+ }
98
+ `;
99
+ }