@rigour-labs/cli 2.10.0 → 2.11.0

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.
package/dist/cli.js CHANGED
@@ -1,25 +1,22 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const commander_1 = require("commander");
8
- const init_js_1 = require("./commands/init.js");
9
- const check_js_1 = require("./commands/check.js");
10
- const explain_js_1 = require("./commands/explain.js");
11
- const run_js_1 = require("./commands/run.js");
12
- const guide_js_1 = require("./commands/guide.js");
13
- const setup_js_1 = require("./commands/setup.js");
14
- const index_js_1 = require("./commands/index.js");
15
- const chalk_1 = __importDefault(require("chalk"));
16
- const program = new commander_1.Command();
17
- program.addCommand(index_js_1.indexCommand);
2
+ import { Command } from 'commander';
3
+ import { initCommand } from './commands/init.js';
4
+ import { checkCommand } from './commands/check.js';
5
+ import { explainCommand } from './commands/explain.js';
6
+ import { runLoop } from './commands/run.js';
7
+ import { guideCommand } from './commands/guide.js';
8
+ import { setupCommand } from './commands/setup.js';
9
+ import { indexCommand } from './commands/index.js';
10
+ import { studioCommand } from './commands/studio.js';
11
+ import chalk from 'chalk';
12
+ const program = new Command();
13
+ program.addCommand(indexCommand);
14
+ program.addCommand(studioCommand);
18
15
  program
19
16
  .name('rigour')
20
17
  .description('🛡️ Rigour: The Quality Gate Loop for AI-Assisted Engineering')
21
18
  .version('2.0.0')
22
- .addHelpText('before', chalk_1.default.bold.cyan(`
19
+ .addHelpText('before', chalk.bold.cyan(`
23
20
  ____ _
24
21
  / __ \\(_)____ ___ __ __ _____
25
22
  / /_/ // // __ \`/ / / / / // ___/
@@ -43,7 +40,7 @@ Examples:
43
40
  $ rigour init --ide all # Create files for all IDEs
44
41
  `)
45
42
  .action(async (options) => {
46
- await (0, init_js_1.initCommand)(process.cwd(), options);
43
+ await initCommand(process.cwd(), options);
47
44
  });
48
45
  program
49
46
  .command('check')
@@ -61,7 +58,7 @@ Examples:
61
58
  $ rigour check --ci # Run in CI environment
62
59
  `)
63
60
  .action(async (files, options) => {
64
- await (0, check_js_1.checkCommand)(process.cwd(), files, options);
61
+ await checkCommand(process.cwd(), files, options);
65
62
  });
66
63
  program
67
64
  .command('explain')
@@ -71,7 +68,7 @@ Examples:
71
68
  $ rigour explain # Get a human-readable violation summary
72
69
  `)
73
70
  .action(async () => {
74
- await (0, explain_js_1.explainCommand)(process.cwd());
71
+ await explainCommand(process.cwd());
75
72
  });
76
73
  program
77
74
  .command('run')
@@ -85,7 +82,7 @@ Examples:
85
82
  $ rigour run -c 5 -- cursor-agent # Run Cursor agent for up to 5 cycles
86
83
  `)
87
84
  .action(async (args, options) => {
88
- await (0, run_js_1.runLoop)(process.cwd(), args, {
85
+ await runLoop(process.cwd(), args, {
89
86
  iterations: parseInt(options.maxCycles),
90
87
  failFast: !!options.failFast
91
88
  });
@@ -94,12 +91,12 @@ program
94
91
  .command('guide')
95
92
  .description('Show the interactive engineering guide')
96
93
  .action(async () => {
97
- await (0, guide_js_1.guideCommand)();
94
+ await guideCommand();
98
95
  });
99
96
  program
100
97
  .command('setup')
101
98
  .description('Show installation and global setup guidance')
102
99
  .action(async () => {
103
- await (0, setup_js_1.setupCommand)();
100
+ await setupCommand();
104
101
  });
105
102
  program.parse();
@@ -1,50 +1,77 @@
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.checkCommand = checkCommand;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
- const path_1 = __importDefault(require("path"));
9
- const chalk_1 = __importDefault(require("chalk"));
10
- const yaml_1 = __importDefault(require("yaml"));
11
- const core_1 = require("@rigour-labs/core");
12
- const inquirer_1 = __importDefault(require("inquirer"));
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import yaml from 'yaml';
5
+ import { GateRunner, ConfigSchema } from '@rigour-labs/core';
6
+ import inquirer from 'inquirer';
7
+ import { randomUUID } from 'crypto';
13
8
  // Exit codes per spec
14
9
  const EXIT_PASS = 0;
15
10
  const EXIT_FAIL = 1;
16
11
  const EXIT_CONFIG_ERROR = 2;
17
12
  const EXIT_INTERNAL_ERROR = 3;
18
- async function checkCommand(cwd, files = [], options = {}) {
19
- const configPath = path_1.default.join(cwd, 'rigour.yml');
20
- if (!(await fs_extra_1.default.pathExists(configPath))) {
13
+ // Helper to log events for Rigour Studio
14
+ async function logStudioEvent(cwd, event) {
15
+ try {
16
+ const rigourDir = path.join(cwd, ".rigour");
17
+ await fs.ensureDir(rigourDir);
18
+ const eventsPath = path.join(rigourDir, "events.jsonl");
19
+ const logEntry = JSON.stringify({
20
+ id: randomUUID(),
21
+ timestamp: new Date().toISOString(),
22
+ ...event
23
+ }) + "\n";
24
+ await fs.appendFile(eventsPath, logEntry);
25
+ }
26
+ catch {
27
+ // Silent fail
28
+ }
29
+ }
30
+ export async function checkCommand(cwd, files = [], options = {}) {
31
+ const configPath = path.join(cwd, 'rigour.yml');
32
+ if (!(await fs.pathExists(configPath))) {
21
33
  if (options.json) {
22
34
  console.log(JSON.stringify({ error: 'CONFIG_ERROR', message: 'rigour.yml not found' }));
23
35
  }
24
36
  else if (!options.ci) {
25
- console.error(chalk_1.default.red('Error: rigour.yml not found. Run `rigour init` first.'));
37
+ console.error(chalk.red('Error: rigour.yml not found. Run `rigour init` first.'));
26
38
  }
27
39
  process.exit(EXIT_CONFIG_ERROR);
28
40
  }
29
41
  try {
30
- const configContent = await fs_extra_1.default.readFile(configPath, 'utf-8');
31
- const rawConfig = yaml_1.default.parse(configContent);
32
- const config = core_1.ConfigSchema.parse(rawConfig);
42
+ const configContent = await fs.readFile(configPath, 'utf-8');
43
+ const rawConfig = yaml.parse(configContent);
44
+ const config = ConfigSchema.parse(rawConfig);
33
45
  if (!options.ci && !options.json) {
34
- console.log(chalk_1.default.blue('Running Rigour checks...\n'));
46
+ console.log(chalk.blue('Running Rigour checks...\n'));
35
47
  }
36
- const runner = new core_1.GateRunner(config);
48
+ const runner = new GateRunner(config);
49
+ const requestId = randomUUID();
50
+ await logStudioEvent(cwd, {
51
+ type: "tool_call",
52
+ requestId,
53
+ tool: "rigour_check",
54
+ arguments: { files }
55
+ });
37
56
  const report = await runner.run(cwd, files.length > 0 ? files : undefined);
38
57
  // Write machine report
39
- const reportPath = path_1.default.join(cwd, config.output.report_path);
40
- await fs_extra_1.default.writeJson(reportPath, report, { spaces: 2 });
58
+ const reportPath = path.join(cwd, config.output.report_path);
59
+ await fs.writeJson(reportPath, report, { spaces: 2 });
60
+ await logStudioEvent(cwd, {
61
+ type: "tool_response",
62
+ requestId,
63
+ tool: "rigour_check",
64
+ status: report.status === 'PASS' ? 'success' : 'error',
65
+ content: [{ type: "text", text: `Audit Result: ${report.status}` }],
66
+ _rigour_report: report
67
+ });
41
68
  // Generate Fix Packet v2 on failure
42
69
  if (report.status === 'FAIL') {
43
70
  const { FixPacketService } = await import('@rigour-labs/core');
44
71
  const fixPacketService = new FixPacketService();
45
72
  const fixPacket = fixPacketService.generate(report, config);
46
- const fixPacketPath = path_1.default.join(cwd, 'rigour-fix-packet.json');
47
- await fs_extra_1.default.writeJson(fixPacketPath, fixPacket, { spaces: 2 });
73
+ const fixPacketPath = path.join(cwd, 'rigour-fix-packet.json');
74
+ await fs.writeJson(fixPacketPath, fixPacket, { spaces: 2 });
48
75
  }
49
76
  // JSON output mode
50
77
  if (options.json) {
@@ -70,25 +97,25 @@ async function checkCommand(cwd, files = [], options = {}) {
70
97
  }
71
98
  // Normal human-readable output
72
99
  if (report.status === 'PASS') {
73
- console.log(chalk_1.default.green.bold('✔ PASS - All quality gates satisfied.'));
100
+ console.log(chalk.green.bold('✔ PASS - All quality gates satisfied.'));
74
101
  }
75
102
  else {
76
- console.log(chalk_1.default.red.bold('✘ FAIL - Quality gate violations found.\n'));
103
+ console.log(chalk.red.bold('✘ FAIL - Quality gate violations found.\n'));
77
104
  for (const failure of report.failures) {
78
- console.log(chalk_1.default.red(`[${failure.id}] ${failure.title}`));
79
- console.log(chalk_1.default.dim(` Details: ${failure.details}`));
105
+ console.log(chalk.red(`[${failure.id}] ${failure.title}`));
106
+ console.log(chalk.dim(` Details: ${failure.details}`));
80
107
  if (failure.files && failure.files.length > 0) {
81
- console.log(chalk_1.default.dim(' Files:'));
82
- failure.files.forEach((f) => console.log(chalk_1.default.dim(` - ${f}`)));
108
+ console.log(chalk.dim(' Files:'));
109
+ failure.files.forEach((f) => console.log(chalk.dim(` - ${f}`)));
83
110
  }
84
111
  if (failure.hint) {
85
- console.log(chalk_1.default.cyan(` Hint: ${failure.hint}`));
112
+ console.log(chalk.cyan(` Hint: ${failure.hint}`));
86
113
  }
87
114
  console.log('');
88
115
  }
89
- console.log(chalk_1.default.yellow(`See ${config.output.report_path} for full details.`));
116
+ console.log(chalk.yellow(`See ${config.output.report_path} for full details.`));
90
117
  }
91
- console.log(chalk_1.default.dim(`\nFinished in ${report.stats.duration_ms}ms`));
118
+ console.log(chalk.dim(`\nFinished in ${report.stats.duration_ms}ms`));
92
119
  process.exit(report.status === 'PASS' ? EXIT_PASS : EXIT_FAIL);
93
120
  }
94
121
  catch (error) {
@@ -97,9 +124,9 @@ async function checkCommand(cwd, files = [], options = {}) {
97
124
  console.log(JSON.stringify({ error: 'CONFIG_ERROR', details: error.issues }));
98
125
  }
99
126
  else {
100
- console.error(chalk_1.default.red('\nInvalid rigour.yml configuration:'));
127
+ console.error(chalk.red('\nInvalid rigour.yml configuration:'));
101
128
  error.issues.forEach((issue) => {
102
- console.error(chalk_1.default.red(` • ${issue.path.join('.')}: ${issue.message}`));
129
+ console.error(chalk.red(` • ${issue.path.join('.')}: ${issue.message}`));
103
130
  });
104
131
  }
105
132
  process.exit(EXIT_CONFIG_ERROR);
@@ -108,24 +135,24 @@ async function checkCommand(cwd, files = [], options = {}) {
108
135
  console.log(JSON.stringify({ error: 'INTERNAL_ERROR', message: error.message }));
109
136
  }
110
137
  else if (!options.ci) {
111
- console.error(chalk_1.default.red(`Internal error: ${error.message}`));
138
+ console.error(chalk.red(`Internal error: ${error.message}`));
112
139
  }
113
140
  process.exit(EXIT_INTERNAL_ERROR);
114
141
  }
115
142
  }
116
143
  async function interactiveMode(report, config) {
117
144
  console.clear();
118
- console.log(chalk_1.default.bold.blue('══ Rigour Interactive Review ══\n'));
119
- console.log(chalk_1.default.yellow(`${report.failures.length} violations found.\n`));
145
+ console.log(chalk.bold.blue('══ Rigour Interactive Review ══\n'));
146
+ console.log(chalk.yellow(`${report.failures.length} violations found.\n`));
120
147
  const choices = report.failures.map((f, i) => ({
121
148
  name: `[${f.id}] ${f.title}`,
122
149
  value: i
123
150
  }));
124
- choices.push(new inquirer_1.default.Separator());
151
+ choices.push(new inquirer.Separator());
125
152
  choices.push({ name: 'Exit', value: -1 });
126
153
  let exit = false;
127
154
  while (!exit) {
128
- const { index } = await inquirer_1.default.prompt([
155
+ const { index } = await inquirer.prompt([
129
156
  {
130
157
  type: 'list',
131
158
  name: 'index',
@@ -140,19 +167,19 @@ async function interactiveMode(report, config) {
140
167
  }
141
168
  const failure = report.failures[index];
142
169
  console.clear();
143
- console.log(chalk_1.default.bold.red(`\nViolation: ${failure.title}`));
144
- console.log(chalk_1.default.dim(`ID: ${failure.id}`));
145
- console.log(`\n${chalk_1.default.bold('Details:')}\n${failure.details}`);
170
+ console.log(chalk.bold.red(`\nViolation: ${failure.title}`));
171
+ console.log(chalk.dim(`ID: ${failure.id}`));
172
+ console.log(`\n${chalk.bold('Details:')}\n${failure.details}`);
146
173
  if (failure.files && failure.files.length > 0) {
147
- console.log(`\n${chalk_1.default.bold('Impacted Files:')}`);
148
- failure.files.forEach((f) => console.log(chalk_1.default.dim(` - ${f}`)));
174
+ console.log(`\n${chalk.bold('Impacted Files:')}`);
175
+ failure.files.forEach((f) => console.log(chalk.dim(` - ${f}`)));
149
176
  }
150
177
  if (failure.hint) {
151
- console.log(`\n${chalk_1.default.bold.cyan('Hint:')} ${failure.hint}`);
178
+ console.log(`\n${chalk.bold.cyan('Hint:')} ${failure.hint}`);
152
179
  }
153
- console.log(chalk_1.default.dim('\n' + '─'.repeat(40)));
154
- await inquirer_1.default.prompt([{ type: 'input', name: 'continue', message: 'Press Enter to return to list...' }]);
180
+ console.log(chalk.dim('\n' + '─'.repeat(40)));
181
+ await inquirer.prompt([{ type: 'input', name: 'continue', message: 'Press Enter to return to list...' }]);
155
182
  console.clear();
156
- console.log(chalk_1.default.bold.blue('══ Rigour Interactive Review ══\n'));
183
+ console.log(chalk.bold.blue('══ Rigour Interactive Review ══\n'));
157
184
  }
158
185
  }
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AGNOSTIC_AI_INSTRUCTIONS = exports.COLLABORATION_RULES = exports.DEBUGGING_RULES = exports.CODE_QUALITY_RULES = void 0;
4
- exports.CODE_QUALITY_RULES = `
1
+ export const CODE_QUALITY_RULES = `
5
2
  # Code Quality Standards
6
3
 
7
4
  ## PRODUCTION-GRADE CODE ONLY
@@ -60,7 +57,7 @@ Before asking for "approval," internally verify:
60
57
  - **Cost Impact**: Does this change increase egress costs (e.g., unnecessary cross-region logging)?
61
58
  - **Error Handling**: Does the UI have a graceful fallback if the backend service is slow?
62
59
  `;
63
- exports.DEBUGGING_RULES = `
60
+ export const DEBUGGING_RULES = `
64
61
  # Investigation & Debugging Protocol
65
62
 
66
63
  ## INVESTIGATION PROTOCOL
@@ -109,7 +106,7 @@ Before proposing any fix:
109
106
  3. Trace the data flow that led to the error
110
107
  4. Verify the fix doesn't break other paths
111
108
  `;
112
- exports.COLLABORATION_RULES = `
109
+ export const COLLABORATION_RULES = `
113
110
  # Role & Collaboration
114
111
 
115
112
  You are a Senior Staff Engineer working alongside a Principal Engineer (the user).
@@ -186,7 +183,7 @@ If thresholds genuinely need adjustment, escalate to the team lead with justific
186
183
  8. ❌ Losing context between messages
187
184
  9. ❌ Modifying rigour.yml to pass quality checks
188
185
  `;
189
- exports.AGNOSTIC_AI_INSTRUCTIONS = `
186
+ export const AGNOSTIC_AI_INSTRUCTIONS = `
190
187
  # 🤖 CRITICAL INSTRUCTION FOR AI
191
188
 
192
189
  When asked to implement a feature or fix an issue:
@@ -1,73 +1,67 @@
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.explainCommand = explainCommand;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
- const path_1 = __importDefault(require("path"));
9
- const chalk_1 = __importDefault(require("chalk"));
10
- async function explainCommand(cwd) {
11
- const configPath = path_1.default.join(cwd, 'rigour.yml');
12
- let reportPath = path_1.default.join(cwd, 'rigour-report.json');
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ export async function explainCommand(cwd) {
5
+ const configPath = path.join(cwd, 'rigour.yml');
6
+ let reportPath = path.join(cwd, 'rigour-report.json');
13
7
  // Try to read custom path from config
14
- if (await fs_extra_1.default.pathExists(configPath)) {
8
+ if (await fs.pathExists(configPath)) {
15
9
  try {
16
10
  const yaml = await import('yaml');
17
- const configContent = await fs_extra_1.default.readFile(configPath, 'utf-8');
11
+ const configContent = await fs.readFile(configPath, 'utf-8');
18
12
  const config = yaml.parse(configContent);
19
13
  if (config?.output?.report_path) {
20
- reportPath = path_1.default.join(cwd, config.output.report_path);
14
+ reportPath = path.join(cwd, config.output.report_path);
21
15
  }
22
16
  }
23
17
  catch (e) { }
24
18
  }
25
- if (!(await fs_extra_1.default.pathExists(reportPath))) {
26
- console.error(chalk_1.default.red(`Error: No report found at ${reportPath}`));
27
- console.error(chalk_1.default.dim('Run `rigour check` first to generate a report.'));
19
+ if (!(await fs.pathExists(reportPath))) {
20
+ console.error(chalk.red(`Error: No report found at ${reportPath}`));
21
+ console.error(chalk.dim('Run `rigour check` first to generate a report.'));
28
22
  process.exit(2);
29
23
  }
30
24
  try {
31
- const reportContent = await fs_extra_1.default.readFile(reportPath, 'utf-8');
25
+ const reportContent = await fs.readFile(reportPath, 'utf-8');
32
26
  const report = JSON.parse(reportContent);
33
- console.log(chalk_1.default.bold('\n📋 Rigour Report Explanation\n'));
34
- console.log(chalk_1.default.bold('Status: ') + (report.status === 'PASS'
35
- ? chalk_1.default.green.bold('✅ PASS')
36
- : chalk_1.default.red.bold('🛑 FAIL')));
37
- console.log(chalk_1.default.bold('\nGate Summary:'));
27
+ console.log(chalk.bold('\n📋 Rigour Report Explanation\n'));
28
+ console.log(chalk.bold('Status: ') + (report.status === 'PASS'
29
+ ? chalk.green.bold('✅ PASS')
30
+ : chalk.red.bold('🛑 FAIL')));
31
+ console.log(chalk.bold('\nGate Summary:'));
38
32
  for (const [gate, status] of Object.entries(report.summary || {})) {
39
33
  const icon = status === 'PASS' ? '✅' : status === 'FAIL' ? '❌' : '⏭️';
40
34
  console.log(` ${icon} ${gate}: ${status}`);
41
35
  }
42
36
  if (report.failures && report.failures.length > 0) {
43
- console.log(chalk_1.default.bold.red(`\n🔧 ${report.failures.length} Violation(s) to Fix:\n`));
37
+ console.log(chalk.bold.red(`\n🔧 ${report.failures.length} Violation(s) to Fix:\n`));
44
38
  report.failures.forEach((failure, index) => {
45
- console.log(chalk_1.default.white(`${index + 1}. `) + chalk_1.default.bold.yellow(`[${failure.id.toUpperCase()}]`) + chalk_1.default.white(` ${failure.title}`));
46
- console.log(chalk_1.default.dim(` └─ ${failure.details}`));
39
+ console.log(chalk.white(`${index + 1}. `) + chalk.bold.yellow(`[${failure.id.toUpperCase()}]`) + chalk.white(` ${failure.title}`));
40
+ console.log(chalk.dim(` └─ ${failure.details}`));
47
41
  if (failure.files && failure.files.length > 0) {
48
- console.log(chalk_1.default.cyan(` 📁 Files: ${failure.files.join(', ')}`));
42
+ console.log(chalk.cyan(` 📁 Files: ${failure.files.join(', ')}`));
49
43
  }
50
44
  if (failure.hint) {
51
- console.log(chalk_1.default.green(` 💡 Hint: ${failure.hint}`));
45
+ console.log(chalk.green(` 💡 Hint: ${failure.hint}`));
52
46
  }
53
47
  console.log('');
54
48
  });
55
49
  }
56
50
  else if (report.status === 'PASS') {
57
- console.log(chalk_1.default.green('\n✨ All quality gates passed! No violations found.\n'));
51
+ console.log(chalk.green('\n✨ All quality gates passed! No violations found.\n'));
58
52
  }
59
53
  if (report.status === 'FAIL') {
60
- console.log(chalk_1.default.bold('\n👉 Next Steps:'));
61
- console.log(chalk_1.default.dim(' 1. Refactor the code to address the violations above.'));
62
- console.log(chalk_1.default.dim(' 2. Run `rigour check` again to verify your fixes.'));
63
- console.log(chalk_1.default.dim(' 3. If using an agent, pass it the violations as constraints.\n'));
54
+ console.log(chalk.bold('\n👉 Next Steps:'));
55
+ console.log(chalk.dim(' 1. Refactor the code to address the violations above.'));
56
+ console.log(chalk.dim(' 2. Run `rigour check` again to verify your fixes.'));
57
+ console.log(chalk.dim(' 3. If using an agent, pass it the violations as constraints.\n'));
64
58
  }
65
59
  if (report.stats) {
66
- console.log(chalk_1.default.dim(`Duration: ${report.stats.duration_ms}ms`));
60
+ console.log(chalk.dim(`Duration: ${report.stats.duration_ms}ms`));
67
61
  }
68
62
  }
69
63
  catch (error) {
70
- console.error(chalk_1.default.red(`Error reading report: ${error.message}`));
64
+ console.error(chalk.red(`Error reading report: ${error.message}`));
71
65
  process.exit(3);
72
66
  }
73
67
  }
@@ -1,22 +1,16 @@
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.guideCommand = guideCommand;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- async function guideCommand() {
9
- console.log(chalk_1.default.bold.cyan('\n🛡️ Rigour Labs | The Engineering Guide\n'));
10
- console.log(chalk_1.default.bold('Getting Started:'));
11
- console.log(chalk_1.default.dim(' 1. Run ') + chalk_1.default.cyan('rigour init') + chalk_1.default.dim(' to detect your project role and apply standards.'));
12
- console.log(chalk_1.default.dim(' 2. Run ') + chalk_1.default.cyan('rigour check') + chalk_1.default.dim(' to see existing violations.'));
13
- console.log(chalk_1.default.dim(' 3. Run ') + chalk_1.default.cyan('rigour run -- <your-agent-command>') + chalk_1.default.dim(' to automate the fix loop.\n'));
14
- console.log(chalk_1.default.bold('Key Concepts:'));
15
- console.log(chalk_1.default.yellow(' Fix Packet v2') + chalk_1.default.dim(': Structured diagnostics fed directly into AI agents.'));
16
- console.log(chalk_1.default.yellow(' • Safety Rails') + chalk_1.default.dim(': Prevents "explosive" refactoring (max files changed).'));
17
- console.log(chalk_1.default.yellow(' • Strategic Guardians') + chalk_1.default.dim(': Dependency and Architectural boundary enforcement.\n'));
18
- console.log(chalk_1.default.bold('Workflow Integration:'));
19
- console.log(chalk_1.default.green(' • Cursor') + chalk_1.default.dim(': Add the MCP server or use the ') + chalk_1.default.cyan('.cursor/rules/rigour.mdc') + chalk_1.default.dim(' handshake.'));
20
- console.log(chalk_1.default.green(' • CI/CD') + chalk_1.default.dim(': Use ') + chalk_1.default.cyan('rigour check --ci') + chalk_1.default.dim(' to fail PRs that violate quality gates.\n'));
21
- console.log(chalk_1.default.dim('For more detailed docs, visit: ') + chalk_1.default.underline('https://github.com/erashu212/rigour/docs\n'));
1
+ import chalk from 'chalk';
2
+ export async function guideCommand() {
3
+ console.log(chalk.bold.cyan('\n🛡️ Rigour Labs | The Engineering Guide\n'));
4
+ console.log(chalk.bold('Getting Started:'));
5
+ console.log(chalk.dim(' 1. Run ') + chalk.cyan('rigour init') + chalk.dim(' to detect your project role and apply standards.'));
6
+ console.log(chalk.dim(' 2. Run ') + chalk.cyan('rigour check') + chalk.dim(' to see existing violations.'));
7
+ console.log(chalk.dim(' 3. Run ') + chalk.cyan('rigour run -- <your-agent-command>') + chalk.dim(' to automate the fix loop.\n'));
8
+ console.log(chalk.bold('Key Concepts:'));
9
+ console.log(chalk.yellow(' • Fix Packet v2') + chalk.dim(': Structured diagnostics fed directly into AI agents.'));
10
+ console.log(chalk.yellow(' • Safety Rails') + chalk.dim(': Prevents "explosive" refactoring (max files changed).'));
11
+ console.log(chalk.yellow(' Strategic Guardians') + chalk.dim(': Dependency and Architectural boundary enforcement.\n'));
12
+ console.log(chalk.bold('Workflow Integration:'));
13
+ console.log(chalk.green(' • Cursor') + chalk.dim(': Add the MCP server or use the ') + chalk.cyan('.cursor/rules/rigour.mdc') + chalk.dim(' handshake.'));
14
+ console.log(chalk.green(' • CI/CD') + chalk.dim(': Use ') + chalk.cyan('rigour check --ci') + chalk.dim(' to fail PRs that violate quality gates.\n'));
15
+ console.log(chalk.dim('For more detailed docs, visit: ') + chalk.underline('https://github.com/erashu212/rigour/docs\n'));
22
16
  }
@@ -1,20 +1,34 @@
1
- "use strict";
2
1
  /**
3
2
  * Index Command
4
3
  *
5
4
  * Builds and updates the Rigour Pattern Index to prevent code reinvention.
6
5
  */
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.indexCommand = void 0;
12
- const commander_1 = require("commander");
13
- const chalk_1 = __importDefault(require("chalk"));
14
- const ora_1 = __importDefault(require("ora"));
6
+ import { Command } from 'commander';
7
+ import path from 'path';
8
+ import chalk from 'chalk';
9
+ import ora from 'ora';
10
+ import fs from 'fs-extra';
11
+ import { randomUUID } from 'crypto';
12
+ // Helper to log events for Rigour Studio
13
+ async function logStudioEvent(cwd, event) {
14
+ try {
15
+ const rigourDir = path.join(cwd, ".rigour");
16
+ await fs.ensureDir(rigourDir);
17
+ const eventsPath = path.join(rigourDir, "events.jsonl");
18
+ const logEntry = JSON.stringify({
19
+ id: randomUUID(),
20
+ timestamp: new Date().toISOString(),
21
+ ...event
22
+ }) + "\n";
23
+ await fs.appendFile(eventsPath, logEntry);
24
+ }
25
+ catch {
26
+ // Silent fail
27
+ }
28
+ }
15
29
  // Dynamic imports are used inside the action handler below to prevent
16
30
  // native dependency issues from affecting the rest of the CLI.
17
- exports.indexCommand = new commander_1.Command('index')
31
+ export const indexCommand = new Command('index')
18
32
  .description('Build or update the pattern index for the current project')
19
33
  .option('-s, --semantic', 'Generate semantic embeddings for better matching (requires Transformers.js)', false)
20
34
  .option('-f, --force', 'Force a full rebuild of the index', false)
@@ -24,8 +38,15 @@ exports.indexCommand = new commander_1.Command('index')
24
38
  // Dynamic import to isolate native dependencies
25
39
  const { PatternIndexer, savePatternIndex, loadPatternIndex, getDefaultIndexPath } = await import('@rigour-labs/core/pattern-index');
26
40
  const indexPath = options.output || getDefaultIndexPath(cwd);
27
- const spinner = (0, ora_1.default)('Initializing pattern indexer...').start();
41
+ const spinner = ora('Initializing pattern indexer...').start();
28
42
  try {
43
+ const requestId = randomUUID();
44
+ await logStudioEvent(cwd, {
45
+ type: "tool_call",
46
+ requestId,
47
+ tool: "rigour_index",
48
+ arguments: options
49
+ });
29
50
  const indexer = new PatternIndexer(cwd, {
30
51
  useEmbeddings: options.semantic
31
52
  });
@@ -41,20 +62,27 @@ exports.indexCommand = new commander_1.Command('index')
41
62
  }
42
63
  spinner.text = 'Saving index to disk...';
43
64
  await savePatternIndex(index, indexPath);
44
- spinner.succeed(chalk_1.default.green(`Pattern index built successfully!`));
45
- console.log(chalk_1.default.blue(`- Total Patterns: ${index.stats.totalPatterns}`));
46
- console.log(chalk_1.default.blue(`- Total Files: ${index.stats.totalFiles}`));
47
- console.log(chalk_1.default.blue(`- Index Path: ${indexPath}`));
65
+ spinner.succeed(chalk.green(`Pattern index built successfully!`));
66
+ await logStudioEvent(cwd, {
67
+ type: "tool_response",
68
+ requestId,
69
+ tool: "rigour_index",
70
+ status: "success",
71
+ content: [{ type: "text", text: `Index built: ${index.stats.totalPatterns} patterns` }]
72
+ });
73
+ console.log(chalk.blue(`- Total Patterns: ${index.stats.totalPatterns}`));
74
+ console.log(chalk.blue(`- Total Files: ${index.stats.totalFiles}`));
75
+ console.log(chalk.blue(`- Index Path: ${indexPath}`));
48
76
  if (options.semantic) {
49
- console.log(chalk_1.default.magenta(`- Semantic Search: Enabled (Local Transformers.js)`));
77
+ console.log(chalk.magenta(`- Semantic Search: Enabled (Local Transformers.js)`));
50
78
  }
51
79
  const byType = Object.entries(index.stats.byType)
52
80
  .map(([type, count]) => `${type}: ${count}`)
53
81
  .join(', ');
54
- console.log(chalk_1.default.gray(`Types: ${byType}`));
82
+ console.log(chalk.gray(`Types: ${byType}`));
55
83
  }
56
84
  catch (error) {
57
- spinner.fail(chalk_1.default.red(`Failed to build pattern index: ${error.message}`));
85
+ spinner.fail(chalk.red(`Failed to build pattern index: ${error.message}`));
58
86
  process.exit(1);
59
87
  }
60
88
  });