vigthoria-cli 1.13.20 → 1.13.22

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 (185) hide show
  1. package/completions/_vigthoria +49 -0
  2. package/completions/vigthoria.bash +6 -0
  3. package/completions/vigthoria.fish +41 -0
  4. package/dist/commands/auth.d.ts +1 -0
  5. package/dist/commands/auth.js +63 -128
  6. package/dist/commands/background.d.ts +0 -2
  7. package/dist/commands/background.js +26 -34
  8. package/dist/commands/bridge.js +45 -41
  9. package/dist/commands/cancel.d.ts +1 -0
  10. package/dist/commands/cancel.js +22 -16
  11. package/dist/commands/chat.d.ts +3 -42
  12. package/dist/commands/chat.js +378 -1123
  13. package/dist/commands/coding-registration.d.ts +4 -0
  14. package/dist/commands/coding-registration.js +24 -0
  15. package/dist/commands/config.js +23 -29
  16. package/dist/commands/conversation-registration.d.ts +4 -0
  17. package/dist/commands/conversation-registration.js +122 -0
  18. package/dist/commands/deploy.d.ts +8 -2
  19. package/dist/commands/deploy.js +92 -90
  20. package/dist/commands/device.d.ts +1 -2
  21. package/dist/commands/device.js +37 -21
  22. package/dist/commands/doctor-registration.d.ts +4 -0
  23. package/dist/commands/doctor-registration.js +200 -0
  24. package/dist/commands/edit.js +22 -33
  25. package/dist/commands/explain.js +7 -10
  26. package/dist/commands/fork.d.ts +1 -2
  27. package/dist/commands/fork.js +72 -22
  28. package/dist/commands/game.d.ts +1 -1
  29. package/dist/commands/game.js +17 -6
  30. package/dist/commands/generate.js +7 -9
  31. package/dist/commands/history.js +11 -7
  32. package/dist/commands/hub.d.ts +2 -2
  33. package/dist/commands/hub.js +34 -35
  34. package/dist/commands/legion.d.ts +0 -1
  35. package/dist/commands/legion.js +62 -79
  36. package/dist/commands/music.d.ts +1 -2
  37. package/dist/commands/music.js +62 -27
  38. package/dist/commands/platform-registration.d.ts +4 -0
  39. package/dist/commands/platform-registration.js +45 -0
  40. package/dist/commands/preview.d.ts +0 -1
  41. package/dist/commands/preview.js +82 -35
  42. package/dist/commands/product-run-registration.d.ts +4 -0
  43. package/dist/commands/product-run-registration.js +490 -0
  44. package/dist/commands/replay.d.ts +1 -2
  45. package/dist/commands/replay.js +15 -11
  46. package/dist/commands/repo.d.ts +14 -7
  47. package/dist/commands/repo.js +245 -196
  48. package/dist/commands/review.js +9 -12
  49. package/dist/commands/security.d.ts +1 -2
  50. package/dist/commands/security.js +12 -6
  51. package/dist/commands/update-registration.d.ts +3 -0
  52. package/dist/commands/update-registration.js +338 -0
  53. package/dist/commands/v4-registration.d.ts +4 -0
  54. package/dist/commands/v4-registration.js +24 -0
  55. package/dist/commands/v4.d.ts +1 -1
  56. package/dist/commands/v4.js +46 -8
  57. package/dist/commands/wallet.d.ts +1 -3
  58. package/dist/commands/wallet.js +18 -45
  59. package/dist/commands/workflow.d.ts +2 -0
  60. package/dist/commands/workflow.js +52 -39
  61. package/dist/index.js +122 -1589
  62. package/dist/utils/agent-stream-state.d.ts +27 -0
  63. package/dist/utils/agent-stream-state.js +93 -0
  64. package/dist/utils/agentRoute.d.ts +2 -1
  65. package/dist/utils/agentRoute.js +22 -9
  66. package/dist/utils/agentRunOutcome.d.ts +16 -0
  67. package/dist/utils/agentRunOutcome.js +37 -2
  68. package/dist/utils/api-client-factory.d.ts +8 -0
  69. package/dist/utils/api-client-factory.js +8 -0
  70. package/dist/utils/api.d.ts +44 -266
  71. package/dist/utils/api.js +647 -3180
  72. package/dist/utils/auth-session.d.ts +41 -0
  73. package/dist/utils/auth-session.js +224 -0
  74. package/dist/utils/brain-hub-client.d.ts +0 -4
  75. package/dist/utils/brain-hub-client.js +6 -3
  76. package/dist/utils/bridge-client.js +2 -0
  77. package/dist/utils/capability-health-service.d.ts +48 -0
  78. package/dist/utils/capability-health-service.js +64 -0
  79. package/dist/utils/chat-prompt-policy.d.ts +18 -0
  80. package/dist/utils/chat-prompt-policy.js +61 -0
  81. package/dist/utils/chat-tool-call-parser.d.ts +11 -0
  82. package/dist/utils/chat-tool-call-parser.js +71 -0
  83. package/dist/utils/cli-state.d.ts +22 -4
  84. package/dist/utils/cli-state.js +105 -47
  85. package/dist/utils/code-operations-service.d.ts +104 -0
  86. package/dist/utils/code-operations-service.js +837 -0
  87. package/dist/utils/codebase-indexer.d.ts +1 -0
  88. package/dist/utils/codebase-indexer.js +28 -8
  89. package/dist/utils/command-contract.d.ts +61 -0
  90. package/dist/utils/command-contract.js +149 -0
  91. package/dist/utils/command-policy.d.ts +10 -0
  92. package/dist/utils/command-policy.js +54 -0
  93. package/dist/utils/config.d.ts +13 -5
  94. package/dist/utils/config.js +220 -94
  95. package/dist/utils/context-ranker.js +11 -2
  96. package/dist/utils/context-state.d.ts +39 -0
  97. package/dist/utils/context-state.js +52 -0
  98. package/dist/utils/deckEvents.d.ts +0 -5
  99. package/dist/utils/deckEvents.js +3 -2
  100. package/dist/utils/desktop-bridge-client.js +2 -0
  101. package/dist/utils/direct-output-policy.d.ts +3 -0
  102. package/dist/utils/direct-output-policy.js +76 -0
  103. package/dist/utils/durable-json.d.ts +57 -0
  104. package/dist/utils/durable-json.js +319 -0
  105. package/dist/utils/fastAgentRouter.d.ts +5 -6
  106. package/dist/utils/fastAgentRouter.js +17 -25
  107. package/dist/utils/files.js +21 -13
  108. package/dist/utils/frontend-preview-service.d.ts +76 -0
  109. package/dist/utils/frontend-preview-service.js +482 -0
  110. package/dist/utils/goaEvents.d.ts +0 -4
  111. package/dist/utils/goaEvents.js +5 -2
  112. package/dist/utils/logger.d.ts +2 -1
  113. package/dist/utils/logger.js +27 -20
  114. package/dist/utils/mcp-context-client.d.ts +24 -0
  115. package/dist/utils/mcp-context-client.js +58 -0
  116. package/dist/utils/model-governance.d.ts +18 -0
  117. package/dist/utils/model-governance.js +75 -0
  118. package/dist/utils/model-transport-service.d.ts +44 -0
  119. package/dist/utils/model-transport-service.js +111 -0
  120. package/dist/utils/mutation-journal.d.ts +42 -0
  121. package/dist/utils/mutation-journal.js +387 -0
  122. package/dist/utils/network-policy.d.ts +24 -0
  123. package/dist/utils/network-policy.js +202 -0
  124. package/dist/utils/operator-client.d.ts +45 -0
  125. package/dist/utils/operator-client.js +159 -0
  126. package/dist/utils/post-write-validator.js +7 -9
  127. package/dist/utils/preview-screenshot-adapter.d.ts +13 -0
  128. package/dist/utils/preview-screenshot-adapter.js +36 -0
  129. package/dist/utils/process-policy.d.ts +23 -0
  130. package/dist/utils/process-policy.js +284 -0
  131. package/dist/utils/project-memory.d.ts +13 -3
  132. package/dist/utils/project-memory.js +70 -17
  133. package/dist/utils/prompt-workspace-resolver.d.ts +14 -0
  134. package/dist/utils/prompt-workspace-resolver.js +64 -0
  135. package/dist/utils/release-install.d.ts +11 -0
  136. package/dist/utils/release-install.js +155 -0
  137. package/dist/utils/release-policy.d.ts +64 -0
  138. package/dist/utils/release-policy.js +293 -0
  139. package/dist/utils/requestIntent.js +22 -3
  140. package/dist/utils/runtime-capability.d.ts +8 -0
  141. package/dist/utils/runtime-capability.js +16 -0
  142. package/dist/utils/secret-policy.d.ts +20 -0
  143. package/dist/utils/secret-policy.js +160 -0
  144. package/dist/utils/session.d.ts +17 -3
  145. package/dist/utils/session.js +354 -110
  146. package/dist/utils/tool-approval-service.d.ts +17 -0
  147. package/dist/utils/tool-approval-service.js +78 -0
  148. package/dist/utils/tool-capability-providers.d.ts +57 -0
  149. package/dist/utils/tool-capability-providers.js +57 -0
  150. package/dist/utils/tools.d.ts +2 -23
  151. package/dist/utils/tools.js +216 -508
  152. package/dist/utils/update-policy.d.ts +18 -0
  153. package/dist/utils/update-policy.js +137 -0
  154. package/dist/utils/v3-agent-client.d.ts +40 -0
  155. package/dist/utils/v3-agent-client.js +165 -0
  156. package/dist/utils/v3-workspace-service.d.ts +28 -0
  157. package/dist/utils/v3-workspace-service.js +279 -0
  158. package/dist/utils/vigflow-client.d.ts +95 -0
  159. package/dist/utils/vigflow-client.js +105 -0
  160. package/dist/utils/workspace-boundary.d.ts +45 -0
  161. package/dist/utils/workspace-boundary.js +377 -0
  162. package/dist/utils/workspace-brain-service.d.ts +2 -0
  163. package/dist/utils/workspace-brain-service.js +11 -1
  164. package/dist/utils/workspace-cache.js +37 -15
  165. package/dist/utils/workspace-stream.js +35 -10
  166. package/install.ps1 +85 -142
  167. package/install.sh +75 -80
  168. package/package.json +43 -9
  169. package/release-policy.json +43 -0
  170. package/scripts/release/LOCAL_MACHINE_USER_VERIFICATION.md +1 -1
  171. package/scripts/release/generate-completions.mjs +24 -0
  172. package/scripts/release/install-release.mjs +10 -0
  173. package/scripts/release/publish-cli-release.mjs +116 -0
  174. package/scripts/release/publish-cli-release.sh +2 -70
  175. package/scripts/release/resolve-release-manifest.mjs +26 -0
  176. package/scripts/release/test-balanced-model-live.sh +42 -0
  177. package/scripts/release/validate-live-service-gates.sh +90 -0
  178. package/scripts/release/validate-no-go-gates.sh +135 -174
  179. package/scripts/release/verify-runtime-consistency.mjs +4 -1
  180. package/dist/commands/index.d.ts +0 -12
  181. package/dist/commands/index.js +0 -194
  182. package/dist/commands/update.d.ts +0 -9
  183. package/dist/commands/update.js +0 -301
  184. package/dist/utils/templateInstantPath.d.ts +0 -18
  185. package/dist/utils/templateInstantPath.js +0 -228
@@ -13,10 +13,15 @@ import chalk from 'chalk';
13
13
  import * as fs from 'fs';
14
14
  import * as path from 'path';
15
15
  import * as http from 'http';
16
+ import { execFileSync } from 'node:child_process';
16
17
  import { createRequire } from 'node:module';
17
18
  import { structuredPatch } from 'diff';
18
19
  import { createSpinner, CH } from '../utils/logger.js';
19
- import { APIClient } from '../utils/api.js';
20
+ import { createAPIClient } from '../utils/api-client-factory.js';
21
+ import { resolveWorkspacePath } from '../utils/workspace-boundary.js';
22
+ import { hardenGitArguments, safeGitEnvironment } from '../utils/process-policy.js';
23
+ import { safeChildProcessEnv } from '../utils/secret-policy.js';
24
+ import { CliCommandError, commandFailure } from '../utils/command-contract.js';
20
25
  const require = createRequire(import.meta.url);
21
26
  // Common MIME types for static file serving
22
27
  const MIME_TYPES = {
@@ -47,21 +52,20 @@ const MIME_TYPES = {
47
52
  '.map': 'application/json',
48
53
  };
49
54
  export class PreviewCommand {
50
- config;
51
55
  logger;
52
56
  api;
53
57
  server = null;
54
58
  constructor(config, logger) {
55
- this.config = config;
56
59
  this.logger = logger;
57
- this.api = new APIClient(config, logger);
60
+ this.api = createAPIClient(config, logger);
58
61
  }
59
62
  async run(options) {
60
63
  const projectPath = path.resolve(options.project || process.cwd());
61
64
  if (!fs.existsSync(projectPath) || !fs.statSync(projectPath).isDirectory()) {
62
- this.logger.error(`Project directory not found: ${projectPath}`);
63
65
  this.api.destroy();
64
- return;
66
+ throw new CliCommandError(`Project directory not found: ${projectPath}`, {
67
+ code: 'PROJECT_DIRECTORY_NOT_FOUND', category: 'usage',
68
+ });
65
69
  }
66
70
  console.log();
67
71
  console.log(chalk.bold.white(` ${CH.hLine.repeat(3)} Vigthoria Preview ${CH.hLine.repeat(40)}`));
@@ -88,7 +92,9 @@ export class PreviewCommand {
88
92
  this.logger.warn('No HTML entry file found. Use --entry <file> to specify one.');
89
93
  if (!options.diff && !options.proof) {
90
94
  this.api.destroy();
91
- return;
95
+ throw new CliCommandError('No HTML entry file found. Use --entry <file> to specify one.', {
96
+ code: 'PREVIEW_ENTRY_NOT_FOUND', category: 'configuration',
97
+ });
92
98
  }
93
99
  this.api.destroy();
94
100
  return;
@@ -102,9 +108,15 @@ export class PreviewCommand {
102
108
  */
103
109
  detectEntryFile(projectPath, specified) {
104
110
  if (specified) {
105
- const fullPath = path.join(projectPath, specified);
106
- if (fs.existsSync(fullPath))
107
- return specified;
111
+ try {
112
+ const fullPath = resolveWorkspacePath(projectPath, specified);
113
+ if (fs.statSync(fullPath).isFile())
114
+ return specified.replace(/\\/g, '/');
115
+ }
116
+ catch {
117
+ this.logger.warn(`Refused entry file outside project boundary: ${specified}`);
118
+ return null;
119
+ }
108
120
  this.logger.warn(`Specified entry file not found: ${specified}`);
109
121
  return null;
110
122
  }
@@ -152,28 +164,35 @@ export class PreviewCommand {
152
164
  async startServer(projectPath, entryFile, port, autoOpen) {
153
165
  return new Promise((resolve) => {
154
166
  this.server = http.createServer((req, res) => {
155
- // Sanitize URL to prevent path traversal
156
- const urlPath = decodeURIComponent(new URL(req.url || '/', `http://localhost:${port}`).pathname);
157
- const safePath = path.normalize(urlPath).replace(/^(\.\.[/\\])+/, '');
158
- let filePath = path.join(projectPath, safePath);
159
- // Ensure the resolved path is within the project directory
160
- const resolvedPath = path.resolve(filePath);
161
- if (!resolvedPath.startsWith(path.resolve(projectPath))) {
167
+ let filePath;
168
+ try {
169
+ const urlPath = decodeURIComponent(new URL(req.url || '/', `http://localhost:${port}`).pathname);
170
+ const relativeRequest = urlPath.replace(/^\/+/, '') || entryFile;
171
+ filePath = resolveWorkspacePath(projectPath, relativeRequest, { allowMissing: true });
172
+ }
173
+ catch {
162
174
  res.writeHead(403);
163
175
  res.end('Forbidden');
164
176
  return;
165
177
  }
166
178
  // Directory → serve index.html
167
179
  if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
168
- filePath = path.join(filePath, 'index.html');
180
+ try {
181
+ filePath = resolveWorkspacePath(projectPath, `${path.relative(projectPath, filePath).replace(/\\/g, '/')}/index.html`, { allowMissing: true });
182
+ }
183
+ catch {
184
+ res.writeHead(403);
185
+ res.end('Forbidden');
186
+ return;
187
+ }
169
188
  }
170
189
  // SPA fallback
171
190
  if (!fs.existsSync(filePath)) {
172
- const spaFallback = path.join(projectPath, entryFile);
173
- if (fs.existsSync(spaFallback)) {
191
+ try {
192
+ const spaFallback = resolveWorkspacePath(projectPath, entryFile);
174
193
  filePath = spaFallback;
175
194
  }
176
- else {
195
+ catch {
177
196
  res.writeHead(404);
178
197
  res.end('Not found');
179
198
  return;
@@ -225,20 +244,21 @@ export class PreviewCommand {
225
244
  if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:')
226
245
  return;
227
246
  const safeUrl = parsed.href;
247
+ const options = { env: safeChildProcessEnv(), windowsHide: true, timeout: 10_000 };
228
248
  if (platform === 'darwin') {
229
- execFile('open', [safeUrl], (err) => {
249
+ execFile('open', [safeUrl], options, (err) => {
230
250
  if (err)
231
251
  this.logger.debug(`Could not auto-open browser: ${err.message}`);
232
252
  });
233
253
  }
234
254
  else if (platform === 'win32') {
235
- execFile('cmd', ['/c', 'start', '', safeUrl], (err) => {
255
+ execFile('rundll32.exe', ['url.dll,FileProtocolHandler', safeUrl], options, (err) => {
236
256
  if (err)
237
257
  this.logger.debug(`Could not auto-open browser: ${err.message}`);
238
258
  });
239
259
  }
240
260
  else {
241
- execFile('xdg-open', [safeUrl], (err) => {
261
+ execFile('xdg-open', [safeUrl], options, (err) => {
242
262
  if (err)
243
263
  this.logger.debug(`Could not auto-open browser: ${err.message}`);
244
264
  });
@@ -254,15 +274,20 @@ export class PreviewCommand {
254
274
  async showConsolidatedDiff(projectPath) {
255
275
  console.log(chalk.bold.white(` ${CH.hLine.repeat(3)} Change Summary ${CH.hLine.repeat(43)}`));
256
276
  console.log();
257
- const proofDir = path.join(projectPath, '.vigthoria', 'proof', 'preview');
277
+ const proofDir = resolveWorkspacePath(projectPath, '.vigthoria/proof/preview', { allowMissing: true });
258
278
  const hasProof = fs.existsSync(proofDir);
259
279
  // Try git diff first (most reliable)
260
280
  try {
261
- const { execSync } = require('child_process');
262
281
  const isGit = fs.existsSync(path.join(projectPath, '.git'));
263
282
  if (isGit) {
264
283
  // Get list of changed files (unstaged + staged)
265
- const statusOutput = execSync('git status --porcelain', { cwd: projectPath, encoding: 'utf-8' }).trim();
284
+ const statusOutput = execFileSync('git', hardenGitArguments(['status', '--porcelain']), {
285
+ cwd: projectPath,
286
+ encoding: 'utf8',
287
+ windowsHide: true,
288
+ timeout: 30_000,
289
+ env: safeChildProcessEnv(safeGitEnvironment()),
290
+ }).trim();
266
291
  if (!statusOutput) {
267
292
  console.log(chalk.gray(' No changes detected (working tree clean).'));
268
293
  console.log();
@@ -295,9 +320,13 @@ export class PreviewCommand {
295
320
  // Show unified diffs for modified and created files (limit to keep terminal manageable)
296
321
  const diffTargets = [...modified, ...created].slice(0, 20);
297
322
  for (const relPath of diffTargets) {
298
- const absPath = path.join(projectPath, relPath);
299
- if (!fs.existsSync(absPath))
323
+ let absPath;
324
+ try {
325
+ absPath = resolveWorkspacePath(projectPath, relPath);
326
+ }
327
+ catch {
300
328
  continue;
329
+ }
301
330
  const ext = path.extname(relPath).toLowerCase();
302
331
  const textExts = ['.html', '.css', '.js', '.ts', '.jsx', '.tsx', '.json', '.md', '.yml', '.yaml', '.txt', '.xml', '.svg', '.py', '.sh', '.env'];
303
332
  if (!textExts.includes(ext))
@@ -309,7 +338,13 @@ export class PreviewCommand {
309
338
  try {
310
339
  // Validate relPath is a safe relative path before interpolating — prevents injection
311
340
  if (/^[a-zA-Z0-9_\-./]+$/.test(relPath) && !relPath.includes('..')) {
312
- oldContent = execSync(`git show HEAD:${relPath}`, { cwd: projectPath, encoding: 'utf-8' });
341
+ oldContent = execFileSync('git', hardenGitArguments(['show', `HEAD:${relPath}`]), {
342
+ cwd: projectPath,
343
+ encoding: 'utf8',
344
+ windowsHide: true,
345
+ timeout: 30_000,
346
+ env: safeChildProcessEnv(safeGitEnvironment()),
347
+ });
313
348
  }
314
349
  }
315
350
  catch {
@@ -363,7 +398,8 @@ export class PreviewCommand {
363
398
  console.log(chalk.white(' Recent proof bundles:'));
364
399
  for (const m of manifests) {
365
400
  try {
366
- const manifest = JSON.parse(fs.readFileSync(path.join(proofDir, m), 'utf-8'));
401
+ const manifestPath = resolveWorkspacePath(projectPath, `.vigthoria/proof/preview/${m}`);
402
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
367
403
  const passed = manifest.previewGate?.passed ? chalk.green('passed') : chalk.red('failed');
368
404
  console.log(chalk.gray(` ${manifest.createdAt || m} `) + passed + chalk.gray(` ${manifest.entryPath || '-'}`));
369
405
  }
@@ -390,14 +426,17 @@ export class PreviewCommand {
390
426
  workspacePath: projectPath,
391
427
  projectPath: projectPath,
392
428
  targetPath: projectPath,
429
+ forceFrontendPreview: true,
430
+ requireScreenshot: captureScreenshot === true,
393
431
  });
394
432
  spinner.stop();
395
433
  console.log(chalk.bold.white(` ${CH.hLine.repeat(3)} Preview Proof Gate ${CH.hLine.repeat(39)}`));
396
434
  console.log();
397
435
  if (!result.required) {
398
- console.log(chalk.gray(' Preview gate: not required (no frontend artifacts detected)'));
399
- console.log();
400
- return;
436
+ throw new CliCommandError('Preview proof was explicitly requested, but the proof service did not require or validate it.', {
437
+ code: 'PREVIEW_PROOF_SKIPPED',
438
+ details: result,
439
+ });
401
440
  }
402
441
  const statusIcon = result.passed ? chalk.green(CH.success) : chalk.red(CH.error);
403
442
  console.log(` ${statusIcon} Preview gate: ${result.passed ? chalk.green('PASSED') : chalk.red('FAILED')}`);
@@ -458,10 +497,18 @@ export class PreviewCommand {
458
497
  }
459
498
  }
460
499
  console.log();
500
+ if (!result.passed || result.skipped === true) {
501
+ throw new CliCommandError(result.error || 'Preview proof did not pass.', {
502
+ code: 'PREVIEW_PROOF_FAILED',
503
+ category: result.partialMutation === false ? 'execution' : 'partial_mutation',
504
+ partialMutation: result.partialMutation ?? false,
505
+ details: result,
506
+ });
507
+ }
461
508
  }
462
509
  catch (error) {
463
510
  spinner.stop();
464
- this.logger.error(`Preview proof gate failed: ${error?.message || String(error)}`);
511
+ throw commandFailure(error, { code: 'PREVIEW_PROOF_FAILED' });
465
512
  }
466
513
  }
467
514
  }
@@ -0,0 +1,4 @@
1
+ import type { Command } from 'commander';
2
+ import type { Config } from '../utils/config.js';
3
+ import type { Logger } from '../utils/logger.js';
4
+ export declare function registerProductAndRunCommands(program: Command, config: Config, logger: Logger): void;