vigthoria-cli 1.9.10 → 1.9.19

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 (52) hide show
  1. package/README.md +4 -4
  2. package/dist/commands/auth.js +48 -65
  3. package/dist/commands/bridge.js +12 -19
  4. package/dist/commands/cancel.js +15 -22
  5. package/dist/commands/chat.d.ts +11 -0
  6. package/dist/commands/chat.js +404 -248
  7. package/dist/commands/config.js +31 -71
  8. package/dist/commands/deploy.js +83 -123
  9. package/dist/commands/device.d.ts +35 -0
  10. package/dist/commands/device.js +239 -0
  11. package/dist/commands/edit.js +32 -39
  12. package/dist/commands/explain.js +18 -25
  13. package/dist/commands/fork.js +22 -27
  14. package/dist/commands/generate.js +37 -44
  15. package/dist/commands/history.js +20 -25
  16. package/dist/commands/hub.js +95 -102
  17. package/dist/commands/index.js +41 -46
  18. package/dist/commands/legion.d.ts +1 -0
  19. package/dist/commands/legion.js +162 -209
  20. package/dist/commands/preview.js +60 -98
  21. package/dist/commands/replay.js +27 -32
  22. package/dist/commands/repo.js +103 -141
  23. package/dist/commands/review.js +29 -36
  24. package/dist/commands/security.js +5 -12
  25. package/dist/commands/update.js +15 -49
  26. package/dist/commands/workflow.d.ts +8 -1
  27. package/dist/commands/workflow.js +53 -19
  28. package/dist/index.js +409 -234
  29. package/dist/utils/api.d.ts +5 -0
  30. package/dist/utils/api.js +373 -166
  31. package/dist/utils/bridge-client.js +11 -52
  32. package/dist/utils/cli-state.d.ts +54 -0
  33. package/dist/utils/cli-state.js +185 -0
  34. package/dist/utils/config.d.ts +5 -0
  35. package/dist/utils/config.js +35 -14
  36. package/dist/utils/context-ranker.js +15 -21
  37. package/dist/utils/files.js +5 -42
  38. package/dist/utils/logger.js +42 -50
  39. package/dist/utils/post-write-validator.js +22 -29
  40. package/dist/utils/project-memory.d.ts +56 -0
  41. package/dist/utils/project-memory.js +289 -0
  42. package/dist/utils/session.d.ts +29 -3
  43. package/dist/utils/session.js +137 -85
  44. package/dist/utils/task-display.js +13 -20
  45. package/dist/utils/tools.d.ts +19 -0
  46. package/dist/utils/tools.js +84 -87
  47. package/dist/utils/workspace-cache.js +18 -26
  48. package/dist/utils/workspace-stream.js +26 -64
  49. package/install.ps1 +14 -0
  50. package/package.json +5 -3
  51. package/scripts/release/LOCAL_MACHINE_USER_VERIFICATION.md +1 -1
  52. package/scripts/release/validate-no-go-gates.sh +2 -2
@@ -1,19 +1,13 @@
1
- "use strict";
2
1
  /**
3
2
  * Review Command - Code review with AI
4
3
  */
5
- var __importDefault = (this && this.__importDefault) || function (mod) {
6
- return (mod && mod.__esModule) ? mod : { "default": mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.ReviewCommand = void 0;
10
- const chalk_1 = __importDefault(require("chalk"));
11
- const marked_1 = require("marked");
12
- const marked_terminal_1 = require("marked-terminal");
13
- const logger_js_1 = require("../utils/logger.js");
14
- const api_js_1 = require("../utils/api.js");
15
- const files_js_1 = require("../utils/files.js");
16
- class ReviewCommand {
4
+ import chalk from 'chalk';
5
+ import { Marked } from 'marked';
6
+ import { markedTerminal } from 'marked-terminal';
7
+ import { createSpinner, CH } from '../utils/logger.js';
8
+ import { APIClient, CLIError, classifyError, formatCLIError } from '../utils/api.js';
9
+ import { FileUtils } from '../utils/files.js';
10
+ export class ReviewCommand {
17
11
  config;
18
12
  logger;
19
13
  api;
@@ -22,10 +16,10 @@ class ReviewCommand {
22
16
  constructor(config, logger) {
23
17
  this.config = config;
24
18
  this.logger = logger;
25
- this.api = new api_js_1.APIClient(config, logger);
26
- this.fileUtils = new files_js_1.FileUtils(process.cwd(), config.get('project').ignorePatterns);
27
- this.marked = new marked_1.Marked();
28
- this.marked.use((0, marked_terminal_1.markedTerminal)({
19
+ this.api = new APIClient(config, logger);
20
+ this.fileUtils = new FileUtils(process.cwd(), config.get('project').ignorePatterns);
21
+ this.marked = new Marked();
22
+ this.marked.use(markedTerminal({
29
23
  showSectionPrefix: false,
30
24
  tab: 2,
31
25
  width: 80,
@@ -51,9 +45,9 @@ class ReviewCommand {
51
45
  return;
52
46
  }
53
47
  this.logger.section(`Reviewing: ${file.relativePath}`);
54
- console.log(chalk_1.default.gray(`Language: ${file.language} | Lines: ${file.lines}`));
48
+ console.log(chalk.gray(`Language: ${file.language} | Lines: ${file.lines}`));
55
49
  console.log();
56
- const spinner = (0, logger_js_1.createSpinner)({
50
+ const spinner = createSpinner({
57
51
  text: 'Analyzing code quality...',
58
52
  spinner: 'dots',
59
53
  }).start();
@@ -76,15 +70,15 @@ class ReviewCommand {
76
70
  }
77
71
  catch (error) {
78
72
  spinner.stop();
79
- const cliErr = error instanceof api_js_1.CLIError ? error : (0, api_js_1.classifyError)(error);
80
- this.logger.error((0, api_js_1.formatCLIError)(cliErr));
73
+ const cliErr = error instanceof CLIError ? error : classifyError(error);
74
+ this.logger.error(formatCLIError(cliErr));
81
75
  }
82
76
  }
83
77
  printTextReview(review) {
84
78
  // Score
85
- const scoreColor = review.score >= 80 ? chalk_1.default.green : review.score >= 60 ? chalk_1.default.yellow : chalk_1.default.red;
79
+ const scoreColor = review.score >= 80 ? chalk.green : review.score >= 60 ? chalk.yellow : chalk.red;
86
80
  console.log();
87
- console.log(chalk_1.default.bold('Quality Score: ') + scoreColor(`${review.score}/100`));
81
+ console.log(chalk.bold('Quality Score: ') + scoreColor(`${review.score}/100`));
88
82
  console.log(this.renderScoreBar(review.score));
89
83
  console.log();
90
84
  // Issues
@@ -94,7 +88,7 @@ class ReviewCommand {
94
88
  const severityIcon = this.getSeverityIcon(issue.severity);
95
89
  const severityColor = this.getSeverityColor(issue.severity);
96
90
  console.log(severityColor(`${severityIcon} [${issue.type}]`) +
97
- chalk_1.default.gray(` Line ${issue.line}:`) +
91
+ chalk.gray(` Line ${issue.line}:`) +
98
92
  ` ${issue.message}`);
99
93
  });
100
94
  console.log();
@@ -106,7 +100,7 @@ class ReviewCommand {
106
100
  if (review.suggestions.length > 0) {
107
101
  this.logger.section('Suggestions');
108
102
  review.suggestions.forEach((suggestion, i) => {
109
- console.log(chalk_1.default.cyan(`${i + 1}.`) + ` ${suggestion}`);
103
+ console.log(chalk.cyan(`${i + 1}.`) + ` ${suggestion}`);
110
104
  });
111
105
  console.log();
112
106
  }
@@ -133,10 +127,10 @@ class ReviewCommand {
133
127
  const width = 30;
134
128
  const filled = Math.round((score / 100) * width);
135
129
  const empty = width - filled;
136
- const color = score >= 80 ? chalk_1.default.green : score >= 60 ? chalk_1.default.yellow : chalk_1.default.red;
130
+ const color = score >= 80 ? chalk.green : score >= 60 ? chalk.yellow : chalk.red;
137
131
  const filledChar = process.platform === 'win32' ? '#' : '\u2588';
138
132
  const emptyChar = process.platform === 'win32' ? '.' : '\u2591';
139
- return color(filledChar.repeat(filled)) + chalk_1.default.gray(emptyChar.repeat(empty));
133
+ return color(filledChar.repeat(filled)) + chalk.gray(emptyChar.repeat(empty));
140
134
  }
141
135
  /**
142
136
  * Clean marked-terminal output for release-grade CLI presentation.
@@ -157,26 +151,25 @@ class ReviewCommand {
157
151
  getSeverityIcon(severity) {
158
152
  switch (severity.toLowerCase()) {
159
153
  case 'error':
160
- return logger_js_1.CH.error;
154
+ return CH.error;
161
155
  case 'warning':
162
- return logger_js_1.CH.warn;
156
+ return CH.warn;
163
157
  case 'info':
164
- return logger_js_1.CH.info;
158
+ return CH.info;
165
159
  default:
166
- return logger_js_1.CH.bullet;
160
+ return CH.bullet;
167
161
  }
168
162
  }
169
163
  getSeverityColor(severity) {
170
164
  switch (severity.toLowerCase()) {
171
165
  case 'error':
172
- return chalk_1.default.red;
166
+ return chalk.red;
173
167
  case 'warning':
174
- return chalk_1.default.yellow;
168
+ return chalk.yellow;
175
169
  case 'info':
176
- return chalk_1.default.blue;
170
+ return chalk.blue;
177
171
  default:
178
- return chalk_1.default.white;
172
+ return chalk.white;
179
173
  }
180
174
  }
181
175
  }
182
- exports.ReviewCommand = ReviewCommand;
@@ -1,12 +1,6 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SecurityCommand = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
- const path_1 = __importDefault(require("path"));
9
- class SecurityCommand {
1
+ import axios from 'axios';
2
+ import path from 'path';
3
+ export class SecurityCommand {
10
4
  config;
11
5
  logger;
12
6
  constructor(config, logger) {
@@ -21,11 +15,11 @@ class SecurityCommand {
21
15
  return 'http://127.0.0.1:4008';
22
16
  }
23
17
  resolveDir(dir) {
24
- return path_1.default.resolve(dir || process.cwd());
18
+ return path.resolve(dir || process.cwd());
25
19
  }
26
20
  async execute(tool, parameters) {
27
21
  const baseUrl = this.getMcpBaseUrl();
28
- const response = await axios_1.default.post(`${baseUrl}/mcp/execute`, {
22
+ const response = await axios.post(`${baseUrl}/mcp/execute`, {
29
23
  tool,
30
24
  parameters,
31
25
  context: {
@@ -95,4 +89,3 @@ class SecurityCommand {
95
89
  }
96
90
  }
97
91
  }
98
- exports.SecurityCommand = SecurityCommand;
@@ -1,46 +1,12 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.updateCommand = updateCommand;
37
- exports.update = update;
38
- const node_child_process_1 = require("node:child_process");
39
- const node_fs_1 = require("node:fs");
40
- const path = __importStar(require("node:path"));
41
- const node_util_1 = require("node:util");
42
- const tools_js_1 = require("../utils/tools.js");
43
- const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
1
+ import { execFile } from 'node:child_process';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { promisify } from 'node:util';
6
+ import { installUpdateWindows } from '../utils/tools.js';
7
+ // ESM shim — __filename is unavailable under "type": "module".
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const execFileAsync = promisify(execFile);
44
10
  function markSuccessExit() {
45
11
  process.exitCode = 0;
46
12
  }
@@ -51,7 +17,7 @@ function findPackageJson(startDir) {
51
17
  let currentDir = startDir;
52
18
  for (let depth = 0; depth < 8; depth += 1) {
53
19
  const candidate = path.join(currentDir, 'package.json');
54
- if ((0, node_fs_1.existsSync)(candidate)) {
20
+ if (existsSync(candidate)) {
55
21
  return candidate;
56
22
  }
57
23
  const parentDir = path.join(currentDir, '..');
@@ -69,7 +35,7 @@ function readOwnPackageJson() {
69
35
  throw new Error('Unable to locate package.json for the Vigthoria CLI.');
70
36
  }
71
37
  try {
72
- return JSON.parse((0, node_fs_1.readFileSync)(packagePath, 'utf8'));
38
+ return JSON.parse(readFileSync(packagePath, 'utf8'));
73
39
  }
74
40
  catch (error) {
75
41
  const message = error instanceof Error ? error.message : String(error);
@@ -169,7 +135,7 @@ async function runInstall(packageManager, packageName, installGlobal) {
169
135
  const installCommand = resolveInstallCommand(packageManager, packageName, installGlobal);
170
136
  await execPackageManager(installCommand.command, installCommand.args, 120_000);
171
137
  }
172
- async function updateCommand(options = {}) {
138
+ export async function updateCommand(options = {}) {
173
139
  try {
174
140
  const info = await getVersionInfo();
175
141
  console.log(`Vigthoria CLI current version: ${info.current}`);
@@ -188,7 +154,7 @@ async function updateCommand(options = {}) {
188
154
  const installGlobal = options.global ?? true;
189
155
  console.log(`Installing ${info.packageName}@latest with ${packageManager}...`);
190
156
  if (process.platform === 'win32') {
191
- const installerResult = await (0, tools_js_1.installUpdateWindows)();
157
+ const installerResult = await installUpdateWindows();
192
158
  if (!installerResult.success && installerResult.error === 'ENOENT') {
193
159
  const fallbackCommand = resolveInstallCommand(packageManager, info.packageName, installGlobal);
194
160
  console.warn('Windows update installer was not found (ENOENT).');
@@ -218,7 +184,7 @@ async function updateCommand(options = {}) {
218
184
  markErrorExit();
219
185
  }
220
186
  }
221
- async function update() {
187
+ export async function update() {
222
188
  try {
223
189
  await updateCommand();
224
190
  if (process.exitCode === 1) {
@@ -232,4 +198,4 @@ async function update() {
232
198
  markErrorExit();
233
199
  }
234
200
  }
235
- exports.default = updateCommand;
201
+ export default updateCommand;
@@ -13,6 +13,10 @@ interface WorkflowUseOptions extends WorkflowOutputOptions {
13
13
  }
14
14
  interface WorkflowRunOptions extends WorkflowOutputOptions {
15
15
  data?: string;
16
+ brain?: boolean;
17
+ }
18
+ interface WorkflowStatusOptions extends WorkflowOutputOptions {
19
+ brain?: boolean;
16
20
  }
17
21
  export declare class WorkflowCommand {
18
22
  private config;
@@ -22,10 +26,13 @@ export declare class WorkflowCommand {
22
26
  private ensureAuthenticated;
23
27
  private parseJsonOption;
24
28
  private printJson;
29
+ private createProjectMemory;
30
+ private buildBrainPayload;
31
+ private rememberWorkflowEvent;
25
32
  templates(options: WorkflowTemplateOptions): Promise<void>;
26
33
  list(options: WorkflowOutputOptions): Promise<void>;
27
34
  useTemplate(templateId: string, options: WorkflowUseOptions): Promise<void>;
28
35
  run(workflowId: string, options: WorkflowRunOptions): Promise<void>;
29
- status(executionId: string, options: WorkflowOutputOptions): Promise<void>;
36
+ status(executionId: string, options: WorkflowStatusOptions): Promise<void>;
30
37
  }
31
38
  export {};
@@ -1,19 +1,14 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.WorkflowCommand = void 0;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const api_js_1 = require("../utils/api.js");
9
- class WorkflowCommand {
1
+ import chalk from 'chalk';
2
+ import { APIClient, } from '../utils/api.js';
3
+ import { ProjectMemoryService } from '../utils/project-memory.js';
4
+ export class WorkflowCommand {
10
5
  config;
11
6
  logger;
12
7
  api;
13
8
  constructor(config, logger) {
14
9
  this.config = config;
15
10
  this.logger = logger;
16
- this.api = new api_js_1.APIClient(config, logger);
11
+ this.api = new APIClient(config, logger);
17
12
  }
18
13
  ensureAuthenticated(json = false) {
19
14
  if (this.config.isAuthenticated()) {
@@ -46,6 +41,34 @@ class WorkflowCommand {
46
41
  printJson(payload) {
47
42
  console.log(JSON.stringify(payload, null, 2));
48
43
  }
44
+ createProjectMemory() {
45
+ return new ProjectMemoryService(process.cwd());
46
+ }
47
+ buildBrainPayload(workflowId, data) {
48
+ const memory = this.createProjectMemory();
49
+ const prompt = [workflowId, JSON.stringify(data || {})].join(' ');
50
+ const context = memory.buildContextForPrompt(prompt);
51
+ const status = memory.getStatus();
52
+ if (!context && status.itemCount === 0) {
53
+ return undefined;
54
+ }
55
+ return {
56
+ schema: 'vigthoria.project-brain.v1',
57
+ source: 'vigthoria-cli.workflow',
58
+ memoryDir: status.memoryDir,
59
+ itemCount: status.itemCount,
60
+ updatedAt: status.updatedAt,
61
+ context,
62
+ };
63
+ }
64
+ rememberWorkflowEvent(type, text) {
65
+ try {
66
+ this.createProjectMemory().remember(type, text, { source: 'vigflow', mode: 'workflow' });
67
+ }
68
+ catch {
69
+ // Project Brain should never break workflow execution.
70
+ }
71
+ }
49
72
  async templates(options) {
50
73
  this.ensureAuthenticated(Boolean(options.json));
51
74
  let templates;
@@ -74,7 +97,7 @@ class WorkflowCommand {
74
97
  }
75
98
  this.logger.section('Workflow Templates');
76
99
  if (templates.length === 0) {
77
- console.log(chalk_1.default.yellow('No templates matched your filters.'));
100
+ console.log(chalk.yellow('No templates matched your filters.'));
78
101
  return;
79
102
  }
80
103
  this.logger.table(['ID', 'Name', 'Category', 'Tags'], templates.map((template) => [
@@ -109,7 +132,7 @@ class WorkflowCommand {
109
132
  }
110
133
  this.logger.section('Workflows');
111
134
  if (workflows.length === 0) {
112
- console.log(chalk_1.default.yellow('No workflows found for this account.'));
135
+ console.log(chalk.yellow('No workflows found for this account.'));
113
136
  return;
114
137
  }
115
138
  this.logger.table(['ID', 'Name', 'Nodes', 'Runs', 'Updated'], workflows.map((workflow) => [
@@ -132,29 +155,41 @@ class WorkflowCommand {
132
155
  return;
133
156
  }
134
157
  this.logger.success(`Created workflow ${workflow.name}`);
135
- console.log(chalk_1.default.gray(`Workflow ID: ${workflow.id}`));
158
+ console.log(chalk.gray(`Workflow ID: ${workflow.id}`));
136
159
  if (workflow.fromTemplate) {
137
- console.log(chalk_1.default.gray(`Template: ${workflow.fromTemplate}`));
160
+ console.log(chalk.gray(`Template: ${workflow.fromTemplate}`));
138
161
  }
139
162
  }
140
163
  async run(workflowId, options) {
141
164
  this.ensureAuthenticated(Boolean(options.json));
142
165
  const data = this.parseJsonOption(options.data, 'data');
143
- const execution = await this.api.runVigFlowWorkflow(workflowId, { data });
166
+ const executionData = { ...data };
167
+ if (options.brain !== false) {
168
+ const brainPayload = this.buildBrainPayload(workflowId, data);
169
+ if (brainPayload) {
170
+ executionData.vigthoriaBrain = brainPayload;
171
+ }
172
+ }
173
+ this.rememberWorkflowEvent('task', `VigFlow workflow ${workflowId} started with Project Brain context: ${options.brain !== false ? 'enabled' : 'disabled'}.`);
174
+ const execution = await this.api.runVigFlowWorkflow(workflowId, { data: executionData });
175
+ this.rememberWorkflowEvent(execution.error ? 'issue' : 'validation', `VigFlow workflow ${workflowId} execution ${execution.executionId || 'unknown'} finished with status ${execution.status}; nodes executed ${execution.nodesExecuted ?? 0}${execution.error ? `; error: ${execution.error}` : ''}.`);
144
176
  if (options.json) {
145
177
  this.printJson({ success: true, execution });
146
178
  return;
147
179
  }
148
180
  this.logger.success(`Workflow execution ${execution.status}`);
149
- console.log(chalk_1.default.gray(`Execution ID: ${execution.executionId}`));
150
- console.log(chalk_1.default.gray(`Nodes executed: ${execution.nodesExecuted ?? 0}`));
181
+ console.log(chalk.gray(`Execution ID: ${execution.executionId}`));
182
+ console.log(chalk.gray(`Nodes executed: ${execution.nodesExecuted ?? 0}`));
151
183
  if (execution.error) {
152
- console.log(chalk_1.default.red(execution.error));
184
+ console.log(chalk.red(execution.error));
153
185
  }
154
186
  }
155
187
  async status(executionId, options) {
156
188
  this.ensureAuthenticated(Boolean(options.json));
157
189
  const execution = await this.api.getVigFlowExecutionStatus(executionId);
190
+ if (options.brain !== false) {
191
+ this.rememberWorkflowEvent(execution.status === 'failed' ? 'issue' : 'validation', `VigFlow execution ${execution.id} for workflow ${execution.workflowId} status ${execution.status}; nodes ${execution.nodesExecuted ?? 0}/${execution.totalNodes ?? '-'}.`);
192
+ }
158
193
  if (options.json) {
159
194
  this.printJson({ success: true, execution });
160
195
  return;
@@ -169,4 +204,3 @@ class WorkflowCommand {
169
204
  ].join('\n'), 'Workflow Status');
170
205
  }
171
206
  }
172
- exports.WorkflowCommand = WorkflowCommand;