@rigour-labs/cli 2.9.4 → 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.
@@ -1,42 +1,54 @@
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.initCommand = initCommand;
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 constants_js_1 = require("./constants.js");
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import yaml from 'yaml';
5
+ import { DiscoveryService } from '@rigour-labs/core';
6
+ import { CODE_QUALITY_RULES, DEBUGGING_RULES, COLLABORATION_RULES, AGNOSTIC_AI_INSTRUCTIONS } from './constants.js';
7
+ import { randomUUID } from 'crypto';
8
+ // Helper to log events for Rigour Studio
9
+ async function logStudioEvent(cwd, event) {
10
+ try {
11
+ const rigourDir = path.join(cwd, ".rigour");
12
+ await fs.ensureDir(rigourDir);
13
+ const eventsPath = path.join(rigourDir, "events.jsonl");
14
+ const logEntry = JSON.stringify({
15
+ id: randomUUID(),
16
+ timestamp: new Date().toISOString(),
17
+ ...event
18
+ }) + "\n";
19
+ await fs.appendFile(eventsPath, logEntry);
20
+ }
21
+ catch {
22
+ // Silent fail
23
+ }
24
+ }
13
25
  function detectIDE(cwd) {
14
26
  // Check for Claude Code markers
15
- if (fs_extra_1.default.existsSync(path_1.default.join(cwd, 'CLAUDE.md')) || fs_extra_1.default.existsSync(path_1.default.join(cwd, '.claude'))) {
27
+ if (fs.existsSync(path.join(cwd, 'CLAUDE.md')) || fs.existsSync(path.join(cwd, '.claude'))) {
16
28
  return 'claude';
17
29
  }
18
30
  // Check for Gemini Code Assist markers
19
- if (fs_extra_1.default.existsSync(path_1.default.join(cwd, '.gemini'))) {
31
+ if (fs.existsSync(path.join(cwd, '.gemini'))) {
20
32
  return 'gemini';
21
33
  }
22
34
  // Check for Codex/Aider AGENTS.md (universal standard)
23
- if (fs_extra_1.default.existsSync(path_1.default.join(cwd, 'AGENTS.md'))) {
35
+ if (fs.existsSync(path.join(cwd, 'AGENTS.md'))) {
24
36
  return 'codex';
25
37
  }
26
38
  // Check for Windsurf markers
27
- if (fs_extra_1.default.existsSync(path_1.default.join(cwd, '.windsurfrules')) || fs_extra_1.default.existsSync(path_1.default.join(cwd, '.windsurf'))) {
39
+ if (fs.existsSync(path.join(cwd, '.windsurfrules')) || fs.existsSync(path.join(cwd, '.windsurf'))) {
28
40
  return 'windsurf';
29
41
  }
30
42
  // Check for Cline-specific markers
31
- if (fs_extra_1.default.existsSync(path_1.default.join(cwd, '.clinerules'))) {
43
+ if (fs.existsSync(path.join(cwd, '.clinerules'))) {
32
44
  return 'cline';
33
45
  }
34
46
  // Check for Cursor-specific markers
35
- if (fs_extra_1.default.existsSync(path_1.default.join(cwd, '.cursor'))) {
47
+ if (fs.existsSync(path.join(cwd, '.cursor'))) {
36
48
  return 'cursor';
37
49
  }
38
50
  // Check for VS Code markers
39
- if (fs_extra_1.default.existsSync(path_1.default.join(cwd, '.vscode'))) {
51
+ if (fs.existsSync(path.join(cwd, '.vscode'))) {
40
52
  return 'vscode';
41
53
  }
42
54
  // Check environment variables that IDEs/Agents set
@@ -62,8 +74,8 @@ function detectIDE(cwd) {
62
74
  }
63
75
  return 'unknown';
64
76
  }
65
- async function initCommand(cwd, options = {}) {
66
- const discovery = new core_1.DiscoveryService();
77
+ export async function initCommand(cwd, options = {}) {
78
+ const discovery = new DiscoveryService();
67
79
  const result = await discovery.discover(cwd);
68
80
  let recommendedConfig = result.config;
69
81
  // Override with user options if provided and re-apply template logic if necessary
@@ -97,33 +109,40 @@ async function initCommand(cwd, options = {}) {
97
109
  recommendedConfig.paradigm = options.paradigm;
98
110
  }
99
111
  if (options.dryRun || options.explain) {
100
- console.log(chalk_1.default.bold.blue('\nšŸ” Rigour Auto-Discovery (Dry Run):'));
112
+ console.log(chalk.bold.blue('\nšŸ” Rigour Auto-Discovery (Dry Run):'));
101
113
  if (recommendedConfig.preset) {
102
- console.log(chalk_1.default.cyan(` Role: `) + chalk_1.default.bold(recommendedConfig.preset.toUpperCase()));
114
+ console.log(chalk.cyan(` Role: `) + chalk.bold(recommendedConfig.preset.toUpperCase()));
103
115
  if (options.explain && result.matches.preset) {
104
- console.log(chalk_1.default.dim(` (Marker found: ${result.matches.preset.marker})`));
116
+ console.log(chalk.dim(` (Marker found: ${result.matches.preset.marker})`));
105
117
  }
106
118
  }
107
119
  if (recommendedConfig.paradigm) {
108
- console.log(chalk_1.default.cyan(` Paradigm: `) + chalk_1.default.bold(recommendedConfig.paradigm.toUpperCase()));
120
+ console.log(chalk.cyan(` Paradigm: `) + chalk.bold(recommendedConfig.paradigm.toUpperCase()));
109
121
  if (options.explain && result.matches.paradigm) {
110
- console.log(chalk_1.default.dim(` (Marker found: ${result.matches.paradigm.marker})`));
122
+ console.log(chalk.dim(` (Marker found: ${result.matches.paradigm.marker})`));
111
123
  }
112
124
  }
113
- console.log(chalk_1.default.yellow('\n[DRY RUN] No files will be written.'));
125
+ console.log(chalk.yellow('\n[DRY RUN] No files will be written.'));
114
126
  return;
115
127
  }
116
- const configPath = path_1.default.join(cwd, 'rigour.yml');
117
- if (await fs_extra_1.default.pathExists(configPath)) {
118
- console.log(chalk_1.default.yellow('rigour.yml already exists. Skipping initialization.'));
128
+ const configPath = path.join(cwd, 'rigour.yml');
129
+ if (await fs.pathExists(configPath)) {
130
+ console.log(chalk.yellow('rigour.yml already exists. Skipping initialization.'));
119
131
  return;
120
132
  }
121
- console.log(chalk_1.default.bold.blue('\nšŸ” Rigour Auto-Discovery:'));
133
+ console.log(chalk.bold.blue('\nšŸ” Rigour Auto-Discovery:'));
134
+ const requestId = randomUUID();
135
+ await logStudioEvent(cwd, {
136
+ type: "tool_call",
137
+ requestId,
138
+ tool: "rigour_init",
139
+ arguments: options
140
+ });
122
141
  if (recommendedConfig.preset) {
123
- console.log(chalk_1.default.cyan(` Role: `) + chalk_1.default.bold(recommendedConfig.preset.toUpperCase()));
142
+ console.log(chalk.cyan(` Role: `) + chalk.bold(recommendedConfig.preset.toUpperCase()));
124
143
  }
125
144
  if (recommendedConfig.paradigm) {
126
- console.log(chalk_1.default.cyan(` Paradigm: `) + chalk_1.default.bold(recommendedConfig.paradigm.toUpperCase()));
145
+ console.log(chalk.cyan(` Paradigm: `) + chalk.bold(recommendedConfig.paradigm.toUpperCase()));
127
146
  }
128
147
  console.log('');
129
148
  const yamlHeader = `# āš ļø TEAM STANDARD - DO NOT MODIFY WITHOUT TEAM APPROVAL
@@ -132,90 +151,86 @@ async function initCommand(cwd, options = {}) {
132
151
  # See: docs/AGENT_INSTRUCTIONS.md for the correct workflow.
133
152
 
134
153
  `;
135
- await fs_extra_1.default.writeFile(configPath, yamlHeader + yaml_1.default.stringify(recommendedConfig));
136
- console.log(chalk_1.default.green('āœ” Created rigour.yml'));
154
+ await fs.writeFile(configPath, yamlHeader + yaml.stringify(recommendedConfig));
155
+ console.log(chalk.green('āœ” Created rigour.yml'));
137
156
  // Create required directories and files
138
157
  const requireddocs = recommendedConfig.gates.required_files || [];
139
158
  for (const file of requireddocs) {
140
- const filePath = path_1.default.join(cwd, file);
141
- if (!(await fs_extra_1.default.pathExists(filePath))) {
142
- await fs_extra_1.default.ensureFile(filePath);
143
- console.log(chalk_1.default.dim(` - Created ${file}`));
159
+ const filePath = path.join(cwd, file);
160
+ if (!(await fs.pathExists(filePath))) {
161
+ await fs.ensureDir(path.dirname(filePath)); // Ensure parent directory exists
162
+ await fs.ensureFile(filePath);
163
+ console.log(chalk.dim(` - Created ${file}`));
144
164
  }
145
165
  }
146
166
  // Agent Handshake (Universal / AntiGravity / Cursor)
147
- const rigourDocsDir = path_1.default.join(cwd, 'docs');
148
- await fs_extra_1.default.ensureDir(rigourDocsDir);
149
- const instructionsPath = path_1.default.join(rigourDocsDir, 'AGENT_INSTRUCTIONS.md');
150
- const ruleContent = `# šŸ›”ļø Rigour: Engineering Excellence Protocol
151
-
152
- You are an Elite Software Engineer. You do not just write code that "works"; you write code that is **modular, maintainable, and rigorously verified.**
153
-
154
- ## 🚦 The Rigour Loop (Mandatory)
155
- Before claiming "Done" for any task, you MUST follow this loop:
167
+ const rigourDocsDir = path.join(cwd, 'docs');
168
+ await fs.ensureDir(rigourDocsDir);
169
+ const instructionsPath = path.join(rigourDocsDir, 'AGENT_INSTRUCTIONS.md');
170
+ const ruleContent = `# šŸ›”ļø Rigour: Mandatory Engineering Governance Protocol
156
171
 
157
- 1. **Check**: Run \`npx @rigour-labs/cli check\` to verify compliance.
158
- 2. **Analyze**: If it fails, read \`rigour-fix-packet.json\` (V2 High-Fidelity) for exact failure points and constraints.
159
- 3. **Refactor**: Apply **SOLID** and **DRY** principles to resolve the violations according to constraints.
160
- 4. **Repeat**: Continue until \`npx @rigour-labs/cli check\` returns **PASS**.
172
+ **You are an AI Engineering Agent governed by Rigour.**
161
173
 
162
- ## šŸ› ļø Commands
163
- \`\`\`bash
164
- # Verify current state
165
- npx @rigour-labs/cli check
174
+ Your access to this codebase is conditional upon your strict adherence to the **Rigour Governance Protocol**. This is an automated requirement for every engineering task.
166
175
 
167
- # Self-healing agent loop
168
- npx @rigour-labs/cli run -- <agent-command>
169
- \`\`\`
176
+ ## 🚦 The Mandatory Governance Loop
177
+ You MUST execute this loop for every task. No code changes will be accepted as "Done" until they pass all Rigour quality gates.
170
178
 
171
- ${constants_js_1.AGNOSTIC_AI_INSTRUCTIONS}
172
- ${constants_js_1.CODE_QUALITY_RULES}
179
+ 1. **Context Loading**: Call \`rigour_recall\` (MCP) to align with project-specific engineering memory.
180
+ 2. **Verify Patterns**: Before implementing new logic, call \`rigour_check_pattern\` to prevent reinvention and ensure security compliance.
181
+ 3. **Audit Enforcement**: Before finishing, you MUST call \`npx @rigour-labs/cli check\`.
182
+ 4. **Failure Remediation**: If the check returns **FAIL**, you MUST implement all required engineering refinements.
183
+ 5. **PASS or REJECT**: You may only declare a task complete when the check returns **PASS**.
173
184
 
174
- ${constants_js_1.DEBUGGING_RULES}
185
+ ## āš–ļø Transparency & Accountability
186
+ **Every action, tool call, and logic shift you perform is automatically logged to the project's local audit trail.** This data is visible in real-time in the human-monitored **Rigour Studio**.
175
187
 
176
- ${constants_js_1.COLLABORATION_RULES}
188
+ ${AGNOSTIC_AI_INSTRUCTIONS}
189
+ ${CODE_QUALITY_RULES}
190
+ ${DEBUGGING_RULES}
191
+ ${COLLABORATION_RULES}
177
192
  `;
178
193
  // 1. Create Universal Instructions
179
- if (!(await fs_extra_1.default.pathExists(instructionsPath))) {
180
- await fs_extra_1.default.writeFile(instructionsPath, ruleContent);
181
- console.log(chalk_1.default.green('āœ” Initialized Universal Agent Handshake (docs/AGENT_INSTRUCTIONS.md)'));
194
+ if (!(await fs.pathExists(instructionsPath))) {
195
+ await fs.writeFile(instructionsPath, ruleContent);
196
+ console.log(chalk.green('āœ” Initialized Universal Agent Handshake (docs/AGENT_INSTRUCTIONS.md)'));
182
197
  }
183
198
  // 2. Create IDE-Specific Rules based on detection or user preference
184
199
  const detectedIDE = detectIDE(cwd);
185
200
  const targetIDE = options.ide || (detectedIDE !== 'unknown' ? detectedIDE : 'all');
186
201
  if (detectedIDE !== 'unknown' && !options.ide) {
187
- console.log(chalk_1.default.dim(` (Auto-detected IDE: ${detectedIDE})`));
202
+ console.log(chalk.dim(` (Auto-detected IDE: ${detectedIDE})`));
188
203
  }
189
204
  if (targetIDE === 'cursor' || targetIDE === 'all') {
190
- const cursorRulesDir = path_1.default.join(cwd, '.cursor', 'rules');
191
- await fs_extra_1.default.ensureDir(cursorRulesDir);
192
- const mdcPath = path_1.default.join(cursorRulesDir, 'rigour.mdc');
205
+ const cursorRulesDir = path.join(cwd, '.cursor', 'rules');
206
+ await fs.ensureDir(cursorRulesDir);
207
+ const mdcPath = path.join(cursorRulesDir, 'rigour.mdc');
193
208
  const mdcContent = `---
194
209
  description: Enforcement of Rigour quality gates and best practices.
195
210
  globs: **/*
196
211
  ---
197
212
 
198
213
  ${ruleContent}`;
199
- if (!(await fs_extra_1.default.pathExists(mdcPath))) {
200
- await fs_extra_1.default.writeFile(mdcPath, mdcContent);
201
- console.log(chalk_1.default.green('āœ” Initialized Cursor Handshake (.cursor/rules/rigour.mdc)'));
214
+ if (!(await fs.pathExists(mdcPath))) {
215
+ await fs.writeFile(mdcPath, mdcContent);
216
+ console.log(chalk.green('āœ” Initialized Cursor Handshake (.cursor/rules/rigour.mdc)'));
202
217
  }
203
218
  }
204
219
  if (targetIDE === 'vscode' || targetIDE === 'all') {
205
220
  // VS Code users use the universal AGENT_INSTRUCTIONS.md (already created above)
206
221
  // We could also add .vscode/settings.json or snippets here if needed
207
- console.log(chalk_1.default.green('āœ” VS Code mode - using Universal Handshake (docs/AGENT_INSTRUCTIONS.md)'));
222
+ console.log(chalk.green('āœ” VS Code mode - using Universal Handshake (docs/AGENT_INSTRUCTIONS.md)'));
208
223
  }
209
224
  if (targetIDE === 'cline' || targetIDE === 'all') {
210
- const clineRulesPath = path_1.default.join(cwd, '.clinerules');
211
- if (!(await fs_extra_1.default.pathExists(clineRulesPath))) {
212
- await fs_extra_1.default.writeFile(clineRulesPath, ruleContent);
213
- console.log(chalk_1.default.green('āœ” Initialized Cline Handshake (.clinerules)'));
225
+ const clineRulesPath = path.join(cwd, '.clinerules');
226
+ if (!(await fs.pathExists(clineRulesPath))) {
227
+ await fs.writeFile(clineRulesPath, ruleContent);
228
+ console.log(chalk.green('āœ” Initialized Cline Handshake (.clinerules)'));
214
229
  }
215
230
  }
216
231
  // Claude Code (CLAUDE.md)
217
232
  if (targetIDE === 'claude' || targetIDE === 'all') {
218
- const claudePath = path_1.default.join(cwd, 'CLAUDE.md');
233
+ const claudePath = path.join(cwd, 'CLAUDE.md');
219
234
  const claudeContent = `# CLAUDE.md - Project Instructions for Claude Code
220
235
 
221
236
  This file provides Claude Code with context about this project.
@@ -238,16 +253,16 @@ npx @rigour-labs/cli run -- claude "<task>"
238
253
  \`\`\`
239
254
 
240
255
  ${ruleContent}`;
241
- if (!(await fs_extra_1.default.pathExists(claudePath))) {
242
- await fs_extra_1.default.writeFile(claudePath, claudeContent);
243
- console.log(chalk_1.default.green('āœ” Initialized Claude Code Handshake (CLAUDE.md)'));
256
+ if (!(await fs.pathExists(claudePath))) {
257
+ await fs.writeFile(claudePath, claudeContent);
258
+ console.log(chalk.green('āœ” Initialized Claude Code Handshake (CLAUDE.md)'));
244
259
  }
245
260
  }
246
261
  // Gemini Code Assist (.gemini/styleguide.md)
247
262
  if (targetIDE === 'gemini' || targetIDE === 'all') {
248
- const geminiDir = path_1.default.join(cwd, '.gemini');
249
- await fs_extra_1.default.ensureDir(geminiDir);
250
- const geminiStylePath = path_1.default.join(geminiDir, 'styleguide.md');
263
+ const geminiDir = path.join(cwd, '.gemini');
264
+ await fs.ensureDir(geminiDir);
265
+ const geminiStylePath = path.join(geminiDir, 'styleguide.md');
251
266
  const geminiContent = `# Gemini Code Assist Style Guide
252
267
 
253
268
  This project uses Rigour for quality gates.
@@ -257,14 +272,14 @@ This project uses Rigour for quality gates.
257
272
  Always run \`npx @rigour-labs/cli check\` before marking any task complete.
258
273
 
259
274
  ${ruleContent}`;
260
- if (!(await fs_extra_1.default.pathExists(geminiStylePath))) {
261
- await fs_extra_1.default.writeFile(geminiStylePath, geminiContent);
262
- console.log(chalk_1.default.green('āœ” Initialized Gemini Handshake (.gemini/styleguide.md)'));
275
+ if (!(await fs.pathExists(geminiStylePath))) {
276
+ await fs.writeFile(geminiStylePath, geminiContent);
277
+ console.log(chalk.green('āœ” Initialized Gemini Handshake (.gemini/styleguide.md)'));
263
278
  }
264
279
  }
265
280
  // OpenAI Codex / Aider (AGENTS.md - Universal Standard)
266
281
  if (targetIDE === 'codex' || targetIDE === 'all') {
267
- const agentsPath = path_1.default.join(cwd, 'AGENTS.md');
282
+ const agentsPath = path.join(cwd, 'AGENTS.md');
268
283
  const agentsContent = `# AGENTS.md - Universal AI Agent Instructions
269
284
 
270
285
  This file provides instructions for AI coding agents (Codex, Aider, and others).
@@ -286,40 +301,62 @@ npx @rigour-labs/cli check
286
301
  \`\`\`
287
302
 
288
303
  ${ruleContent}`;
289
- if (!(await fs_extra_1.default.pathExists(agentsPath))) {
290
- await fs_extra_1.default.writeFile(agentsPath, agentsContent);
291
- console.log(chalk_1.default.green('āœ” Initialized Universal Agent Handshake (AGENTS.md)'));
304
+ if (!(await fs.pathExists(agentsPath))) {
305
+ await fs.writeFile(agentsPath, agentsContent);
306
+ console.log(chalk.green('āœ” Initialized Universal Agent Handshake (AGENTS.md)'));
292
307
  }
293
308
  }
294
309
  // Windsurf (.windsurfrules)
295
310
  if (targetIDE === 'windsurf' || targetIDE === 'all') {
296
- const windsurfPath = path_1.default.join(cwd, '.windsurfrules');
297
- if (!(await fs_extra_1.default.pathExists(windsurfPath))) {
298
- await fs_extra_1.default.writeFile(windsurfPath, ruleContent);
299
- console.log(chalk_1.default.green('āœ” Initialized Windsurf Handshake (.windsurfrules)'));
311
+ const windsurfPath = path.join(cwd, '.windsurfrules');
312
+ if (!(await fs.pathExists(windsurfPath))) {
313
+ await fs.writeFile(windsurfPath, ruleContent);
314
+ console.log(chalk.green('āœ” Initialized Windsurf Handshake (.windsurfrules)'));
300
315
  }
301
316
  }
302
317
  // 3. Update .gitignore
303
- const gitignorePath = path_1.default.join(cwd, '.gitignore');
318
+ const gitignorePath = path.join(cwd, '.gitignore');
304
319
  const ignorePatterns = ['rigour-report.json', 'rigour-fix-packet.json', '.rigour/'];
305
320
  try {
306
321
  let content = '';
307
- if (await fs_extra_1.default.pathExists(gitignorePath)) {
308
- content = await fs_extra_1.default.readFile(gitignorePath, 'utf-8');
322
+ if (await fs.pathExists(gitignorePath)) {
323
+ content = await fs.readFile(gitignorePath, 'utf-8');
309
324
  }
310
325
  const toAdd = ignorePatterns.filter(p => !content.includes(p));
311
326
  if (toAdd.length > 0) {
312
327
  const separator = content.endsWith('\n') ? '' : '\n';
313
328
  const newContent = `${content}${separator}\n# Rigour Artifacts\n${toAdd.join('\n')}\n`;
314
- await fs_extra_1.default.writeFile(gitignorePath, newContent);
315
- console.log(chalk_1.default.green('āœ” Updated .gitignore'));
329
+ await fs.writeFile(gitignorePath, newContent);
330
+ console.log(chalk.green('āœ” Updated .gitignore'));
316
331
  }
317
332
  }
318
333
  catch (e) {
319
334
  // Failing to update .gitignore isn't fatal
320
335
  }
321
- console.log(chalk_1.default.blue('\nRigour is ready. Run `npx @rigour-labs/cli check` to verify your project.'));
322
- console.log(chalk_1.default.dim('\nšŸ’” Tip: Planning to use a framework like Next.js?'));
323
- console.log(chalk_1.default.dim(' Run its scaffolding tool (e.g., npx create-next-app) BEFORE rigour init,'));
324
- console.log(chalk_1.default.dim(' or move rigour.yml and docs/ aside temporarily to satisfy empty-directory checks.'));
336
+ console.log(chalk.blue('\nRigour is ready. Run `npx @rigour-labs/cli check` to verify your project.'));
337
+ console.log(chalk.cyan('Next Step: ') + chalk.bold('rigour index') + chalk.dim(' (Populate the Pattern Index)'));
338
+ // Bootstrap initial memory for the Studio
339
+ const rigourDir = path.join(cwd, ".rigour");
340
+ await fs.ensureDir(rigourDir);
341
+ const memPath = path.join(rigourDir, "memory.json");
342
+ if (!(await fs.pathExists(memPath))) {
343
+ await fs.writeJson(memPath, {
344
+ memories: {
345
+ "project_boot": {
346
+ value: `Governance initiated via '${options.preset || 'api'}' preset. This project is now monitored by Rigour Studio.`,
347
+ timestamp: new Date().toISOString()
348
+ }
349
+ }
350
+ }, { spaces: 2 });
351
+ }
352
+ console.log(chalk.dim('\nšŸ’” Tip: Planning to use a framework like Next.js?'));
353
+ console.log(chalk.dim(' Run its scaffolding tool (e.g., npx create-next-app) BEFORE rigour init,'));
354
+ console.log(chalk.dim(' or move rigour.yml and docs/ aside temporarily to satisfy empty-directory checks.'));
355
+ await logStudioEvent(cwd, {
356
+ type: "tool_response",
357
+ requestId,
358
+ tool: "rigour_init",
359
+ status: "success",
360
+ content: [{ type: "text", text: `Rigour Governance Initialized` }]
361
+ });
325
362
  }
@@ -1,49 +1,43 @@
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.runLoop = runLoop;
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 execa_1 = require("execa");
12
- const core_1 = require("@rigour-labs/core");
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import yaml from 'yaml';
5
+ import { execa } from 'execa';
6
+ import { GateRunner, ConfigSchema } from '@rigour-labs/core';
13
7
  // Exit codes per spec
14
8
  const EXIT_PASS = 0;
15
9
  const EXIT_FAIL = 1;
16
10
  const EXIT_CONFIG_ERROR = 2;
17
11
  const EXIT_INTERNAL_ERROR = 3;
18
- async function runLoop(cwd, agentArgs, options) {
19
- const configPath = path_1.default.join(cwd, 'rigour.yml');
20
- if (!(await fs_extra_1.default.pathExists(configPath))) {
21
- console.error(chalk_1.default.red('Error: rigour.yml not found. Run `rigour init` first.'));
12
+ export async function runLoop(cwd, agentArgs, options) {
13
+ const configPath = path.join(cwd, 'rigour.yml');
14
+ if (!(await fs.pathExists(configPath))) {
15
+ console.error(chalk.red('Error: rigour.yml not found. Run `rigour init` first.'));
22
16
  process.exit(EXIT_CONFIG_ERROR);
23
17
  }
24
18
  try {
25
- const configContent = await fs_extra_1.default.readFile(configPath, 'utf-8');
26
- const rawConfig = yaml_1.default.parse(configContent);
27
- const config = core_1.ConfigSchema.parse(rawConfig);
28
- const runner = new core_1.GateRunner(config);
19
+ const configContent = await fs.readFile(configPath, 'utf-8');
20
+ const rawConfig = yaml.parse(configContent);
21
+ const config = ConfigSchema.parse(rawConfig);
22
+ const runner = new GateRunner(config);
29
23
  let iteration = 0;
30
24
  const maxIterations = options.iterations;
31
25
  while (iteration < maxIterations) {
32
26
  iteration++;
33
- console.log(chalk_1.default.bold.blue(`\n══════════════════════════════════════════════════════════════════`));
34
- console.log(chalk_1.default.bold.blue(` RIGOUR LOOP: Iteration ${iteration}/${maxIterations}`));
35
- console.log(chalk_1.default.bold.blue(`══════════════════════════════════════════════════════════════════`));
27
+ console.log(chalk.bold.blue(`\n══════════════════════════════════════════════════════════════════`));
28
+ console.log(chalk.bold.blue(` RIGOUR LOOP: Iteration ${iteration}/${maxIterations}`));
29
+ console.log(chalk.bold.blue(`══════════════════════════════════════════════════════════════════`));
36
30
  // 1. Prepare Command
37
31
  let currentArgs = [...agentArgs];
38
32
  if (iteration > 1 && agentArgs.length > 0) {
39
33
  // Iteration contract: In later cycles, we focus strictly on the fix packet
40
- console.log(chalk_1.default.yellow(`\nšŸ”„ REFINEMENT CYCLE - Instructing agent to fix specific violations...`));
34
+ console.log(chalk.yellow(`\nšŸ”„ REFINEMENT CYCLE - Instructing agent to fix specific violations...`));
41
35
  // We keep the first part of the command (the agent) but can append or wrap
42
36
  // For simplicity, we assume the agent can read the JSON file we generate
43
37
  }
44
38
  const getTrackedChanges = async () => {
45
39
  try {
46
- const { stdout } = await (0, execa_1.execa)('git', ['status', '--porcelain'], { cwd });
40
+ const { stdout } = await execa('git', ['status', '--porcelain'], { cwd });
47
41
  return stdout.split('\n')
48
42
  .filter(l => l.trim())
49
43
  .filter(line => /M|A|D|R/.test(line.slice(0, 2)))
@@ -57,13 +51,13 @@ async function runLoop(cwd, agentArgs, options) {
57
51
  const beforeFiles = await getTrackedChanges();
58
52
  // 2. Run the agent command
59
53
  if (currentArgs.length > 0) {
60
- console.log(chalk_1.default.cyan(`\nšŸš€ DEPLOYING AGENT:`));
61
- console.log(chalk_1.default.dim(` Command: ${currentArgs.join(' ')}`));
54
+ console.log(chalk.cyan(`\nšŸš€ DEPLOYING AGENT:`));
55
+ console.log(chalk.dim(` Command: ${currentArgs.join(' ')}`));
62
56
  try {
63
- await (0, execa_1.execa)(currentArgs[0], currentArgs.slice(1), { shell: true, stdio: 'inherit', cwd });
57
+ await execa(currentArgs[0], currentArgs.slice(1), { shell: true, stdio: 'inherit', cwd });
64
58
  }
65
59
  catch (error) {
66
- console.warn(chalk_1.default.yellow(`\nāš ļø Agent command finished with non-zero exit code. Rigour will now verify state...`));
60
+ console.warn(chalk.yellow(`\nāš ļø Agent command finished with non-zero exit code. Rigour will now verify state...`));
67
61
  }
68
62
  }
69
63
  // Snapshot changed files after agent runs
@@ -71,51 +65,51 @@ async function runLoop(cwd, agentArgs, options) {
71
65
  const changedThisCycle = afterFiles.filter(f => !beforeFiles.includes(f));
72
66
  const maxFiles = config.gates.safety?.max_files_changed_per_cycle || 10;
73
67
  if (changedThisCycle.length > maxFiles) {
74
- console.log(chalk_1.default.red.bold(`\nšŸ›‘ SAFETY RAIL ABORT: Agent changed ${changedThisCycle.length} files (max: ${maxFiles}).`));
75
- console.log(chalk_1.default.red(` This looks like explosive behavior. Check your agent's instructions.`));
68
+ console.log(chalk.red.bold(`\nšŸ›‘ SAFETY RAIL ABORT: Agent changed ${changedThisCycle.length} files (max: ${maxFiles}).`));
69
+ console.log(chalk.red(` This looks like explosive behavior. Check your agent's instructions.`));
76
70
  process.exit(EXIT_FAIL);
77
71
  }
78
72
  // 3. Run Rigour Check
79
- console.log(chalk_1.default.magenta('\nšŸ” AUDITING QUALITY GATES...'));
73
+ console.log(chalk.magenta('\nšŸ” AUDITING QUALITY GATES...'));
80
74
  const report = await runner.run(cwd);
81
75
  // Write report
82
- const reportPath = path_1.default.join(cwd, config.output.report_path);
83
- await fs_extra_1.default.writeJson(reportPath, report, { spaces: 2 });
76
+ const reportPath = path.join(cwd, config.output.report_path);
77
+ await fs.writeJson(reportPath, report, { spaces: 2 });
84
78
  if (report.status === 'PASS') {
85
- console.log(chalk_1.default.green.bold('\n✨ PASS - All quality gates satisfied.'));
86
- console.log(chalk_1.default.green(` Your solution meets the required Engineering Rigour criteria.\n`));
79
+ console.log(chalk.green.bold('\n✨ PASS - All quality gates satisfied.'));
80
+ console.log(chalk.green(` Your solution meets the required Engineering Rigour criteria.\n`));
87
81
  return;
88
82
  }
89
83
  // 4. Generate Fix Packet v2
90
84
  const { FixPacketService } = await import('@rigour-labs/core');
91
85
  const fixPacketService = new FixPacketService();
92
86
  const fixPacket = fixPacketService.generate(report, config);
93
- const fixPacketPath = path_1.default.join(cwd, 'rigour-fix-packet.json');
94
- await fs_extra_1.default.writeJson(fixPacketPath, fixPacket, { spaces: 2 });
95
- console.log(chalk_1.default.red.bold(`\nšŸ›‘ FAIL - Found ${report.failures.length} engineering violations.`));
96
- console.log(chalk_1.default.dim(` Fix Packet generated: rigour-fix-packet.json`));
87
+ const fixPacketPath = path.join(cwd, 'rigour-fix-packet.json');
88
+ await fs.writeJson(fixPacketPath, fixPacket, { spaces: 2 });
89
+ console.log(chalk.red.bold(`\nšŸ›‘ FAIL - Found ${report.failures.length} engineering violations.`));
90
+ console.log(chalk.dim(` Fix Packet generated: rigour-fix-packet.json`));
97
91
  if (options.failFast) {
98
- console.log(chalk_1.default.red.bold(`\nšŸ›‘ FAIL-FAST: Aborting loop as requested.`));
92
+ console.log(chalk.red.bold(`\nšŸ›‘ FAIL-FAST: Aborting loop as requested.`));
99
93
  process.exit(EXIT_FAIL);
100
94
  }
101
95
  // Print summary
102
96
  const summary = report.failures.map((f, i) => {
103
- return chalk_1.default.white(`${i + 1}. `) + chalk_1.default.bold.red(`[${f.id.toUpperCase()}] `) + chalk_1.default.white(f.title);
97
+ return chalk.white(`${i + 1}. `) + chalk.bold.red(`[${f.id.toUpperCase()}] `) + chalk.white(f.title);
104
98
  }).join('\n');
105
- console.log(chalk_1.default.bold.white('\nšŸ“‹ VIOLATIONS SUMMARY:'));
99
+ console.log(chalk.bold.white('\nšŸ“‹ VIOLATIONS SUMMARY:'));
106
100
  console.log(summary);
107
101
  if (iteration === maxIterations) {
108
- console.log(chalk_1.default.red.bold(`\nāŒ CRITICAL: Reached maximum iterations (${maxIterations}).`));
109
- console.log(chalk_1.default.red(` Quality gates remain unfulfilled. Refactor manually or check agent logs.`));
102
+ console.log(chalk.red.bold(`\nāŒ CRITICAL: Reached maximum iterations (${maxIterations}).`));
103
+ console.log(chalk.red(` Quality gates remain unfulfilled. Refactor manually or check agent logs.`));
110
104
  process.exit(EXIT_FAIL);
111
105
  }
112
- console.log(chalk_1.default.dim('\nReturning control to agent for the next refinement cycle...'));
106
+ console.log(chalk.dim('\nReturning control to agent for the next refinement cycle...'));
113
107
  }
114
108
  }
115
109
  catch (error) {
116
- console.error(chalk_1.default.red(`\nāŒ FATAL ERROR: ${error.message}`));
110
+ console.error(chalk.red(`\nāŒ FATAL ERROR: ${error.message}`));
117
111
  if (error.issues) {
118
- console.error(chalk_1.default.dim(JSON.stringify(error.issues, null, 2)));
112
+ console.error(chalk.dim(JSON.stringify(error.issues, null, 2)));
119
113
  }
120
114
  process.exit(EXIT_INTERNAL_ERROR);
121
115
  }
@@ -1,28 +1,22 @@
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.setupCommand = setupCommand;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- async function setupCommand() {
9
- console.log(chalk_1.default.bold.cyan('\nšŸ› ļø Rigour Labs | Setup & Installation\n'));
10
- console.log(chalk_1.default.bold('1. Global Installation (Recommended)'));
11
- console.log(chalk_1.default.dim(' To use Rigour anywhere in your terminal:'));
12
- console.log(chalk_1.default.green(' $ npm install -g @rigour-labs/cli\n'));
13
- console.log(chalk_1.default.bold('2. Project-Local installation'));
14
- console.log(chalk_1.default.dim(' To keep Rigour versioned with your project:'));
15
- console.log(chalk_1.default.green(' $ npm install --save-dev @rigour-labs/cli\n'));
16
- console.log(chalk_1.default.bold('3. Standalone Binaries (Zero-Install)'));
17
- console.log(chalk_1.default.dim(' If you do not want to use Node.js:'));
18
- console.log(chalk_1.default.dim(' • macOS: ') + chalk_1.default.cyan('https://github.com/erashu212/rigour/releases/latest/download/rigour-macos'));
19
- console.log(chalk_1.default.dim(' • Linux: ') + chalk_1.default.cyan('https://github.com/erashu212/rigour/releases/latest/download/rigour-linux'));
20
- console.log(chalk_1.default.dim(' • Windows: ') + chalk_1.default.cyan('https://github.com/erashu212/rigour/releases/latest/download/rigour-windows.exe\n'));
21
- console.log(chalk_1.default.bold('4. MCP Integration (for AI Agents)'));
22
- console.log(chalk_1.default.dim(' To let Cursor or Claude use Rigour natively:'));
23
- console.log(chalk_1.default.dim(' Path to MCP: ') + chalk_1.default.cyan('packages/rigour-mcp/dist/index.js'));
24
- console.log(chalk_1.default.dim(' Add this to your Cursor/Claude settings.\n'));
25
- console.log(chalk_1.default.bold('Update Guidance:'));
26
- console.log(chalk_1.default.dim(' Keep Rigour sharp by updating regularly:'));
27
- console.log(chalk_1.default.green(' $ npm install -g @rigour-labs/cli@latest\n'));
1
+ import chalk from 'chalk';
2
+ export async function setupCommand() {
3
+ console.log(chalk.bold.cyan('\nšŸ› ļø Rigour Labs | Setup & Installation\n'));
4
+ console.log(chalk.bold('1. Global Installation (Recommended)'));
5
+ console.log(chalk.dim(' To use Rigour anywhere in your terminal:'));
6
+ console.log(chalk.green(' $ npm install -g @rigour-labs/cli\n'));
7
+ console.log(chalk.bold('2. Project-Local installation'));
8
+ console.log(chalk.dim(' To keep Rigour versioned with your project:'));
9
+ console.log(chalk.green(' $ npm install --save-dev @rigour-labs/cli\n'));
10
+ console.log(chalk.bold('3. Standalone Binaries (Zero-Install)'));
11
+ console.log(chalk.dim(' If you do not want to use Node.js:'));
12
+ console.log(chalk.dim(' • macOS: ') + chalk.cyan('https://github.com/erashu212/rigour/releases/latest/download/rigour-macos'));
13
+ console.log(chalk.dim(' • Linux: ') + chalk.cyan('https://github.com/erashu212/rigour/releases/latest/download/rigour-linux'));
14
+ console.log(chalk.dim(' • Windows: ') + chalk.cyan('https://github.com/erashu212/rigour/releases/latest/download/rigour-windows.exe\n'));
15
+ console.log(chalk.bold('4. MCP Integration (for AI Agents)'));
16
+ console.log(chalk.dim(' To let Cursor or Claude use Rigour natively:'));
17
+ console.log(chalk.dim(' Path to MCP: ') + chalk.cyan('packages/rigour-mcp/dist/index.js'));
18
+ console.log(chalk.dim(' Add this to your Cursor/Claude settings.\n'));
19
+ console.log(chalk.bold('Update Guidance:'));
20
+ console.log(chalk.dim(' Keep Rigour sharp by updating regularly:'));
21
+ console.log(chalk.green(' $ npm install -g @rigour-labs/cli@latest\n'));
28
22
  }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const studioCommand: Command;