@rigstate/cli 0.7.23 → 0.7.25
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/index.cjs +875 -787
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +875 -787
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/daemon.ts +1 -115
- package/src/commands/link.ts +53 -6
- package/src/daemon/core.ts +30 -0
- package/src/utils/service-manager.ts +109 -0
package/dist/index.js
CHANGED
|
@@ -286,12 +286,12 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false) {
|
|
|
286
286
|
}
|
|
287
287
|
const files = syncResponse.data.data.files;
|
|
288
288
|
if (files && Array.isArray(files)) {
|
|
289
|
-
const
|
|
290
|
-
const
|
|
289
|
+
const fs24 = await import("fs/promises");
|
|
290
|
+
const path27 = await import("path");
|
|
291
291
|
for (const file of files) {
|
|
292
|
-
const filePath =
|
|
293
|
-
await
|
|
294
|
-
await
|
|
292
|
+
const filePath = path27.join(process.cwd(), file.path);
|
|
293
|
+
await fs24.mkdir(path27.dirname(filePath), { recursive: true });
|
|
294
|
+
await fs24.writeFile(filePath, file.content, "utf-8");
|
|
295
295
|
}
|
|
296
296
|
console.log(chalk3.dim(` \u{1F4BE} Wrote ${files.length} rule files to local .cursor/rules/`));
|
|
297
297
|
}
|
|
@@ -335,12 +335,142 @@ var init_sync_rules = __esm({
|
|
|
335
335
|
}
|
|
336
336
|
});
|
|
337
337
|
|
|
338
|
+
// src/commands/hooks.ts
|
|
339
|
+
var hooks_exports = {};
|
|
340
|
+
__export(hooks_exports, {
|
|
341
|
+
createHooksCommand: () => createHooksCommand
|
|
342
|
+
});
|
|
343
|
+
import { Command as Command4 } from "commander";
|
|
344
|
+
import chalk4 from "chalk";
|
|
345
|
+
import fs2 from "fs/promises";
|
|
346
|
+
import path3 from "path";
|
|
347
|
+
function createHooksCommand() {
|
|
348
|
+
const hooks = new Command4("hooks").description("Manage git hooks for Guardian integration");
|
|
349
|
+
hooks.command("install").description("Install pre-commit hook to run Guardian checks").option("--strict [level]", 'Strict level: "all" or "critical" (default)', "critical").action(async (options) => {
|
|
350
|
+
try {
|
|
351
|
+
const gitDir = path3.join(process.cwd(), ".git");
|
|
352
|
+
try {
|
|
353
|
+
await fs2.access(gitDir);
|
|
354
|
+
} catch {
|
|
355
|
+
console.log(chalk4.red("\u274C Not a git repository."));
|
|
356
|
+
console.log(chalk4.dim(' Initialize with "git init" first.'));
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
const hooksDir = path3.join(gitDir, "hooks");
|
|
360
|
+
await fs2.mkdir(hooksDir, { recursive: true });
|
|
361
|
+
const preCommitPath = path3.join(hooksDir, "pre-commit");
|
|
362
|
+
let existingContent = "";
|
|
363
|
+
try {
|
|
364
|
+
existingContent = await fs2.readFile(preCommitPath, "utf-8");
|
|
365
|
+
if (existingContent.includes("rigstate")) {
|
|
366
|
+
console.log(chalk4.yellow("\u26A0 Rigstate pre-commit hook already installed."));
|
|
367
|
+
console.log(chalk4.dim(' Use "rigstate hooks uninstall" to remove first.'));
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
} catch {
|
|
371
|
+
}
|
|
372
|
+
let script = PRE_COMMIT_SCRIPT;
|
|
373
|
+
if (options.strict === "all") {
|
|
374
|
+
script = script.replace("--strict=critical", "--strict");
|
|
375
|
+
}
|
|
376
|
+
if (existingContent && !existingContent.includes("rigstate")) {
|
|
377
|
+
const combinedScript = existingContent + "\n\n" + script.replace("#!/bin/sh\n", "");
|
|
378
|
+
await fs2.writeFile(preCommitPath, combinedScript, { mode: 493 });
|
|
379
|
+
console.log(chalk4.green("\u2705 Rigstate hook appended to existing pre-commit."));
|
|
380
|
+
} else {
|
|
381
|
+
await fs2.writeFile(preCommitPath, script, { mode: 493 });
|
|
382
|
+
console.log(chalk4.green("\u2705 Pre-commit hook installed!"));
|
|
383
|
+
}
|
|
384
|
+
console.log(chalk4.dim(` Path: ${preCommitPath}`));
|
|
385
|
+
console.log(chalk4.dim(` Strict level: ${options.strict}`));
|
|
386
|
+
console.log("");
|
|
387
|
+
console.log(chalk4.cyan("Guardian will now check your code before each commit."));
|
|
388
|
+
console.log(chalk4.dim('Use "rigstate hooks uninstall" to remove the hook.'));
|
|
389
|
+
} catch (error) {
|
|
390
|
+
console.error(chalk4.red("Failed to install hook:"), error.message);
|
|
391
|
+
process.exit(1);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
hooks.command("uninstall").description("Remove Rigstate pre-commit hook").action(async () => {
|
|
395
|
+
try {
|
|
396
|
+
const preCommitPath = path3.join(process.cwd(), ".git", "hooks", "pre-commit");
|
|
397
|
+
try {
|
|
398
|
+
const content = await fs2.readFile(preCommitPath, "utf-8");
|
|
399
|
+
if (!content.includes("rigstate")) {
|
|
400
|
+
console.log(chalk4.yellow("\u26A0 No Rigstate hook found in pre-commit."));
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (content.includes("# Rigstate Guardian Pre-commit Hook") && content.trim().split("\n").filter((l) => l && !l.startsWith("#")).length <= 4) {
|
|
404
|
+
await fs2.unlink(preCommitPath);
|
|
405
|
+
console.log(chalk4.green("\u2705 Pre-commit hook removed."));
|
|
406
|
+
} else {
|
|
407
|
+
const lines = content.split("\n");
|
|
408
|
+
const filteredLines = [];
|
|
409
|
+
let inRigstateSection = false;
|
|
410
|
+
for (const line of lines) {
|
|
411
|
+
if (line.includes("Rigstate Guardian Pre-commit Hook")) {
|
|
412
|
+
inRigstateSection = true;
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
if (inRigstateSection && line.includes("exit $?")) {
|
|
416
|
+
inRigstateSection = false;
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
if (!inRigstateSection && !line.includes("rigstate check")) {
|
|
420
|
+
filteredLines.push(line);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
await fs2.writeFile(preCommitPath, filteredLines.join("\n"), { mode: 493 });
|
|
424
|
+
console.log(chalk4.green("\u2705 Rigstate section removed from pre-commit hook."));
|
|
425
|
+
}
|
|
426
|
+
} catch {
|
|
427
|
+
console.log(chalk4.yellow("\u26A0 No pre-commit hook found."));
|
|
428
|
+
}
|
|
429
|
+
} catch (error) {
|
|
430
|
+
console.error(chalk4.red("Failed to uninstall hook:"), error.message);
|
|
431
|
+
process.exit(1);
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
return hooks;
|
|
435
|
+
}
|
|
436
|
+
var PRE_COMMIT_SCRIPT;
|
|
437
|
+
var init_hooks = __esm({
|
|
438
|
+
"src/commands/hooks.ts"() {
|
|
439
|
+
"use strict";
|
|
440
|
+
init_esm_shims();
|
|
441
|
+
PRE_COMMIT_SCRIPT = `#!/bin/sh
|
|
442
|
+
# Rigstate Guardian Pre-commit Hook
|
|
443
|
+
# Installed by: rigstate hooks install
|
|
444
|
+
|
|
445
|
+
# 1. Silent Sentinel Check (Phase 5)
|
|
446
|
+
if [ -f .rigstate/guardian.lock ]; then
|
|
447
|
+
echo "\u{1F6D1} INTERVENTION ACTIVE: Commit blocked by Silent Sentinel."
|
|
448
|
+
echo " A critical violation ('HARD_LOCK') was detected by the Guardian Daemon."
|
|
449
|
+
echo " Please fix the violation to unlock the repo."
|
|
450
|
+
echo ""
|
|
451
|
+
if grep -q "HARD_LOCK_ACTIVE" .rigstate/guardian.lock; then
|
|
452
|
+
cat .rigstate/guardian.lock
|
|
453
|
+
fi
|
|
454
|
+
exit 1
|
|
455
|
+
fi
|
|
456
|
+
|
|
457
|
+
echo "\u{1F6E1}\uFE0F Running Guardian checks..."
|
|
458
|
+
|
|
459
|
+
# Run check with strict mode for critical violations
|
|
460
|
+
rigstate check --staged --strict=critical
|
|
461
|
+
|
|
462
|
+
# Exit with the same code as rigstate check
|
|
463
|
+
exit $?
|
|
464
|
+
`;
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
|
|
338
468
|
// src/commands/suggest.ts
|
|
339
469
|
var suggest_exports = {};
|
|
340
470
|
__export(suggest_exports, {
|
|
341
471
|
suggestNextMove: () => suggestNextMove
|
|
342
472
|
});
|
|
343
|
-
import
|
|
473
|
+
import chalk5 from "chalk";
|
|
344
474
|
import axios3 from "axios";
|
|
345
475
|
async function suggestNextMove(projectId, apiKey, apiUrl) {
|
|
346
476
|
try {
|
|
@@ -360,18 +490,18 @@ async function suggestNextMove(projectId, apiKey, apiUrl) {
|
|
|
360
490
|
if (tasks.length === 0) return;
|
|
361
491
|
const nextTask = tasks[0];
|
|
362
492
|
console.log("");
|
|
363
|
-
console.log(
|
|
364
|
-
console.log(
|
|
365
|
-
console.log(`${
|
|
366
|
-
console.log(`${
|
|
493
|
+
console.log(chalk5.bold("\u{1F3AF} TACTICAL INTELLIGENCE"));
|
|
494
|
+
console.log(chalk5.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
495
|
+
console.log(`${chalk5.bold("Active Phase:")} Implementation`);
|
|
496
|
+
console.log(`${chalk5.bold("Next Mission:")} ${chalk5.cyan(nextTask.title)}`);
|
|
367
497
|
if (nextTask.role) {
|
|
368
|
-
console.log(`${
|
|
498
|
+
console.log(`${chalk5.bold("Required Role:")} ${chalk5.magenta(nextTask.role)}`);
|
|
369
499
|
}
|
|
370
500
|
console.log("");
|
|
371
|
-
console.log(
|
|
372
|
-
console.log(
|
|
373
|
-
console.log(
|
|
374
|
-
console.log(
|
|
501
|
+
console.log(chalk5.yellow("SUGGESTED NEXT MOVE:"));
|
|
502
|
+
console.log(chalk5.white(`> rigstate work start ${nextTask.id} `) + chalk5.dim("(Start this task)"));
|
|
503
|
+
console.log(chalk5.white(`> rigstate chat "How do I solve T-${nextTask.step_number}?" `) + chalk5.dim("(Ask Architect)"));
|
|
504
|
+
console.log(chalk5.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
375
505
|
console.log("");
|
|
376
506
|
} catch (e) {
|
|
377
507
|
}
|
|
@@ -391,9 +521,9 @@ __export(skills_provisioner_exports, {
|
|
|
391
521
|
provisionSkills: () => provisionSkills
|
|
392
522
|
});
|
|
393
523
|
import axios6 from "axios";
|
|
394
|
-
import
|
|
395
|
-
import
|
|
396
|
-
import
|
|
524
|
+
import fs7 from "fs/promises";
|
|
525
|
+
import path8 from "path";
|
|
526
|
+
import chalk9 from "chalk";
|
|
397
527
|
async function provisionSkills(apiUrl, apiKey, projectId, rootDir) {
|
|
398
528
|
const skills = [];
|
|
399
529
|
try {
|
|
@@ -415,18 +545,18 @@ async function provisionSkills(apiUrl, apiKey, projectId, rootDir) {
|
|
|
415
545
|
}
|
|
416
546
|
} catch (e) {
|
|
417
547
|
const msg = e.response?.data?.error || e.message;
|
|
418
|
-
console.log(
|
|
548
|
+
console.log(chalk9.dim(` (Skills API not available: ${msg}, using core library)`));
|
|
419
549
|
}
|
|
420
550
|
if (skills.length === 0) {
|
|
421
551
|
const { getRigstateStandardSkills } = await import("@rigstate/rules-engine");
|
|
422
552
|
const coreSkills = getRigstateStandardSkills();
|
|
423
553
|
skills.push(...coreSkills);
|
|
424
554
|
}
|
|
425
|
-
const skillsDir =
|
|
426
|
-
await
|
|
555
|
+
const skillsDir = path8.join(rootDir, ".agent", "skills");
|
|
556
|
+
await fs7.mkdir(skillsDir, { recursive: true });
|
|
427
557
|
for (const skill of skills) {
|
|
428
|
-
const skillDir =
|
|
429
|
-
await
|
|
558
|
+
const skillDir = path8.join(skillsDir, skill.name);
|
|
559
|
+
await fs7.mkdir(skillDir, { recursive: true });
|
|
430
560
|
const skillContent = `---
|
|
431
561
|
name: ${skill.name}
|
|
432
562
|
description: ${skill.description}
|
|
@@ -439,10 +569,10 @@ ${skill.content}
|
|
|
439
569
|
|
|
440
570
|
---
|
|
441
571
|
*Provisioned by Rigstate CLI. Do not modify manually.*`;
|
|
442
|
-
const skillPath =
|
|
443
|
-
await
|
|
572
|
+
const skillPath = path8.join(skillDir, "SKILL.md");
|
|
573
|
+
await fs7.writeFile(skillPath, skillContent, "utf-8");
|
|
444
574
|
}
|
|
445
|
-
console.log(
|
|
575
|
+
console.log(chalk9.green(` \u2705 Provisioned ${skills.length} skill(s) to .agent/skills/`));
|
|
446
576
|
return skills;
|
|
447
577
|
}
|
|
448
578
|
function generateSkillsDiscoveryBlock(skills) {
|
|
@@ -457,16 +587,16 @@ ${skillBlocks}
|
|
|
457
587
|
</available_skills>`;
|
|
458
588
|
}
|
|
459
589
|
async function jitProvisionSkill(skillId, apiUrl, apiKey, projectId, rootDir) {
|
|
460
|
-
const rulesPath =
|
|
590
|
+
const rulesPath = path8.join(rootDir, ".cursorrules");
|
|
461
591
|
let rulesContent = "";
|
|
462
592
|
try {
|
|
463
|
-
rulesContent = await
|
|
593
|
+
rulesContent = await fs7.readFile(rulesPath, "utf-8");
|
|
464
594
|
} catch (e) {
|
|
465
595
|
return false;
|
|
466
596
|
}
|
|
467
597
|
const isProvisioned = rulesContent.includes(`<name>${skillId}</name>`) || rulesContent.includes(`.agent/skills/${skillId}`);
|
|
468
598
|
if (isProvisioned) return false;
|
|
469
|
-
console.log(
|
|
599
|
+
console.log(chalk9.yellow(` \u26A1 JIT PROVISIONING: Injecting ${skillId}...`));
|
|
470
600
|
try {
|
|
471
601
|
const skills = await provisionSkills(apiUrl, apiKey, projectId, rootDir);
|
|
472
602
|
const skillsBlock = generateSkillsDiscoveryBlock(skills);
|
|
@@ -481,10 +611,10 @@ async function jitProvisionSkill(skillId, apiUrl, apiKey, projectId, rootDir) {
|
|
|
481
611
|
rulesContent = rulesContent.slice(0, insertPoint + 3) + "\n\n" + skillsBlock + "\n" + rulesContent.slice(insertPoint + 3);
|
|
482
612
|
}
|
|
483
613
|
}
|
|
484
|
-
await
|
|
614
|
+
await fs7.writeFile(rulesPath, rulesContent, "utf-8");
|
|
485
615
|
return true;
|
|
486
616
|
} catch (e) {
|
|
487
|
-
console.log(
|
|
617
|
+
console.log(chalk9.red(` Failed to provision skill: ${e.message}`));
|
|
488
618
|
return false;
|
|
489
619
|
}
|
|
490
620
|
}
|
|
@@ -505,13 +635,13 @@ __export(governance_exports, {
|
|
|
505
635
|
performOverride: () => performOverride,
|
|
506
636
|
setSoftLock: () => setSoftLock
|
|
507
637
|
});
|
|
508
|
-
import
|
|
509
|
-
import
|
|
510
|
-
import
|
|
638
|
+
import fs8 from "fs/promises";
|
|
639
|
+
import path9 from "path";
|
|
640
|
+
import chalk10 from "chalk";
|
|
511
641
|
async function getGovernanceConfig(rootDir = process.cwd()) {
|
|
512
642
|
try {
|
|
513
|
-
const configPath =
|
|
514
|
-
const content = await
|
|
643
|
+
const configPath = path9.join(rootDir, "rigstate.config.json");
|
|
644
|
+
const content = await fs8.readFile(configPath, "utf-8");
|
|
515
645
|
const userConfig = JSON.parse(content);
|
|
516
646
|
return {
|
|
517
647
|
governance: {
|
|
@@ -525,37 +655,37 @@ async function getGovernanceConfig(rootDir = process.cwd()) {
|
|
|
525
655
|
}
|
|
526
656
|
async function getSessionState(rootDir = process.cwd()) {
|
|
527
657
|
try {
|
|
528
|
-
const sessionPath =
|
|
529
|
-
const content = await
|
|
658
|
+
const sessionPath = path9.join(rootDir, ".rigstate", "session.json");
|
|
659
|
+
const content = await fs8.readFile(sessionPath, "utf-8");
|
|
530
660
|
return JSON.parse(content);
|
|
531
661
|
} catch (e) {
|
|
532
662
|
return DEFAULT_SESSION;
|
|
533
663
|
}
|
|
534
664
|
}
|
|
535
665
|
async function setSoftLock(reason, violationId, rootDir = process.cwd()) {
|
|
536
|
-
const sessionPath =
|
|
666
|
+
const sessionPath = path9.join(rootDir, ".rigstate", "session.json");
|
|
537
667
|
const state = {
|
|
538
668
|
status: "SOFT_LOCK",
|
|
539
669
|
active_violation: violationId,
|
|
540
670
|
lock_reason: reason,
|
|
541
671
|
last_updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
542
672
|
};
|
|
543
|
-
await
|
|
544
|
-
await
|
|
673
|
+
await fs8.mkdir(path9.dirname(sessionPath), { recursive: true });
|
|
674
|
+
await fs8.writeFile(sessionPath, JSON.stringify(state, null, 2), "utf-8");
|
|
545
675
|
}
|
|
546
676
|
async function clearSoftLock(rootDir = process.cwd()) {
|
|
547
|
-
const sessionPath =
|
|
677
|
+
const sessionPath = path9.join(rootDir, ".rigstate", "session.json");
|
|
548
678
|
const state = {
|
|
549
679
|
...DEFAULT_SESSION,
|
|
550
680
|
last_updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
551
681
|
};
|
|
552
|
-
await
|
|
553
|
-
await
|
|
682
|
+
await fs8.mkdir(path9.dirname(sessionPath), { recursive: true });
|
|
683
|
+
await fs8.writeFile(sessionPath, JSON.stringify(state, null, 2), "utf-8");
|
|
554
684
|
}
|
|
555
685
|
async function performOverride(violationId, reason, rootDir = process.cwd()) {
|
|
556
686
|
const config2 = await getGovernanceConfig(rootDir);
|
|
557
687
|
if (!config2.governance.allow_overrides) {
|
|
558
|
-
console.log(
|
|
688
|
+
console.log(chalk10.red("\u274C Overrides are disabled for this project."));
|
|
559
689
|
return false;
|
|
560
690
|
}
|
|
561
691
|
await clearSoftLock(rootDir);
|
|
@@ -592,22 +722,22 @@ var watchdog_exports = {};
|
|
|
592
722
|
__export(watchdog_exports, {
|
|
593
723
|
runGuardianWatchdog: () => runGuardianWatchdog
|
|
594
724
|
});
|
|
595
|
-
import
|
|
596
|
-
import
|
|
597
|
-
import
|
|
725
|
+
import fs9 from "fs/promises";
|
|
726
|
+
import path10 from "path";
|
|
727
|
+
import chalk11 from "chalk";
|
|
598
728
|
import axios7 from "axios";
|
|
599
729
|
async function countLines(filePath) {
|
|
600
730
|
try {
|
|
601
|
-
const content = await
|
|
731
|
+
const content = await fs9.readFile(filePath, "utf-8");
|
|
602
732
|
return content.split("\n").length;
|
|
603
733
|
} catch (e) {
|
|
604
734
|
return 0;
|
|
605
735
|
}
|
|
606
736
|
}
|
|
607
737
|
async function getFiles(dir, extension) {
|
|
608
|
-
const entries = await
|
|
738
|
+
const entries = await fs9.readdir(dir, { withFileTypes: true });
|
|
609
739
|
const files = await Promise.all(entries.map(async (entry) => {
|
|
610
|
-
const res =
|
|
740
|
+
const res = path10.resolve(dir, entry.name);
|
|
611
741
|
if (entry.isDirectory()) {
|
|
612
742
|
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === ".next" || entry.name === "dist") return [];
|
|
613
743
|
return getFiles(res, extension);
|
|
@@ -635,8 +765,8 @@ async function fetchRulesFromApi(projectId) {
|
|
|
635
765
|
}
|
|
636
766
|
} catch (error) {
|
|
637
767
|
try {
|
|
638
|
-
const cachePath =
|
|
639
|
-
const content = await
|
|
768
|
+
const cachePath = path10.join(process.cwd(), CACHE_FILE);
|
|
769
|
+
const content = await fs9.readFile(cachePath, "utf-8");
|
|
640
770
|
const cached = JSON.parse(content);
|
|
641
771
|
if (cached.settings) {
|
|
642
772
|
return {
|
|
@@ -655,7 +785,7 @@ async function fetchRulesFromApi(projectId) {
|
|
|
655
785
|
};
|
|
656
786
|
}
|
|
657
787
|
async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
658
|
-
console.log(
|
|
788
|
+
console.log(chalk11.bold("\n\u{1F6E1}\uFE0F Active Guardian Watchdog Initiated..."));
|
|
659
789
|
let lmax = settings.lmax || DEFAULT_LMAX;
|
|
660
790
|
let lmaxWarning = settings.lmax_warning || DEFAULT_LMAX_WARNING;
|
|
661
791
|
let ruleSource = settings.lmax ? "Settings (Passed)" : "Default";
|
|
@@ -665,47 +795,47 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
665
795
|
lmaxWarning = apiRules.lmaxWarning;
|
|
666
796
|
ruleSource = apiRules.source;
|
|
667
797
|
}
|
|
668
|
-
console.log(
|
|
798
|
+
console.log(chalk11.dim(`Governance Rules: L_max=${lmax}, L_max_warning=${lmaxWarning}, Source: ${ruleSource}`));
|
|
669
799
|
const targetExtensions = [".ts", ".tsx"];
|
|
670
800
|
let scanTarget = rootPath;
|
|
671
|
-
const webSrc =
|
|
801
|
+
const webSrc = path10.join(rootPath, "apps", "web", "src");
|
|
672
802
|
try {
|
|
673
|
-
await
|
|
803
|
+
await fs9.access(webSrc);
|
|
674
804
|
scanTarget = webSrc;
|
|
675
805
|
} catch {
|
|
676
806
|
}
|
|
677
|
-
console.log(
|
|
807
|
+
console.log(chalk11.dim(`Scanning target: ${path10.relative(process.cwd(), scanTarget)}`));
|
|
678
808
|
const files = await getFiles(scanTarget, targetExtensions);
|
|
679
809
|
let violations = 0;
|
|
680
810
|
let warnings = 0;
|
|
681
811
|
const results = [];
|
|
682
812
|
for (const file of files) {
|
|
683
813
|
const lines = await countLines(file);
|
|
684
|
-
const relPath =
|
|
814
|
+
const relPath = path10.relative(rootPath, file);
|
|
685
815
|
if (lines > lmax) {
|
|
686
816
|
results.push({ file: relPath, lines, status: "VIOLATION" });
|
|
687
817
|
violations++;
|
|
688
|
-
console.log(
|
|
818
|
+
console.log(chalk11.red(`[VIOLATION] ${relPath}: ${lines} lines (Limit: ${lmax})`));
|
|
689
819
|
} else if (lines > lmaxWarning) {
|
|
690
820
|
results.push({ file: relPath, lines, status: "WARNING" });
|
|
691
821
|
warnings++;
|
|
692
|
-
console.log(
|
|
822
|
+
console.log(chalk11.yellow(`[WARNING] ${relPath}: ${lines} lines (Threshold: ${lmaxWarning})`));
|
|
693
823
|
}
|
|
694
824
|
}
|
|
695
825
|
if (violations === 0 && warnings === 0) {
|
|
696
|
-
console.log(
|
|
826
|
+
console.log(chalk11.green(`\u2714 All ${files.length} files are within governance limits.`));
|
|
697
827
|
} else {
|
|
698
|
-
console.log("\n" +
|
|
699
|
-
console.log(
|
|
700
|
-
console.log(
|
|
828
|
+
console.log("\n" + chalk11.bold("Summary:"));
|
|
829
|
+
console.log(chalk11.red(`Violations: ${violations}`));
|
|
830
|
+
console.log(chalk11.yellow(`Warnings: ${warnings}`));
|
|
701
831
|
const { getGovernanceConfig: getGovernanceConfig2, setSoftLock: setSoftLock2, InterventionLevel: InterventionLevel2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
702
832
|
const { governance } = await getGovernanceConfig2(rootPath);
|
|
703
|
-
console.log(
|
|
833
|
+
console.log(chalk11.dim(`Intervention Level: ${InterventionLevel2[governance.intervention_level] || "UNKNOWN"} (${governance.intervention_level})`));
|
|
704
834
|
if (violations > 0) {
|
|
705
|
-
console.log(
|
|
835
|
+
console.log(chalk11.red.bold("\nCRITICAL: Governance violations detected. Immediate refactoring required."));
|
|
706
836
|
if (governance.intervention_level >= InterventionLevel2.SENTINEL) {
|
|
707
|
-
console.log(
|
|
708
|
-
console.log(
|
|
837
|
+
console.log(chalk11.red.bold("\u{1F6D1} SENTINEL MODE: Session SOFT_LOCKED until resolved."));
|
|
838
|
+
console.log(chalk11.red(' Run "rigstate override <id> --reason \\"...\\"" if this is an emergency.'));
|
|
709
839
|
await setSoftLock2("Sentinel Mode: Governance Violations Detected", "ARC-VIOLATION", rootPath);
|
|
710
840
|
}
|
|
711
841
|
}
|
|
@@ -728,9 +858,9 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
728
858
|
}, {
|
|
729
859
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
730
860
|
});
|
|
731
|
-
console.log(
|
|
861
|
+
console.log(chalk11.dim("\u2714 Violations synced to Rigstate Cloud."));
|
|
732
862
|
} catch (e) {
|
|
733
|
-
console.log(
|
|
863
|
+
console.log(chalk11.dim("\u26A0 Cloud sync skipped: " + (e.message || "Unknown")));
|
|
734
864
|
}
|
|
735
865
|
}
|
|
736
866
|
}
|
|
@@ -1533,10 +1663,10 @@ var require_src2 = __commonJS({
|
|
|
1533
1663
|
var fs_1 = __require("fs");
|
|
1534
1664
|
var debug_1 = __importDefault(require_src());
|
|
1535
1665
|
var log = debug_1.default("@kwsites/file-exists");
|
|
1536
|
-
function check(
|
|
1537
|
-
log(`checking %s`,
|
|
1666
|
+
function check(path27, isFile, isDirectory) {
|
|
1667
|
+
log(`checking %s`, path27);
|
|
1538
1668
|
try {
|
|
1539
|
-
const stat = fs_1.statSync(
|
|
1669
|
+
const stat = fs_1.statSync(path27);
|
|
1540
1670
|
if (stat.isFile() && isFile) {
|
|
1541
1671
|
log(`[OK] path represents a file`);
|
|
1542
1672
|
return true;
|
|
@@ -1556,8 +1686,8 @@ var require_src2 = __commonJS({
|
|
|
1556
1686
|
throw e;
|
|
1557
1687
|
}
|
|
1558
1688
|
}
|
|
1559
|
-
function exists2(
|
|
1560
|
-
return check(
|
|
1689
|
+
function exists2(path27, type = exports.READABLE) {
|
|
1690
|
+
return check(path27, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
1561
1691
|
}
|
|
1562
1692
|
exports.exists = exists2;
|
|
1563
1693
|
exports.FILE = 1;
|
|
@@ -1627,7 +1757,7 @@ var require_package = __commonJS({
|
|
|
1627
1757
|
"package.json"(exports, module) {
|
|
1628
1758
|
module.exports = {
|
|
1629
1759
|
name: "@rigstate/cli",
|
|
1630
|
-
version: "0.7.
|
|
1760
|
+
version: "0.7.25",
|
|
1631
1761
|
description: "Rigstate CLI - Code audit, sync and supervision tool",
|
|
1632
1762
|
type: "module",
|
|
1633
1763
|
main: "./dist/index.js",
|
|
@@ -1684,7 +1814,7 @@ var require_package = __commonJS({
|
|
|
1684
1814
|
// src/index.ts
|
|
1685
1815
|
init_esm_shims();
|
|
1686
1816
|
import { Command as Command23 } from "commander";
|
|
1687
|
-
import
|
|
1817
|
+
import chalk34 from "chalk";
|
|
1688
1818
|
|
|
1689
1819
|
// src/commands/login.ts
|
|
1690
1820
|
init_esm_shims();
|
|
@@ -1737,30 +1867,30 @@ Your API key has been securely stored. You can now use "rigstate scan" to audit
|
|
|
1737
1867
|
// src/commands/link.ts
|
|
1738
1868
|
init_esm_shims();
|
|
1739
1869
|
init_config();
|
|
1740
|
-
import { Command as
|
|
1741
|
-
import
|
|
1742
|
-
import
|
|
1743
|
-
import
|
|
1870
|
+
import { Command as Command5 } from "commander";
|
|
1871
|
+
import fs3 from "fs/promises";
|
|
1872
|
+
import path4 from "path";
|
|
1873
|
+
import chalk6 from "chalk";
|
|
1744
1874
|
import os from "os";
|
|
1745
1875
|
function createLinkCommand() {
|
|
1746
|
-
return new
|
|
1876
|
+
return new Command5("link").description("Link current directory to a Rigstate project").argument("<projectId>", "Project ID to link").action(async (projectId) => {
|
|
1747
1877
|
try {
|
|
1748
|
-
const globalPath =
|
|
1749
|
-
const globalData = await
|
|
1878
|
+
const globalPath = path4.join(os.homedir(), ".rigstate", "config.json");
|
|
1879
|
+
const globalData = await fs3.readFile(globalPath, "utf-8").catch(() => null);
|
|
1750
1880
|
if (globalData) {
|
|
1751
1881
|
const config2 = JSON.parse(globalData);
|
|
1752
1882
|
const cwd = process.cwd();
|
|
1753
1883
|
if (config2.overrides && config2.overrides[cwd]) {
|
|
1754
1884
|
const overrideId = config2.overrides[cwd];
|
|
1755
1885
|
if (overrideId !== projectId) {
|
|
1756
|
-
console.warn(
|
|
1886
|
+
console.warn(chalk6.yellow(`Global override detected. Enforcing project ID: ${overrideId}`));
|
|
1757
1887
|
projectId = overrideId;
|
|
1758
1888
|
}
|
|
1759
1889
|
}
|
|
1760
1890
|
}
|
|
1761
1891
|
} catch (e) {
|
|
1762
1892
|
}
|
|
1763
|
-
const manifestPath =
|
|
1893
|
+
const manifestPath = path4.join(process.cwd(), ".rigstate");
|
|
1764
1894
|
const content = {
|
|
1765
1895
|
project_id: projectId,
|
|
1766
1896
|
linked_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -1770,82 +1900,123 @@ function createLinkCommand() {
|
|
|
1770
1900
|
content.api_url = currentUrl;
|
|
1771
1901
|
}
|
|
1772
1902
|
try {
|
|
1773
|
-
await
|
|
1774
|
-
console.log(
|
|
1775
|
-
console.log(
|
|
1903
|
+
await fs3.writeFile(manifestPath, JSON.stringify(content, null, 2), "utf-8");
|
|
1904
|
+
console.log(chalk6.green(`\u2714 Linked to project ID: ${projectId}`));
|
|
1905
|
+
console.log(chalk6.dim(`Created local context manifest at .rigstate`));
|
|
1776
1906
|
console.log("");
|
|
1777
|
-
console.log(
|
|
1907
|
+
console.log(chalk6.bold("\u{1F916} Rigstate Automation Detected"));
|
|
1778
1908
|
console.log("");
|
|
1779
1909
|
const { getApiKey: _getApiKey, getApiUrl: _getApiUrl } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
1780
1910
|
const apiKey = getApiKey();
|
|
1781
1911
|
const apiUrl = getApiUrl();
|
|
1782
1912
|
if (apiKey) {
|
|
1783
|
-
console.log(
|
|
1913
|
+
console.log(chalk6.blue("\u{1F510} Checking Vault for secrets..."));
|
|
1784
1914
|
const { syncEnv: syncEnv2 } = await Promise.resolve().then(() => (init_env(), env_exports));
|
|
1785
1915
|
await syncEnv2(projectId, apiKey, apiUrl, true);
|
|
1786
|
-
console.log(
|
|
1916
|
+
console.log(chalk6.blue("\u{1F9E0} Syncing neural instructions..."));
|
|
1787
1917
|
const { syncProjectRules: syncProjectRules2 } = await Promise.resolve().then(() => (init_sync_rules(), sync_rules_exports));
|
|
1788
1918
|
await syncProjectRules2(projectId, apiKey, apiUrl);
|
|
1789
|
-
console.log(
|
|
1919
|
+
console.log(chalk6.blue("\u{1F6E1}\uFE0F Injecting Guardian hooks..."));
|
|
1920
|
+
const { createHooksCommand: createHooksCommand2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
|
|
1790
1921
|
await installHooks(process.cwd());
|
|
1791
1922
|
console.log("");
|
|
1792
|
-
console.log(
|
|
1923
|
+
console.log(chalk6.bold.green("\u{1F680} Link Complete! Your environment is ready."));
|
|
1793
1924
|
const { suggestNextMove: suggestNextMove2 } = await Promise.resolve().then(() => (init_suggest(), suggest_exports));
|
|
1794
1925
|
await suggestNextMove2(projectId, apiKey, apiUrl);
|
|
1795
1926
|
} else {
|
|
1796
1927
|
console.log("");
|
|
1797
|
-
console.log(
|
|
1928
|
+
console.log(chalk6.bold.green("\u{1F680} Link Complete!"));
|
|
1798
1929
|
}
|
|
1799
1930
|
} catch (error) {
|
|
1800
1931
|
if (error.message.includes("Not authenticated")) {
|
|
1801
|
-
console.warn(
|
|
1932
|
+
console.warn(chalk6.yellow('\u26A0\uFE0F Not authenticated. Run "rigstate login" to enable automation features.'));
|
|
1802
1933
|
} else {
|
|
1803
|
-
console.error(
|
|
1934
|
+
console.error(chalk6.red(`Failed to link project: ${error.message}`));
|
|
1804
1935
|
}
|
|
1805
1936
|
}
|
|
1806
1937
|
});
|
|
1807
1938
|
}
|
|
1808
1939
|
async function installHooks(cwd) {
|
|
1809
|
-
const
|
|
1810
|
-
const
|
|
1940
|
+
const fs24 = await import("fs/promises");
|
|
1941
|
+
const path27 = await import("path");
|
|
1811
1942
|
try {
|
|
1812
|
-
await
|
|
1943
|
+
await fs24.access(path27.join(cwd, ".git"));
|
|
1813
1944
|
} catch {
|
|
1814
|
-
console.log(
|
|
1945
|
+
console.log(chalk6.dim(" (Not a git repository, skipping hooks)"));
|
|
1815
1946
|
return;
|
|
1816
1947
|
}
|
|
1817
|
-
const hooksDir =
|
|
1948
|
+
const hooksDir = path27.join(cwd, ".husky");
|
|
1818
1949
|
try {
|
|
1819
|
-
const preCommitPath =
|
|
1950
|
+
const preCommitPath = path27.join(cwd, ".git/hooks/pre-commit");
|
|
1951
|
+
let shouldInstall = false;
|
|
1820
1952
|
try {
|
|
1821
|
-
await
|
|
1822
|
-
|
|
1953
|
+
await fs24.access(preCommitPath);
|
|
1954
|
+
const content = await fs24.readFile(preCommitPath, "utf-8");
|
|
1955
|
+
if (content.includes("rigstate")) {
|
|
1956
|
+
console.log(chalk6.green(" \u2714 Git hooks already active"));
|
|
1957
|
+
} else {
|
|
1958
|
+
shouldInstall = true;
|
|
1959
|
+
}
|
|
1823
1960
|
} catch {
|
|
1824
|
-
|
|
1961
|
+
shouldInstall = true;
|
|
1962
|
+
}
|
|
1963
|
+
if (shouldInstall) {
|
|
1964
|
+
const PRE_COMMIT_SCRIPT2 = `#!/bin/sh
|
|
1965
|
+
# Rigstate Guardian Pre-commit Hook
|
|
1966
|
+
# Installed by: rigstate link (v0.7.25)
|
|
1967
|
+
|
|
1968
|
+
# 1. Silent Sentinel Check
|
|
1969
|
+
if [ -f .rigstate/guardian.lock ]; then
|
|
1970
|
+
echo "\u{1F6D1} INTERVENTION ACTIVE: Commit blocked by Silent Sentinel."
|
|
1971
|
+
exit 1
|
|
1972
|
+
fi
|
|
1973
|
+
|
|
1974
|
+
echo "\u{1F6E1}\uFE0F Running Guardian checks..."
|
|
1975
|
+
rigstate check --staged --strict=critical
|
|
1976
|
+
exit $?
|
|
1977
|
+
`;
|
|
1978
|
+
await fs24.mkdir(path27.dirname(preCommitPath), { recursive: true });
|
|
1979
|
+
if (await fileExists(preCommitPath)) {
|
|
1980
|
+
const existing = await fs24.readFile(preCommitPath, "utf-8");
|
|
1981
|
+
await fs24.writeFile(preCommitPath, existing + "\n\n" + PRE_COMMIT_SCRIPT2.replace("#!/bin/sh\n", ""), { mode: 493 });
|
|
1982
|
+
} else {
|
|
1983
|
+
await fs24.writeFile(preCommitPath, PRE_COMMIT_SCRIPT2, { mode: 493 });
|
|
1984
|
+
}
|
|
1985
|
+
console.log(chalk6.green(" \u2714 Applied Guardian protection (git-hooks)"));
|
|
1825
1986
|
}
|
|
1826
1987
|
} catch (e) {
|
|
1988
|
+
console.log(chalk6.dim(" (Skipped hooks: " + e.message + ")"));
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
async function fileExists(path27) {
|
|
1992
|
+
const fs24 = await import("fs/promises");
|
|
1993
|
+
try {
|
|
1994
|
+
await fs24.access(path27);
|
|
1995
|
+
return true;
|
|
1996
|
+
} catch {
|
|
1997
|
+
return false;
|
|
1827
1998
|
}
|
|
1828
1999
|
}
|
|
1829
2000
|
|
|
1830
2001
|
// src/commands/scan.ts
|
|
1831
2002
|
init_esm_shims();
|
|
1832
2003
|
init_config();
|
|
1833
|
-
import { Command as
|
|
1834
|
-
import
|
|
2004
|
+
import { Command as Command6 } from "commander";
|
|
2005
|
+
import chalk7 from "chalk";
|
|
1835
2006
|
import ora3 from "ora";
|
|
1836
2007
|
import axios4 from "axios";
|
|
1837
2008
|
import { glob } from "glob";
|
|
1838
|
-
import
|
|
1839
|
-
import
|
|
2009
|
+
import fs5 from "fs/promises";
|
|
2010
|
+
import path6 from "path";
|
|
1840
2011
|
|
|
1841
2012
|
// src/utils/files.ts
|
|
1842
2013
|
init_esm_shims();
|
|
1843
|
-
import
|
|
1844
|
-
import
|
|
2014
|
+
import fs4 from "fs/promises";
|
|
2015
|
+
import path5 from "path";
|
|
1845
2016
|
async function readGitignore(dir) {
|
|
1846
|
-
const gitignorePath =
|
|
2017
|
+
const gitignorePath = path5.join(dir, ".gitignore");
|
|
1847
2018
|
try {
|
|
1848
|
-
const content = await
|
|
2019
|
+
const content = await fs4.readFile(gitignorePath, "utf-8");
|
|
1849
2020
|
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
1850
2021
|
} catch (error) {
|
|
1851
2022
|
return [];
|
|
@@ -1907,13 +2078,13 @@ function isCodeFile(filePath) {
|
|
|
1907
2078
|
".vue",
|
|
1908
2079
|
".svelte"
|
|
1909
2080
|
];
|
|
1910
|
-
const ext =
|
|
2081
|
+
const ext = path5.extname(filePath).toLowerCase();
|
|
1911
2082
|
return codeExtensions.includes(ext);
|
|
1912
2083
|
}
|
|
1913
2084
|
|
|
1914
2085
|
// src/commands/scan.ts
|
|
1915
2086
|
function createScanCommand() {
|
|
1916
|
-
return new
|
|
2087
|
+
return new Command6("scan").description("Scan code files for security and quality issues").argument("[path]", "Directory or file to scan", ".").option("--json", "Output results as JSON").option("--project <id>", "Project ID to associate with this scan").action(async (targetPath, options) => {
|
|
1917
2088
|
const spinner = ora3();
|
|
1918
2089
|
try {
|
|
1919
2090
|
const apiKey = getApiKey();
|
|
@@ -1921,26 +2092,26 @@ function createScanCommand() {
|
|
|
1921
2092
|
const projectId = options.project || getProjectId();
|
|
1922
2093
|
if (!projectId) {
|
|
1923
2094
|
console.warn(
|
|
1924
|
-
|
|
2095
|
+
chalk7.yellow(
|
|
1925
2096
|
"\u26A0\uFE0F No project ID specified. Use --project <id> or set a default."
|
|
1926
2097
|
)
|
|
1927
2098
|
);
|
|
1928
2099
|
}
|
|
1929
|
-
const scanPath =
|
|
1930
|
-
spinner.start(`Scanning ${
|
|
2100
|
+
const scanPath = path6.resolve(process.cwd(), targetPath);
|
|
2101
|
+
spinner.start(`Scanning ${chalk7.cyan(scanPath)}...`);
|
|
1931
2102
|
const gitignorePatterns = await readGitignore(scanPath);
|
|
1932
|
-
const pattern =
|
|
2103
|
+
const pattern = path6.join(scanPath, "**/*");
|
|
1933
2104
|
const allFiles = await glob(pattern, {
|
|
1934
2105
|
nodir: true,
|
|
1935
2106
|
dot: false,
|
|
1936
2107
|
ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**", "**/build/**"]
|
|
1937
2108
|
});
|
|
1938
2109
|
const codeFiles = allFiles.filter((file) => {
|
|
1939
|
-
const relativePath =
|
|
2110
|
+
const relativePath = path6.relative(scanPath, file);
|
|
1940
2111
|
return isCodeFile(file) && !shouldIgnore(relativePath, gitignorePatterns);
|
|
1941
2112
|
});
|
|
1942
2113
|
if (codeFiles.length === 0) {
|
|
1943
|
-
spinner.warn(
|
|
2114
|
+
spinner.warn(chalk7.yellow("No code files found to scan."));
|
|
1944
2115
|
return;
|
|
1945
2116
|
}
|
|
1946
2117
|
spinner.text = `Found ${codeFiles.length} files. Scanning...`;
|
|
@@ -1949,10 +2120,10 @@ function createScanCommand() {
|
|
|
1949
2120
|
const severityCounts = {};
|
|
1950
2121
|
for (let i = 0; i < codeFiles.length; i++) {
|
|
1951
2122
|
const filePath = codeFiles[i];
|
|
1952
|
-
const relativePath =
|
|
2123
|
+
const relativePath = path6.relative(scanPath, filePath);
|
|
1953
2124
|
spinner.text = `Scanning ${i + 1}/${codeFiles.length}: ${relativePath}`;
|
|
1954
2125
|
try {
|
|
1955
|
-
const content = await
|
|
2126
|
+
const content = await fs5.readFile(filePath, "utf-8");
|
|
1956
2127
|
const response = await axios4.post(
|
|
1957
2128
|
`${apiUrl}/api/v1/audit`,
|
|
1958
2129
|
{
|
|
@@ -1988,15 +2159,15 @@ function createScanCommand() {
|
|
|
1988
2159
|
}
|
|
1989
2160
|
} catch (fileError) {
|
|
1990
2161
|
if (axios4.isAxiosError(fileError)) {
|
|
1991
|
-
console.warn(
|
|
2162
|
+
console.warn(chalk7.yellow(`
|
|
1992
2163
|
\u26A0\uFE0F Skipping ${relativePath}: ${fileError.message}`));
|
|
1993
2164
|
} else {
|
|
1994
|
-
console.warn(
|
|
2165
|
+
console.warn(chalk7.yellow(`
|
|
1995
2166
|
\u26A0\uFE0F Error reading ${relativePath}`));
|
|
1996
2167
|
}
|
|
1997
2168
|
}
|
|
1998
2169
|
}
|
|
1999
|
-
spinner.succeed(
|
|
2170
|
+
spinner.succeed(chalk7.green("\u2705 Scan completed!"));
|
|
2000
2171
|
const aggregatedResponse = {
|
|
2001
2172
|
results,
|
|
2002
2173
|
summary: {
|
|
@@ -2011,21 +2182,21 @@ function createScanCommand() {
|
|
|
2011
2182
|
printPrettyResults(aggregatedResponse);
|
|
2012
2183
|
}
|
|
2013
2184
|
} catch (error) {
|
|
2014
|
-
spinner.fail(
|
|
2185
|
+
spinner.fail(chalk7.red("\u274C Scan failed"));
|
|
2015
2186
|
if (axios4.isAxiosError(error)) {
|
|
2016
2187
|
if (error.response) {
|
|
2017
|
-
console.error(
|
|
2188
|
+
console.error(chalk7.red("API Error:"), error.response.data);
|
|
2018
2189
|
} else if (error.request) {
|
|
2019
2190
|
console.error(
|
|
2020
|
-
|
|
2191
|
+
chalk7.red("Network Error:"),
|
|
2021
2192
|
"Could not reach the API. Is the server running?"
|
|
2022
2193
|
);
|
|
2023
2194
|
} else {
|
|
2024
|
-
console.error(
|
|
2195
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2025
2196
|
}
|
|
2026
2197
|
} else {
|
|
2027
2198
|
console.error(
|
|
2028
|
-
|
|
2199
|
+
chalk7.red("Error:"),
|
|
2029
2200
|
error instanceof Error ? error.message : "Unknown error"
|
|
2030
2201
|
);
|
|
2031
2202
|
}
|
|
@@ -2035,10 +2206,10 @@ function createScanCommand() {
|
|
|
2035
2206
|
}
|
|
2036
2207
|
function printPrettyResults(data) {
|
|
2037
2208
|
const { results, summary } = data;
|
|
2038
|
-
console.log("\n" +
|
|
2039
|
-
console.log(
|
|
2040
|
-
console.log(`Total Files Scanned: ${
|
|
2041
|
-
console.log(`Total Issues Found: ${
|
|
2209
|
+
console.log("\n" + chalk7.bold("\u{1F4CA} Scan Summary"));
|
|
2210
|
+
console.log(chalk7.dim("\u2500".repeat(60)));
|
|
2211
|
+
console.log(`Total Files Scanned: ${chalk7.cyan(summary.total_files)}`);
|
|
2212
|
+
console.log(`Total Issues Found: ${chalk7.yellow(summary.total_issues)}`);
|
|
2042
2213
|
if (summary.by_severity) {
|
|
2043
2214
|
console.log("\nIssues by Severity:");
|
|
2044
2215
|
Object.entries(summary.by_severity).forEach(([severity, count]) => {
|
|
@@ -2047,87 +2218,87 @@ function printPrettyResults(data) {
|
|
|
2047
2218
|
});
|
|
2048
2219
|
}
|
|
2049
2220
|
if (results && results.length > 0) {
|
|
2050
|
-
console.log("\n" +
|
|
2051
|
-
console.log(
|
|
2221
|
+
console.log("\n" + chalk7.bold("\u{1F50D} Detailed Results"));
|
|
2222
|
+
console.log(chalk7.dim("\u2500".repeat(60)));
|
|
2052
2223
|
results.forEach((result) => {
|
|
2053
2224
|
if (result.issues && result.issues.length > 0) {
|
|
2054
2225
|
console.log(`
|
|
2055
|
-
${
|
|
2226
|
+
${chalk7.bold(result.file_path)}`);
|
|
2056
2227
|
result.issues.forEach((issue) => {
|
|
2057
2228
|
const severityColor = getSeverityColor(issue.severity);
|
|
2058
|
-
const lineInfo = issue.line ?
|
|
2229
|
+
const lineInfo = issue.line ? chalk7.dim(`:${issue.line}`) : "";
|
|
2059
2230
|
console.log(
|
|
2060
2231
|
` ${severityColor(`[${issue.severity.toUpperCase()}]`)} ${issue.type}${lineInfo}`
|
|
2061
2232
|
);
|
|
2062
|
-
console.log(` ${
|
|
2233
|
+
console.log(` ${chalk7.dim(issue.message)}`);
|
|
2063
2234
|
});
|
|
2064
2235
|
}
|
|
2065
2236
|
});
|
|
2066
2237
|
}
|
|
2067
|
-
console.log("\n" +
|
|
2238
|
+
console.log("\n" + chalk7.dim("\u2500".repeat(60)));
|
|
2068
2239
|
}
|
|
2069
2240
|
function getSeverityColor(severity) {
|
|
2070
2241
|
switch (severity.toLowerCase()) {
|
|
2071
2242
|
case "critical":
|
|
2072
|
-
return
|
|
2243
|
+
return chalk7.red.bold;
|
|
2073
2244
|
case "high":
|
|
2074
|
-
return
|
|
2245
|
+
return chalk7.red;
|
|
2075
2246
|
case "medium":
|
|
2076
|
-
return
|
|
2247
|
+
return chalk7.yellow;
|
|
2077
2248
|
case "low":
|
|
2078
|
-
return
|
|
2249
|
+
return chalk7.blue;
|
|
2079
2250
|
case "info":
|
|
2080
|
-
return
|
|
2251
|
+
return chalk7.gray;
|
|
2081
2252
|
default:
|
|
2082
|
-
return
|
|
2253
|
+
return chalk7.white;
|
|
2083
2254
|
}
|
|
2084
2255
|
}
|
|
2085
2256
|
|
|
2086
2257
|
// src/commands/fix.ts
|
|
2087
2258
|
init_esm_shims();
|
|
2088
2259
|
init_config();
|
|
2089
|
-
import { Command as
|
|
2090
|
-
import
|
|
2260
|
+
import { Command as Command7 } from "commander";
|
|
2261
|
+
import chalk8 from "chalk";
|
|
2091
2262
|
import ora4 from "ora";
|
|
2092
2263
|
import axios5 from "axios";
|
|
2093
2264
|
import { glob as glob2 } from "glob";
|
|
2094
|
-
import
|
|
2095
|
-
import
|
|
2265
|
+
import fs6 from "fs/promises";
|
|
2266
|
+
import path7 from "path";
|
|
2096
2267
|
import inquirer from "inquirer";
|
|
2097
2268
|
import * as Diff from "diff";
|
|
2098
2269
|
function createFixCommand() {
|
|
2099
|
-
return new
|
|
2270
|
+
return new Command7("fix").description("Scan and interactively FIX detected issues using Rigstate AI").argument("[path]", "Directory or file to scan", ".").option("--project <id>", "Project ID to context-aware audit").action(async (targetPath, options) => {
|
|
2100
2271
|
const spinner = ora4();
|
|
2101
2272
|
try {
|
|
2102
2273
|
const apiKey = getApiKey();
|
|
2103
2274
|
const apiUrl = getApiUrl();
|
|
2104
2275
|
const projectId = options.project || getProjectId();
|
|
2105
2276
|
if (!projectId) {
|
|
2106
|
-
console.log(
|
|
2277
|
+
console.log(chalk8.yellow("\u26A0\uFE0F Project ID is required for fixing. Using default or pass --project <id>"));
|
|
2107
2278
|
}
|
|
2108
|
-
const scanPath =
|
|
2279
|
+
const scanPath = path7.resolve(process.cwd(), targetPath);
|
|
2109
2280
|
const gitignorePatterns = await readGitignore(scanPath);
|
|
2110
|
-
const pattern =
|
|
2281
|
+
const pattern = path7.join(scanPath, "**/*");
|
|
2111
2282
|
const allFiles = await glob2(pattern, { nodir: true, dot: false, ignore: ["**/node_modules/**", "**/.git/**"] });
|
|
2112
2283
|
const codeFiles = allFiles.filter((file) => {
|
|
2113
|
-
const relativePath =
|
|
2284
|
+
const relativePath = path7.relative(scanPath, file);
|
|
2114
2285
|
return isCodeFile(file) && !shouldIgnore(relativePath, gitignorePatterns);
|
|
2115
2286
|
});
|
|
2116
2287
|
if (codeFiles.length === 0) {
|
|
2117
|
-
console.log(
|
|
2288
|
+
console.log(chalk8.yellow("No code files found."));
|
|
2118
2289
|
return;
|
|
2119
2290
|
}
|
|
2120
|
-
console.log(
|
|
2291
|
+
console.log(chalk8.bold(`
|
|
2121
2292
|
\u{1F9E0} Rigstate Fix Mode`));
|
|
2122
|
-
console.log(
|
|
2293
|
+
console.log(chalk8.dim(`Scanning ${codeFiles.length} files with Project Context...
|
|
2123
2294
|
`));
|
|
2124
2295
|
let fixedCount = 0;
|
|
2125
2296
|
for (let i = 0; i < codeFiles.length; i++) {
|
|
2126
2297
|
const filePath = codeFiles[i];
|
|
2127
|
-
const relativePath =
|
|
2298
|
+
const relativePath = path7.relative(scanPath, filePath);
|
|
2128
2299
|
spinner.start(`Analyzing ${relativePath}...`);
|
|
2129
2300
|
try {
|
|
2130
|
-
const content = await
|
|
2301
|
+
const content = await fs6.readFile(filePath, "utf-8");
|
|
2131
2302
|
const response = await axios5.post(
|
|
2132
2303
|
`${apiUrl}/api/v1/audit`,
|
|
2133
2304
|
{ content, file_path: relativePath, project_id: projectId },
|
|
@@ -2138,22 +2309,22 @@ function createFixCommand() {
|
|
|
2138
2309
|
if (fixableIssues.length > 0) {
|
|
2139
2310
|
spinner.stop();
|
|
2140
2311
|
console.log(`
|
|
2141
|
-
${
|
|
2312
|
+
${chalk8.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
2142
2313
|
for (const issue of fixableIssues) {
|
|
2143
|
-
console.log(
|
|
2314
|
+
console.log(chalk8.red(`
|
|
2144
2315
|
[${issue.type}] ${issue.title}`));
|
|
2145
|
-
console.log(
|
|
2316
|
+
console.log(chalk8.dim(issue.suggestion || issue.message));
|
|
2146
2317
|
const diff = Diff.createTwoFilesPatch(relativePath, relativePath, content, issue.fixed_content, "Current", "Fixed");
|
|
2147
2318
|
console.log("\n" + diff.split("\n").slice(0, 15).join("\n") + (diff.split("\n").length > 15 ? "\n..." : ""));
|
|
2148
2319
|
const { apply } = await inquirer.prompt([{
|
|
2149
2320
|
type: "confirm",
|
|
2150
2321
|
name: "apply",
|
|
2151
|
-
message: `Apply this fix to ${
|
|
2322
|
+
message: `Apply this fix to ${chalk8.cyan(relativePath)}?`,
|
|
2152
2323
|
default: true
|
|
2153
2324
|
}]);
|
|
2154
2325
|
if (apply) {
|
|
2155
|
-
await
|
|
2156
|
-
console.log(
|
|
2326
|
+
await fs6.writeFile(filePath, issue.fixed_content);
|
|
2327
|
+
console.log(chalk8.green(`\u2705 Fixed applied!`));
|
|
2157
2328
|
fixedCount++;
|
|
2158
2329
|
if (issue.related_step_id) {
|
|
2159
2330
|
const { completeStep } = await inquirer.prompt([{
|
|
@@ -2169,15 +2340,15 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
2169
2340
|
{ step_id: issue.related_step_id, status: "COMPLETED", project_id: projectId },
|
|
2170
2341
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
2171
2342
|
);
|
|
2172
|
-
console.log(
|
|
2343
|
+
console.log(chalk8.green(`\u{1F680} Roadmap updated! Mission Control is in sync.`));
|
|
2173
2344
|
} catch (err) {
|
|
2174
|
-
console.error(
|
|
2345
|
+
console.error(chalk8.yellow(`Failed to update roadmap: ${err.message}`));
|
|
2175
2346
|
}
|
|
2176
2347
|
}
|
|
2177
2348
|
}
|
|
2178
2349
|
break;
|
|
2179
2350
|
} else {
|
|
2180
|
-
console.log(
|
|
2351
|
+
console.log(chalk8.dim("Skipped."));
|
|
2181
2352
|
}
|
|
2182
2353
|
}
|
|
2183
2354
|
} else {
|
|
@@ -2187,11 +2358,11 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
2187
2358
|
}
|
|
2188
2359
|
}
|
|
2189
2360
|
spinner.stop();
|
|
2190
|
-
console.log(
|
|
2361
|
+
console.log(chalk8.bold.green(`
|
|
2191
2362
|
|
|
2192
2363
|
\u{1F680} Fix session complete!`));
|
|
2193
2364
|
console.log(`Frank fixed ${fixedCount} detected issues.`);
|
|
2194
|
-
console.log(
|
|
2365
|
+
console.log(chalk8.dim(`Run 'rigstate scan' to verify remaining issues.`));
|
|
2195
2366
|
} catch (error) {
|
|
2196
2367
|
spinner.fail("Fix session failed");
|
|
2197
2368
|
console.error(error.message);
|
|
@@ -2202,14 +2373,14 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
2202
2373
|
// src/commands/sync.ts
|
|
2203
2374
|
init_esm_shims();
|
|
2204
2375
|
init_config();
|
|
2205
|
-
import { Command as
|
|
2206
|
-
import
|
|
2376
|
+
import { Command as Command8 } from "commander";
|
|
2377
|
+
import chalk12 from "chalk";
|
|
2207
2378
|
import ora5 from "ora";
|
|
2208
2379
|
import axios8 from "axios";
|
|
2209
|
-
import
|
|
2210
|
-
import
|
|
2380
|
+
import fs10 from "fs/promises";
|
|
2381
|
+
import path11 from "path";
|
|
2211
2382
|
function createSyncCommand() {
|
|
2212
|
-
const sync = new
|
|
2383
|
+
const sync = new Command8("sync");
|
|
2213
2384
|
sync.description("Synchronize local state with Rigstate Cloud").option("-p, --project <id>", "Specify Project ID (saves to config automatically)").action(async (options) => {
|
|
2214
2385
|
const spinner = ora5("Synchronizing project state...").start();
|
|
2215
2386
|
try {
|
|
@@ -2223,8 +2394,8 @@ function createSyncCommand() {
|
|
|
2223
2394
|
let projectId = options.project;
|
|
2224
2395
|
if (!projectId) {
|
|
2225
2396
|
try {
|
|
2226
|
-
const manifestPath =
|
|
2227
|
-
const manifestContent = await
|
|
2397
|
+
const manifestPath = path11.join(process.cwd(), ".rigstate");
|
|
2398
|
+
const manifestContent = await fs10.readFile(manifestPath, "utf-8");
|
|
2228
2399
|
const manifest = JSON.parse(manifestContent);
|
|
2229
2400
|
if (manifest.project_id) projectId = manifest.project_id;
|
|
2230
2401
|
} catch (e) {
|
|
@@ -2248,31 +2419,31 @@ function createSyncCommand() {
|
|
|
2248
2419
|
}
|
|
2249
2420
|
const { roadmap, project } = response.data.data;
|
|
2250
2421
|
const timestamp = response.data.timestamp;
|
|
2251
|
-
const targetPath =
|
|
2422
|
+
const targetPath = path11.join(process.cwd(), "roadmap.json");
|
|
2252
2423
|
const fileContent = JSON.stringify({
|
|
2253
2424
|
project,
|
|
2254
2425
|
last_synced: timestamp,
|
|
2255
2426
|
roadmap
|
|
2256
2427
|
}, null, 2);
|
|
2257
|
-
await
|
|
2428
|
+
await fs10.writeFile(targetPath, fileContent, "utf-8");
|
|
2258
2429
|
try {
|
|
2259
|
-
const manifestPath =
|
|
2430
|
+
const manifestPath = path11.join(process.cwd(), ".rigstate");
|
|
2260
2431
|
const manifestContent = {
|
|
2261
2432
|
project_id: projectId,
|
|
2262
2433
|
project_name: project,
|
|
2263
2434
|
last_synced: timestamp,
|
|
2264
2435
|
api_url: apiUrl
|
|
2265
2436
|
};
|
|
2266
|
-
await
|
|
2437
|
+
await fs10.writeFile(manifestPath, JSON.stringify(manifestContent, null, 2), "utf-8");
|
|
2267
2438
|
} catch (e) {
|
|
2268
2439
|
}
|
|
2269
|
-
console.log(
|
|
2440
|
+
console.log(chalk12.bold("\n\u{1F9E0} Agent Skills Provisioning..."));
|
|
2270
2441
|
try {
|
|
2271
2442
|
const { provisionSkills: provisionSkills2, generateSkillsDiscoveryBlock: generateSkillsDiscoveryBlock2 } = await Promise.resolve().then(() => (init_skills_provisioner(), skills_provisioner_exports));
|
|
2272
2443
|
const skills = await provisionSkills2(apiUrl, apiKey, projectId, process.cwd());
|
|
2273
|
-
const cursorRulesPath =
|
|
2444
|
+
const cursorRulesPath = path11.join(process.cwd(), ".cursorrules");
|
|
2274
2445
|
try {
|
|
2275
|
-
let rulesContent = await
|
|
2446
|
+
let rulesContent = await fs10.readFile(cursorRulesPath, "utf-8");
|
|
2276
2447
|
const skillsBlock = generateSkillsDiscoveryBlock2(skills);
|
|
2277
2448
|
if (rulesContent.includes("<available_skills>")) {
|
|
2278
2449
|
rulesContent = rulesContent.replace(
|
|
@@ -2285,17 +2456,17 @@ function createSyncCommand() {
|
|
|
2285
2456
|
rulesContent = rulesContent.slice(0, insertPoint + 3) + "\n\n" + skillsBlock + "\n" + rulesContent.slice(insertPoint + 3);
|
|
2286
2457
|
}
|
|
2287
2458
|
}
|
|
2288
|
-
await
|
|
2289
|
-
console.log(
|
|
2459
|
+
await fs10.writeFile(cursorRulesPath, rulesContent, "utf-8");
|
|
2460
|
+
console.log(chalk12.dim(` Updated .cursorrules with skills discovery block`));
|
|
2290
2461
|
} catch (e) {
|
|
2291
2462
|
}
|
|
2292
2463
|
} catch (e) {
|
|
2293
|
-
console.log(
|
|
2464
|
+
console.log(chalk12.yellow(` \u26A0 Skills provisioning skipped: ${e.message}`));
|
|
2294
2465
|
}
|
|
2295
2466
|
try {
|
|
2296
|
-
const logPath =
|
|
2467
|
+
const logPath = path11.join(process.cwd(), ".rigstate", "logs", "last_execution.json");
|
|
2297
2468
|
try {
|
|
2298
|
-
const logContent = await
|
|
2469
|
+
const logContent = await fs10.readFile(logPath, "utf-8");
|
|
2299
2470
|
const logData = JSON.parse(logContent);
|
|
2300
2471
|
if (logData.task_summary) {
|
|
2301
2472
|
await axios8.post(`${apiUrl}/api/v1/execution-logs`, {
|
|
@@ -2305,8 +2476,8 @@ function createSyncCommand() {
|
|
|
2305
2476
|
}, {
|
|
2306
2477
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2307
2478
|
});
|
|
2308
|
-
await
|
|
2309
|
-
console.log(
|
|
2479
|
+
await fs10.unlink(logPath);
|
|
2480
|
+
console.log(chalk12.dim(`\u2714 Mission Report uploaded.`));
|
|
2310
2481
|
}
|
|
2311
2482
|
} catch (e) {
|
|
2312
2483
|
if (e.code !== "ENOENT") {
|
|
@@ -2314,12 +2485,12 @@ function createSyncCommand() {
|
|
|
2314
2485
|
}
|
|
2315
2486
|
} catch (e) {
|
|
2316
2487
|
}
|
|
2317
|
-
spinner.succeed(
|
|
2318
|
-
console.log(
|
|
2488
|
+
spinner.succeed(chalk12.green(`Synced ${roadmap.length} roadmap steps for project "${project}"`));
|
|
2489
|
+
console.log(chalk12.dim(`Local files updated: roadmap.json`));
|
|
2319
2490
|
const { runGuardianWatchdog: runGuardianWatchdog2 } = await Promise.resolve().then(() => (init_watchdog(), watchdog_exports));
|
|
2320
2491
|
const settings = response.data.data.settings || {};
|
|
2321
2492
|
await runGuardianWatchdog2(process.cwd(), settings, projectId);
|
|
2322
|
-
console.log(
|
|
2493
|
+
console.log(chalk12.bold("\n\u{1F4E1} Agent Bridge Heartbeat..."));
|
|
2323
2494
|
try {
|
|
2324
2495
|
const bridgeResponse = await axios8.get(`${apiUrl}/api/v1/agent/bridge`, {
|
|
2325
2496
|
params: { project_id: projectId },
|
|
@@ -2330,10 +2501,10 @@ function createSyncCommand() {
|
|
|
2330
2501
|
const pending = tasks.filter((t) => t.status === "PENDING");
|
|
2331
2502
|
const approved = tasks.filter((t) => t.status === "APPROVED");
|
|
2332
2503
|
if (pending.length > 0 || approved.length > 0) {
|
|
2333
|
-
console.log(
|
|
2334
|
-
console.log(
|
|
2504
|
+
console.log(chalk12.yellow(`\u26A0 Bridge Alert: ${pending.length} pending, ${approved.length} approved tasks found.`));
|
|
2505
|
+
console.log(chalk12.dim('Run "rigstate fix" to process these tasks or ensure your IDE MCP server is active.'));
|
|
2335
2506
|
} else {
|
|
2336
|
-
console.log(
|
|
2507
|
+
console.log(chalk12.green("\u2714 Heartbeat healthy. No pending bridge tasks."));
|
|
2337
2508
|
}
|
|
2338
2509
|
const pings = pending.filter((t) => t.proposal?.startsWith("ping"));
|
|
2339
2510
|
for (const ping of pings) {
|
|
@@ -2344,25 +2515,25 @@ function createSyncCommand() {
|
|
|
2344
2515
|
}, {
|
|
2345
2516
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2346
2517
|
});
|
|
2347
|
-
console.log(
|
|
2518
|
+
console.log(chalk12.cyan(`\u{1F3D3} Pong! Acknowledged heartbeat signal [${ping.id}]`));
|
|
2348
2519
|
}
|
|
2349
2520
|
}
|
|
2350
2521
|
} catch (e) {
|
|
2351
|
-
console.log(
|
|
2522
|
+
console.log(chalk12.yellow(`\u26A0 Could not verify Bridge status: ${e.message}`));
|
|
2352
2523
|
}
|
|
2353
2524
|
if (options.project) {
|
|
2354
|
-
console.log(
|
|
2525
|
+
console.log(chalk12.blue(`Project context saved. Future commands will use this project.`));
|
|
2355
2526
|
}
|
|
2356
2527
|
try {
|
|
2357
|
-
const migrationDir =
|
|
2358
|
-
const files = await
|
|
2528
|
+
const migrationDir = path11.join(process.cwd(), "supabase", "migrations");
|
|
2529
|
+
const files = await fs10.readdir(migrationDir);
|
|
2359
2530
|
const sqlFiles = files.filter((f) => f.endsWith(".sql")).sort();
|
|
2360
2531
|
if (sqlFiles.length > 0) {
|
|
2361
2532
|
const latestMigration = sqlFiles[sqlFiles.length - 1];
|
|
2362
|
-
console.log(
|
|
2533
|
+
console.log(chalk12.dim(`
|
|
2363
2534
|
\u{1F6E1} Migration Guard:`));
|
|
2364
|
-
console.log(
|
|
2365
|
-
console.log(
|
|
2535
|
+
console.log(chalk12.dim(` Latest Local: ${latestMigration}`));
|
|
2536
|
+
console.log(chalk12.yellow(` \u26A0 Ensure DB schema matches this version. CLI cannot verify Remote RLS policies directly.`));
|
|
2366
2537
|
}
|
|
2367
2538
|
} catch (e) {
|
|
2368
2539
|
}
|
|
@@ -2374,15 +2545,15 @@ function createSyncCommand() {
|
|
|
2374
2545
|
);
|
|
2375
2546
|
if (vaultResponse.data.success) {
|
|
2376
2547
|
const vaultContent = vaultResponse.data.data.content || "";
|
|
2377
|
-
const localEnvPath =
|
|
2548
|
+
const localEnvPath = path11.join(process.cwd(), ".env.local");
|
|
2378
2549
|
let localContent = "";
|
|
2379
2550
|
try {
|
|
2380
|
-
localContent = await
|
|
2551
|
+
localContent = await fs10.readFile(localEnvPath, "utf-8");
|
|
2381
2552
|
} catch (e) {
|
|
2382
2553
|
}
|
|
2383
2554
|
if (vaultContent.trim() !== localContent.trim()) {
|
|
2384
|
-
console.log(
|
|
2385
|
-
console.log(
|
|
2555
|
+
console.log(chalk12.bold("\n\u{1F510} Sovereign Foundation (Vault):"));
|
|
2556
|
+
console.log(chalk12.yellow(" Status: Drift Detected / Update Available"));
|
|
2386
2557
|
const { syncVault } = await import("inquirer").then((m) => m.default.prompt([{
|
|
2387
2558
|
type: "confirm",
|
|
2388
2559
|
name: "syncVault",
|
|
@@ -2390,25 +2561,25 @@ function createSyncCommand() {
|
|
|
2390
2561
|
default: false
|
|
2391
2562
|
}]));
|
|
2392
2563
|
if (syncVault) {
|
|
2393
|
-
await
|
|
2394
|
-
console.log(
|
|
2564
|
+
await fs10.writeFile(localEnvPath, vaultContent, "utf-8");
|
|
2565
|
+
console.log(chalk12.green(" \u2705 .env.local synchronized with Vault."));
|
|
2395
2566
|
} else {
|
|
2396
|
-
console.log(
|
|
2567
|
+
console.log(chalk12.dim(" Skipped vault sync."));
|
|
2397
2568
|
}
|
|
2398
2569
|
} else {
|
|
2399
|
-
console.log(
|
|
2570
|
+
console.log(chalk12.dim("\n\u{1F510} Sovereign Foundation: Synced."));
|
|
2400
2571
|
}
|
|
2401
2572
|
}
|
|
2402
2573
|
} catch (e) {
|
|
2403
2574
|
}
|
|
2404
|
-
console.log(
|
|
2575
|
+
console.log(chalk12.dim("\n\u{1F6E1}\uFE0F System Integrity Check..."));
|
|
2405
2576
|
await checkSystemIntegrity(apiUrl, apiKey, projectId);
|
|
2406
2577
|
} catch (error) {
|
|
2407
2578
|
if (axios8.isAxiosError(error)) {
|
|
2408
2579
|
const message = error.response?.data?.error || error.message;
|
|
2409
|
-
spinner.fail(
|
|
2580
|
+
spinner.fail(chalk12.red(`Sync failed: ${message}`));
|
|
2410
2581
|
} else {
|
|
2411
|
-
spinner.fail(
|
|
2582
|
+
spinner.fail(chalk12.red("Sync failed: " + (error.message || "Unknown error")));
|
|
2412
2583
|
}
|
|
2413
2584
|
}
|
|
2414
2585
|
});
|
|
@@ -2424,57 +2595,57 @@ async function checkSystemIntegrity(apiUrl, apiKey, projectId) {
|
|
|
2424
2595
|
const { migrations, rls, guardian_violations } = response.data.data;
|
|
2425
2596
|
if (migrations) {
|
|
2426
2597
|
if (migrations.in_sync) {
|
|
2427
|
-
console.log(
|
|
2598
|
+
console.log(chalk12.green(` \u2705 Migrations synced (${migrations.count} versions)`));
|
|
2428
2599
|
} else {
|
|
2429
|
-
console.log(
|
|
2600
|
+
console.log(chalk12.red(` \u{1F6D1} CRITICAL: DB Schema out of sync! ${migrations.missing?.length || 0} migrations not applied.`));
|
|
2430
2601
|
if (migrations.missing?.length > 0) {
|
|
2431
|
-
console.log(
|
|
2602
|
+
console.log(chalk12.dim(` Missing: ${migrations.missing.slice(0, 3).join(", ")}${migrations.missing.length > 3 ? "..." : ""}`));
|
|
2432
2603
|
}
|
|
2433
|
-
console.log(
|
|
2604
|
+
console.log(chalk12.yellow(` Run 'supabase db push' or apply migrations immediately.`));
|
|
2434
2605
|
}
|
|
2435
2606
|
}
|
|
2436
2607
|
if (rls) {
|
|
2437
2608
|
if (rls.all_secured) {
|
|
2438
|
-
console.log(
|
|
2609
|
+
console.log(chalk12.green(` \u2705 RLS Audit Passed (${rls.table_count} tables secured)`));
|
|
2439
2610
|
} else {
|
|
2440
|
-
console.log(
|
|
2611
|
+
console.log(chalk12.red(` \u{1F6D1} CRITICAL: Security Vulnerability! ${rls.unsecured?.length || 0} tables have RLS disabled.`));
|
|
2441
2612
|
rls.unsecured?.forEach((table) => {
|
|
2442
|
-
console.log(
|
|
2613
|
+
console.log(chalk12.red(` - ${table}`));
|
|
2443
2614
|
});
|
|
2444
|
-
console.log(
|
|
2615
|
+
console.log(chalk12.yellow(' Enable RLS immediately: ALTER TABLE "table" ENABLE ROW LEVEL SECURITY;'));
|
|
2445
2616
|
}
|
|
2446
2617
|
}
|
|
2447
2618
|
if (guardian_violations) {
|
|
2448
2619
|
if (guardian_violations.count === 0) {
|
|
2449
|
-
console.log(
|
|
2620
|
+
console.log(chalk12.green(" \u2705 Guardian: No active violations"));
|
|
2450
2621
|
} else {
|
|
2451
|
-
console.log(
|
|
2452
|
-
console.log(
|
|
2622
|
+
console.log(chalk12.yellow(` \u26A0\uFE0F Guardian: ${guardian_violations.count} active violations`));
|
|
2623
|
+
console.log(chalk12.dim(' Run "rigstate check" for details.'));
|
|
2453
2624
|
}
|
|
2454
2625
|
}
|
|
2455
2626
|
}
|
|
2456
2627
|
} catch (e) {
|
|
2457
|
-
console.log(
|
|
2628
|
+
console.log(chalk12.dim(" (System integrity check skipped - API endpoint not available)"));
|
|
2458
2629
|
}
|
|
2459
2630
|
}
|
|
2460
2631
|
|
|
2461
2632
|
// src/commands/init.ts
|
|
2462
2633
|
init_esm_shims();
|
|
2463
|
-
import { Command as
|
|
2464
|
-
import
|
|
2465
|
-
import
|
|
2466
|
-
import
|
|
2634
|
+
import { Command as Command9 } from "commander";
|
|
2635
|
+
import chalk13 from "chalk";
|
|
2636
|
+
import fs12 from "fs/promises";
|
|
2637
|
+
import path13 from "path";
|
|
2467
2638
|
import ora6 from "ora";
|
|
2468
2639
|
import { execSync } from "child_process";
|
|
2469
2640
|
|
|
2470
2641
|
// src/utils/manifest.ts
|
|
2471
2642
|
init_esm_shims();
|
|
2472
|
-
import
|
|
2473
|
-
import
|
|
2643
|
+
import fs11 from "fs/promises";
|
|
2644
|
+
import path12 from "path";
|
|
2474
2645
|
async function loadManifest() {
|
|
2475
2646
|
try {
|
|
2476
|
-
const manifestPath =
|
|
2477
|
-
const content = await
|
|
2647
|
+
const manifestPath = path12.join(process.cwd(), ".rigstate");
|
|
2648
|
+
const content = await fs11.readFile(manifestPath, "utf-8");
|
|
2478
2649
|
return JSON.parse(content);
|
|
2479
2650
|
} catch {
|
|
2480
2651
|
return null;
|
|
@@ -2485,13 +2656,13 @@ async function loadManifest() {
|
|
|
2485
2656
|
init_config();
|
|
2486
2657
|
import axios9 from "axios";
|
|
2487
2658
|
function createInitCommand() {
|
|
2488
|
-
return new
|
|
2659
|
+
return new Command9("init").description("Initialize or link a Rigstate project (interactive mode available)").argument("[project-id]", "ID of the project to link (optional, prompts if not provided)").option("-f, --force", "Overwrite existing .cursorrules file").option("--rules-only", "Only regenerate .cursorrules without interactive setup").action(async (projectIdArg, options) => {
|
|
2489
2660
|
const spinner = ora6("Initializing Rigstate project...").start();
|
|
2490
2661
|
let apiKey;
|
|
2491
2662
|
try {
|
|
2492
2663
|
apiKey = getApiKey();
|
|
2493
2664
|
} catch (e) {
|
|
2494
|
-
spinner.fail(
|
|
2665
|
+
spinner.fail(chalk13.red('Not authenticated. Run "rigstate login" first.'));
|
|
2495
2666
|
return;
|
|
2496
2667
|
}
|
|
2497
2668
|
const apiUrl = getApiUrl();
|
|
@@ -2588,7 +2759,7 @@ function createInitCommand() {
|
|
|
2588
2759
|
selectedOrgId = orgId;
|
|
2589
2760
|
}
|
|
2590
2761
|
if (!selectedOrgId) {
|
|
2591
|
-
console.log(
|
|
2762
|
+
console.log(chalk13.yellow("No organization available. Please create the project via the Rigstate dashboard."));
|
|
2592
2763
|
return;
|
|
2593
2764
|
}
|
|
2594
2765
|
spinner.start("Creating new project...");
|
|
@@ -2600,13 +2771,13 @@ function createInitCommand() {
|
|
|
2600
2771
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2601
2772
|
});
|
|
2602
2773
|
if (!createResponse.data.success) {
|
|
2603
|
-
spinner.fail(
|
|
2774
|
+
spinner.fail(chalk13.red("Failed to create project: " + createResponse.data.error));
|
|
2604
2775
|
return;
|
|
2605
2776
|
}
|
|
2606
2777
|
projectId = createResponse.data.data.project.id;
|
|
2607
|
-
spinner.succeed(
|
|
2778
|
+
spinner.succeed(chalk13.green(`Created new project: ${newName}`));
|
|
2608
2779
|
} catch (e) {
|
|
2609
|
-
spinner.fail(
|
|
2780
|
+
spinner.fail(chalk13.red("Project creation API not available. Please create via dashboard."));
|
|
2610
2781
|
return;
|
|
2611
2782
|
}
|
|
2612
2783
|
} else {
|
|
@@ -2616,28 +2787,28 @@ function createInitCommand() {
|
|
|
2616
2787
|
spinner.start(`Linking to project ID: ${projectId}...`);
|
|
2617
2788
|
}
|
|
2618
2789
|
setProjectId(projectId);
|
|
2619
|
-
const manifestPath =
|
|
2790
|
+
const manifestPath = path13.join(process.cwd(), ".rigstate");
|
|
2620
2791
|
const manifestContent = {
|
|
2621
2792
|
project_id: projectId,
|
|
2622
2793
|
last_linked: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2623
2794
|
api_url: apiUrl
|
|
2624
2795
|
};
|
|
2625
|
-
await
|
|
2796
|
+
await fs12.writeFile(manifestPath, JSON.stringify(manifestContent, null, 2), "utf-8");
|
|
2626
2797
|
try {
|
|
2627
|
-
await
|
|
2798
|
+
await fs12.access(".git");
|
|
2628
2799
|
} catch {
|
|
2629
2800
|
spinner.text = "Initializing git repository...";
|
|
2630
2801
|
execSync("git init", { stdio: "ignore" });
|
|
2631
2802
|
}
|
|
2632
|
-
spinner.succeed(
|
|
2803
|
+
spinner.succeed(chalk13.green(`\u2705 Linked to project: ${projectId}`));
|
|
2633
2804
|
await generateRules(apiUrl, apiKey, projectId, options.force, spinner);
|
|
2634
2805
|
console.log("");
|
|
2635
|
-
console.log(
|
|
2636
|
-
console.log(
|
|
2637
|
-
console.log(
|
|
2638
|
-
console.log(
|
|
2806
|
+
console.log(chalk13.blue("Next steps:"));
|
|
2807
|
+
console.log(chalk13.dim(" rigstate sync - Sync roadmap and context"));
|
|
2808
|
+
console.log(chalk13.dim(" rigstate watch - Start development loop"));
|
|
2809
|
+
console.log(chalk13.dim(" rigstate focus - Get current task"));
|
|
2639
2810
|
} catch (e) {
|
|
2640
|
-
spinner.fail(
|
|
2811
|
+
spinner.fail(chalk13.red("Initialization failed: " + e.message));
|
|
2641
2812
|
}
|
|
2642
2813
|
});
|
|
2643
2814
|
}
|
|
@@ -2652,67 +2823,67 @@ async function generateRules(apiUrl, apiKey, projectId, force, spinner) {
|
|
|
2652
2823
|
if (response.data.success || response.data.files) {
|
|
2653
2824
|
const files = response.data.files || [];
|
|
2654
2825
|
if (files.length === 0 && response.data.rules) {
|
|
2655
|
-
const rulesPath =
|
|
2656
|
-
await
|
|
2657
|
-
spinner.succeed(
|
|
2826
|
+
const rulesPath = path13.join(process.cwd(), ".cursorrules");
|
|
2827
|
+
await fs12.writeFile(rulesPath, response.data.rules, "utf-8");
|
|
2828
|
+
spinner.succeed(chalk13.green("\u2714 Generated .cursorrules (legacy mode)"));
|
|
2658
2829
|
return;
|
|
2659
2830
|
}
|
|
2660
2831
|
for (const file of files) {
|
|
2661
|
-
const targetPath =
|
|
2662
|
-
const targetDir =
|
|
2663
|
-
await
|
|
2832
|
+
const targetPath = path13.join(process.cwd(), file.path);
|
|
2833
|
+
const targetDir = path13.dirname(targetPath);
|
|
2834
|
+
await fs12.mkdir(targetDir, { recursive: true });
|
|
2664
2835
|
try {
|
|
2665
|
-
await
|
|
2836
|
+
await fs12.access(targetPath);
|
|
2666
2837
|
if (!force && !file.path.startsWith(".cursor/rules/")) {
|
|
2667
|
-
console.log(
|
|
2838
|
+
console.log(chalk13.dim(` ${file.path} already exists. Skipping.`));
|
|
2668
2839
|
continue;
|
|
2669
2840
|
}
|
|
2670
2841
|
} catch {
|
|
2671
2842
|
}
|
|
2672
|
-
await
|
|
2843
|
+
await fs12.writeFile(targetPath, file.content, "utf-8");
|
|
2673
2844
|
}
|
|
2674
2845
|
if (files.length > 0) {
|
|
2675
|
-
const legacyPath =
|
|
2846
|
+
const legacyPath = path13.join(process.cwd(), ".cursorrules");
|
|
2676
2847
|
try {
|
|
2677
|
-
const stats = await
|
|
2848
|
+
const stats = await fs12.stat(legacyPath);
|
|
2678
2849
|
if (stats.isFile()) {
|
|
2679
|
-
await
|
|
2680
|
-
console.log(
|
|
2850
|
+
await fs12.rename(legacyPath, `${legacyPath}.bak`);
|
|
2851
|
+
console.log(chalk13.dim(" Moved legacy .cursorrules to .cursorrules.bak"));
|
|
2681
2852
|
}
|
|
2682
2853
|
} catch (e) {
|
|
2683
2854
|
}
|
|
2684
2855
|
}
|
|
2685
|
-
spinner.succeed(
|
|
2856
|
+
spinner.succeed(chalk13.green(`\u2714 Generated ${files.length} rule files (v${response.data.version || "3.0"})`));
|
|
2686
2857
|
} else {
|
|
2687
|
-
spinner.info(
|
|
2858
|
+
spinner.info(chalk13.dim(" Rules generation skipped (API response invalid)"));
|
|
2688
2859
|
}
|
|
2689
2860
|
} catch (e) {
|
|
2690
|
-
spinner.info(
|
|
2861
|
+
spinner.info(chalk13.dim(` Rules generation failed: ${e.message}`));
|
|
2691
2862
|
}
|
|
2692
2863
|
}
|
|
2693
2864
|
|
|
2694
2865
|
// src/commands/check.ts
|
|
2695
2866
|
init_esm_shims();
|
|
2696
2867
|
init_config();
|
|
2697
|
-
import { Command as
|
|
2698
|
-
import
|
|
2868
|
+
import { Command as Command10 } from "commander";
|
|
2869
|
+
import chalk15 from "chalk";
|
|
2699
2870
|
import ora7 from "ora";
|
|
2700
2871
|
import axios10 from "axios";
|
|
2701
2872
|
import { glob as glob3 } from "glob";
|
|
2702
|
-
import
|
|
2703
|
-
import
|
|
2873
|
+
import fs14 from "fs/promises";
|
|
2874
|
+
import path15 from "path";
|
|
2704
2875
|
import { execSync as execSync2 } from "child_process";
|
|
2705
2876
|
|
|
2706
2877
|
// src/utils/rule-engine.ts
|
|
2707
2878
|
init_esm_shims();
|
|
2708
|
-
import
|
|
2709
|
-
import
|
|
2710
|
-
import
|
|
2879
|
+
import fs13 from "fs/promises";
|
|
2880
|
+
import path14 from "path";
|
|
2881
|
+
import chalk14 from "chalk";
|
|
2711
2882
|
async function checkFile(filePath, rules, rootPath) {
|
|
2712
2883
|
const violations = [];
|
|
2713
|
-
const relativePath =
|
|
2884
|
+
const relativePath = path14.relative(rootPath, filePath);
|
|
2714
2885
|
try {
|
|
2715
|
-
const content = await
|
|
2886
|
+
const content = await fs13.readFile(filePath, "utf-8");
|
|
2716
2887
|
const lines = content.split("\n");
|
|
2717
2888
|
for (const rule of rules) {
|
|
2718
2889
|
const ruleViolations = await evaluateRule(rule, content, lines, relativePath);
|
|
@@ -2803,7 +2974,7 @@ async function evaluateRule(rule, content, lines, filePath) {
|
|
|
2803
2974
|
case "NAMING_CONVENTION": {
|
|
2804
2975
|
const value = rule.value;
|
|
2805
2976
|
const pattern = new RegExp(value.pattern);
|
|
2806
|
-
const fileName =
|
|
2977
|
+
const fileName = path14.basename(filePath);
|
|
2807
2978
|
if (filePath.includes(value.context) && !pattern.test(fileName)) {
|
|
2808
2979
|
violations.push({
|
|
2809
2980
|
file: filePath,
|
|
@@ -2862,12 +3033,12 @@ function checkFunctionLines(content, lines, filePath, rule, limit) {
|
|
|
2862
3033
|
}
|
|
2863
3034
|
function formatViolations(violations) {
|
|
2864
3035
|
for (const v of violations) {
|
|
2865
|
-
const severityColor = v.severity === "critical" ?
|
|
2866
|
-
const lineInfo = v.line ?
|
|
3036
|
+
const severityColor = v.severity === "critical" ? chalk14.red : v.severity === "warning" ? chalk14.yellow : chalk14.blue;
|
|
3037
|
+
const lineInfo = v.line ? chalk14.dim(`:${v.line}`) : "";
|
|
2867
3038
|
console.log(` ${severityColor(`[${v.severity.toUpperCase()}]`)} ${v.file}${lineInfo}`);
|
|
2868
3039
|
console.log(` ${v.message}`);
|
|
2869
3040
|
if (v.details) {
|
|
2870
|
-
console.log(` ${
|
|
3041
|
+
console.log(` ${chalk14.dim(v.details)}`);
|
|
2871
3042
|
}
|
|
2872
3043
|
}
|
|
2873
3044
|
}
|
|
@@ -2896,7 +3067,7 @@ var CACHE_FILE2 = ".rigstate/rules-cache.json";
|
|
|
2896
3067
|
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
2897
3068
|
var CACHE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
2898
3069
|
function createCheckCommand() {
|
|
2899
|
-
return new
|
|
3070
|
+
return new Command10("check").description("Validate code against Guardian architectural rules").argument("[path]", "Directory or file to check", ".").option("--project <id>", "Project ID (or use .rigstate manifest)").option("--strict [level]", 'Exit 1 on violations. Level: "all" (default) or "critical"').option("--staged", "Only check git staged files (for pre-commit hooks)").option("--json", "Output results as JSON").option("--no-cache", "Skip rule cache and fetch fresh from API").action(async (targetPath, options) => {
|
|
2900
3071
|
const spinner = ora7();
|
|
2901
3072
|
try {
|
|
2902
3073
|
let projectId = options.project;
|
|
@@ -2912,15 +3083,15 @@ function createCheckCommand() {
|
|
|
2912
3083
|
projectId = getProjectId();
|
|
2913
3084
|
}
|
|
2914
3085
|
if (!projectId) {
|
|
2915
|
-
console.log(
|
|
2916
|
-
console.log(
|
|
3086
|
+
console.log(chalk15.red("\u274C No project context found."));
|
|
3087
|
+
console.log(chalk15.dim(' Run "rigstate link" or pass --project <id>'));
|
|
2917
3088
|
process.exit(2);
|
|
2918
3089
|
}
|
|
2919
3090
|
let apiKey;
|
|
2920
3091
|
try {
|
|
2921
3092
|
apiKey = getApiKey();
|
|
2922
3093
|
} catch {
|
|
2923
|
-
console.log(
|
|
3094
|
+
console.log(chalk15.red('\u274C Not authenticated. Run "rigstate login" first.'));
|
|
2924
3095
|
process.exit(2);
|
|
2925
3096
|
}
|
|
2926
3097
|
spinner.start("Fetching Guardian rules...");
|
|
@@ -2948,17 +3119,17 @@ function createCheckCommand() {
|
|
|
2948
3119
|
} catch (apiError) {
|
|
2949
3120
|
const cached = await loadCachedRules(projectId);
|
|
2950
3121
|
if (cached && !isStale(cached.timestamp, CACHE_MAX_AGE_MS)) {
|
|
2951
|
-
spinner.warn(
|
|
3122
|
+
spinner.warn(chalk15.yellow("Using cached rules (API unavailable)"));
|
|
2952
3123
|
rules = cached.rules;
|
|
2953
3124
|
settings = cached.settings;
|
|
2954
3125
|
} else {
|
|
2955
|
-
spinner.fail(
|
|
2956
|
-
console.log(
|
|
3126
|
+
spinner.fail(chalk15.red("Failed to fetch rules and no valid cache"));
|
|
3127
|
+
console.log(chalk15.dim(` Error: ${apiError.message}`));
|
|
2957
3128
|
process.exit(2);
|
|
2958
3129
|
}
|
|
2959
3130
|
}
|
|
2960
3131
|
spinner.succeed(`Loaded ${rules.length} Guardian rules`);
|
|
2961
|
-
const scanPath =
|
|
3132
|
+
const scanPath = path15.resolve(process.cwd(), targetPath);
|
|
2962
3133
|
let filesToCheck;
|
|
2963
3134
|
if (options.staged) {
|
|
2964
3135
|
spinner.start("Getting staged files...");
|
|
@@ -2967,14 +3138,14 @@ function createCheckCommand() {
|
|
|
2967
3138
|
encoding: "utf-8",
|
|
2968
3139
|
cwd: process.cwd()
|
|
2969
3140
|
});
|
|
2970
|
-
filesToCheck = stagedOutput.split("\n").filter((f) => f.trim()).filter((f) => isCodeFile2(f)).map((f) =>
|
|
3141
|
+
filesToCheck = stagedOutput.split("\n").filter((f) => f.trim()).filter((f) => isCodeFile2(f)).map((f) => path15.resolve(process.cwd(), f));
|
|
2971
3142
|
} catch {
|
|
2972
3143
|
spinner.fail("Not a git repository or no staged files");
|
|
2973
3144
|
process.exit(2);
|
|
2974
3145
|
}
|
|
2975
3146
|
} else {
|
|
2976
|
-
spinner.start(`Scanning ${
|
|
2977
|
-
const pattern =
|
|
3147
|
+
spinner.start(`Scanning ${chalk15.cyan(targetPath)}...`);
|
|
3148
|
+
const pattern = path15.join(scanPath, "**/*");
|
|
2978
3149
|
const allFiles = await glob3(pattern, {
|
|
2979
3150
|
nodir: true,
|
|
2980
3151
|
dot: false,
|
|
@@ -2990,7 +3161,7 @@ function createCheckCommand() {
|
|
|
2990
3161
|
filesToCheck = allFiles.filter((f) => isCodeFile2(f));
|
|
2991
3162
|
}
|
|
2992
3163
|
if (filesToCheck.length === 0) {
|
|
2993
|
-
spinner.warn(
|
|
3164
|
+
spinner.warn(chalk15.yellow("No code files found to check."));
|
|
2994
3165
|
outputResults([], !!options.json);
|
|
2995
3166
|
process.exit(0);
|
|
2996
3167
|
}
|
|
@@ -2999,7 +3170,7 @@ function createCheckCommand() {
|
|
|
2999
3170
|
const results = [];
|
|
3000
3171
|
for (let i = 0; i < filesToCheck.length; i++) {
|
|
3001
3172
|
const file = filesToCheck[i];
|
|
3002
|
-
spinner.text = `Checking ${i + 1}/${filesToCheck.length}: ${
|
|
3173
|
+
spinner.text = `Checking ${i + 1}/${filesToCheck.length}: ${path15.basename(file)}`;
|
|
3003
3174
|
const result = await checkFile(file, rules, process.cwd());
|
|
3004
3175
|
results.push(result);
|
|
3005
3176
|
}
|
|
@@ -3009,47 +3180,47 @@ function createCheckCommand() {
|
|
|
3009
3180
|
outputResults(results, true);
|
|
3010
3181
|
} else {
|
|
3011
3182
|
outputResults(results, false);
|
|
3012
|
-
console.log("\n" +
|
|
3013
|
-
console.log(
|
|
3014
|
-
console.log(`Files checked: ${
|
|
3015
|
-
console.log(`Total violations: ${summary.totalViolations > 0 ?
|
|
3183
|
+
console.log("\n" + chalk15.bold("\u{1F4CA} Summary"));
|
|
3184
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
3185
|
+
console.log(`Files checked: ${chalk15.cyan(summary.totalFiles)}`);
|
|
3186
|
+
console.log(`Total violations: ${summary.totalViolations > 0 ? chalk15.red(summary.totalViolations) : chalk15.green(0)}`);
|
|
3016
3187
|
if (summary.totalViolations > 0) {
|
|
3017
|
-
console.log(` ${
|
|
3018
|
-
console.log(` ${
|
|
3019
|
-
console.log(` ${
|
|
3188
|
+
console.log(` ${chalk15.red("Critical:")} ${summary.criticalCount}`);
|
|
3189
|
+
console.log(` ${chalk15.yellow("Warning:")} ${summary.warningCount}`);
|
|
3190
|
+
console.log(` ${chalk15.blue("Info:")} ${summary.infoCount}`);
|
|
3020
3191
|
}
|
|
3021
|
-
console.log(
|
|
3192
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
3022
3193
|
}
|
|
3023
3194
|
if (options.strict !== void 0) {
|
|
3024
3195
|
const strictLevel = typeof options.strict === "string" ? options.strict : "all";
|
|
3025
3196
|
if (strictLevel === "critical" && summary.criticalCount > 0) {
|
|
3026
|
-
console.log(
|
|
3197
|
+
console.log(chalk15.red("\n\u274C Check failed: Critical violations found"));
|
|
3027
3198
|
process.exit(1);
|
|
3028
3199
|
} else if (strictLevel === "all" && summary.totalViolations > 0) {
|
|
3029
|
-
console.log(
|
|
3200
|
+
console.log(chalk15.red("\n\u274C Check failed: Violations found"));
|
|
3030
3201
|
process.exit(1);
|
|
3031
3202
|
}
|
|
3032
3203
|
}
|
|
3033
3204
|
if (summary.totalViolations === 0) {
|
|
3034
|
-
console.log(
|
|
3205
|
+
console.log(chalk15.green("\n\u2705 All checks passed!"));
|
|
3035
3206
|
}
|
|
3036
3207
|
process.exit(0);
|
|
3037
3208
|
} catch (error) {
|
|
3038
|
-
spinner.fail(
|
|
3039
|
-
console.error(
|
|
3209
|
+
spinner.fail(chalk15.red("Check failed"));
|
|
3210
|
+
console.error(chalk15.red("Error:"), error.message);
|
|
3040
3211
|
process.exit(2);
|
|
3041
3212
|
}
|
|
3042
3213
|
});
|
|
3043
3214
|
}
|
|
3044
3215
|
function isCodeFile2(filePath) {
|
|
3045
3216
|
const codeExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
3046
|
-
const ext =
|
|
3217
|
+
const ext = path15.extname(filePath).toLowerCase();
|
|
3047
3218
|
return codeExtensions.includes(ext);
|
|
3048
3219
|
}
|
|
3049
3220
|
async function loadCachedRules(projectId) {
|
|
3050
3221
|
try {
|
|
3051
|
-
const cachePath =
|
|
3052
|
-
const content = await
|
|
3222
|
+
const cachePath = path15.join(process.cwd(), CACHE_FILE2);
|
|
3223
|
+
const content = await fs14.readFile(cachePath, "utf-8");
|
|
3053
3224
|
const cached = JSON.parse(content);
|
|
3054
3225
|
if (cached.projectId !== projectId) {
|
|
3055
3226
|
return null;
|
|
@@ -3061,175 +3232,56 @@ async function loadCachedRules(projectId) {
|
|
|
3061
3232
|
}
|
|
3062
3233
|
async function saveCachedRules(projectId, rules, settings) {
|
|
3063
3234
|
try {
|
|
3064
|
-
const cacheDir =
|
|
3065
|
-
await
|
|
3235
|
+
const cacheDir = path15.join(process.cwd(), ".rigstate");
|
|
3236
|
+
await fs14.mkdir(cacheDir, { recursive: true });
|
|
3066
3237
|
const cached = {
|
|
3067
3238
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3068
3239
|
projectId,
|
|
3069
3240
|
rules,
|
|
3070
3241
|
settings
|
|
3071
3242
|
};
|
|
3072
|
-
await
|
|
3073
|
-
|
|
3243
|
+
await fs14.writeFile(
|
|
3244
|
+
path15.join(cacheDir, "rules-cache.json"),
|
|
3074
3245
|
JSON.stringify(cached, null, 2)
|
|
3075
3246
|
);
|
|
3076
3247
|
} catch {
|
|
3077
3248
|
}
|
|
3078
3249
|
}
|
|
3079
|
-
function isStale(timestamp, maxAge) {
|
|
3080
|
-
const age = Date.now() - new Date(timestamp).getTime();
|
|
3081
|
-
return age > maxAge;
|
|
3082
|
-
}
|
|
3083
|
-
function outputResults(results, json) {
|
|
3084
|
-
if (json) {
|
|
3085
|
-
console.log(JSON.stringify({
|
|
3086
|
-
results,
|
|
3087
|
-
summary: summarizeResults(results)
|
|
3088
|
-
}, null, 2));
|
|
3089
|
-
return;
|
|
3090
|
-
}
|
|
3091
|
-
const hasViolations = results.some((r) => r.violations.length > 0);
|
|
3092
|
-
if (!hasViolations) {
|
|
3093
|
-
return;
|
|
3094
|
-
}
|
|
3095
|
-
console.log("\n" +
|
|
3096
|
-
console.log(
|
|
3097
|
-
for (const result of results) {
|
|
3098
|
-
if (result.violations.length > 0) {
|
|
3099
|
-
formatViolations(result.violations);
|
|
3100
|
-
}
|
|
3101
|
-
}
|
|
3102
|
-
}
|
|
3103
|
-
|
|
3104
|
-
// src/commands/hooks.ts
|
|
3105
|
-
init_esm_shims();
|
|
3106
|
-
import { Command as Command10 } from "commander";
|
|
3107
|
-
import chalk15 from "chalk";
|
|
3108
|
-
import fs14 from "fs/promises";
|
|
3109
|
-
import path15 from "path";
|
|
3110
|
-
var PRE_COMMIT_SCRIPT = `#!/bin/sh
|
|
3111
|
-
# Rigstate Guardian Pre-commit Hook
|
|
3112
|
-
# Installed by: rigstate hooks install
|
|
3113
|
-
|
|
3114
|
-
# 1. Silent Sentinel Check (Phase 5)
|
|
3115
|
-
if [ -f .rigstate/guardian.lock ]; then
|
|
3116
|
-
echo "\u{1F6D1} INTERVENTION ACTIVE: Commit blocked by Silent Sentinel."
|
|
3117
|
-
echo " A critical violation ('HARD_LOCK') was detected by the Guardian Daemon."
|
|
3118
|
-
echo " Please fix the violation to unlock the repo."
|
|
3119
|
-
echo ""
|
|
3120
|
-
if grep -q "HARD_LOCK_ACTIVE" .rigstate/guardian.lock; then
|
|
3121
|
-
cat .rigstate/guardian.lock
|
|
3122
|
-
fi
|
|
3123
|
-
exit 1
|
|
3124
|
-
fi
|
|
3125
|
-
|
|
3126
|
-
echo "\u{1F6E1}\uFE0F Running Guardian checks..."
|
|
3127
|
-
|
|
3128
|
-
# Run check with strict mode for critical violations
|
|
3129
|
-
rigstate check --staged --strict=critical
|
|
3130
|
-
|
|
3131
|
-
# Exit with the same code as rigstate check
|
|
3132
|
-
exit $?
|
|
3133
|
-
`;
|
|
3134
|
-
function createHooksCommand() {
|
|
3135
|
-
const hooks = new Command10("hooks").description("Manage git hooks for Guardian integration");
|
|
3136
|
-
hooks.command("install").description("Install pre-commit hook to run Guardian checks").option("--strict [level]", 'Strict level: "all" or "critical" (default)', "critical").action(async (options) => {
|
|
3137
|
-
try {
|
|
3138
|
-
const gitDir = path15.join(process.cwd(), ".git");
|
|
3139
|
-
try {
|
|
3140
|
-
await fs14.access(gitDir);
|
|
3141
|
-
} catch {
|
|
3142
|
-
console.log(chalk15.red("\u274C Not a git repository."));
|
|
3143
|
-
console.log(chalk15.dim(' Initialize with "git init" first.'));
|
|
3144
|
-
process.exit(1);
|
|
3145
|
-
}
|
|
3146
|
-
const hooksDir = path15.join(gitDir, "hooks");
|
|
3147
|
-
await fs14.mkdir(hooksDir, { recursive: true });
|
|
3148
|
-
const preCommitPath = path15.join(hooksDir, "pre-commit");
|
|
3149
|
-
let existingContent = "";
|
|
3150
|
-
try {
|
|
3151
|
-
existingContent = await fs14.readFile(preCommitPath, "utf-8");
|
|
3152
|
-
if (existingContent.includes("rigstate")) {
|
|
3153
|
-
console.log(chalk15.yellow("\u26A0 Rigstate pre-commit hook already installed."));
|
|
3154
|
-
console.log(chalk15.dim(' Use "rigstate hooks uninstall" to remove first.'));
|
|
3155
|
-
return;
|
|
3156
|
-
}
|
|
3157
|
-
} catch {
|
|
3158
|
-
}
|
|
3159
|
-
let script = PRE_COMMIT_SCRIPT;
|
|
3160
|
-
if (options.strict === "all") {
|
|
3161
|
-
script = script.replace("--strict=critical", "--strict");
|
|
3162
|
-
}
|
|
3163
|
-
if (existingContent && !existingContent.includes("rigstate")) {
|
|
3164
|
-
const combinedScript = existingContent + "\n\n" + script.replace("#!/bin/sh\n", "");
|
|
3165
|
-
await fs14.writeFile(preCommitPath, combinedScript, { mode: 493 });
|
|
3166
|
-
console.log(chalk15.green("\u2705 Rigstate hook appended to existing pre-commit."));
|
|
3167
|
-
} else {
|
|
3168
|
-
await fs14.writeFile(preCommitPath, script, { mode: 493 });
|
|
3169
|
-
console.log(chalk15.green("\u2705 Pre-commit hook installed!"));
|
|
3170
|
-
}
|
|
3171
|
-
console.log(chalk15.dim(` Path: ${preCommitPath}`));
|
|
3172
|
-
console.log(chalk15.dim(` Strict level: ${options.strict}`));
|
|
3173
|
-
console.log("");
|
|
3174
|
-
console.log(chalk15.cyan("Guardian will now check your code before each commit."));
|
|
3175
|
-
console.log(chalk15.dim('Use "rigstate hooks uninstall" to remove the hook.'));
|
|
3176
|
-
} catch (error) {
|
|
3177
|
-
console.error(chalk15.red("Failed to install hook:"), error.message);
|
|
3178
|
-
process.exit(1);
|
|
3179
|
-
}
|
|
3180
|
-
});
|
|
3181
|
-
hooks.command("uninstall").description("Remove Rigstate pre-commit hook").action(async () => {
|
|
3182
|
-
try {
|
|
3183
|
-
const preCommitPath = path15.join(process.cwd(), ".git", "hooks", "pre-commit");
|
|
3184
|
-
try {
|
|
3185
|
-
const content = await fs14.readFile(preCommitPath, "utf-8");
|
|
3186
|
-
if (!content.includes("rigstate")) {
|
|
3187
|
-
console.log(chalk15.yellow("\u26A0 No Rigstate hook found in pre-commit."));
|
|
3188
|
-
return;
|
|
3189
|
-
}
|
|
3190
|
-
if (content.includes("# Rigstate Guardian Pre-commit Hook") && content.trim().split("\n").filter((l) => l && !l.startsWith("#")).length <= 4) {
|
|
3191
|
-
await fs14.unlink(preCommitPath);
|
|
3192
|
-
console.log(chalk15.green("\u2705 Pre-commit hook removed."));
|
|
3193
|
-
} else {
|
|
3194
|
-
const lines = content.split("\n");
|
|
3195
|
-
const filteredLines = [];
|
|
3196
|
-
let inRigstateSection = false;
|
|
3197
|
-
for (const line of lines) {
|
|
3198
|
-
if (line.includes("Rigstate Guardian Pre-commit Hook")) {
|
|
3199
|
-
inRigstateSection = true;
|
|
3200
|
-
continue;
|
|
3201
|
-
}
|
|
3202
|
-
if (inRigstateSection && line.includes("exit $?")) {
|
|
3203
|
-
inRigstateSection = false;
|
|
3204
|
-
continue;
|
|
3205
|
-
}
|
|
3206
|
-
if (!inRigstateSection && !line.includes("rigstate check")) {
|
|
3207
|
-
filteredLines.push(line);
|
|
3208
|
-
}
|
|
3209
|
-
}
|
|
3210
|
-
await fs14.writeFile(preCommitPath, filteredLines.join("\n"), { mode: 493 });
|
|
3211
|
-
console.log(chalk15.green("\u2705 Rigstate section removed from pre-commit hook."));
|
|
3212
|
-
}
|
|
3213
|
-
} catch {
|
|
3214
|
-
console.log(chalk15.yellow("\u26A0 No pre-commit hook found."));
|
|
3215
|
-
}
|
|
3216
|
-
} catch (error) {
|
|
3217
|
-
console.error(chalk15.red("Failed to uninstall hook:"), error.message);
|
|
3218
|
-
process.exit(1);
|
|
3250
|
+
function isStale(timestamp, maxAge) {
|
|
3251
|
+
const age = Date.now() - new Date(timestamp).getTime();
|
|
3252
|
+
return age > maxAge;
|
|
3253
|
+
}
|
|
3254
|
+
function outputResults(results, json) {
|
|
3255
|
+
if (json) {
|
|
3256
|
+
console.log(JSON.stringify({
|
|
3257
|
+
results,
|
|
3258
|
+
summary: summarizeResults(results)
|
|
3259
|
+
}, null, 2));
|
|
3260
|
+
return;
|
|
3261
|
+
}
|
|
3262
|
+
const hasViolations = results.some((r) => r.violations.length > 0);
|
|
3263
|
+
if (!hasViolations) {
|
|
3264
|
+
return;
|
|
3265
|
+
}
|
|
3266
|
+
console.log("\n" + chalk15.bold("\u{1F50D} Violations Found"));
|
|
3267
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
3268
|
+
for (const result of results) {
|
|
3269
|
+
if (result.violations.length > 0) {
|
|
3270
|
+
formatViolations(result.violations);
|
|
3219
3271
|
}
|
|
3220
|
-
}
|
|
3221
|
-
return hooks;
|
|
3272
|
+
}
|
|
3222
3273
|
}
|
|
3223
3274
|
|
|
3275
|
+
// src/index.ts
|
|
3276
|
+
init_hooks();
|
|
3277
|
+
|
|
3224
3278
|
// src/commands/daemon.ts
|
|
3225
3279
|
init_esm_shims();
|
|
3226
3280
|
import { Command as Command11 } from "commander";
|
|
3227
|
-
import
|
|
3281
|
+
import chalk21 from "chalk";
|
|
3228
3282
|
import ora8 from "ora";
|
|
3229
|
-
import
|
|
3230
|
-
import
|
|
3231
|
-
import { execSync as execSync3 } from "child_process";
|
|
3232
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3283
|
+
import fs19 from "fs/promises";
|
|
3284
|
+
import path22 from "path";
|
|
3233
3285
|
|
|
3234
3286
|
// src/daemon/factory.ts
|
|
3235
3287
|
init_esm_shims();
|
|
@@ -3238,6 +3290,7 @@ init_esm_shims();
|
|
|
3238
3290
|
init_esm_shims();
|
|
3239
3291
|
import chalk19 from "chalk";
|
|
3240
3292
|
import * as fs17 from "fs/promises";
|
|
3293
|
+
import path20 from "path";
|
|
3241
3294
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
3242
3295
|
|
|
3243
3296
|
// src/daemon/file-watcher.ts
|
|
@@ -3905,6 +3958,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
3905
3958
|
}
|
|
3906
3959
|
}
|
|
3907
3960
|
this.printActive();
|
|
3961
|
+
await this.updateViolationReport([]);
|
|
3908
3962
|
this.emit("started", this.state);
|
|
3909
3963
|
}
|
|
3910
3964
|
printWelcome() {
|
|
@@ -3927,7 +3981,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
3927
3981
|
setupFileWatcher() {
|
|
3928
3982
|
Logger.info("Starting file watcher...");
|
|
3929
3983
|
this.fileWatcher = createFileWatcher(this.config.watchPath);
|
|
3930
|
-
this.fileWatcher.on("change", (
|
|
3984
|
+
this.fileWatcher.on("change", (path27) => this.handleFileChange(path27));
|
|
3931
3985
|
this.fileWatcher.start();
|
|
3932
3986
|
Logger.info("File watcher active");
|
|
3933
3987
|
}
|
|
@@ -3968,11 +4022,37 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
3968
4022
|
this.state.filesChecked++;
|
|
3969
4023
|
if (result.violations.length > 0) {
|
|
3970
4024
|
this.handleViolations(filePath, result.violations);
|
|
4025
|
+
} else {
|
|
4026
|
+
await this.updateViolationReport([]);
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
async updateViolationReport(violations) {
|
|
4030
|
+
const reportPath = path20.join(process.cwd(), ".rigstate", "ACTIVE_VIOLATIONS.md");
|
|
4031
|
+
let content = `# \u{1F6E1}\uFE0F Guardian Status: ${violations.length > 0 ? "\u26A0\uFE0F ATTENTION" : "\u2705 PASS"}
|
|
4032
|
+
|
|
4033
|
+
`;
|
|
4034
|
+
content += `*Last check: ${(/* @__PURE__ */ new Date()).toLocaleString()}*
|
|
4035
|
+
|
|
4036
|
+
`;
|
|
4037
|
+
if (violations.length === 0) {
|
|
4038
|
+
content += "All systems within architectural limits. Frank is satisfied. \u{1F92B}\n";
|
|
4039
|
+
} else {
|
|
4040
|
+
content += "### \u{1F6A8} Active Violations\n\n";
|
|
4041
|
+
for (const v of violations) {
|
|
4042
|
+
content += `- **[${v.severity.toUpperCase()}]**: ${v.message}
|
|
4043
|
+
`;
|
|
4044
|
+
}
|
|
4045
|
+
content += "\n---\n*Rigstate Daemon is watching. Fix violations to clear this report.*";
|
|
4046
|
+
}
|
|
4047
|
+
try {
|
|
4048
|
+
await fs17.writeFile(reportPath, content, "utf-8");
|
|
4049
|
+
} catch (e) {
|
|
3971
4050
|
}
|
|
3972
4051
|
}
|
|
3973
4052
|
handleViolations(filePath, violations) {
|
|
3974
4053
|
this.state.violationsFound += violations.length;
|
|
3975
4054
|
this.emit("violation", { file: filePath, violations });
|
|
4055
|
+
this.updateViolationReport(violations);
|
|
3976
4056
|
for (const v of violations) {
|
|
3977
4057
|
const level = v.severity === "critical" ? "error" : v.severity === "warning" ? "warn" : "info";
|
|
3978
4058
|
Logger[level](`[${v.severity.toUpperCase()}] ${filePath}: ${v.message}`);
|
|
@@ -4039,6 +4119,102 @@ async function createDaemon(options) {
|
|
|
4039
4119
|
return new GuardianDaemon(config2);
|
|
4040
4120
|
}
|
|
4041
4121
|
|
|
4122
|
+
// src/utils/service-manager.ts
|
|
4123
|
+
init_esm_shims();
|
|
4124
|
+
import chalk20 from "chalk";
|
|
4125
|
+
import fs18 from "fs/promises";
|
|
4126
|
+
import path21 from "path";
|
|
4127
|
+
import { execSync as execSync3 } from "child_process";
|
|
4128
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4129
|
+
async function execShellCommand(cmd) {
|
|
4130
|
+
try {
|
|
4131
|
+
const output = execSync3(cmd, { stdio: "pipe" }).toString();
|
|
4132
|
+
return output;
|
|
4133
|
+
} catch (error) {
|
|
4134
|
+
return error.stderr?.toString() || error.stdout?.toString() || error.message;
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4137
|
+
async function enableDaemon() {
|
|
4138
|
+
console.log(chalk20.bold("\n\u2699\uFE0F Enabling Rigstate Background Service (macOS)\n"));
|
|
4139
|
+
if (process.platform !== "darwin") {
|
|
4140
|
+
console.error(chalk20.red("\u274C Currently only macOS is supported for auto-start."));
|
|
4141
|
+
console.error(chalk20.yellow("PRs welcome for Linux/Windows support!"));
|
|
4142
|
+
return;
|
|
4143
|
+
}
|
|
4144
|
+
const homeDir = process.env.HOME || "";
|
|
4145
|
+
if (!homeDir) {
|
|
4146
|
+
console.error(chalk20.red("\u274C Could not determine HOME directory."));
|
|
4147
|
+
return;
|
|
4148
|
+
}
|
|
4149
|
+
const agentsDir = path21.join(homeDir, "Library/LaunchAgents");
|
|
4150
|
+
const logDir = path21.join(homeDir, ".rigstate/logs");
|
|
4151
|
+
const plistPath = path21.join(agentsDir, "com.rigstate.daemon.plist");
|
|
4152
|
+
await fs18.mkdir(agentsDir, { recursive: true });
|
|
4153
|
+
await fs18.mkdir(logDir, { recursive: true });
|
|
4154
|
+
const scriptPath = fileURLToPath2(import.meta.url);
|
|
4155
|
+
const nodePath = process.execPath;
|
|
4156
|
+
const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
4157
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
4158
|
+
<plist version="1.0">
|
|
4159
|
+
<dict>
|
|
4160
|
+
<key>Label</key>
|
|
4161
|
+
<string>com.rigstate.daemon</string>
|
|
4162
|
+
<key>ProgramArguments</key>
|
|
4163
|
+
<array>
|
|
4164
|
+
<string>${nodePath}</string>
|
|
4165
|
+
<string>${scriptPath}</string>
|
|
4166
|
+
<string>daemon</string>
|
|
4167
|
+
<string>--no-bridge</string>
|
|
4168
|
+
</array>
|
|
4169
|
+
<key>WorkingDirectory</key>
|
|
4170
|
+
<string>${process.cwd()}</string>
|
|
4171
|
+
<key>StandardOutPath</key>
|
|
4172
|
+
<string>${path21.join(logDir, "daemon.out.log")}</string>
|
|
4173
|
+
<key>StandardErrorPath</key>
|
|
4174
|
+
<string>${path21.join(logDir, "daemon.err.log")}</string>
|
|
4175
|
+
<key>RunAtLoad</key>
|
|
4176
|
+
<true/>
|
|
4177
|
+
<key>KeepAlive</key>
|
|
4178
|
+
<true/>
|
|
4179
|
+
<key>EnvironmentVariables</key>
|
|
4180
|
+
<dict>
|
|
4181
|
+
<key>PATH</key>
|
|
4182
|
+
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:${process.env.PATH}</string>
|
|
4183
|
+
</dict>
|
|
4184
|
+
</dict>
|
|
4185
|
+
</plist>`;
|
|
4186
|
+
try {
|
|
4187
|
+
await fs18.writeFile(plistPath, plistContent);
|
|
4188
|
+
console.log(chalk20.dim(`Created plist at: ${plistPath}`));
|
|
4189
|
+
try {
|
|
4190
|
+
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
4191
|
+
} catch (e) {
|
|
4192
|
+
}
|
|
4193
|
+
await execShellCommand(`launchctl load ${plistPath}`);
|
|
4194
|
+
console.log(chalk20.green("\u2705 Successfully enabled background daemon!"));
|
|
4195
|
+
console.log(chalk20.dim(`Logs: ${logDir}`));
|
|
4196
|
+
console.log(chalk20.dim("The daemon will now restart automatically if it crashes or on reboot."));
|
|
4197
|
+
} catch (error) {
|
|
4198
|
+
console.error(chalk20.red("\u274C Failed to enable daemon:"), error.message);
|
|
4199
|
+
}
|
|
4200
|
+
}
|
|
4201
|
+
async function disableDaemon() {
|
|
4202
|
+
console.log(chalk20.bold("\n\u2699\uFE0F Disabling Rigstate Background Service\n"));
|
|
4203
|
+
const homeDir = process.env.HOME || "";
|
|
4204
|
+
const plistPath = path21.join(homeDir, "Library/LaunchAgents/com.rigstate.daemon.plist");
|
|
4205
|
+
try {
|
|
4206
|
+
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
4207
|
+
await fs18.unlink(plistPath);
|
|
4208
|
+
console.log(chalk20.green("\u2705 Successfully disabled background daemon."));
|
|
4209
|
+
} catch (error) {
|
|
4210
|
+
if (error.code === "ENOENT") {
|
|
4211
|
+
console.log(chalk20.green("\u2705 Daemon was not enabled."));
|
|
4212
|
+
} else {
|
|
4213
|
+
console.error(chalk20.red("\u274C Failed to disable daemon:"), error.message);
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
|
|
4042
4218
|
// src/commands/daemon.ts
|
|
4043
4219
|
var PID_FILE = ".rigstate/daemon.pid";
|
|
4044
4220
|
var STATE_FILE = ".rigstate/daemon.state.json";
|
|
@@ -4059,17 +4235,17 @@ function createDaemonCommand() {
|
|
|
4059
4235
|
}
|
|
4060
4236
|
const spinner = ora8();
|
|
4061
4237
|
try {
|
|
4062
|
-
const pidPath =
|
|
4238
|
+
const pidPath = path22.join(process.cwd(), PID_FILE);
|
|
4063
4239
|
try {
|
|
4064
|
-
const content = await
|
|
4240
|
+
const content = await fs19.readFile(pidPath, "utf-8");
|
|
4065
4241
|
const pid = parseInt(content.trim(), 10);
|
|
4066
4242
|
try {
|
|
4067
4243
|
process.kill(pid, 0);
|
|
4068
|
-
console.log(
|
|
4069
|
-
console.log(
|
|
4244
|
+
console.log(chalk21.yellow("\u26A0 Another daemon instance is active (PID " + pid + ")."));
|
|
4245
|
+
console.log(chalk21.dim(` Run "rigstate daemon status" for details or Ctrl+C to stop.
|
|
4070
4246
|
`));
|
|
4071
4247
|
} catch {
|
|
4072
|
-
await
|
|
4248
|
+
await fs19.unlink(pidPath).catch(() => {
|
|
4073
4249
|
});
|
|
4074
4250
|
}
|
|
4075
4251
|
} catch {
|
|
@@ -4084,7 +4260,7 @@ function createDaemonCommand() {
|
|
|
4084
4260
|
spinner.stop();
|
|
4085
4261
|
await writePidFile();
|
|
4086
4262
|
process.on("SIGINT", async () => {
|
|
4087
|
-
console.log(
|
|
4263
|
+
console.log(chalk21.dim("\n\nShutting down..."));
|
|
4088
4264
|
await daemonInstance.stop();
|
|
4089
4265
|
await cleanupPidFile();
|
|
4090
4266
|
process.exit(0);
|
|
@@ -4104,8 +4280,8 @@ function createDaemonCommand() {
|
|
|
4104
4280
|
await new Promise(() => {
|
|
4105
4281
|
});
|
|
4106
4282
|
} catch (error) {
|
|
4107
|
-
spinner.fail(
|
|
4108
|
-
console.error(
|
|
4283
|
+
spinner.fail(chalk21.red("Failed to start daemon"));
|
|
4284
|
+
console.error(chalk21.red("Error:"), error.message);
|
|
4109
4285
|
process.exit(1);
|
|
4110
4286
|
}
|
|
4111
4287
|
});
|
|
@@ -4113,14 +4289,14 @@ function createDaemonCommand() {
|
|
|
4113
4289
|
}
|
|
4114
4290
|
async function isRunning() {
|
|
4115
4291
|
try {
|
|
4116
|
-
const pidPath =
|
|
4117
|
-
const content = await
|
|
4292
|
+
const pidPath = path22.join(process.cwd(), PID_FILE);
|
|
4293
|
+
const content = await fs19.readFile(pidPath, "utf-8");
|
|
4118
4294
|
const pid = parseInt(content.trim(), 10);
|
|
4119
4295
|
try {
|
|
4120
4296
|
process.kill(pid, 0);
|
|
4121
4297
|
return true;
|
|
4122
4298
|
} catch {
|
|
4123
|
-
await
|
|
4299
|
+
await fs19.unlink(pidPath);
|
|
4124
4300
|
return false;
|
|
4125
4301
|
}
|
|
4126
4302
|
} catch {
|
|
@@ -4129,156 +4305,68 @@ async function isRunning() {
|
|
|
4129
4305
|
}
|
|
4130
4306
|
async function writePidFile() {
|
|
4131
4307
|
try {
|
|
4132
|
-
const dir =
|
|
4133
|
-
await
|
|
4134
|
-
await
|
|
4308
|
+
const dir = path22.join(process.cwd(), ".rigstate");
|
|
4309
|
+
await fs19.mkdir(dir, { recursive: true });
|
|
4310
|
+
await fs19.writeFile(path22.join(dir, "daemon.pid"), process.pid.toString());
|
|
4135
4311
|
} catch {
|
|
4136
4312
|
}
|
|
4137
4313
|
}
|
|
4138
4314
|
async function cleanupPidFile() {
|
|
4139
4315
|
try {
|
|
4140
|
-
await
|
|
4141
|
-
await
|
|
4316
|
+
await fs19.unlink(path22.join(process.cwd(), PID_FILE));
|
|
4317
|
+
await fs19.unlink(path22.join(process.cwd(), STATE_FILE));
|
|
4142
4318
|
} catch {
|
|
4143
4319
|
}
|
|
4144
4320
|
}
|
|
4145
4321
|
async function writeStateFile(state) {
|
|
4146
4322
|
try {
|
|
4147
|
-
const dir =
|
|
4148
|
-
await
|
|
4149
|
-
await
|
|
4150
|
-
|
|
4323
|
+
const dir = path22.join(process.cwd(), ".rigstate");
|
|
4324
|
+
await fs19.mkdir(dir, { recursive: true });
|
|
4325
|
+
await fs19.writeFile(
|
|
4326
|
+
path22.join(dir, "daemon.state.json"),
|
|
4151
4327
|
JSON.stringify(state, null, 2)
|
|
4152
4328
|
);
|
|
4153
4329
|
} catch {
|
|
4154
4330
|
}
|
|
4155
4331
|
}
|
|
4156
4332
|
async function showStatus() {
|
|
4157
|
-
console.log(
|
|
4333
|
+
console.log(chalk21.bold("\n\u{1F6E1}\uFE0F Guardian Daemon Status\n"));
|
|
4158
4334
|
const running = await isRunning();
|
|
4159
4335
|
if (!running) {
|
|
4160
|
-
console.log(
|
|
4161
|
-
console.log(
|
|
4336
|
+
console.log(chalk21.yellow("Status: Not running"));
|
|
4337
|
+
console.log(chalk21.dim('Use "rigstate daemon" to start.\n'));
|
|
4162
4338
|
return;
|
|
4163
4339
|
}
|
|
4164
|
-
console.log(
|
|
4340
|
+
console.log(chalk21.green("Status: Running"));
|
|
4165
4341
|
try {
|
|
4166
|
-
const statePath =
|
|
4167
|
-
const content = await
|
|
4342
|
+
const statePath = path22.join(process.cwd(), STATE_FILE);
|
|
4343
|
+
const content = await fs19.readFile(statePath, "utf-8");
|
|
4168
4344
|
const state = JSON.parse(content);
|
|
4169
|
-
console.log(
|
|
4345
|
+
console.log(chalk21.dim("\u2500".repeat(40)));
|
|
4170
4346
|
console.log(`Started at: ${state.startedAt || "Unknown"}`);
|
|
4171
4347
|
console.log(`Files checked: ${state.filesChecked || 0}`);
|
|
4172
4348
|
console.log(`Violations: ${state.violationsFound || 0}`);
|
|
4173
4349
|
console.log(`Tasks processed: ${state.tasksProcessed || 0}`);
|
|
4174
4350
|
console.log(`Last activity: ${state.lastActivity || "None"}`);
|
|
4175
|
-
console.log(
|
|
4351
|
+
console.log(chalk21.dim("\u2500".repeat(40)));
|
|
4176
4352
|
} catch {
|
|
4177
|
-
console.log(
|
|
4353
|
+
console.log(chalk21.dim("(State file not found)"));
|
|
4178
4354
|
}
|
|
4179
4355
|
try {
|
|
4180
|
-
const pidPath =
|
|
4181
|
-
const pid = await
|
|
4182
|
-
console.log(
|
|
4356
|
+
const pidPath = path22.join(process.cwd(), PID_FILE);
|
|
4357
|
+
const pid = await fs19.readFile(pidPath, "utf-8");
|
|
4358
|
+
console.log(chalk21.dim(`PID: ${pid.trim()}`));
|
|
4183
4359
|
} catch {
|
|
4184
4360
|
}
|
|
4185
4361
|
console.log("");
|
|
4186
4362
|
}
|
|
4187
|
-
async function enableDaemon() {
|
|
4188
|
-
console.log(chalk20.bold("\n\u2699\uFE0F Enabling Rigstate Background Service (macOS)\n"));
|
|
4189
|
-
if (process.platform !== "darwin") {
|
|
4190
|
-
console.error(chalk20.red("\u274C Currently only macOS is supported for auto-start."));
|
|
4191
|
-
console.error(chalk20.yellow("PRs welcome for Linux/Windows support!"));
|
|
4192
|
-
return;
|
|
4193
|
-
}
|
|
4194
|
-
const homeDir = process.env.HOME || "";
|
|
4195
|
-
if (!homeDir) {
|
|
4196
|
-
console.error(chalk20.red("\u274C Could not determine HOME directory."));
|
|
4197
|
-
return;
|
|
4198
|
-
}
|
|
4199
|
-
const agentsDir = path20.join(homeDir, "Library/LaunchAgents");
|
|
4200
|
-
const logDir = path20.join(homeDir, ".rigstate/logs");
|
|
4201
|
-
const plistPath = path20.join(agentsDir, "com.rigstate.daemon.plist");
|
|
4202
|
-
await fs18.mkdir(agentsDir, { recursive: true });
|
|
4203
|
-
await fs18.mkdir(logDir, { recursive: true });
|
|
4204
|
-
const scriptPath = fileURLToPath2(import.meta.url);
|
|
4205
|
-
const nodePath = process.execPath;
|
|
4206
|
-
const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
4207
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
4208
|
-
<plist version="1.0">
|
|
4209
|
-
<dict>
|
|
4210
|
-
<key>Label</key>
|
|
4211
|
-
<string>com.rigstate.daemon</string>
|
|
4212
|
-
<key>ProgramArguments</key>
|
|
4213
|
-
<array>
|
|
4214
|
-
<string>${nodePath}</string>
|
|
4215
|
-
<string>${scriptPath}</string>
|
|
4216
|
-
<string>daemon</string>
|
|
4217
|
-
<string>--no-bridge</string>
|
|
4218
|
-
</array>
|
|
4219
|
-
<key>WorkingDirectory</key>
|
|
4220
|
-
<string>${process.cwd()}</string>
|
|
4221
|
-
<key>StandardOutPath</key>
|
|
4222
|
-
<string>${path20.join(logDir, "daemon.out.log")}</string>
|
|
4223
|
-
<key>StandardErrorPath</key>
|
|
4224
|
-
<string>${path20.join(logDir, "daemon.err.log")}</string>
|
|
4225
|
-
<key>RunAtLoad</key>
|
|
4226
|
-
<true/>
|
|
4227
|
-
<key>KeepAlive</key>
|
|
4228
|
-
<true/>
|
|
4229
|
-
<key>EnvironmentVariables</key>
|
|
4230
|
-
<dict>
|
|
4231
|
-
<key>PATH</key>
|
|
4232
|
-
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:${process.env.PATH}</string>
|
|
4233
|
-
</dict>
|
|
4234
|
-
</dict>
|
|
4235
|
-
</plist>`;
|
|
4236
|
-
try {
|
|
4237
|
-
await fs18.writeFile(plistPath, plistContent);
|
|
4238
|
-
console.log(chalk20.dim(`Created plist at: ${plistPath}`));
|
|
4239
|
-
try {
|
|
4240
|
-
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
4241
|
-
} catch (e) {
|
|
4242
|
-
}
|
|
4243
|
-
await execShellCommand(`launchctl load ${plistPath}`);
|
|
4244
|
-
console.log(chalk20.green("\u2705 Successfully enabled background daemon!"));
|
|
4245
|
-
console.log(chalk20.dim(`Logs: ${logDir}`));
|
|
4246
|
-
console.log(chalk20.dim("The daemon will now restart automatically if it crashes or on reboot."));
|
|
4247
|
-
} catch (error) {
|
|
4248
|
-
console.error(chalk20.red("\u274C Failed to enable daemon:"), error.message);
|
|
4249
|
-
}
|
|
4250
|
-
}
|
|
4251
|
-
async function disableDaemon() {
|
|
4252
|
-
console.log(chalk20.bold("\n\u2699\uFE0F Disabling Rigstate Background Service\n"));
|
|
4253
|
-
const homeDir = process.env.HOME || "";
|
|
4254
|
-
const plistPath = path20.join(homeDir, "Library/LaunchAgents/com.rigstate.daemon.plist");
|
|
4255
|
-
try {
|
|
4256
|
-
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
4257
|
-
await fs18.unlink(plistPath);
|
|
4258
|
-
console.log(chalk20.green("\u2705 Successfully disabled background daemon."));
|
|
4259
|
-
} catch (error) {
|
|
4260
|
-
if (error.code === "ENOENT") {
|
|
4261
|
-
console.log(chalk20.green("\u2705 Daemon was not enabled."));
|
|
4262
|
-
} else {
|
|
4263
|
-
console.error(chalk20.red("\u274C Failed to disable daemon:"), error.message);
|
|
4264
|
-
}
|
|
4265
|
-
}
|
|
4266
|
-
}
|
|
4267
|
-
async function execShellCommand(cmd) {
|
|
4268
|
-
try {
|
|
4269
|
-
const output = execSync3(cmd, { stdio: "pipe" }).toString();
|
|
4270
|
-
return output;
|
|
4271
|
-
} catch (error) {
|
|
4272
|
-
return error.stderr?.toString() || error.stdout?.toString() || error.message;
|
|
4273
|
-
}
|
|
4274
|
-
}
|
|
4275
4363
|
|
|
4276
4364
|
// src/commands/work.ts
|
|
4277
4365
|
init_esm_shims();
|
|
4278
4366
|
init_config();
|
|
4279
4367
|
init_suggest();
|
|
4280
4368
|
import { Command as Command12 } from "commander";
|
|
4281
|
-
import
|
|
4369
|
+
import chalk22 from "chalk";
|
|
4282
4370
|
import ora9 from "ora";
|
|
4283
4371
|
import axios15 from "axios";
|
|
4284
4372
|
import inquirer2 from "inquirer";
|
|
@@ -4313,7 +4401,7 @@ async function listInteractive() {
|
|
|
4313
4401
|
});
|
|
4314
4402
|
spinner.stop();
|
|
4315
4403
|
if (actionableTasks.length === 0) {
|
|
4316
|
-
console.log(
|
|
4404
|
+
console.log(chalk22.yellow("Roadmap clear. No actionable tasks found."));
|
|
4317
4405
|
return;
|
|
4318
4406
|
}
|
|
4319
4407
|
const choices = actionableTasks.map((t) => {
|
|
@@ -4322,7 +4410,7 @@ async function listInteractive() {
|
|
|
4322
4410
|
if (t.status === "IN_PROGRESS") icon = "\u{1F525}";
|
|
4323
4411
|
if (t.status === "ACTIVE") icon = "\u25B6\uFE0F";
|
|
4324
4412
|
return {
|
|
4325
|
-
name: `${icon} ${
|
|
4413
|
+
name: `${icon} ${chalk22.bold(id)}: ${t.title} [${t.status}]`,
|
|
4326
4414
|
value: t.id
|
|
4327
4415
|
};
|
|
4328
4416
|
});
|
|
@@ -4365,25 +4453,25 @@ async function setTaskStatus(taskId, status) {
|
|
|
4365
4453
|
{ step_id: realId, status, project_id: projectId },
|
|
4366
4454
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
4367
4455
|
);
|
|
4368
|
-
spinner.succeed(
|
|
4456
|
+
spinner.succeed(chalk22.green(`Task updated to ${status}.`));
|
|
4369
4457
|
if (status === "IN_PROGRESS") {
|
|
4370
|
-
console.log(
|
|
4458
|
+
console.log(chalk22.blue(`
|
|
4371
4459
|
\u{1F4A1} Tip: Provide 'Frank' with context by mentioning @.cursorrules in your chat.`));
|
|
4372
4460
|
}
|
|
4373
4461
|
} catch (e) {
|
|
4374
|
-
spinner.fail(
|
|
4462
|
+
spinner.fail(chalk22.red(`Failed: ${e.message}`));
|
|
4375
4463
|
}
|
|
4376
4464
|
}
|
|
4377
4465
|
async function finishTask(taskId) {
|
|
4378
4466
|
console.log("");
|
|
4379
|
-
console.log(
|
|
4380
|
-
console.log(
|
|
4467
|
+
console.log(chalk22.bold.yellow("\u{1F6E1}\uFE0F FRANK'S QUALITY GATE"));
|
|
4468
|
+
console.log(chalk22.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
4381
4469
|
const auditSpinner = ora9(" Analyzing architectural integrity...").start();
|
|
4382
4470
|
await new Promise((r) => setTimeout(r, 1500));
|
|
4383
4471
|
auditSpinner.succeed("Architecture: VALIDATED (SEC-ARCH-01 Pass)");
|
|
4384
4472
|
await setTaskStatus(taskId, "COMPLETED");
|
|
4385
4473
|
console.log("");
|
|
4386
|
-
console.log(
|
|
4474
|
+
console.log(chalk22.bold.green("\u{1F389} TASK COMPLETE! Momentum Preserved."));
|
|
4387
4475
|
const { projectId, apiKey, apiUrl } = getContext();
|
|
4388
4476
|
await suggestNextMove(projectId, apiKey, apiUrl);
|
|
4389
4477
|
}
|
|
@@ -4401,39 +4489,39 @@ function getContext() {
|
|
|
4401
4489
|
init_esm_shims();
|
|
4402
4490
|
init_config();
|
|
4403
4491
|
import { Command as Command13 } from "commander";
|
|
4404
|
-
import
|
|
4492
|
+
import chalk23 from "chalk";
|
|
4405
4493
|
import ora10 from "ora";
|
|
4406
4494
|
import chokidar2 from "chokidar";
|
|
4407
|
-
import
|
|
4408
|
-
import
|
|
4495
|
+
import fs20 from "fs/promises";
|
|
4496
|
+
import path23 from "path";
|
|
4409
4497
|
import { execSync as execSync4 } from "child_process";
|
|
4410
4498
|
import axios16 from "axios";
|
|
4411
4499
|
function createWatchCommand() {
|
|
4412
4500
|
const watch2 = new Command13("watch");
|
|
4413
4501
|
watch2.description("Watch for changes and auto-verify roadmap tasks").option("--no-auto-commit", "Disable auto-commit on verification").option("--no-auto-push", "Disable auto-push after commit").option("--run-tests", "Run tests before committing").option("--test-command <cmd>", "Custom test command (default: npm test)").action(async (options) => {
|
|
4414
|
-
console.log(
|
|
4415
|
-
console.log(
|
|
4502
|
+
console.log(chalk23.bold.blue("\u{1F52D} Rigstate Watch Mode"));
|
|
4503
|
+
console.log(chalk23.dim("Monitoring for task completion..."));
|
|
4416
4504
|
console.log("");
|
|
4417
4505
|
let apiKey;
|
|
4418
4506
|
let projectId;
|
|
4419
4507
|
try {
|
|
4420
4508
|
apiKey = getApiKey();
|
|
4421
4509
|
} catch (e) {
|
|
4422
|
-
console.log(
|
|
4510
|
+
console.log(chalk23.red('Not authenticated. Run "rigstate login" first.'));
|
|
4423
4511
|
return;
|
|
4424
4512
|
}
|
|
4425
4513
|
projectId = getProjectId();
|
|
4426
4514
|
if (!projectId) {
|
|
4427
4515
|
try {
|
|
4428
|
-
const manifestPath =
|
|
4429
|
-
const content = await
|
|
4516
|
+
const manifestPath = path23.join(process.cwd(), ".rigstate");
|
|
4517
|
+
const content = await fs20.readFile(manifestPath, "utf-8");
|
|
4430
4518
|
const manifest = JSON.parse(content);
|
|
4431
4519
|
projectId = manifest.project_id;
|
|
4432
4520
|
} catch (e) {
|
|
4433
4521
|
}
|
|
4434
4522
|
}
|
|
4435
4523
|
if (!projectId) {
|
|
4436
|
-
console.log(
|
|
4524
|
+
console.log(chalk23.red('No project context. Run "rigstate link" or "rigstate sync --project <id>" first.'));
|
|
4437
4525
|
return;
|
|
4438
4526
|
}
|
|
4439
4527
|
const apiUrl = getApiUrl();
|
|
@@ -4443,8 +4531,8 @@ function createWatchCommand() {
|
|
|
4443
4531
|
runTests: options.runTests || false,
|
|
4444
4532
|
testCommand: options.testCommand || "npm test"
|
|
4445
4533
|
};
|
|
4446
|
-
console.log(
|
|
4447
|
-
console.log(
|
|
4534
|
+
console.log(chalk23.dim(`Auto-commit: ${config2.autoCommit ? "ON" : "OFF"}`));
|
|
4535
|
+
console.log(chalk23.dim(`Auto-push: ${config2.autoPush ? "ON" : "OFF"}`));
|
|
4448
4536
|
console.log("");
|
|
4449
4537
|
const fetchActiveTask = async () => {
|
|
4450
4538
|
try {
|
|
@@ -4472,17 +4560,17 @@ function createWatchCommand() {
|
|
|
4472
4560
|
};
|
|
4473
4561
|
const checkCriteria = async (criteria) => {
|
|
4474
4562
|
try {
|
|
4475
|
-
const fullPath =
|
|
4563
|
+
const fullPath = path23.resolve(process.cwd(), criteria.path);
|
|
4476
4564
|
switch (criteria.type) {
|
|
4477
4565
|
case "file_exists":
|
|
4478
|
-
await
|
|
4566
|
+
await fs20.access(fullPath);
|
|
4479
4567
|
return true;
|
|
4480
4568
|
case "file_content":
|
|
4481
|
-
const content = await
|
|
4569
|
+
const content = await fs20.readFile(fullPath, "utf-8");
|
|
4482
4570
|
return content.length > 0;
|
|
4483
4571
|
case "content_match":
|
|
4484
4572
|
if (!criteria.match) return false;
|
|
4485
|
-
const fileContent = await
|
|
4573
|
+
const fileContent = await fs20.readFile(fullPath, "utf-8");
|
|
4486
4574
|
return fileContent.includes(criteria.match);
|
|
4487
4575
|
default:
|
|
4488
4576
|
return false;
|
|
@@ -4511,7 +4599,7 @@ function createWatchCommand() {
|
|
|
4511
4599
|
}, {
|
|
4512
4600
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4513
4601
|
});
|
|
4514
|
-
spinner.succeed(
|
|
4602
|
+
spinner.succeed(chalk23.green(`\u2705 Task #${task.step_number} completed: ${task.title}`));
|
|
4515
4603
|
if (config2.autoCommit) {
|
|
4516
4604
|
spinner.start("Committing changes...");
|
|
4517
4605
|
try {
|
|
@@ -4533,7 +4621,7 @@ function createWatchCommand() {
|
|
|
4533
4621
|
}
|
|
4534
4622
|
}
|
|
4535
4623
|
console.log("");
|
|
4536
|
-
console.log(
|
|
4624
|
+
console.log(chalk23.blue("Watching for next task..."));
|
|
4537
4625
|
} catch (e) {
|
|
4538
4626
|
spinner.fail(`Failed to complete task: ${e.message}`);
|
|
4539
4627
|
}
|
|
@@ -4546,7 +4634,7 @@ function createWatchCommand() {
|
|
|
4546
4634
|
const task = await fetchActiveTask();
|
|
4547
4635
|
if (!task) {
|
|
4548
4636
|
if (currentTask) {
|
|
4549
|
-
console.log(
|
|
4637
|
+
console.log(chalk23.green("\u{1F389} All tasks completed! Watching for new tasks..."));
|
|
4550
4638
|
currentTask = null;
|
|
4551
4639
|
}
|
|
4552
4640
|
isProcessing = false;
|
|
@@ -4555,10 +4643,10 @@ function createWatchCommand() {
|
|
|
4555
4643
|
if (!currentTask || currentTask.id !== task.id) {
|
|
4556
4644
|
currentTask = task;
|
|
4557
4645
|
console.log("");
|
|
4558
|
-
console.log(
|
|
4559
|
-
console.log(
|
|
4646
|
+
console.log(chalk23.bold.yellow(`\u{1F4CC} Active Task #${task.step_number}: ${task.title}`));
|
|
4647
|
+
console.log(chalk23.dim(`Status: ${task.status}`));
|
|
4560
4648
|
if (task.verification_criteria) {
|
|
4561
|
-
console.log(
|
|
4649
|
+
console.log(chalk23.dim("Verification: Auto-checking criteria..."));
|
|
4562
4650
|
}
|
|
4563
4651
|
}
|
|
4564
4652
|
if (task.verification_criteria && Array.isArray(task.verification_criteria)) {
|
|
@@ -4571,7 +4659,7 @@ function createWatchCommand() {
|
|
|
4571
4659
|
}
|
|
4572
4660
|
}
|
|
4573
4661
|
if (allPassed) {
|
|
4574
|
-
console.log(
|
|
4662
|
+
console.log(chalk23.green("\u2713 All verification criteria passed!"));
|
|
4575
4663
|
await completeTask(task.id, task);
|
|
4576
4664
|
currentTask = null;
|
|
4577
4665
|
}
|
|
@@ -4596,11 +4684,11 @@ function createWatchCommand() {
|
|
|
4596
4684
|
setTimeout(() => processActiveTask(), 500);
|
|
4597
4685
|
}
|
|
4598
4686
|
});
|
|
4599
|
-
console.log(
|
|
4687
|
+
console.log(chalk23.dim("Watching for file changes... (Ctrl+C to exit)"));
|
|
4600
4688
|
setInterval(() => processActiveTask(), 3e4);
|
|
4601
4689
|
process.on("SIGINT", () => {
|
|
4602
4690
|
console.log("");
|
|
4603
|
-
console.log(
|
|
4691
|
+
console.log(chalk23.dim("Watch mode stopped."));
|
|
4604
4692
|
watcher.close();
|
|
4605
4693
|
process.exit(0);
|
|
4606
4694
|
});
|
|
@@ -4612,12 +4700,12 @@ function createWatchCommand() {
|
|
|
4612
4700
|
init_esm_shims();
|
|
4613
4701
|
init_config();
|
|
4614
4702
|
import { Command as Command14 } from "commander";
|
|
4615
|
-
import
|
|
4703
|
+
import chalk24 from "chalk";
|
|
4616
4704
|
import ora11 from "ora";
|
|
4617
4705
|
import axios17 from "axios";
|
|
4618
4706
|
import { execSync as execSync5 } from "child_process";
|
|
4619
|
-
import
|
|
4620
|
-
import
|
|
4707
|
+
import fs21 from "fs/promises";
|
|
4708
|
+
import path24 from "path";
|
|
4621
4709
|
function createFocusCommand() {
|
|
4622
4710
|
const focus = new Command14("focus");
|
|
4623
4711
|
focus.alias("task").description("Get the next active roadmap task and copy its prompt to clipboard").option("--no-copy", "Do not copy to clipboard").action(async (options) => {
|
|
@@ -4627,21 +4715,21 @@ function createFocusCommand() {
|
|
|
4627
4715
|
try {
|
|
4628
4716
|
apiKey = getApiKey();
|
|
4629
4717
|
} catch (e) {
|
|
4630
|
-
spinner.fail(
|
|
4718
|
+
spinner.fail(chalk24.red('Not authenticated. Run "rigstate login" first.'));
|
|
4631
4719
|
return;
|
|
4632
4720
|
}
|
|
4633
4721
|
projectId = getProjectId();
|
|
4634
4722
|
if (!projectId) {
|
|
4635
4723
|
try {
|
|
4636
|
-
const manifestPath =
|
|
4637
|
-
const content = await
|
|
4724
|
+
const manifestPath = path24.join(process.cwd(), ".rigstate");
|
|
4725
|
+
const content = await fs21.readFile(manifestPath, "utf-8");
|
|
4638
4726
|
const manifest = JSON.parse(content);
|
|
4639
4727
|
projectId = manifest.project_id;
|
|
4640
4728
|
} catch (e) {
|
|
4641
4729
|
}
|
|
4642
4730
|
}
|
|
4643
4731
|
if (!projectId) {
|
|
4644
|
-
spinner.fail(
|
|
4732
|
+
spinner.fail(chalk24.red('No project context. Run "rigstate link" first.'));
|
|
4645
4733
|
return;
|
|
4646
4734
|
}
|
|
4647
4735
|
const apiUrl = getApiUrl();
|
|
@@ -4672,41 +4760,41 @@ function createFocusCommand() {
|
|
|
4672
4760
|
const nextTask = activeTasks[0];
|
|
4673
4761
|
spinner.stop();
|
|
4674
4762
|
console.log("");
|
|
4675
|
-
console.log(
|
|
4676
|
-
const statusColor = nextTask.status === "IN_PROGRESS" ?
|
|
4677
|
-
console.log(
|
|
4678
|
-
console.log(
|
|
4763
|
+
console.log(chalk24.bold.blue(`\u{1F4CC} Task #${nextTask.step_number || "?"}: ${nextTask.title}`));
|
|
4764
|
+
const statusColor = nextTask.status === "IN_PROGRESS" ? chalk24.yellow : nextTask.status === "ACTIVE" ? chalk24.green : chalk24.dim;
|
|
4765
|
+
console.log(chalk24.dim("Status: ") + statusColor(nextTask.status));
|
|
4766
|
+
console.log(chalk24.dim("\u2500".repeat(60)));
|
|
4679
4767
|
if (nextTask.prompt_content) {
|
|
4680
|
-
console.log(
|
|
4681
|
-
console.log(
|
|
4768
|
+
console.log(chalk24.white(nextTask.prompt_content));
|
|
4769
|
+
console.log(chalk24.dim("\u2500".repeat(60)));
|
|
4682
4770
|
if (options.copy !== false) {
|
|
4683
4771
|
try {
|
|
4684
4772
|
if (process.platform === "darwin") {
|
|
4685
4773
|
execSync5("pbcopy", { input: nextTask.prompt_content });
|
|
4686
|
-
console.log(
|
|
4774
|
+
console.log(chalk24.green("\u2705 Prompt copied to clipboard! Ready to paste (Cmd+V)."));
|
|
4687
4775
|
} else if (process.platform === "linux") {
|
|
4688
4776
|
try {
|
|
4689
4777
|
execSync5("xclip -selection clipboard", { input: nextTask.prompt_content });
|
|
4690
|
-
console.log(
|
|
4778
|
+
console.log(chalk24.green("\u2705 Prompt copied to clipboard!"));
|
|
4691
4779
|
} catch (e) {
|
|
4692
|
-
console.log(
|
|
4780
|
+
console.log(chalk24.yellow("\u2139\uFE0F Copy prompt manually (xclip not available)"));
|
|
4693
4781
|
}
|
|
4694
4782
|
} else {
|
|
4695
|
-
console.log(
|
|
4783
|
+
console.log(chalk24.yellow("\u2139\uFE0F Copy prompt manually (Auto-copy not supported on this OS)"));
|
|
4696
4784
|
}
|
|
4697
4785
|
} catch (e) {
|
|
4698
4786
|
}
|
|
4699
4787
|
}
|
|
4700
4788
|
} else {
|
|
4701
|
-
console.log(
|
|
4789
|
+
console.log(chalk24.yellow("No prompt instructions available."));
|
|
4702
4790
|
if (nextTask.architectural_brief) {
|
|
4703
|
-
console.log(
|
|
4791
|
+
console.log(chalk24.bold("Brief:"));
|
|
4704
4792
|
console.log(nextTask.architectural_brief);
|
|
4705
4793
|
}
|
|
4706
4794
|
}
|
|
4707
4795
|
console.log("");
|
|
4708
4796
|
} catch (e) {
|
|
4709
|
-
spinner.fail(
|
|
4797
|
+
spinner.fail(chalk24.red(`Failed to fetch task: ${e.message}`));
|
|
4710
4798
|
}
|
|
4711
4799
|
});
|
|
4712
4800
|
return focus;
|
|
@@ -4719,25 +4807,25 @@ init_env();
|
|
|
4719
4807
|
init_esm_shims();
|
|
4720
4808
|
init_config();
|
|
4721
4809
|
import { Command as Command15 } from "commander";
|
|
4722
|
-
import
|
|
4810
|
+
import chalk25 from "chalk";
|
|
4723
4811
|
function createConfigCommand() {
|
|
4724
4812
|
const config2 = new Command15("config");
|
|
4725
4813
|
config2.description("View or modify Rigstate configuration").argument("[key]", "Configuration key to view/set (api_key, project_id, api_url)").argument("[value]", "Value to set").action(async (key, value) => {
|
|
4726
4814
|
if (!key) {
|
|
4727
|
-
console.log(
|
|
4728
|
-
console.log(
|
|
4815
|
+
console.log(chalk25.bold("Rigstate Configuration"));
|
|
4816
|
+
console.log(chalk25.dim("\u2500".repeat(40)));
|
|
4729
4817
|
try {
|
|
4730
4818
|
const apiKey = getApiKey();
|
|
4731
|
-
console.log(`${
|
|
4819
|
+
console.log(`${chalk25.cyan("api_key")}: ${apiKey.substring(0, 20)}...`);
|
|
4732
4820
|
} catch (e) {
|
|
4733
|
-
console.log(`${
|
|
4821
|
+
console.log(`${chalk25.cyan("api_key")}: ${chalk25.dim("(not set)")}`);
|
|
4734
4822
|
}
|
|
4735
4823
|
const projectId = getProjectId();
|
|
4736
|
-
console.log(`${
|
|
4824
|
+
console.log(`${chalk25.cyan("project_id")}: ${projectId || chalk25.dim("(not set)")}`);
|
|
4737
4825
|
const apiUrl = getApiUrl();
|
|
4738
|
-
console.log(`${
|
|
4826
|
+
console.log(`${chalk25.cyan("api_url")}: ${apiUrl}`);
|
|
4739
4827
|
console.log("");
|
|
4740
|
-
console.log(
|
|
4828
|
+
console.log(chalk25.dim('Use "rigstate config <key> <value>" to set a value.'));
|
|
4741
4829
|
return;
|
|
4742
4830
|
}
|
|
4743
4831
|
if (!value) {
|
|
@@ -4747,37 +4835,37 @@ function createConfigCommand() {
|
|
|
4747
4835
|
const apiKey = getApiKey();
|
|
4748
4836
|
console.log(apiKey);
|
|
4749
4837
|
} catch (e) {
|
|
4750
|
-
console.log(
|
|
4838
|
+
console.log(chalk25.dim("(not set)"));
|
|
4751
4839
|
}
|
|
4752
4840
|
break;
|
|
4753
4841
|
case "project_id":
|
|
4754
|
-
console.log(getProjectId() ||
|
|
4842
|
+
console.log(getProjectId() || chalk25.dim("(not set)"));
|
|
4755
4843
|
break;
|
|
4756
4844
|
case "api_url":
|
|
4757
4845
|
console.log(getApiUrl());
|
|
4758
4846
|
break;
|
|
4759
4847
|
default:
|
|
4760
|
-
console.log(
|
|
4761
|
-
console.log(
|
|
4848
|
+
console.log(chalk25.red(`Unknown config key: ${key}`));
|
|
4849
|
+
console.log(chalk25.dim("Valid keys: api_key, project_id, api_url"));
|
|
4762
4850
|
}
|
|
4763
4851
|
return;
|
|
4764
4852
|
}
|
|
4765
4853
|
switch (key) {
|
|
4766
4854
|
case "api_key":
|
|
4767
4855
|
setApiKey(value);
|
|
4768
|
-
console.log(
|
|
4856
|
+
console.log(chalk25.green(`\u2705 api_key updated`));
|
|
4769
4857
|
break;
|
|
4770
4858
|
case "project_id":
|
|
4771
4859
|
setProjectId(value);
|
|
4772
|
-
console.log(
|
|
4860
|
+
console.log(chalk25.green(`\u2705 project_id updated`));
|
|
4773
4861
|
break;
|
|
4774
4862
|
case "api_url":
|
|
4775
4863
|
setApiUrl(value);
|
|
4776
|
-
console.log(
|
|
4864
|
+
console.log(chalk25.green(`\u2705 api_url updated`));
|
|
4777
4865
|
break;
|
|
4778
4866
|
default:
|
|
4779
|
-
console.log(
|
|
4780
|
-
console.log(
|
|
4867
|
+
console.log(chalk25.red(`Unknown config key: ${key}`));
|
|
4868
|
+
console.log(chalk25.dim("Valid keys: api_key, project_id, api_url"));
|
|
4781
4869
|
}
|
|
4782
4870
|
});
|
|
4783
4871
|
return config2;
|
|
@@ -4787,41 +4875,41 @@ function createConfigCommand() {
|
|
|
4787
4875
|
init_esm_shims();
|
|
4788
4876
|
init_config();
|
|
4789
4877
|
import { Command as Command16 } from "commander";
|
|
4790
|
-
import
|
|
4878
|
+
import chalk26 from "chalk";
|
|
4791
4879
|
import { spawn } from "child_process";
|
|
4792
|
-
import
|
|
4793
|
-
import
|
|
4880
|
+
import path25 from "path";
|
|
4881
|
+
import fs22 from "fs";
|
|
4794
4882
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4795
4883
|
var __filename2 = fileURLToPath3(import.meta.url);
|
|
4796
|
-
var __dirname2 =
|
|
4884
|
+
var __dirname2 = path25.dirname(__filename2);
|
|
4797
4885
|
function createMcpCommand() {
|
|
4798
4886
|
const mcp = new Command16("mcp");
|
|
4799
4887
|
mcp.description("Run the Rigstate MCP server for AI editors").action(async () => {
|
|
4800
4888
|
const possiblePaths = [
|
|
4801
4889
|
// From packages/cli -> packages/mcp (sibling package)
|
|
4802
|
-
|
|
4890
|
+
path25.resolve(__dirname2, "../../mcp/dist/index.js"),
|
|
4803
4891
|
// If installed globally or via npm
|
|
4804
|
-
|
|
4892
|
+
path25.resolve(__dirname2, "../../../mcp/dist/index.js"),
|
|
4805
4893
|
// Development path from packages/cli/dist
|
|
4806
|
-
|
|
4894
|
+
path25.resolve(__dirname2, "../../../packages/mcp/dist/index.js")
|
|
4807
4895
|
];
|
|
4808
4896
|
let serverPath = "";
|
|
4809
4897
|
for (const p of possiblePaths) {
|
|
4810
|
-
if (
|
|
4898
|
+
if (fs22.existsSync(p)) {
|
|
4811
4899
|
serverPath = p;
|
|
4812
4900
|
break;
|
|
4813
4901
|
}
|
|
4814
4902
|
}
|
|
4815
4903
|
if (!serverPath) {
|
|
4816
|
-
console.error(
|
|
4817
|
-
console.error(
|
|
4818
|
-
console.error(
|
|
4904
|
+
console.error(chalk26.red("\u274C Error: Rigstate MCP Server binary not found."));
|
|
4905
|
+
console.error(chalk26.yellow("Please ensure that the mcp package is built:"));
|
|
4906
|
+
console.error(chalk26.white(" cd packages/mcp && npm run build"));
|
|
4819
4907
|
console.error("");
|
|
4820
|
-
console.error(
|
|
4821
|
-
console.error(
|
|
4908
|
+
console.error(chalk26.dim("Or run directly with:"));
|
|
4909
|
+
console.error(chalk26.white(" npx @rigstate/mcp"));
|
|
4822
4910
|
process.exit(1);
|
|
4823
4911
|
}
|
|
4824
|
-
console.log(
|
|
4912
|
+
console.log(chalk26.dim(`Starting MCP server from: ${serverPath}`));
|
|
4825
4913
|
const env = { ...process.env };
|
|
4826
4914
|
try {
|
|
4827
4915
|
const apiKey = getApiKey();
|
|
@@ -4840,7 +4928,7 @@ function createMcpCommand() {
|
|
|
4840
4928
|
stdio: ["inherit", "inherit", "inherit"]
|
|
4841
4929
|
});
|
|
4842
4930
|
worker.on("error", (err) => {
|
|
4843
|
-
console.error(
|
|
4931
|
+
console.error(chalk26.red(`\u274C Failed to start MCP server: ${err.message}`));
|
|
4844
4932
|
process.exit(1);
|
|
4845
4933
|
});
|
|
4846
4934
|
worker.on("exit", (code) => {
|
|
@@ -4855,7 +4943,7 @@ function createMcpCommand() {
|
|
|
4855
4943
|
// src/commands/nexus.ts
|
|
4856
4944
|
init_esm_shims();
|
|
4857
4945
|
import { Command as Command17 } from "commander";
|
|
4858
|
-
import
|
|
4946
|
+
import chalk28 from "chalk";
|
|
4859
4947
|
|
|
4860
4948
|
// src/nexus/dispatcher.ts
|
|
4861
4949
|
init_esm_shims();
|
|
@@ -4923,7 +5011,7 @@ var HiveScrubber = class {
|
|
|
4923
5011
|
};
|
|
4924
5012
|
|
|
4925
5013
|
// src/hive/gateway.ts
|
|
4926
|
-
import
|
|
5014
|
+
import chalk27 from "chalk";
|
|
4927
5015
|
var HiveGateway = class {
|
|
4928
5016
|
client;
|
|
4929
5017
|
enabled;
|
|
@@ -4933,7 +5021,7 @@ var HiveGateway = class {
|
|
|
4933
5021
|
constructor(baseUrl, token) {
|
|
4934
5022
|
this.enabled = !!token;
|
|
4935
5023
|
if (!this.enabled) {
|
|
4936
|
-
console.log(
|
|
5024
|
+
console.log(chalk27.dim("\u26A0\uFE0F Hive Gateway disabled (No Token provided). Running in localized mode."));
|
|
4937
5025
|
}
|
|
4938
5026
|
this.client = axios18.create({
|
|
4939
5027
|
baseURL: baseUrl,
|
|
@@ -4953,23 +5041,23 @@ var HiveGateway = class {
|
|
|
4953
5041
|
if (!this.enabled) return false;
|
|
4954
5042
|
const now = Date.now();
|
|
4955
5043
|
if (now - this.lastSignalTime < this.MIN_INTERVAL_MS) {
|
|
4956
|
-
console.warn(
|
|
5044
|
+
console.warn(chalk27.yellow("\u23F3 Hive Gateway Throttled. Signal dropped to preventing spam."));
|
|
4957
5045
|
return false;
|
|
4958
5046
|
}
|
|
4959
5047
|
const scrubResult = HiveScrubber.scrub(signal.ruleContent);
|
|
4960
5048
|
if (scrubResult.riskScore > 20) {
|
|
4961
|
-
console.error(
|
|
5049
|
+
console.error(chalk27.red(`\u{1F6D1} HIVE BLOCKED: Signal contains sensitive data (Risk: ${scrubResult.riskScore})`));
|
|
4962
5050
|
return false;
|
|
4963
5051
|
}
|
|
4964
5052
|
try {
|
|
4965
|
-
console.log(
|
|
5053
|
+
console.log(chalk27.blue(`\u{1F4E1} Uplinking to Hive... [${signal.vector}]`));
|
|
4966
5054
|
const payload = { ...signal, ruleContent: scrubResult.sanitizedContent };
|
|
4967
5055
|
await this.client.post("/signal", payload);
|
|
4968
5056
|
this.lastSignalTime = now;
|
|
4969
|
-
console.log(
|
|
5057
|
+
console.log(chalk27.green("\u2705 Signal Received by Hive Core. Knowledge Shared."));
|
|
4970
5058
|
return true;
|
|
4971
5059
|
} catch (error) {
|
|
4972
|
-
console.error(
|
|
5060
|
+
console.error(chalk27.red(`\u274C Hive Transmission Failed: ${error.message}`));
|
|
4973
5061
|
return false;
|
|
4974
5062
|
}
|
|
4975
5063
|
}
|
|
@@ -5071,10 +5159,10 @@ import inquirer3 from "inquirer";
|
|
|
5071
5159
|
function createNexusCommand() {
|
|
5072
5160
|
const command = new Command17("nexus");
|
|
5073
5161
|
command.description("Interact with The Multi-Agent Nexus (Phase 8)").argument("<intent>", "The natural language instruction for the swarm").option("--dry-run", "Enable Dry-Run mode (Kill-Switch Active)", true).option("--force", "Disable Dry-Run mode (DANGEROUS)", false).action(async (intent, options) => {
|
|
5074
|
-
console.log(
|
|
5162
|
+
console.log(chalk28.bold.magenta("\n\u{1F981} Welcome to The Nexus (Phase 8)\n"));
|
|
5075
5163
|
const dryRun = !options.force;
|
|
5076
5164
|
if (!dryRun) {
|
|
5077
|
-
console.log(
|
|
5165
|
+
console.log(chalk28.black.bgYellow(" WARNING ") + chalk28.yellow(" Dry-Run disabled! Eitri is authorized to write code."));
|
|
5078
5166
|
const { confirm } = await inquirer3.prompt([{
|
|
5079
5167
|
type: "confirm",
|
|
5080
5168
|
name: "confirm",
|
|
@@ -5095,26 +5183,26 @@ function createNexusCommand() {
|
|
|
5095
5183
|
};
|
|
5096
5184
|
const dispatcher = new NexusDispatcher(context);
|
|
5097
5185
|
dispatcher.on("order:created", (o) => {
|
|
5098
|
-
console.log(
|
|
5186
|
+
console.log(chalk28.blue(`\u{1F195} [${o.id.slice(0, 6)}] Order Created: `) + o.intent);
|
|
5099
5187
|
});
|
|
5100
5188
|
dispatcher.on("order:started", (o) => {
|
|
5101
|
-
console.log(
|
|
5189
|
+
console.log(chalk28.yellow(`\u23F3 [${o.id.slice(0, 6)}] Processing...`));
|
|
5102
5190
|
});
|
|
5103
5191
|
dispatcher.on("order:blocked", (o) => {
|
|
5104
|
-
console.log(
|
|
5105
|
-
console.log(
|
|
5106
|
-
console.log(
|
|
5192
|
+
console.log(chalk28.red(`\u{1F6D1} [${o.id.slice(0, 6)}] BLOCKED by Kill-Switch`));
|
|
5193
|
+
console.log(chalk28.dim(` Target: ${o.targetAgent} | Action: ${o.action}`));
|
|
5194
|
+
console.log(chalk28.dim(" Run with --force to execute automatically (NOT RECOMMENDED)."));
|
|
5107
5195
|
});
|
|
5108
|
-
dispatcher.on("agent:SINDRE", (o) => console.log(
|
|
5109
|
-
dispatcher.on("agent:EITRI", (o) => console.log(
|
|
5110
|
-
console.log(
|
|
5196
|
+
dispatcher.on("agent:SINDRE", (o) => console.log(chalk28.cyan(`\u{1F916} Sindre (Vault): I'm on it! (${o.action})`)));
|
|
5197
|
+
dispatcher.on("agent:EITRI", (o) => console.log(chalk28.green(`\u{1F477} Eitri (Smith): Ready to build! (${o.action})`)));
|
|
5198
|
+
console.log(chalk28.dim("\u{1F9E0} Frank is analyzing your intent..."));
|
|
5111
5199
|
await new Promise((r) => setTimeout(r, 800));
|
|
5112
5200
|
if (intent.toLowerCase().includes("db") || intent.toLowerCase().includes("database")) {
|
|
5113
5201
|
await dispatcher.dispatch("FRANK", "SINDRE", intent, "db.analyze", { raw: intent });
|
|
5114
5202
|
} else if (intent.toLowerCase().includes("create") || intent.toLowerCase().includes("code")) {
|
|
5115
5203
|
await dispatcher.dispatch("FRANK", "EITRI", intent, "fs.write", { path: "src/demo.ts", content: "// demo" });
|
|
5116
5204
|
} else {
|
|
5117
|
-
console.log(
|
|
5205
|
+
console.log(chalk28.gray("Frank didn't understand. Try 'create file' or 'check database'."));
|
|
5118
5206
|
}
|
|
5119
5207
|
});
|
|
5120
5208
|
return command;
|
|
@@ -5128,25 +5216,25 @@ init_esm_shims();
|
|
|
5128
5216
|
init_governance();
|
|
5129
5217
|
init_config();
|
|
5130
5218
|
import { Command as Command18 } from "commander";
|
|
5131
|
-
import
|
|
5219
|
+
import chalk29 from "chalk";
|
|
5132
5220
|
import axios19 from "axios";
|
|
5133
5221
|
function createOverrideCommand() {
|
|
5134
5222
|
const override = new Command18("override");
|
|
5135
5223
|
override.description("Emergency Override for Governance Soft Locks").argument("<violationId>", 'ID of the violation to override (or "all")').requiredOption("-r, --reason <reason>", "Description of why this override is necessary").action(async (violationId, options) => {
|
|
5136
5224
|
const { reason } = options;
|
|
5137
|
-
console.log(
|
|
5225
|
+
console.log(chalk29.bold(`
|
|
5138
5226
|
\u{1F513} Initiating Governance Override Protocol...`));
|
|
5139
5227
|
const session = await getSessionState(process.cwd());
|
|
5140
5228
|
if (session.status !== "SOFT_LOCK") {
|
|
5141
|
-
console.log(
|
|
5229
|
+
console.log(chalk29.yellow(" Info: Session is not currently locked."));
|
|
5142
5230
|
return;
|
|
5143
5231
|
}
|
|
5144
|
-
console.log(
|
|
5145
|
-
console.log(
|
|
5232
|
+
console.log(chalk29.dim(` Active Violation: ${session.active_violation}`));
|
|
5233
|
+
console.log(chalk29.dim(` Reason Provided: "${reason}"`));
|
|
5146
5234
|
const success = await performOverride(violationId, reason, process.cwd());
|
|
5147
5235
|
if (success) {
|
|
5148
|
-
console.log(
|
|
5149
|
-
console.log(
|
|
5236
|
+
console.log(chalk29.green(` \u2705 Session UNLOCKED.`));
|
|
5237
|
+
console.log(chalk29.dim(` This event has been logged to the Mission Report.`));
|
|
5150
5238
|
try {
|
|
5151
5239
|
const projectId = getProjectId();
|
|
5152
5240
|
if (projectId) {
|
|
@@ -5163,13 +5251,13 @@ function createOverrideCommand() {
|
|
|
5163
5251
|
}, {
|
|
5164
5252
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
5165
5253
|
});
|
|
5166
|
-
console.log(
|
|
5254
|
+
console.log(chalk29.dim(` \u2601 Audit log synced to Cloud.`));
|
|
5167
5255
|
}
|
|
5168
5256
|
} catch (e) {
|
|
5169
|
-
console.log(
|
|
5257
|
+
console.log(chalk29.dim(` (Cloud audit sync failed: ${e.message})`));
|
|
5170
5258
|
}
|
|
5171
5259
|
} else {
|
|
5172
|
-
console.log(
|
|
5260
|
+
console.log(chalk29.red(` \u{1F6D1} Override Failed. Check project configuration.`));
|
|
5173
5261
|
}
|
|
5174
5262
|
});
|
|
5175
5263
|
return override;
|
|
@@ -5179,7 +5267,7 @@ function createOverrideCommand() {
|
|
|
5179
5267
|
init_esm_shims();
|
|
5180
5268
|
init_config();
|
|
5181
5269
|
import { Command as Command19 } from "commander";
|
|
5182
|
-
import
|
|
5270
|
+
import chalk30 from "chalk";
|
|
5183
5271
|
import ora12 from "ora";
|
|
5184
5272
|
import axios20 from "axios";
|
|
5185
5273
|
import inquirer4 from "inquirer";
|
|
@@ -5190,7 +5278,7 @@ function createIdeaCommand() {
|
|
|
5190
5278
|
const apiUrl = getApiUrl();
|
|
5191
5279
|
const projectId = getProjectId();
|
|
5192
5280
|
if (!projectId) {
|
|
5193
|
-
console.error(
|
|
5281
|
+
console.error(chalk30.red("Project context missing. Run rigstate link."));
|
|
5194
5282
|
process.exit(1);
|
|
5195
5283
|
}
|
|
5196
5284
|
let ideaTitle = title;
|
|
@@ -5226,14 +5314,14 @@ function createIdeaCommand() {
|
|
|
5226
5314
|
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
5227
5315
|
);
|
|
5228
5316
|
if (response.data.success) {
|
|
5229
|
-
spinner.succeed(
|
|
5230
|
-
console.log(
|
|
5317
|
+
spinner.succeed(chalk30.green("Idea Captured! \u{1F4A1}"));
|
|
5318
|
+
console.log(chalk30.dim(`ID: ${response.data.data?.id || "Saved"}`));
|
|
5231
5319
|
} else {
|
|
5232
5320
|
throw new Error(response.data.error);
|
|
5233
5321
|
}
|
|
5234
5322
|
} catch (e) {
|
|
5235
5323
|
const errorDetail = e.response?.data?.error || e.message;
|
|
5236
|
-
console.error(
|
|
5324
|
+
console.error(chalk30.red(`
|
|
5237
5325
|
Failed to capture idea: ${errorDetail}`));
|
|
5238
5326
|
}
|
|
5239
5327
|
});
|
|
@@ -5243,11 +5331,11 @@ Failed to capture idea: ${errorDetail}`));
|
|
|
5243
5331
|
init_esm_shims();
|
|
5244
5332
|
init_config();
|
|
5245
5333
|
import { Command as Command20 } from "commander";
|
|
5246
|
-
import
|
|
5334
|
+
import chalk31 from "chalk";
|
|
5247
5335
|
import ora13 from "ora";
|
|
5248
5336
|
import inquirer5 from "inquirer";
|
|
5249
|
-
import
|
|
5250
|
-
import
|
|
5337
|
+
import fs23 from "fs/promises";
|
|
5338
|
+
import path26 from "path";
|
|
5251
5339
|
|
|
5252
5340
|
// ../../node_modules/simple-git/dist/esm/index.js
|
|
5253
5341
|
init_esm_shims();
|
|
@@ -5287,8 +5375,8 @@ function pathspec(...paths) {
|
|
|
5287
5375
|
cache.set(key, paths);
|
|
5288
5376
|
return key;
|
|
5289
5377
|
}
|
|
5290
|
-
function isPathSpec(
|
|
5291
|
-
return
|
|
5378
|
+
function isPathSpec(path27) {
|
|
5379
|
+
return path27 instanceof String && cache.has(path27);
|
|
5292
5380
|
}
|
|
5293
5381
|
function toPaths(pathSpec) {
|
|
5294
5382
|
return cache.get(pathSpec) || [];
|
|
@@ -5377,8 +5465,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
5377
5465
|
function forEachLineWithContent(input, callback) {
|
|
5378
5466
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
5379
5467
|
}
|
|
5380
|
-
function folderExists(
|
|
5381
|
-
return (0, import_file_exists.exists)(
|
|
5468
|
+
function folderExists(path27) {
|
|
5469
|
+
return (0, import_file_exists.exists)(path27, import_file_exists.FOLDER);
|
|
5382
5470
|
}
|
|
5383
5471
|
function append(target, item) {
|
|
5384
5472
|
if (Array.isArray(target)) {
|
|
@@ -5782,8 +5870,8 @@ function checkIsRepoRootTask() {
|
|
|
5782
5870
|
commands,
|
|
5783
5871
|
format: "utf-8",
|
|
5784
5872
|
onError,
|
|
5785
|
-
parser(
|
|
5786
|
-
return /^\.(git)?$/.test(
|
|
5873
|
+
parser(path27) {
|
|
5874
|
+
return /^\.(git)?$/.test(path27.trim());
|
|
5787
5875
|
}
|
|
5788
5876
|
};
|
|
5789
5877
|
}
|
|
@@ -6217,11 +6305,11 @@ function parseGrep(grep) {
|
|
|
6217
6305
|
const paths = /* @__PURE__ */ new Set();
|
|
6218
6306
|
const results = {};
|
|
6219
6307
|
forEachLineWithContent(grep, (input) => {
|
|
6220
|
-
const [
|
|
6221
|
-
paths.add(
|
|
6222
|
-
(results[
|
|
6308
|
+
const [path27, line, preview] = input.split(NULL);
|
|
6309
|
+
paths.add(path27);
|
|
6310
|
+
(results[path27] = results[path27] || []).push({
|
|
6223
6311
|
line: asNumber(line),
|
|
6224
|
-
path:
|
|
6312
|
+
path: path27,
|
|
6225
6313
|
preview
|
|
6226
6314
|
});
|
|
6227
6315
|
});
|
|
@@ -6986,14 +7074,14 @@ var init_hash_object = __esm2({
|
|
|
6986
7074
|
init_task();
|
|
6987
7075
|
}
|
|
6988
7076
|
});
|
|
6989
|
-
function parseInit(bare,
|
|
7077
|
+
function parseInit(bare, path27, text) {
|
|
6990
7078
|
const response = String(text).trim();
|
|
6991
7079
|
let result;
|
|
6992
7080
|
if (result = initResponseRegex.exec(response)) {
|
|
6993
|
-
return new InitSummary(bare,
|
|
7081
|
+
return new InitSummary(bare, path27, false, result[1]);
|
|
6994
7082
|
}
|
|
6995
7083
|
if (result = reInitResponseRegex.exec(response)) {
|
|
6996
|
-
return new InitSummary(bare,
|
|
7084
|
+
return new InitSummary(bare, path27, true, result[1]);
|
|
6997
7085
|
}
|
|
6998
7086
|
let gitDir = "";
|
|
6999
7087
|
const tokens = response.split(" ");
|
|
@@ -7004,7 +7092,7 @@ function parseInit(bare, path25, text) {
|
|
|
7004
7092
|
break;
|
|
7005
7093
|
}
|
|
7006
7094
|
}
|
|
7007
|
-
return new InitSummary(bare,
|
|
7095
|
+
return new InitSummary(bare, path27, /^re/i.test(response), gitDir);
|
|
7008
7096
|
}
|
|
7009
7097
|
var InitSummary;
|
|
7010
7098
|
var initResponseRegex;
|
|
@@ -7013,9 +7101,9 @@ var init_InitSummary = __esm2({
|
|
|
7013
7101
|
"src/lib/responses/InitSummary.ts"() {
|
|
7014
7102
|
"use strict";
|
|
7015
7103
|
InitSummary = class {
|
|
7016
|
-
constructor(bare,
|
|
7104
|
+
constructor(bare, path27, existing, gitDir) {
|
|
7017
7105
|
this.bare = bare;
|
|
7018
|
-
this.path =
|
|
7106
|
+
this.path = path27;
|
|
7019
7107
|
this.existing = existing;
|
|
7020
7108
|
this.gitDir = gitDir;
|
|
7021
7109
|
}
|
|
@@ -7027,7 +7115,7 @@ var init_InitSummary = __esm2({
|
|
|
7027
7115
|
function hasBareCommand(command) {
|
|
7028
7116
|
return command.includes(bareCommand);
|
|
7029
7117
|
}
|
|
7030
|
-
function initTask(bare = false,
|
|
7118
|
+
function initTask(bare = false, path27, customArgs) {
|
|
7031
7119
|
const commands = ["init", ...customArgs];
|
|
7032
7120
|
if (bare && !hasBareCommand(commands)) {
|
|
7033
7121
|
commands.splice(1, 0, bareCommand);
|
|
@@ -7036,7 +7124,7 @@ function initTask(bare = false, path25, customArgs) {
|
|
|
7036
7124
|
commands,
|
|
7037
7125
|
format: "utf-8",
|
|
7038
7126
|
parser(text) {
|
|
7039
|
-
return parseInit(commands.includes("--bare"),
|
|
7127
|
+
return parseInit(commands.includes("--bare"), path27, text);
|
|
7040
7128
|
}
|
|
7041
7129
|
};
|
|
7042
7130
|
}
|
|
@@ -7852,12 +7940,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
7852
7940
|
"use strict";
|
|
7853
7941
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
7854
7942
|
FileStatusSummary = class {
|
|
7855
|
-
constructor(
|
|
7856
|
-
this.path =
|
|
7943
|
+
constructor(path27, index, working_dir) {
|
|
7944
|
+
this.path = path27;
|
|
7857
7945
|
this.index = index;
|
|
7858
7946
|
this.working_dir = working_dir;
|
|
7859
7947
|
if (index === "R" || working_dir === "R") {
|
|
7860
|
-
const detail = fromPathRegex.exec(
|
|
7948
|
+
const detail = fromPathRegex.exec(path27) || [null, path27, path27];
|
|
7861
7949
|
this.from = detail[2] || "";
|
|
7862
7950
|
this.path = detail[1] || "";
|
|
7863
7951
|
}
|
|
@@ -7888,14 +7976,14 @@ function splitLine(result, lineStr) {
|
|
|
7888
7976
|
default:
|
|
7889
7977
|
return;
|
|
7890
7978
|
}
|
|
7891
|
-
function data(index, workingDir,
|
|
7979
|
+
function data(index, workingDir, path27) {
|
|
7892
7980
|
const raw = `${index}${workingDir}`;
|
|
7893
7981
|
const handler = parsers6.get(raw);
|
|
7894
7982
|
if (handler) {
|
|
7895
|
-
handler(result,
|
|
7983
|
+
handler(result, path27);
|
|
7896
7984
|
}
|
|
7897
7985
|
if (raw !== "##" && raw !== "!!") {
|
|
7898
|
-
result.files.push(new FileStatusSummary(
|
|
7986
|
+
result.files.push(new FileStatusSummary(path27, index, workingDir));
|
|
7899
7987
|
}
|
|
7900
7988
|
}
|
|
7901
7989
|
}
|
|
@@ -8208,9 +8296,9 @@ var init_simple_git_api = __esm2({
|
|
|
8208
8296
|
next
|
|
8209
8297
|
);
|
|
8210
8298
|
}
|
|
8211
|
-
hashObject(
|
|
8299
|
+
hashObject(path27, write) {
|
|
8212
8300
|
return this._runTask(
|
|
8213
|
-
hashObjectTask(
|
|
8301
|
+
hashObjectTask(path27, write === true),
|
|
8214
8302
|
trailingFunctionArgument(arguments)
|
|
8215
8303
|
);
|
|
8216
8304
|
}
|
|
@@ -8563,8 +8651,8 @@ var init_branch = __esm2({
|
|
|
8563
8651
|
}
|
|
8564
8652
|
});
|
|
8565
8653
|
function toPath(input) {
|
|
8566
|
-
const
|
|
8567
|
-
return
|
|
8654
|
+
const path27 = input.trim().replace(/^["']|["']$/g, "");
|
|
8655
|
+
return path27 && normalize(path27);
|
|
8568
8656
|
}
|
|
8569
8657
|
var parseCheckIgnore;
|
|
8570
8658
|
var init_CheckIgnore = __esm2({
|
|
@@ -8878,8 +8966,8 @@ __export2(sub_module_exports, {
|
|
|
8878
8966
|
subModuleTask: () => subModuleTask,
|
|
8879
8967
|
updateSubModuleTask: () => updateSubModuleTask
|
|
8880
8968
|
});
|
|
8881
|
-
function addSubModuleTask(repo,
|
|
8882
|
-
return subModuleTask(["add", repo,
|
|
8969
|
+
function addSubModuleTask(repo, path27) {
|
|
8970
|
+
return subModuleTask(["add", repo, path27]);
|
|
8883
8971
|
}
|
|
8884
8972
|
function initSubModuleTask(customArgs) {
|
|
8885
8973
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -9209,8 +9297,8 @@ var require_git = __commonJS2({
|
|
|
9209
9297
|
}
|
|
9210
9298
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
9211
9299
|
};
|
|
9212
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
9213
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
9300
|
+
Git2.prototype.submoduleAdd = function(repo, path27, then) {
|
|
9301
|
+
return this._runTask(addSubModuleTask2(repo, path27), trailingFunctionArgument2(arguments));
|
|
9214
9302
|
};
|
|
9215
9303
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
9216
9304
|
return this._runTask(
|
|
@@ -9810,8 +9898,8 @@ function createReleaseCommand() {
|
|
|
9810
9898
|
return;
|
|
9811
9899
|
}
|
|
9812
9900
|
spinner.text = "Scanning completed tasks...";
|
|
9813
|
-
const pkgPath =
|
|
9814
|
-
const pkgContent = await
|
|
9901
|
+
const pkgPath = path26.resolve(process.cwd(), "package.json");
|
|
9902
|
+
const pkgContent = await fs23.readFile(pkgPath, "utf-8");
|
|
9815
9903
|
const pkg2 = JSON.parse(pkgContent);
|
|
9816
9904
|
const currentVersion = pkg2.version;
|
|
9817
9905
|
const [major, minor, patch] = currentVersion.split(".").map(Number);
|
|
@@ -9819,7 +9907,7 @@ function createReleaseCommand() {
|
|
|
9819
9907
|
if (type === "major") newVersion = `${major + 1}.0.0`;
|
|
9820
9908
|
if (type === "minor") newVersion = `${major}.${minor + 1}.0`;
|
|
9821
9909
|
if (type === "patch") newVersion = `${major}.${minor}.${patch + 1}`;
|
|
9822
|
-
spinner.succeed(`Bumping ${pkg2.name} from ${
|
|
9910
|
+
spinner.succeed(`Bumping ${pkg2.name} from ${chalk31.dim(currentVersion)} to ${chalk31.green(newVersion)}`);
|
|
9823
9911
|
const { confirm } = await inquirer5.prompt([{
|
|
9824
9912
|
type: "confirm",
|
|
9825
9913
|
name: "confirm",
|
|
@@ -9831,17 +9919,17 @@ function createReleaseCommand() {
|
|
|
9831
9919
|
return;
|
|
9832
9920
|
}
|
|
9833
9921
|
pkg2.version = newVersion;
|
|
9834
|
-
await
|
|
9835
|
-
const changelogPath =
|
|
9922
|
+
await fs23.writeFile(pkgPath, JSON.stringify(pkg2, null, 4));
|
|
9923
|
+
const changelogPath = path26.resolve(process.cwd(), "CHANGELOG.md");
|
|
9836
9924
|
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
9837
9925
|
const entry = `
|
|
9838
9926
|
## [${newVersion}] - ${date}
|
|
9839
9927
|
- Automated release via Rigstate.
|
|
9840
9928
|
`;
|
|
9841
9929
|
try {
|
|
9842
|
-
await
|
|
9930
|
+
await fs23.appendFile(changelogPath, entry);
|
|
9843
9931
|
} catch {
|
|
9844
|
-
await
|
|
9932
|
+
await fs23.writeFile(changelogPath, "# Changelog\n" + entry);
|
|
9845
9933
|
}
|
|
9846
9934
|
spinner.start("Tagging and pushing...");
|
|
9847
9935
|
await git.add(["package.json", "CHANGELOG.md"]);
|
|
@@ -9849,7 +9937,7 @@ function createReleaseCommand() {
|
|
|
9849
9937
|
await git.addTag(`v${newVersion}`);
|
|
9850
9938
|
await git.push();
|
|
9851
9939
|
await git.pushTags();
|
|
9852
|
-
spinner.succeed(
|
|
9940
|
+
spinner.succeed(chalk31.bold.green(`\u{1F680} Release v${newVersion} shipped!`));
|
|
9853
9941
|
} catch (e) {
|
|
9854
9942
|
spinner.fail(e.message);
|
|
9855
9943
|
}
|
|
@@ -9867,7 +9955,7 @@ function getContext2() {
|
|
|
9867
9955
|
init_esm_shims();
|
|
9868
9956
|
init_config();
|
|
9869
9957
|
import { Command as Command21 } from "commander";
|
|
9870
|
-
import
|
|
9958
|
+
import chalk32 from "chalk";
|
|
9871
9959
|
import ora14 from "ora";
|
|
9872
9960
|
import axios21 from "axios";
|
|
9873
9961
|
function createRoadmapCommand() {
|
|
@@ -9878,7 +9966,7 @@ function createRoadmapCommand() {
|
|
|
9878
9966
|
const apiUrl = getApiUrl();
|
|
9879
9967
|
const projectId = getProjectId();
|
|
9880
9968
|
if (!projectId) {
|
|
9881
|
-
spinner.fail(
|
|
9969
|
+
spinner.fail(chalk32.red('Project context missing. Run "rigstate link".'));
|
|
9882
9970
|
return;
|
|
9883
9971
|
}
|
|
9884
9972
|
const response = await axios21.get(
|
|
@@ -9891,11 +9979,11 @@ function createRoadmapCommand() {
|
|
|
9891
9979
|
const tasks = response.data.data.roadmap || [];
|
|
9892
9980
|
spinner.stop();
|
|
9893
9981
|
if (tasks.length === 0) {
|
|
9894
|
-
console.log(
|
|
9982
|
+
console.log(chalk32.yellow("\nRoadmap is empty. Use the web UI to define your journey."));
|
|
9895
9983
|
return;
|
|
9896
9984
|
}
|
|
9897
|
-
console.log("\n" +
|
|
9898
|
-
console.log(
|
|
9985
|
+
console.log("\n" + chalk32.bold.underline("\u{1F6F0}\uFE0F TACTICAL OVERVIEW: PROJECT ROADMAP"));
|
|
9986
|
+
console.log(chalk32.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
9899
9987
|
const columns = {
|
|
9900
9988
|
"IN_PROGRESS": [],
|
|
9901
9989
|
"ACTIVE": [],
|
|
@@ -9907,14 +9995,14 @@ function createRoadmapCommand() {
|
|
|
9907
9995
|
columns[t.status].push(t);
|
|
9908
9996
|
}
|
|
9909
9997
|
});
|
|
9910
|
-
displayColumn("\u{1F525} IN PROGRESS", columns.IN_PROGRESS,
|
|
9911
|
-
displayColumn("\u25B6\uFE0F ACTIVE / NEXT", columns.ACTIVE,
|
|
9912
|
-
displayColumn("\u{1F512} LOCKED", columns.LOCKED,
|
|
9913
|
-
displayColumn("\u23F3 PENDING", columns.PENDING,
|
|
9914
|
-
console.log(
|
|
9915
|
-
console.log(
|
|
9998
|
+
displayColumn("\u{1F525} IN PROGRESS", columns.IN_PROGRESS, chalk32.yellow);
|
|
9999
|
+
displayColumn("\u25B6\uFE0F ACTIVE / NEXT", columns.ACTIVE, chalk32.green);
|
|
10000
|
+
displayColumn("\u{1F512} LOCKED", columns.LOCKED, chalk32.blue);
|
|
10001
|
+
displayColumn("\u23F3 PENDING", columns.PENDING, chalk32.gray);
|
|
10002
|
+
console.log(chalk32.dim("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
10003
|
+
console.log(chalk32.dim(`Total: ${tasks.length} tasks | Run "rigstate work" to start coding.`));
|
|
9916
10004
|
} catch (e) {
|
|
9917
|
-
spinner.fail(
|
|
10005
|
+
spinner.fail(chalk32.red(`
|
|
9918
10006
|
Failed to fetch roadmap: ${e.message}`));
|
|
9919
10007
|
}
|
|
9920
10008
|
});
|
|
@@ -9925,8 +10013,8 @@ function displayColumn(title, items, color) {
|
|
|
9925
10013
|
${color.bold(title)}`);
|
|
9926
10014
|
items.sort((a, b) => a.step_number - b.step_number).forEach((item) => {
|
|
9927
10015
|
const id = `T-${item.step_number}`.padEnd(8);
|
|
9928
|
-
const priority = item.priority === "MVP" ?
|
|
9929
|
-
console.log(` ${color("\u2022")} ${
|
|
10016
|
+
const priority = item.priority === "MVP" ? chalk32.magenta(" [MVP]") : "";
|
|
10017
|
+
console.log(` ${color("\u2022")} ${chalk32.bold(id)} ${item.title}${priority}`);
|
|
9930
10018
|
});
|
|
9931
10019
|
}
|
|
9932
10020
|
|
|
@@ -9934,7 +10022,7 @@ ${color.bold(title)}`);
|
|
|
9934
10022
|
init_esm_shims();
|
|
9935
10023
|
init_config();
|
|
9936
10024
|
import { Command as Command22 } from "commander";
|
|
9937
|
-
import
|
|
10025
|
+
import chalk33 from "chalk";
|
|
9938
10026
|
import ora15 from "ora";
|
|
9939
10027
|
import inquirer6 from "inquirer";
|
|
9940
10028
|
function createCouncilCommand() {
|
|
@@ -9945,7 +10033,7 @@ function createCouncilCommand() {
|
|
|
9945
10033
|
const apiUrl = getApiUrl();
|
|
9946
10034
|
const projectId = getProjectId();
|
|
9947
10035
|
if (!projectId) {
|
|
9948
|
-
console.error(
|
|
10036
|
+
console.error(chalk33.red('Project context missing. Run "rigstate link".'));
|
|
9949
10037
|
return;
|
|
9950
10038
|
}
|
|
9951
10039
|
let sessionTopic = topic;
|
|
@@ -9957,25 +10045,25 @@ function createCouncilCommand() {
|
|
|
9957
10045
|
}]);
|
|
9958
10046
|
sessionTopic = ans.topic;
|
|
9959
10047
|
}
|
|
9960
|
-
console.log(
|
|
9961
|
-
console.log(
|
|
9962
|
-
console.log(
|
|
9963
|
-
console.log(
|
|
10048
|
+
console.log(chalk33.bold.magenta("\n\u2696\uFE0F CONVENING THE COUNCIL OF SOVEREIGNTY\n"));
|
|
10049
|
+
console.log(chalk33.dim(`Topic: ${sessionTopic}`));
|
|
10050
|
+
console.log(chalk33.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
10051
|
+
console.log(chalk33.yellow("\n\u{1F9E0} Frank (Architect): Analyzing alignment with Project DNA..."));
|
|
9964
10052
|
await sleep(1500);
|
|
9965
|
-
console.log(
|
|
9966
|
-
console.log(
|
|
10053
|
+
console.log(chalk33.gray(' "This decision affects our backend scalability. I recommend caution."'));
|
|
10054
|
+
console.log(chalk33.blue("\n\u{1F6E1}\uFE0F Sigrid (Curator): Checking historical precedents..."));
|
|
9967
10055
|
await sleep(1500);
|
|
9968
|
-
console.log(
|
|
9969
|
-
console.log(
|
|
10056
|
+
console.log(chalk33.gray(` "Similar patterns in other projects led to technical debt. Let's review RLS."`));
|
|
10057
|
+
console.log(chalk33.green("\n\u{1F4D0} Einar (Analyst): Scanning dependency impact..."));
|
|
9970
10058
|
await sleep(1500);
|
|
9971
|
-
console.log(
|
|
9972
|
-
console.log(
|
|
9973
|
-
console.log(
|
|
9974
|
-
console.log(
|
|
9975
|
-
console.log(
|
|
9976
|
-
console.log(
|
|
10059
|
+
console.log(chalk33.gray(' "Implementation will require updating 3 core services."'));
|
|
10060
|
+
console.log(chalk33.bold.white("\n\u{1F4CB} [FINAL DECISION RECORD]"));
|
|
10061
|
+
console.log(chalk33.white(" Status: Approved with conditions"));
|
|
10062
|
+
console.log(chalk33.white(" Rationale: Value outweighs migration cost. Ensure SEC-SQL-01 compliance."));
|
|
10063
|
+
console.log(chalk33.dim("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
10064
|
+
console.log(chalk33.green("\u2705 Decision saved to Project Brain (ADR-102)"));
|
|
9977
10065
|
} catch (e) {
|
|
9978
|
-
console.error(
|
|
10066
|
+
console.error(chalk33.red(`
|
|
9979
10067
|
Council session aborted: ${e.message}`));
|
|
9980
10068
|
}
|
|
9981
10069
|
});
|
|
@@ -10022,19 +10110,19 @@ program.hook("preAction", async () => {
|
|
|
10022
10110
|
});
|
|
10023
10111
|
program.on("--help", () => {
|
|
10024
10112
|
console.log("");
|
|
10025
|
-
console.log(
|
|
10113
|
+
console.log(chalk34.bold("Examples:"));
|
|
10026
10114
|
console.log("");
|
|
10027
|
-
console.log(
|
|
10028
|
-
console.log(
|
|
10115
|
+
console.log(chalk34.cyan(" $ rigstate login sk_rigstate_your_api_key"));
|
|
10116
|
+
console.log(chalk34.dim(" Authenticate with your Rigstate API key"));
|
|
10029
10117
|
console.log("");
|
|
10030
|
-
console.log(
|
|
10031
|
-
console.log(
|
|
10118
|
+
console.log(chalk34.cyan(" $ rigstate scan"));
|
|
10119
|
+
console.log(chalk34.dim(" Scan the current directory"));
|
|
10032
10120
|
console.log("");
|
|
10033
|
-
console.log(
|
|
10034
|
-
console.log(
|
|
10121
|
+
console.log(chalk34.cyan(" $ rigstate scan ./src --project abc123"));
|
|
10122
|
+
console.log(chalk34.dim(" Scan a specific directory with project ID"));
|
|
10035
10123
|
console.log("");
|
|
10036
|
-
console.log(
|
|
10037
|
-
console.log(
|
|
10124
|
+
console.log(chalk34.cyan(" $ rigstate scan --json"));
|
|
10125
|
+
console.log(chalk34.dim(" Output results in JSON format (useful for IDE extensions)"));
|
|
10038
10126
|
console.log("");
|
|
10039
10127
|
});
|
|
10040
10128
|
program.parse(process.argv);
|