@rigstate/cli 0.6.7 → 0.6.9
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 +644 -530
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +641 -528
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/idea.ts +78 -0
- package/src/commands/link.ts +10 -3
- package/src/commands/suggest.ts +67 -0
- package/src/commands/work.ts +168 -161
- package/src/index.ts +3 -0
package/dist/index.js
CHANGED
|
@@ -264,12 +264,12 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false) {
|
|
|
264
264
|
}
|
|
265
265
|
const files = syncResponse.data.data.files;
|
|
266
266
|
if (files && Array.isArray(files)) {
|
|
267
|
-
const
|
|
267
|
+
const fs22 = await import("fs/promises");
|
|
268
268
|
const path24 = await import("path");
|
|
269
269
|
for (const file of files) {
|
|
270
270
|
const filePath = path24.join(process.cwd(), file.path);
|
|
271
|
-
await
|
|
272
|
-
await
|
|
271
|
+
await fs22.mkdir(path24.dirname(filePath), { recursive: true });
|
|
272
|
+
await fs22.writeFile(filePath, file.content, "utf-8");
|
|
273
273
|
}
|
|
274
274
|
console.log(chalk3.dim(` \u{1F4BE} Wrote ${files.length} rule files to local .cursor/rules/`));
|
|
275
275
|
}
|
|
@@ -313,13 +313,61 @@ var init_sync_rules = __esm({
|
|
|
313
313
|
}
|
|
314
314
|
});
|
|
315
315
|
|
|
316
|
+
// src/commands/suggest.ts
|
|
317
|
+
var suggest_exports = {};
|
|
318
|
+
__export(suggest_exports, {
|
|
319
|
+
suggestNextMove: () => suggestNextMove
|
|
320
|
+
});
|
|
321
|
+
import chalk4 from "chalk";
|
|
322
|
+
import axios3 from "axios";
|
|
323
|
+
async function suggestNextMove(projectId, apiKey, apiUrl) {
|
|
324
|
+
try {
|
|
325
|
+
const response = await axios3.get(`${apiUrl}/api/v1/roadmap/chunks`, {
|
|
326
|
+
params: {
|
|
327
|
+
project_id: projectId,
|
|
328
|
+
status: "PENDING",
|
|
329
|
+
limit: 1,
|
|
330
|
+
order: "step_number.asc"
|
|
331
|
+
},
|
|
332
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
333
|
+
});
|
|
334
|
+
if (!response.data.success) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
const tasks = response.data.data.chunks || [];
|
|
338
|
+
if (tasks.length === 0) return;
|
|
339
|
+
const nextTask = tasks[0];
|
|
340
|
+
console.log("");
|
|
341
|
+
console.log(chalk4.bold("\u{1F3AF} TACTICAL INTELLIGENCE"));
|
|
342
|
+
console.log(chalk4.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"));
|
|
343
|
+
console.log(`${chalk4.bold("Active Phase:")} Implementation`);
|
|
344
|
+
console.log(`${chalk4.bold("Next Mission:")} ${chalk4.cyan(nextTask.title)}`);
|
|
345
|
+
if (nextTask.role) {
|
|
346
|
+
console.log(`${chalk4.bold("Required Role:")} ${chalk4.magenta(nextTask.role)}`);
|
|
347
|
+
}
|
|
348
|
+
console.log("");
|
|
349
|
+
console.log(chalk4.yellow("SUGGESTED NEXT MOVE:"));
|
|
350
|
+
console.log(chalk4.white(`> rigstate work start ${nextTask.id} `) + chalk4.dim("(Start this task)"));
|
|
351
|
+
console.log(chalk4.white(`> rigstate chat "How do I solve T-${nextTask.step_number}?" `) + chalk4.dim("(Ask Architect)"));
|
|
352
|
+
console.log(chalk4.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"));
|
|
353
|
+
console.log("");
|
|
354
|
+
} catch (e) {
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
var init_suggest = __esm({
|
|
358
|
+
"src/commands/suggest.ts"() {
|
|
359
|
+
"use strict";
|
|
360
|
+
init_esm_shims();
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
316
364
|
// src/commands/hooks.ts
|
|
317
365
|
var hooks_exports = {};
|
|
318
366
|
__export(hooks_exports, {
|
|
319
367
|
createHooksCommand: () => createHooksCommand
|
|
320
368
|
});
|
|
321
369
|
import { Command as Command4 } from "commander";
|
|
322
|
-
import
|
|
370
|
+
import chalk5 from "chalk";
|
|
323
371
|
import fs2 from "fs/promises";
|
|
324
372
|
import path3 from "path";
|
|
325
373
|
function createHooksCommand() {
|
|
@@ -330,8 +378,8 @@ function createHooksCommand() {
|
|
|
330
378
|
try {
|
|
331
379
|
await fs2.access(gitDir);
|
|
332
380
|
} catch {
|
|
333
|
-
console.log(
|
|
334
|
-
console.log(
|
|
381
|
+
console.log(chalk5.red("\u274C Not a git repository."));
|
|
382
|
+
console.log(chalk5.dim(' Initialize with "git init" first.'));
|
|
335
383
|
process.exit(1);
|
|
336
384
|
}
|
|
337
385
|
const hooksDir = path3.join(gitDir, "hooks");
|
|
@@ -341,8 +389,8 @@ function createHooksCommand() {
|
|
|
341
389
|
try {
|
|
342
390
|
existingContent = await fs2.readFile(preCommitPath, "utf-8");
|
|
343
391
|
if (existingContent.includes("rigstate")) {
|
|
344
|
-
console.log(
|
|
345
|
-
console.log(
|
|
392
|
+
console.log(chalk5.yellow("\u26A0 Rigstate pre-commit hook already installed."));
|
|
393
|
+
console.log(chalk5.dim(' Use "rigstate hooks uninstall" to remove first.'));
|
|
346
394
|
return;
|
|
347
395
|
}
|
|
348
396
|
} catch {
|
|
@@ -354,18 +402,18 @@ function createHooksCommand() {
|
|
|
354
402
|
if (existingContent && !existingContent.includes("rigstate")) {
|
|
355
403
|
const combinedScript = existingContent + "\n\n" + script.replace("#!/bin/sh\n", "");
|
|
356
404
|
await fs2.writeFile(preCommitPath, combinedScript, { mode: 493 });
|
|
357
|
-
console.log(
|
|
405
|
+
console.log(chalk5.green("\u2705 Rigstate hook appended to existing pre-commit."));
|
|
358
406
|
} else {
|
|
359
407
|
await fs2.writeFile(preCommitPath, script, { mode: 493 });
|
|
360
|
-
console.log(
|
|
408
|
+
console.log(chalk5.green("\u2705 Pre-commit hook installed!"));
|
|
361
409
|
}
|
|
362
|
-
console.log(
|
|
363
|
-
console.log(
|
|
410
|
+
console.log(chalk5.dim(` Path: ${preCommitPath}`));
|
|
411
|
+
console.log(chalk5.dim(` Strict level: ${options.strict}`));
|
|
364
412
|
console.log("");
|
|
365
|
-
console.log(
|
|
366
|
-
console.log(
|
|
413
|
+
console.log(chalk5.cyan("Guardian will now check your code before each commit."));
|
|
414
|
+
console.log(chalk5.dim('Use "rigstate hooks uninstall" to remove the hook.'));
|
|
367
415
|
} catch (error) {
|
|
368
|
-
console.error(
|
|
416
|
+
console.error(chalk5.red("Failed to install hook:"), error.message);
|
|
369
417
|
process.exit(1);
|
|
370
418
|
}
|
|
371
419
|
});
|
|
@@ -375,12 +423,12 @@ function createHooksCommand() {
|
|
|
375
423
|
try {
|
|
376
424
|
const content = await fs2.readFile(preCommitPath, "utf-8");
|
|
377
425
|
if (!content.includes("rigstate")) {
|
|
378
|
-
console.log(
|
|
426
|
+
console.log(chalk5.yellow("\u26A0 No Rigstate hook found in pre-commit."));
|
|
379
427
|
return;
|
|
380
428
|
}
|
|
381
429
|
if (content.includes("# Rigstate Guardian Pre-commit Hook") && content.trim().split("\n").filter((l) => l && !l.startsWith("#")).length <= 4) {
|
|
382
430
|
await fs2.unlink(preCommitPath);
|
|
383
|
-
console.log(
|
|
431
|
+
console.log(chalk5.green("\u2705 Pre-commit hook removed."));
|
|
384
432
|
} else {
|
|
385
433
|
const lines = content.split("\n");
|
|
386
434
|
const filteredLines = [];
|
|
@@ -399,13 +447,13 @@ function createHooksCommand() {
|
|
|
399
447
|
}
|
|
400
448
|
}
|
|
401
449
|
await fs2.writeFile(preCommitPath, filteredLines.join("\n"), { mode: 493 });
|
|
402
|
-
console.log(
|
|
450
|
+
console.log(chalk5.green("\u2705 Rigstate section removed from pre-commit hook."));
|
|
403
451
|
}
|
|
404
452
|
} catch {
|
|
405
|
-
console.log(
|
|
453
|
+
console.log(chalk5.yellow("\u26A0 No pre-commit hook found."));
|
|
406
454
|
}
|
|
407
455
|
} catch (error) {
|
|
408
|
-
console.error(
|
|
456
|
+
console.error(chalk5.red("Failed to uninstall hook:"), error.message);
|
|
409
457
|
process.exit(1);
|
|
410
458
|
}
|
|
411
459
|
});
|
|
@@ -450,14 +498,14 @@ __export(skills_provisioner_exports, {
|
|
|
450
498
|
jitProvisionSkill: () => jitProvisionSkill,
|
|
451
499
|
provisionSkills: () => provisionSkills
|
|
452
500
|
});
|
|
453
|
-
import
|
|
501
|
+
import axios6 from "axios";
|
|
454
502
|
import fs7 from "fs/promises";
|
|
455
503
|
import path8 from "path";
|
|
456
|
-
import
|
|
504
|
+
import chalk9 from "chalk";
|
|
457
505
|
async function provisionSkills(apiUrl, apiKey, projectId, rootDir) {
|
|
458
506
|
const skills = [];
|
|
459
507
|
try {
|
|
460
|
-
const response = await
|
|
508
|
+
const response = await axios6.get(`${apiUrl}/api/v1/skills`, {
|
|
461
509
|
params: { project_id: projectId },
|
|
462
510
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
463
511
|
});
|
|
@@ -475,7 +523,7 @@ async function provisionSkills(apiUrl, apiKey, projectId, rootDir) {
|
|
|
475
523
|
}
|
|
476
524
|
} catch (e) {
|
|
477
525
|
const msg = e.response?.data?.error || e.message;
|
|
478
|
-
console.log(
|
|
526
|
+
console.log(chalk9.dim(` (Skills API not available: ${msg}, using core library)`));
|
|
479
527
|
}
|
|
480
528
|
if (skills.length === 0) {
|
|
481
529
|
const { getRigstateStandardSkills } = await import("@rigstate/rules-engine");
|
|
@@ -502,7 +550,7 @@ ${skill.content}
|
|
|
502
550
|
const skillPath = path8.join(skillDir, "SKILL.md");
|
|
503
551
|
await fs7.writeFile(skillPath, skillContent, "utf-8");
|
|
504
552
|
}
|
|
505
|
-
console.log(
|
|
553
|
+
console.log(chalk9.green(` \u2705 Provisioned ${skills.length} skill(s) to .agent/skills/`));
|
|
506
554
|
return skills;
|
|
507
555
|
}
|
|
508
556
|
function generateSkillsDiscoveryBlock(skills) {
|
|
@@ -526,7 +574,7 @@ async function jitProvisionSkill(skillId, apiUrl, apiKey, projectId, rootDir) {
|
|
|
526
574
|
}
|
|
527
575
|
const isProvisioned = rulesContent.includes(`<name>${skillId}</name>`) || rulesContent.includes(`.agent/skills/${skillId}`);
|
|
528
576
|
if (isProvisioned) return false;
|
|
529
|
-
console.log(
|
|
577
|
+
console.log(chalk9.yellow(` \u26A1 JIT PROVISIONING: Injecting ${skillId}...`));
|
|
530
578
|
try {
|
|
531
579
|
const skills = await provisionSkills(apiUrl, apiKey, projectId, rootDir);
|
|
532
580
|
const skillsBlock = generateSkillsDiscoveryBlock(skills);
|
|
@@ -544,7 +592,7 @@ async function jitProvisionSkill(skillId, apiUrl, apiKey, projectId, rootDir) {
|
|
|
544
592
|
await fs7.writeFile(rulesPath, rulesContent, "utf-8");
|
|
545
593
|
return true;
|
|
546
594
|
} catch (e) {
|
|
547
|
-
console.log(
|
|
595
|
+
console.log(chalk9.red(` Failed to provision skill: ${e.message}`));
|
|
548
596
|
return false;
|
|
549
597
|
}
|
|
550
598
|
}
|
|
@@ -567,7 +615,7 @@ __export(governance_exports, {
|
|
|
567
615
|
});
|
|
568
616
|
import fs8 from "fs/promises";
|
|
569
617
|
import path9 from "path";
|
|
570
|
-
import
|
|
618
|
+
import chalk10 from "chalk";
|
|
571
619
|
async function getGovernanceConfig(rootDir = process.cwd()) {
|
|
572
620
|
try {
|
|
573
621
|
const configPath = path9.join(rootDir, "rigstate.config.json");
|
|
@@ -615,7 +663,7 @@ async function clearSoftLock(rootDir = process.cwd()) {
|
|
|
615
663
|
async function performOverride(violationId, reason, rootDir = process.cwd()) {
|
|
616
664
|
const config2 = await getGovernanceConfig(rootDir);
|
|
617
665
|
if (!config2.governance.allow_overrides) {
|
|
618
|
-
console.log(
|
|
666
|
+
console.log(chalk10.red("\u274C Overrides are disabled for this project."));
|
|
619
667
|
return false;
|
|
620
668
|
}
|
|
621
669
|
await clearSoftLock(rootDir);
|
|
@@ -654,8 +702,8 @@ __export(watchdog_exports, {
|
|
|
654
702
|
});
|
|
655
703
|
import fs9 from "fs/promises";
|
|
656
704
|
import path10 from "path";
|
|
657
|
-
import
|
|
658
|
-
import
|
|
705
|
+
import chalk11 from "chalk";
|
|
706
|
+
import axios7 from "axios";
|
|
659
707
|
async function countLines(filePath) {
|
|
660
708
|
try {
|
|
661
709
|
const content = await fs9.readFile(filePath, "utf-8");
|
|
@@ -681,7 +729,7 @@ async function fetchRulesFromApi(projectId) {
|
|
|
681
729
|
try {
|
|
682
730
|
const apiUrl = getApiUrl();
|
|
683
731
|
const apiKey = getApiKey();
|
|
684
|
-
const response = await
|
|
732
|
+
const response = await axios7.get(`${apiUrl}/api/v1/guardian/rules`, {
|
|
685
733
|
params: { project_id: projectId },
|
|
686
734
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
687
735
|
timeout: 1e4
|
|
@@ -715,7 +763,7 @@ async function fetchRulesFromApi(projectId) {
|
|
|
715
763
|
};
|
|
716
764
|
}
|
|
717
765
|
async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
718
|
-
console.log(
|
|
766
|
+
console.log(chalk11.bold("\n\u{1F6E1}\uFE0F Active Guardian Watchdog Initiated..."));
|
|
719
767
|
let lmax = settings.lmax || DEFAULT_LMAX;
|
|
720
768
|
let lmaxWarning = settings.lmax_warning || DEFAULT_LMAX_WARNING;
|
|
721
769
|
let ruleSource = settings.lmax ? "Settings (Passed)" : "Default";
|
|
@@ -725,7 +773,7 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
725
773
|
lmaxWarning = apiRules.lmaxWarning;
|
|
726
774
|
ruleSource = apiRules.source;
|
|
727
775
|
}
|
|
728
|
-
console.log(
|
|
776
|
+
console.log(chalk11.dim(`Governance Rules: L_max=${lmax}, L_max_warning=${lmaxWarning}, Source: ${ruleSource}`));
|
|
729
777
|
const targetExtensions = [".ts", ".tsx"];
|
|
730
778
|
let scanTarget = rootPath;
|
|
731
779
|
const webSrc = path10.join(rootPath, "apps", "web", "src");
|
|
@@ -734,7 +782,7 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
734
782
|
scanTarget = webSrc;
|
|
735
783
|
} catch {
|
|
736
784
|
}
|
|
737
|
-
console.log(
|
|
785
|
+
console.log(chalk11.dim(`Scanning target: ${path10.relative(process.cwd(), scanTarget)}`));
|
|
738
786
|
const files = await getFiles(scanTarget, targetExtensions);
|
|
739
787
|
let violations = 0;
|
|
740
788
|
let warnings = 0;
|
|
@@ -745,27 +793,27 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
745
793
|
if (lines > lmax) {
|
|
746
794
|
results.push({ file: relPath, lines, status: "VIOLATION" });
|
|
747
795
|
violations++;
|
|
748
|
-
console.log(
|
|
796
|
+
console.log(chalk11.red(`[VIOLATION] ${relPath}: ${lines} lines (Limit: ${lmax})`));
|
|
749
797
|
} else if (lines > lmaxWarning) {
|
|
750
798
|
results.push({ file: relPath, lines, status: "WARNING" });
|
|
751
799
|
warnings++;
|
|
752
|
-
console.log(
|
|
800
|
+
console.log(chalk11.yellow(`[WARNING] ${relPath}: ${lines} lines (Threshold: ${lmaxWarning})`));
|
|
753
801
|
}
|
|
754
802
|
}
|
|
755
803
|
if (violations === 0 && warnings === 0) {
|
|
756
|
-
console.log(
|
|
804
|
+
console.log(chalk11.green(`\u2714 All ${files.length} files are within governance limits.`));
|
|
757
805
|
} else {
|
|
758
|
-
console.log("\n" +
|
|
759
|
-
console.log(
|
|
760
|
-
console.log(
|
|
806
|
+
console.log("\n" + chalk11.bold("Summary:"));
|
|
807
|
+
console.log(chalk11.red(`Violations: ${violations}`));
|
|
808
|
+
console.log(chalk11.yellow(`Warnings: ${warnings}`));
|
|
761
809
|
const { getGovernanceConfig: getGovernanceConfig2, setSoftLock: setSoftLock2, InterventionLevel: InterventionLevel2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
762
810
|
const { governance } = await getGovernanceConfig2(rootPath);
|
|
763
|
-
console.log(
|
|
811
|
+
console.log(chalk11.dim(`Intervention Level: ${InterventionLevel2[governance.intervention_level] || "UNKNOWN"} (${governance.intervention_level})`));
|
|
764
812
|
if (violations > 0) {
|
|
765
|
-
console.log(
|
|
813
|
+
console.log(chalk11.red.bold("\nCRITICAL: Governance violations detected. Immediate refactoring required."));
|
|
766
814
|
if (governance.intervention_level >= InterventionLevel2.SENTINEL) {
|
|
767
|
-
console.log(
|
|
768
|
-
console.log(
|
|
815
|
+
console.log(chalk11.red.bold("\u{1F6D1} SENTINEL MODE: Session SOFT_LOCKED until resolved."));
|
|
816
|
+
console.log(chalk11.red(' Run "rigstate override <id> --reason \\"...\\"" if this is an emergency.'));
|
|
769
817
|
await setSoftLock2("Sentinel Mode: Governance Violations Detected", "ARC-VIOLATION", rootPath);
|
|
770
818
|
}
|
|
771
819
|
}
|
|
@@ -781,16 +829,16 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
781
829
|
limitValue: lmax,
|
|
782
830
|
severity: "CRITICAL"
|
|
783
831
|
}));
|
|
784
|
-
await
|
|
832
|
+
await axios7.post(`${apiUrl}/api/v1/guardian/sync`, {
|
|
785
833
|
projectId,
|
|
786
834
|
violations: payloadViolations,
|
|
787
835
|
warnings
|
|
788
836
|
}, {
|
|
789
837
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
790
838
|
});
|
|
791
|
-
console.log(
|
|
839
|
+
console.log(chalk11.dim("\u2714 Violations synced to Rigstate Cloud."));
|
|
792
840
|
} catch (e) {
|
|
793
|
-
console.log(
|
|
841
|
+
console.log(chalk11.dim("\u26A0 Cloud sync skipped: " + (e.message || "Unknown")));
|
|
794
842
|
}
|
|
795
843
|
}
|
|
796
844
|
}
|
|
@@ -808,8 +856,8 @@ var init_watchdog = __esm({
|
|
|
808
856
|
|
|
809
857
|
// src/index.ts
|
|
810
858
|
init_esm_shims();
|
|
811
|
-
import { Command as
|
|
812
|
-
import
|
|
859
|
+
import { Command as Command20 } from "commander";
|
|
860
|
+
import chalk29 from "chalk";
|
|
813
861
|
|
|
814
862
|
// src/commands/login.ts
|
|
815
863
|
init_esm_shims();
|
|
@@ -864,7 +912,7 @@ init_esm_shims();
|
|
|
864
912
|
import { Command as Command5 } from "commander";
|
|
865
913
|
import fs3 from "fs/promises";
|
|
866
914
|
import path4 from "path";
|
|
867
|
-
import
|
|
915
|
+
import chalk6 from "chalk";
|
|
868
916
|
import os from "os";
|
|
869
917
|
function createLinkCommand() {
|
|
870
918
|
return new Command5("link").description("Link current directory to a Rigstate project").argument("<projectId>", "Project ID to link").action(async (projectId) => {
|
|
@@ -877,7 +925,7 @@ function createLinkCommand() {
|
|
|
877
925
|
if (config2.overrides && config2.overrides[cwd]) {
|
|
878
926
|
const overrideId = config2.overrides[cwd];
|
|
879
927
|
if (overrideId !== projectId) {
|
|
880
|
-
console.warn(
|
|
928
|
+
console.warn(chalk6.yellow(`Global override detected. Enforcing project ID: ${overrideId}`));
|
|
881
929
|
projectId = overrideId;
|
|
882
930
|
}
|
|
883
931
|
}
|
|
@@ -892,42 +940,47 @@ function createLinkCommand() {
|
|
|
892
940
|
};
|
|
893
941
|
try {
|
|
894
942
|
await fs3.writeFile(manifestPath, JSON.stringify(content, null, 2), "utf-8");
|
|
895
|
-
console.log(
|
|
896
|
-
console.log(
|
|
943
|
+
console.log(chalk6.green(`\u2714 Linked to project ID: ${projectId}`));
|
|
944
|
+
console.log(chalk6.dim(`Created local context manifest at .rigstate`));
|
|
897
945
|
console.log("");
|
|
898
|
-
console.log(
|
|
946
|
+
console.log(chalk6.bold("\u{1F916} Rigstate Automation Detected"));
|
|
899
947
|
console.log("");
|
|
900
948
|
const { getApiKey: getApiKey2, getApiUrl: getApiUrl2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
901
949
|
const apiKey = getApiKey2();
|
|
902
950
|
const apiUrl = getApiUrl2();
|
|
903
951
|
if (apiKey) {
|
|
904
|
-
console.log(
|
|
952
|
+
console.log(chalk6.blue("\u{1F510} Checking Vault for secrets..."));
|
|
905
953
|
const { syncEnv: syncEnv2 } = await Promise.resolve().then(() => (init_env(), env_exports));
|
|
906
954
|
await syncEnv2(projectId, apiKey, apiUrl, true);
|
|
907
|
-
console.log(
|
|
955
|
+
console.log(chalk6.blue("\u{1F9E0} Syncing neural instructions..."));
|
|
908
956
|
const { syncProjectRules: syncProjectRules2 } = await Promise.resolve().then(() => (init_sync_rules(), sync_rules_exports));
|
|
909
957
|
await syncProjectRules2(projectId, apiKey, apiUrl);
|
|
910
|
-
console.log(
|
|
958
|
+
console.log(chalk6.blue("\u{1F6E1}\uFE0F Checking immunity system..."));
|
|
911
959
|
await installHooks(process.cwd());
|
|
960
|
+
console.log("");
|
|
961
|
+
console.log(chalk6.bold.green("\u{1F680} Link Complete! Your environment is ready."));
|
|
962
|
+
const { suggestNextMove: suggestNextMove2 } = await Promise.resolve().then(() => (init_suggest(), suggest_exports));
|
|
963
|
+
await suggestNextMove2(projectId, apiKey, apiUrl);
|
|
964
|
+
} else {
|
|
965
|
+
console.log("");
|
|
966
|
+
console.log(chalk6.bold.green("\u{1F680} Link Complete!"));
|
|
912
967
|
}
|
|
913
|
-
console.log("");
|
|
914
|
-
console.log(chalk5.bold.green("\u{1F680} Link Complete! Your environment is ready."));
|
|
915
968
|
} catch (error) {
|
|
916
969
|
if (error.message.includes("Not authenticated")) {
|
|
917
|
-
console.warn(
|
|
970
|
+
console.warn(chalk6.yellow('\u26A0\uFE0F Not authenticated. Run "rigstate login" to enable automation features.'));
|
|
918
971
|
} else {
|
|
919
|
-
console.error(
|
|
972
|
+
console.error(chalk6.red(`Failed to link project: ${error.message}`));
|
|
920
973
|
}
|
|
921
974
|
}
|
|
922
975
|
});
|
|
923
976
|
}
|
|
924
977
|
async function installHooks(cwd) {
|
|
925
|
-
const
|
|
978
|
+
const fs22 = await import("fs/promises");
|
|
926
979
|
const path24 = await import("path");
|
|
927
980
|
try {
|
|
928
|
-
await
|
|
981
|
+
await fs22.access(path24.join(cwd, ".git"));
|
|
929
982
|
} catch {
|
|
930
|
-
console.log(
|
|
983
|
+
console.log(chalk6.dim(" (Not a git repository, skipping hooks)"));
|
|
931
984
|
return;
|
|
932
985
|
}
|
|
933
986
|
const hooksDir = path24.join(cwd, ".husky");
|
|
@@ -935,10 +988,10 @@ async function installHooks(cwd) {
|
|
|
935
988
|
const { installHooks: runInstall } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
|
|
936
989
|
const preCommitPath = path24.join(cwd, ".git/hooks/pre-commit");
|
|
937
990
|
try {
|
|
938
|
-
await
|
|
939
|
-
console.log(
|
|
991
|
+
await fs22.access(preCommitPath);
|
|
992
|
+
console.log(chalk6.green(" \u2714 Git hooks already active"));
|
|
940
993
|
} catch {
|
|
941
|
-
console.log(
|
|
994
|
+
console.log(chalk6.yellow(' \u26A0\uFE0F Git hooks missing. Run "rigstate hooks install" to secure repo.'));
|
|
942
995
|
}
|
|
943
996
|
} catch (e) {
|
|
944
997
|
}
|
|
@@ -948,9 +1001,9 @@ async function installHooks(cwd) {
|
|
|
948
1001
|
init_esm_shims();
|
|
949
1002
|
init_config();
|
|
950
1003
|
import { Command as Command6 } from "commander";
|
|
951
|
-
import
|
|
1004
|
+
import chalk7 from "chalk";
|
|
952
1005
|
import ora3 from "ora";
|
|
953
|
-
import
|
|
1006
|
+
import axios4 from "axios";
|
|
954
1007
|
import { glob } from "glob";
|
|
955
1008
|
import fs5 from "fs/promises";
|
|
956
1009
|
import path6 from "path";
|
|
@@ -1038,13 +1091,13 @@ function createScanCommand() {
|
|
|
1038
1091
|
const projectId = options.project || getProjectId();
|
|
1039
1092
|
if (!projectId) {
|
|
1040
1093
|
console.warn(
|
|
1041
|
-
|
|
1094
|
+
chalk7.yellow(
|
|
1042
1095
|
"\u26A0\uFE0F No project ID specified. Use --project <id> or set a default."
|
|
1043
1096
|
)
|
|
1044
1097
|
);
|
|
1045
1098
|
}
|
|
1046
1099
|
const scanPath = path6.resolve(process.cwd(), targetPath);
|
|
1047
|
-
spinner.start(`Scanning ${
|
|
1100
|
+
spinner.start(`Scanning ${chalk7.cyan(scanPath)}...`);
|
|
1048
1101
|
const gitignorePatterns = await readGitignore(scanPath);
|
|
1049
1102
|
const pattern = path6.join(scanPath, "**/*");
|
|
1050
1103
|
const allFiles = await glob(pattern, {
|
|
@@ -1057,7 +1110,7 @@ function createScanCommand() {
|
|
|
1057
1110
|
return isCodeFile(file) && !shouldIgnore(relativePath, gitignorePatterns);
|
|
1058
1111
|
});
|
|
1059
1112
|
if (codeFiles.length === 0) {
|
|
1060
|
-
spinner.warn(
|
|
1113
|
+
spinner.warn(chalk7.yellow("No code files found to scan."));
|
|
1061
1114
|
return;
|
|
1062
1115
|
}
|
|
1063
1116
|
spinner.text = `Found ${codeFiles.length} files. Scanning...`;
|
|
@@ -1070,7 +1123,7 @@ function createScanCommand() {
|
|
|
1070
1123
|
spinner.text = `Scanning ${i + 1}/${codeFiles.length}: ${relativePath}`;
|
|
1071
1124
|
try {
|
|
1072
1125
|
const content = await fs5.readFile(filePath, "utf-8");
|
|
1073
|
-
const response = await
|
|
1126
|
+
const response = await axios4.post(
|
|
1074
1127
|
`${apiUrl}/api/v1/audit`,
|
|
1075
1128
|
{
|
|
1076
1129
|
content,
|
|
@@ -1104,16 +1157,16 @@ function createScanCommand() {
|
|
|
1104
1157
|
});
|
|
1105
1158
|
}
|
|
1106
1159
|
} catch (fileError) {
|
|
1107
|
-
if (
|
|
1108
|
-
console.warn(
|
|
1160
|
+
if (axios4.isAxiosError(fileError)) {
|
|
1161
|
+
console.warn(chalk7.yellow(`
|
|
1109
1162
|
\u26A0\uFE0F Skipping ${relativePath}: ${fileError.message}`));
|
|
1110
1163
|
} else {
|
|
1111
|
-
console.warn(
|
|
1164
|
+
console.warn(chalk7.yellow(`
|
|
1112
1165
|
\u26A0\uFE0F Error reading ${relativePath}`));
|
|
1113
1166
|
}
|
|
1114
1167
|
}
|
|
1115
1168
|
}
|
|
1116
|
-
spinner.succeed(
|
|
1169
|
+
spinner.succeed(chalk7.green("\u2705 Scan completed!"));
|
|
1117
1170
|
const aggregatedResponse = {
|
|
1118
1171
|
results,
|
|
1119
1172
|
summary: {
|
|
@@ -1128,21 +1181,21 @@ function createScanCommand() {
|
|
|
1128
1181
|
printPrettyResults(aggregatedResponse);
|
|
1129
1182
|
}
|
|
1130
1183
|
} catch (error) {
|
|
1131
|
-
spinner.fail(
|
|
1132
|
-
if (
|
|
1184
|
+
spinner.fail(chalk7.red("\u274C Scan failed"));
|
|
1185
|
+
if (axios4.isAxiosError(error)) {
|
|
1133
1186
|
if (error.response) {
|
|
1134
|
-
console.error(
|
|
1187
|
+
console.error(chalk7.red("API Error:"), error.response.data);
|
|
1135
1188
|
} else if (error.request) {
|
|
1136
1189
|
console.error(
|
|
1137
|
-
|
|
1190
|
+
chalk7.red("Network Error:"),
|
|
1138
1191
|
"Could not reach the API. Is the server running?"
|
|
1139
1192
|
);
|
|
1140
1193
|
} else {
|
|
1141
|
-
console.error(
|
|
1194
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1142
1195
|
}
|
|
1143
1196
|
} else {
|
|
1144
1197
|
console.error(
|
|
1145
|
-
|
|
1198
|
+
chalk7.red("Error:"),
|
|
1146
1199
|
error instanceof Error ? error.message : "Unknown error"
|
|
1147
1200
|
);
|
|
1148
1201
|
}
|
|
@@ -1152,10 +1205,10 @@ function createScanCommand() {
|
|
|
1152
1205
|
}
|
|
1153
1206
|
function printPrettyResults(data) {
|
|
1154
1207
|
const { results, summary } = data;
|
|
1155
|
-
console.log("\n" +
|
|
1156
|
-
console.log(
|
|
1157
|
-
console.log(`Total Files Scanned: ${
|
|
1158
|
-
console.log(`Total Issues Found: ${
|
|
1208
|
+
console.log("\n" + chalk7.bold("\u{1F4CA} Scan Summary"));
|
|
1209
|
+
console.log(chalk7.dim("\u2500".repeat(60)));
|
|
1210
|
+
console.log(`Total Files Scanned: ${chalk7.cyan(summary.total_files)}`);
|
|
1211
|
+
console.log(`Total Issues Found: ${chalk7.yellow(summary.total_issues)}`);
|
|
1159
1212
|
if (summary.by_severity) {
|
|
1160
1213
|
console.log("\nIssues by Severity:");
|
|
1161
1214
|
Object.entries(summary.by_severity).forEach(([severity, count]) => {
|
|
@@ -1164,39 +1217,39 @@ function printPrettyResults(data) {
|
|
|
1164
1217
|
});
|
|
1165
1218
|
}
|
|
1166
1219
|
if (results && results.length > 0) {
|
|
1167
|
-
console.log("\n" +
|
|
1168
|
-
console.log(
|
|
1220
|
+
console.log("\n" + chalk7.bold("\u{1F50D} Detailed Results"));
|
|
1221
|
+
console.log(chalk7.dim("\u2500".repeat(60)));
|
|
1169
1222
|
results.forEach((result) => {
|
|
1170
1223
|
if (result.issues && result.issues.length > 0) {
|
|
1171
1224
|
console.log(`
|
|
1172
|
-
${
|
|
1225
|
+
${chalk7.bold(result.file_path)}`);
|
|
1173
1226
|
result.issues.forEach((issue) => {
|
|
1174
1227
|
const severityColor = getSeverityColor(issue.severity);
|
|
1175
|
-
const lineInfo = issue.line ?
|
|
1228
|
+
const lineInfo = issue.line ? chalk7.dim(`:${issue.line}`) : "";
|
|
1176
1229
|
console.log(
|
|
1177
1230
|
` ${severityColor(`[${issue.severity.toUpperCase()}]`)} ${issue.type}${lineInfo}`
|
|
1178
1231
|
);
|
|
1179
|
-
console.log(` ${
|
|
1232
|
+
console.log(` ${chalk7.dim(issue.message)}`);
|
|
1180
1233
|
});
|
|
1181
1234
|
}
|
|
1182
1235
|
});
|
|
1183
1236
|
}
|
|
1184
|
-
console.log("\n" +
|
|
1237
|
+
console.log("\n" + chalk7.dim("\u2500".repeat(60)));
|
|
1185
1238
|
}
|
|
1186
1239
|
function getSeverityColor(severity) {
|
|
1187
1240
|
switch (severity.toLowerCase()) {
|
|
1188
1241
|
case "critical":
|
|
1189
|
-
return
|
|
1242
|
+
return chalk7.red.bold;
|
|
1190
1243
|
case "high":
|
|
1191
|
-
return
|
|
1244
|
+
return chalk7.red;
|
|
1192
1245
|
case "medium":
|
|
1193
|
-
return
|
|
1246
|
+
return chalk7.yellow;
|
|
1194
1247
|
case "low":
|
|
1195
|
-
return
|
|
1248
|
+
return chalk7.blue;
|
|
1196
1249
|
case "info":
|
|
1197
|
-
return
|
|
1250
|
+
return chalk7.gray;
|
|
1198
1251
|
default:
|
|
1199
|
-
return
|
|
1252
|
+
return chalk7.white;
|
|
1200
1253
|
}
|
|
1201
1254
|
}
|
|
1202
1255
|
|
|
@@ -1204,9 +1257,9 @@ function getSeverityColor(severity) {
|
|
|
1204
1257
|
init_esm_shims();
|
|
1205
1258
|
init_config();
|
|
1206
1259
|
import { Command as Command7 } from "commander";
|
|
1207
|
-
import
|
|
1260
|
+
import chalk8 from "chalk";
|
|
1208
1261
|
import ora4 from "ora";
|
|
1209
|
-
import
|
|
1262
|
+
import axios5 from "axios";
|
|
1210
1263
|
import { glob as glob2 } from "glob";
|
|
1211
1264
|
import fs6 from "fs/promises";
|
|
1212
1265
|
import path7 from "path";
|
|
@@ -1220,7 +1273,7 @@ function createFixCommand() {
|
|
|
1220
1273
|
const apiUrl = getApiUrl();
|
|
1221
1274
|
const projectId = options.project || getProjectId();
|
|
1222
1275
|
if (!projectId) {
|
|
1223
|
-
console.log(
|
|
1276
|
+
console.log(chalk8.yellow("\u26A0\uFE0F Project ID is required for fixing. Using default or pass --project <id>"));
|
|
1224
1277
|
}
|
|
1225
1278
|
const scanPath = path7.resolve(process.cwd(), targetPath);
|
|
1226
1279
|
const gitignorePatterns = await readGitignore(scanPath);
|
|
@@ -1231,12 +1284,12 @@ function createFixCommand() {
|
|
|
1231
1284
|
return isCodeFile(file) && !shouldIgnore(relativePath, gitignorePatterns);
|
|
1232
1285
|
});
|
|
1233
1286
|
if (codeFiles.length === 0) {
|
|
1234
|
-
console.log(
|
|
1287
|
+
console.log(chalk8.yellow("No code files found."));
|
|
1235
1288
|
return;
|
|
1236
1289
|
}
|
|
1237
|
-
console.log(
|
|
1290
|
+
console.log(chalk8.bold(`
|
|
1238
1291
|
\u{1F9E0} Rigstate Fix Mode`));
|
|
1239
|
-
console.log(
|
|
1292
|
+
console.log(chalk8.dim(`Scanning ${codeFiles.length} files with Project Context...
|
|
1240
1293
|
`));
|
|
1241
1294
|
let fixedCount = 0;
|
|
1242
1295
|
for (let i = 0; i < codeFiles.length; i++) {
|
|
@@ -1245,7 +1298,7 @@ function createFixCommand() {
|
|
|
1245
1298
|
spinner.start(`Analyzing ${relativePath}...`);
|
|
1246
1299
|
try {
|
|
1247
1300
|
const content = await fs6.readFile(filePath, "utf-8");
|
|
1248
|
-
const response = await
|
|
1301
|
+
const response = await axios5.post(
|
|
1249
1302
|
`${apiUrl}/api/v1/audit`,
|
|
1250
1303
|
{ content, file_path: relativePath, project_id: projectId },
|
|
1251
1304
|
{ headers: { "Authorization": `Bearer ${apiKey}` }, timeout: 12e4 }
|
|
@@ -1255,22 +1308,22 @@ function createFixCommand() {
|
|
|
1255
1308
|
if (fixableIssues.length > 0) {
|
|
1256
1309
|
spinner.stop();
|
|
1257
1310
|
console.log(`
|
|
1258
|
-
${
|
|
1311
|
+
${chalk8.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
1259
1312
|
for (const issue of fixableIssues) {
|
|
1260
|
-
console.log(
|
|
1313
|
+
console.log(chalk8.red(`
|
|
1261
1314
|
[${issue.type}] ${issue.title}`));
|
|
1262
|
-
console.log(
|
|
1315
|
+
console.log(chalk8.dim(issue.suggestion || issue.message));
|
|
1263
1316
|
const diff = Diff.createTwoFilesPatch(relativePath, relativePath, content, issue.fixed_content, "Current", "Fixed");
|
|
1264
1317
|
console.log("\n" + diff.split("\n").slice(0, 15).join("\n") + (diff.split("\n").length > 15 ? "\n..." : ""));
|
|
1265
1318
|
const { apply } = await inquirer.prompt([{
|
|
1266
1319
|
type: "confirm",
|
|
1267
1320
|
name: "apply",
|
|
1268
|
-
message: `Apply this fix to ${
|
|
1321
|
+
message: `Apply this fix to ${chalk8.cyan(relativePath)}?`,
|
|
1269
1322
|
default: true
|
|
1270
1323
|
}]);
|
|
1271
1324
|
if (apply) {
|
|
1272
1325
|
await fs6.writeFile(filePath, issue.fixed_content);
|
|
1273
|
-
console.log(
|
|
1326
|
+
console.log(chalk8.green(`\u2705 Fixed applied!`));
|
|
1274
1327
|
fixedCount++;
|
|
1275
1328
|
if (issue.related_step_id) {
|
|
1276
1329
|
const { completeStep } = await inquirer.prompt([{
|
|
@@ -1281,20 +1334,20 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
1281
1334
|
}]);
|
|
1282
1335
|
if (completeStep) {
|
|
1283
1336
|
try {
|
|
1284
|
-
await
|
|
1337
|
+
await axios5.post(
|
|
1285
1338
|
`${apiUrl}/api/v1/roadmap/update-status`,
|
|
1286
1339
|
{ step_id: issue.related_step_id, status: "COMPLETED", project_id: projectId },
|
|
1287
1340
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
1288
1341
|
);
|
|
1289
|
-
console.log(
|
|
1342
|
+
console.log(chalk8.green(`\u{1F680} Roadmap updated! Mission Control is in sync.`));
|
|
1290
1343
|
} catch (err) {
|
|
1291
|
-
console.error(
|
|
1344
|
+
console.error(chalk8.yellow(`Failed to update roadmap: ${err.message}`));
|
|
1292
1345
|
}
|
|
1293
1346
|
}
|
|
1294
1347
|
}
|
|
1295
1348
|
break;
|
|
1296
1349
|
} else {
|
|
1297
|
-
console.log(
|
|
1350
|
+
console.log(chalk8.dim("Skipped."));
|
|
1298
1351
|
}
|
|
1299
1352
|
}
|
|
1300
1353
|
} else {
|
|
@@ -1304,11 +1357,11 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
1304
1357
|
}
|
|
1305
1358
|
}
|
|
1306
1359
|
spinner.stop();
|
|
1307
|
-
console.log(
|
|
1360
|
+
console.log(chalk8.bold.green(`
|
|
1308
1361
|
|
|
1309
1362
|
\u{1F680} Fix session complete!`));
|
|
1310
1363
|
console.log(`Frank fixed ${fixedCount} detected issues.`);
|
|
1311
|
-
console.log(
|
|
1364
|
+
console.log(chalk8.dim(`Run 'rigstate scan' to verify remaining issues.`));
|
|
1312
1365
|
} catch (error) {
|
|
1313
1366
|
spinner.fail("Fix session failed");
|
|
1314
1367
|
console.error(error.message);
|
|
@@ -1320,9 +1373,9 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
1320
1373
|
init_esm_shims();
|
|
1321
1374
|
init_config();
|
|
1322
1375
|
import { Command as Command8 } from "commander";
|
|
1323
|
-
import
|
|
1376
|
+
import chalk12 from "chalk";
|
|
1324
1377
|
import ora5 from "ora";
|
|
1325
|
-
import
|
|
1378
|
+
import axios8 from "axios";
|
|
1326
1379
|
import fs10 from "fs/promises";
|
|
1327
1380
|
import path11 from "path";
|
|
1328
1381
|
function createSyncCommand() {
|
|
@@ -1356,7 +1409,7 @@ function createSyncCommand() {
|
|
|
1356
1409
|
return;
|
|
1357
1410
|
}
|
|
1358
1411
|
const apiUrl = getApiUrl();
|
|
1359
|
-
const response = await
|
|
1412
|
+
const response = await axios8.get(`${apiUrl}/api/v1/roadmap`, {
|
|
1360
1413
|
params: { project_id: projectId },
|
|
1361
1414
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1362
1415
|
});
|
|
@@ -1383,7 +1436,7 @@ function createSyncCommand() {
|
|
|
1383
1436
|
await fs10.writeFile(manifestPath, JSON.stringify(manifestContent, null, 2), "utf-8");
|
|
1384
1437
|
} catch (e) {
|
|
1385
1438
|
}
|
|
1386
|
-
console.log(
|
|
1439
|
+
console.log(chalk12.bold("\n\u{1F9E0} Agent Skills Provisioning..."));
|
|
1387
1440
|
try {
|
|
1388
1441
|
const { provisionSkills: provisionSkills2, generateSkillsDiscoveryBlock: generateSkillsDiscoveryBlock2 } = await Promise.resolve().then(() => (init_skills_provisioner(), skills_provisioner_exports));
|
|
1389
1442
|
const skills = await provisionSkills2(apiUrl, apiKey, projectId, process.cwd());
|
|
@@ -1403,11 +1456,11 @@ function createSyncCommand() {
|
|
|
1403
1456
|
}
|
|
1404
1457
|
}
|
|
1405
1458
|
await fs10.writeFile(cursorRulesPath, rulesContent, "utf-8");
|
|
1406
|
-
console.log(
|
|
1459
|
+
console.log(chalk12.dim(` Updated .cursorrules with skills discovery block`));
|
|
1407
1460
|
} catch (e) {
|
|
1408
1461
|
}
|
|
1409
1462
|
} catch (e) {
|
|
1410
|
-
console.log(
|
|
1463
|
+
console.log(chalk12.yellow(` \u26A0 Skills provisioning skipped: ${e.message}`));
|
|
1411
1464
|
}
|
|
1412
1465
|
try {
|
|
1413
1466
|
const logPath = path11.join(process.cwd(), ".rigstate", "logs", "last_execution.json");
|
|
@@ -1415,7 +1468,7 @@ function createSyncCommand() {
|
|
|
1415
1468
|
const logContent = await fs10.readFile(logPath, "utf-8");
|
|
1416
1469
|
const logData = JSON.parse(logContent);
|
|
1417
1470
|
if (logData.task_summary) {
|
|
1418
|
-
await
|
|
1471
|
+
await axios8.post(`${apiUrl}/api/v1/execution-logs`, {
|
|
1419
1472
|
project_id: projectId,
|
|
1420
1473
|
...logData,
|
|
1421
1474
|
agent_role: process.env.RIGSTATE_MODE === "SUPERVISOR" ? "SUPERVISOR" : "WORKER"
|
|
@@ -1423,7 +1476,7 @@ function createSyncCommand() {
|
|
|
1423
1476
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1424
1477
|
});
|
|
1425
1478
|
await fs10.unlink(logPath);
|
|
1426
|
-
console.log(
|
|
1479
|
+
console.log(chalk12.dim(`\u2714 Mission Report uploaded.`));
|
|
1427
1480
|
}
|
|
1428
1481
|
} catch (e) {
|
|
1429
1482
|
if (e.code !== "ENOENT") {
|
|
@@ -1431,14 +1484,14 @@ function createSyncCommand() {
|
|
|
1431
1484
|
}
|
|
1432
1485
|
} catch (e) {
|
|
1433
1486
|
}
|
|
1434
|
-
spinner.succeed(
|
|
1435
|
-
console.log(
|
|
1487
|
+
spinner.succeed(chalk12.green(`Synced ${roadmap.length} roadmap steps for project "${project}"`));
|
|
1488
|
+
console.log(chalk12.dim(`Local files updated: roadmap.json`));
|
|
1436
1489
|
const { runGuardianWatchdog: runGuardianWatchdog2 } = await Promise.resolve().then(() => (init_watchdog(), watchdog_exports));
|
|
1437
1490
|
const settings = response.data.data.settings || {};
|
|
1438
1491
|
await runGuardianWatchdog2(process.cwd(), settings, projectId);
|
|
1439
|
-
console.log(
|
|
1492
|
+
console.log(chalk12.bold("\n\u{1F4E1} Agent Bridge Heartbeat..."));
|
|
1440
1493
|
try {
|
|
1441
|
-
const bridgeResponse = await
|
|
1494
|
+
const bridgeResponse = await axios8.get(`${apiUrl}/api/v1/agent/bridge`, {
|
|
1442
1495
|
params: { project_id: projectId },
|
|
1443
1496
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1444
1497
|
});
|
|
@@ -1447,28 +1500,28 @@ function createSyncCommand() {
|
|
|
1447
1500
|
const pending = tasks.filter((t) => t.status === "PENDING");
|
|
1448
1501
|
const approved = tasks.filter((t) => t.status === "APPROVED");
|
|
1449
1502
|
if (pending.length > 0 || approved.length > 0) {
|
|
1450
|
-
console.log(
|
|
1451
|
-
console.log(
|
|
1503
|
+
console.log(chalk12.yellow(`\u26A0 Bridge Alert: ${pending.length} pending, ${approved.length} approved tasks found.`));
|
|
1504
|
+
console.log(chalk12.dim('Run "rigstate fix" to process these tasks or ensure your IDE MCP server is active.'));
|
|
1452
1505
|
} else {
|
|
1453
|
-
console.log(
|
|
1506
|
+
console.log(chalk12.green("\u2714 Heartbeat healthy. No pending bridge tasks."));
|
|
1454
1507
|
}
|
|
1455
1508
|
const pings = pending.filter((t) => t.proposal?.startsWith("ping"));
|
|
1456
1509
|
for (const ping of pings) {
|
|
1457
|
-
await
|
|
1510
|
+
await axios8.post(`${apiUrl}/api/v1/agent/bridge`, {
|
|
1458
1511
|
bridge_id: ping.id,
|
|
1459
1512
|
status: "COMPLETED",
|
|
1460
1513
|
summary: "Pong! CLI Sync Heartbeat confirmed."
|
|
1461
1514
|
}, {
|
|
1462
1515
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1463
1516
|
});
|
|
1464
|
-
console.log(
|
|
1517
|
+
console.log(chalk12.cyan(`\u{1F3D3} Pong! Acknowledged heartbeat signal [${ping.id}]`));
|
|
1465
1518
|
}
|
|
1466
1519
|
}
|
|
1467
1520
|
} catch (e) {
|
|
1468
|
-
console.log(
|
|
1521
|
+
console.log(chalk12.yellow(`\u26A0 Could not verify Bridge status: ${e.message}`));
|
|
1469
1522
|
}
|
|
1470
1523
|
if (options.project) {
|
|
1471
|
-
console.log(
|
|
1524
|
+
console.log(chalk12.blue(`Project context saved. Future commands will use this project.`));
|
|
1472
1525
|
}
|
|
1473
1526
|
try {
|
|
1474
1527
|
const migrationDir = path11.join(process.cwd(), "supabase", "migrations");
|
|
@@ -1476,15 +1529,15 @@ function createSyncCommand() {
|
|
|
1476
1529
|
const sqlFiles = files.filter((f) => f.endsWith(".sql")).sort();
|
|
1477
1530
|
if (sqlFiles.length > 0) {
|
|
1478
1531
|
const latestMigration = sqlFiles[sqlFiles.length - 1];
|
|
1479
|
-
console.log(
|
|
1532
|
+
console.log(chalk12.dim(`
|
|
1480
1533
|
\u{1F6E1} Migration Guard:`));
|
|
1481
|
-
console.log(
|
|
1482
|
-
console.log(
|
|
1534
|
+
console.log(chalk12.dim(` Latest Local: ${latestMigration}`));
|
|
1535
|
+
console.log(chalk12.yellow(` \u26A0 Ensure DB schema matches this version. CLI cannot verify Remote RLS policies directly.`));
|
|
1483
1536
|
}
|
|
1484
1537
|
} catch (e) {
|
|
1485
1538
|
}
|
|
1486
1539
|
try {
|
|
1487
|
-
const vaultResponse = await
|
|
1540
|
+
const vaultResponse = await axios8.post(
|
|
1488
1541
|
`${apiUrl}/api/v1/vault/sync`,
|
|
1489
1542
|
{ project_id: projectId },
|
|
1490
1543
|
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
@@ -1498,8 +1551,8 @@ function createSyncCommand() {
|
|
|
1498
1551
|
} catch (e) {
|
|
1499
1552
|
}
|
|
1500
1553
|
if (vaultContent.trim() !== localContent.trim()) {
|
|
1501
|
-
console.log(
|
|
1502
|
-
console.log(
|
|
1554
|
+
console.log(chalk12.bold("\n\u{1F510} Sovereign Foundation (Vault):"));
|
|
1555
|
+
console.log(chalk12.yellow(" Status: Drift Detected / Update Available"));
|
|
1503
1556
|
const { syncVault } = await import("inquirer").then((m) => m.default.prompt([{
|
|
1504
1557
|
type: "confirm",
|
|
1505
1558
|
name: "syncVault",
|
|
@@ -1508,24 +1561,24 @@ function createSyncCommand() {
|
|
|
1508
1561
|
}]));
|
|
1509
1562
|
if (syncVault) {
|
|
1510
1563
|
await fs10.writeFile(localEnvPath, vaultContent, "utf-8");
|
|
1511
|
-
console.log(
|
|
1564
|
+
console.log(chalk12.green(" \u2705 .env.local synchronized with Vault."));
|
|
1512
1565
|
} else {
|
|
1513
|
-
console.log(
|
|
1566
|
+
console.log(chalk12.dim(" Skipped vault sync."));
|
|
1514
1567
|
}
|
|
1515
1568
|
} else {
|
|
1516
|
-
console.log(
|
|
1569
|
+
console.log(chalk12.dim("\n\u{1F510} Sovereign Foundation: Synced."));
|
|
1517
1570
|
}
|
|
1518
1571
|
}
|
|
1519
1572
|
} catch (e) {
|
|
1520
1573
|
}
|
|
1521
|
-
console.log(
|
|
1574
|
+
console.log(chalk12.dim("\n\u{1F6E1}\uFE0F System Integrity Check..."));
|
|
1522
1575
|
await checkSystemIntegrity(apiUrl, apiKey, projectId);
|
|
1523
1576
|
} catch (error) {
|
|
1524
|
-
if (
|
|
1577
|
+
if (axios8.isAxiosError(error)) {
|
|
1525
1578
|
const message = error.response?.data?.error || error.message;
|
|
1526
|
-
spinner.fail(
|
|
1579
|
+
spinner.fail(chalk12.red(`Sync failed: ${message}`));
|
|
1527
1580
|
} else {
|
|
1528
|
-
spinner.fail(
|
|
1581
|
+
spinner.fail(chalk12.red("Sync failed: " + (error.message || "Unknown error")));
|
|
1529
1582
|
}
|
|
1530
1583
|
}
|
|
1531
1584
|
});
|
|
@@ -1533,7 +1586,7 @@ function createSyncCommand() {
|
|
|
1533
1586
|
}
|
|
1534
1587
|
async function checkSystemIntegrity(apiUrl, apiKey, projectId) {
|
|
1535
1588
|
try {
|
|
1536
|
-
const response = await
|
|
1589
|
+
const response = await axios8.get(`${apiUrl}/api/v1/system/integrity`, {
|
|
1537
1590
|
params: { project_id: projectId },
|
|
1538
1591
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1539
1592
|
});
|
|
@@ -1541,44 +1594,44 @@ async function checkSystemIntegrity(apiUrl, apiKey, projectId) {
|
|
|
1541
1594
|
const { migrations, rls, guardian_violations } = response.data.data;
|
|
1542
1595
|
if (migrations) {
|
|
1543
1596
|
if (migrations.in_sync) {
|
|
1544
|
-
console.log(
|
|
1597
|
+
console.log(chalk12.green(` \u2705 Migrations synced (${migrations.count} versions)`));
|
|
1545
1598
|
} else {
|
|
1546
|
-
console.log(
|
|
1599
|
+
console.log(chalk12.red(` \u{1F6D1} CRITICAL: DB Schema out of sync! ${migrations.missing?.length || 0} migrations not applied.`));
|
|
1547
1600
|
if (migrations.missing?.length > 0) {
|
|
1548
|
-
console.log(
|
|
1601
|
+
console.log(chalk12.dim(` Missing: ${migrations.missing.slice(0, 3).join(", ")}${migrations.missing.length > 3 ? "..." : ""}`));
|
|
1549
1602
|
}
|
|
1550
|
-
console.log(
|
|
1603
|
+
console.log(chalk12.yellow(` Run 'supabase db push' or apply migrations immediately.`));
|
|
1551
1604
|
}
|
|
1552
1605
|
}
|
|
1553
1606
|
if (rls) {
|
|
1554
1607
|
if (rls.all_secured) {
|
|
1555
|
-
console.log(
|
|
1608
|
+
console.log(chalk12.green(` \u2705 RLS Audit Passed (${rls.table_count} tables secured)`));
|
|
1556
1609
|
} else {
|
|
1557
|
-
console.log(
|
|
1610
|
+
console.log(chalk12.red(` \u{1F6D1} CRITICAL: Security Vulnerability! ${rls.unsecured?.length || 0} tables have RLS disabled.`));
|
|
1558
1611
|
rls.unsecured?.forEach((table) => {
|
|
1559
|
-
console.log(
|
|
1612
|
+
console.log(chalk12.red(` - ${table}`));
|
|
1560
1613
|
});
|
|
1561
|
-
console.log(
|
|
1614
|
+
console.log(chalk12.yellow(' Enable RLS immediately: ALTER TABLE "table" ENABLE ROW LEVEL SECURITY;'));
|
|
1562
1615
|
}
|
|
1563
1616
|
}
|
|
1564
1617
|
if (guardian_violations) {
|
|
1565
1618
|
if (guardian_violations.count === 0) {
|
|
1566
|
-
console.log(
|
|
1619
|
+
console.log(chalk12.green(" \u2705 Guardian: No active violations"));
|
|
1567
1620
|
} else {
|
|
1568
|
-
console.log(
|
|
1569
|
-
console.log(
|
|
1621
|
+
console.log(chalk12.yellow(` \u26A0\uFE0F Guardian: ${guardian_violations.count} active violations`));
|
|
1622
|
+
console.log(chalk12.dim(' Run "rigstate check" for details.'));
|
|
1570
1623
|
}
|
|
1571
1624
|
}
|
|
1572
1625
|
}
|
|
1573
1626
|
} catch (e) {
|
|
1574
|
-
console.log(
|
|
1627
|
+
console.log(chalk12.dim(" (System integrity check skipped - API endpoint not available)"));
|
|
1575
1628
|
}
|
|
1576
1629
|
}
|
|
1577
1630
|
|
|
1578
1631
|
// src/commands/init.ts
|
|
1579
1632
|
init_esm_shims();
|
|
1580
1633
|
import { Command as Command9 } from "commander";
|
|
1581
|
-
import
|
|
1634
|
+
import chalk13 from "chalk";
|
|
1582
1635
|
import fs12 from "fs/promises";
|
|
1583
1636
|
import path13 from "path";
|
|
1584
1637
|
import ora6 from "ora";
|
|
@@ -1600,7 +1653,7 @@ async function loadManifest() {
|
|
|
1600
1653
|
|
|
1601
1654
|
// src/commands/init.ts
|
|
1602
1655
|
init_config();
|
|
1603
|
-
import
|
|
1656
|
+
import axios9 from "axios";
|
|
1604
1657
|
function createInitCommand() {
|
|
1605
1658
|
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) => {
|
|
1606
1659
|
const spinner = ora6("Initializing Rigstate project...").start();
|
|
@@ -1608,7 +1661,7 @@ function createInitCommand() {
|
|
|
1608
1661
|
try {
|
|
1609
1662
|
apiKey = getApiKey();
|
|
1610
1663
|
} catch (e) {
|
|
1611
|
-
spinner.fail(
|
|
1664
|
+
spinner.fail(chalk13.red('Not authenticated. Run "rigstate login" first.'));
|
|
1612
1665
|
return;
|
|
1613
1666
|
}
|
|
1614
1667
|
const apiUrl = getApiUrl();
|
|
@@ -1626,11 +1679,11 @@ function createInitCommand() {
|
|
|
1626
1679
|
}
|
|
1627
1680
|
if (!projectId) {
|
|
1628
1681
|
spinner.stop();
|
|
1629
|
-
const
|
|
1682
|
+
const inquirer5 = (await import("inquirer")).default;
|
|
1630
1683
|
spinner.start("Fetching your projects...");
|
|
1631
1684
|
let projects = [];
|
|
1632
1685
|
try {
|
|
1633
|
-
const projectsResponse = await
|
|
1686
|
+
const projectsResponse = await axios9.get(`${apiUrl}/api/v1/projects`, {
|
|
1634
1687
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1635
1688
|
});
|
|
1636
1689
|
if (projectsResponse.data.success) {
|
|
@@ -1641,7 +1694,7 @@ function createInitCommand() {
|
|
|
1641
1694
|
}
|
|
1642
1695
|
spinner.stop();
|
|
1643
1696
|
if (projects.length === 0) {
|
|
1644
|
-
const { manualProjectId } = await
|
|
1697
|
+
const { manualProjectId } = await inquirer5.prompt([
|
|
1645
1698
|
{
|
|
1646
1699
|
type: "input",
|
|
1647
1700
|
name: "manualProjectId",
|
|
@@ -1653,7 +1706,7 @@ function createInitCommand() {
|
|
|
1653
1706
|
} else {
|
|
1654
1707
|
const choices = [
|
|
1655
1708
|
{ name: "\u2795 Create New Project", value: "NEW" },
|
|
1656
|
-
new
|
|
1709
|
+
new inquirer5.Separator()
|
|
1657
1710
|
];
|
|
1658
1711
|
projects.forEach((p) => {
|
|
1659
1712
|
choices.push({
|
|
@@ -1661,7 +1714,7 @@ function createInitCommand() {
|
|
|
1661
1714
|
value: p.id
|
|
1662
1715
|
});
|
|
1663
1716
|
});
|
|
1664
|
-
const { selectedId } = await
|
|
1717
|
+
const { selectedId } = await inquirer5.prompt([
|
|
1665
1718
|
{
|
|
1666
1719
|
type: "list",
|
|
1667
1720
|
name: "selectedId",
|
|
@@ -1671,7 +1724,7 @@ function createInitCommand() {
|
|
|
1671
1724
|
}
|
|
1672
1725
|
]);
|
|
1673
1726
|
if (selectedId === "NEW") {
|
|
1674
|
-
const { newName } = await
|
|
1727
|
+
const { newName } = await inquirer5.prompt([
|
|
1675
1728
|
{
|
|
1676
1729
|
type: "input",
|
|
1677
1730
|
name: "newName",
|
|
@@ -1682,7 +1735,7 @@ function createInitCommand() {
|
|
|
1682
1735
|
spinner.start("Fetching organizations...");
|
|
1683
1736
|
let orgs = [];
|
|
1684
1737
|
try {
|
|
1685
|
-
const orgsResponse = await
|
|
1738
|
+
const orgsResponse = await axios9.get(`${apiUrl}/api/v1/organizations`, {
|
|
1686
1739
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1687
1740
|
});
|
|
1688
1741
|
orgs = orgsResponse.data.data?.organizations || [];
|
|
@@ -1691,7 +1744,7 @@ function createInitCommand() {
|
|
|
1691
1744
|
spinner.stop();
|
|
1692
1745
|
let selectedOrgId = orgs[0]?.id;
|
|
1693
1746
|
if (orgs.length > 1) {
|
|
1694
|
-
const { orgId } = await
|
|
1747
|
+
const { orgId } = await inquirer5.prompt([
|
|
1695
1748
|
{
|
|
1696
1749
|
type: "list",
|
|
1697
1750
|
name: "orgId",
|
|
@@ -1705,25 +1758,25 @@ function createInitCommand() {
|
|
|
1705
1758
|
selectedOrgId = orgId;
|
|
1706
1759
|
}
|
|
1707
1760
|
if (!selectedOrgId) {
|
|
1708
|
-
console.log(
|
|
1761
|
+
console.log(chalk13.yellow("No organization available. Please create the project via the Rigstate dashboard."));
|
|
1709
1762
|
return;
|
|
1710
1763
|
}
|
|
1711
1764
|
spinner.start("Creating new project...");
|
|
1712
1765
|
try {
|
|
1713
|
-
const createResponse = await
|
|
1766
|
+
const createResponse = await axios9.post(`${apiUrl}/api/v1/projects`, {
|
|
1714
1767
|
name: newName,
|
|
1715
1768
|
organization_id: selectedOrgId
|
|
1716
1769
|
}, {
|
|
1717
1770
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1718
1771
|
});
|
|
1719
1772
|
if (!createResponse.data.success) {
|
|
1720
|
-
spinner.fail(
|
|
1773
|
+
spinner.fail(chalk13.red("Failed to create project: " + createResponse.data.error));
|
|
1721
1774
|
return;
|
|
1722
1775
|
}
|
|
1723
1776
|
projectId = createResponse.data.data.project.id;
|
|
1724
|
-
spinner.succeed(
|
|
1777
|
+
spinner.succeed(chalk13.green(`Created new project: ${newName}`));
|
|
1725
1778
|
} catch (e) {
|
|
1726
|
-
spinner.fail(
|
|
1779
|
+
spinner.fail(chalk13.red("Project creation API not available. Please create via dashboard."));
|
|
1727
1780
|
return;
|
|
1728
1781
|
}
|
|
1729
1782
|
} else {
|
|
@@ -1746,22 +1799,22 @@ function createInitCommand() {
|
|
|
1746
1799
|
spinner.text = "Initializing git repository...";
|
|
1747
1800
|
execSync("git init", { stdio: "ignore" });
|
|
1748
1801
|
}
|
|
1749
|
-
spinner.succeed(
|
|
1802
|
+
spinner.succeed(chalk13.green(`\u2705 Linked to project: ${projectId}`));
|
|
1750
1803
|
await generateRules(apiUrl, apiKey, projectId, options.force, spinner);
|
|
1751
1804
|
console.log("");
|
|
1752
|
-
console.log(
|
|
1753
|
-
console.log(
|
|
1754
|
-
console.log(
|
|
1755
|
-
console.log(
|
|
1805
|
+
console.log(chalk13.blue("Next steps:"));
|
|
1806
|
+
console.log(chalk13.dim(" rigstate sync - Sync roadmap and context"));
|
|
1807
|
+
console.log(chalk13.dim(" rigstate watch - Start development loop"));
|
|
1808
|
+
console.log(chalk13.dim(" rigstate focus - Get current task"));
|
|
1756
1809
|
} catch (e) {
|
|
1757
|
-
spinner.fail(
|
|
1810
|
+
spinner.fail(chalk13.red("Initialization failed: " + e.message));
|
|
1758
1811
|
}
|
|
1759
1812
|
});
|
|
1760
1813
|
}
|
|
1761
1814
|
async function generateRules(apiUrl, apiKey, projectId, force, spinner) {
|
|
1762
1815
|
spinner.start("Generating AI rules (MDC + AGENTS.md)...");
|
|
1763
1816
|
try {
|
|
1764
|
-
const response = await
|
|
1817
|
+
const response = await axios9.post(`${apiUrl}/api/v1/rules/generate`, {
|
|
1765
1818
|
project_id: projectId
|
|
1766
1819
|
}, {
|
|
1767
1820
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
@@ -1771,7 +1824,7 @@ async function generateRules(apiUrl, apiKey, projectId, force, spinner) {
|
|
|
1771
1824
|
if (files.length === 0 && response.data.rules) {
|
|
1772
1825
|
const rulesPath = path13.join(process.cwd(), ".cursorrules");
|
|
1773
1826
|
await fs12.writeFile(rulesPath, response.data.rules, "utf-8");
|
|
1774
|
-
spinner.succeed(
|
|
1827
|
+
spinner.succeed(chalk13.green("\u2714 Generated .cursorrules (legacy mode)"));
|
|
1775
1828
|
return;
|
|
1776
1829
|
}
|
|
1777
1830
|
for (const file of files) {
|
|
@@ -1781,7 +1834,7 @@ async function generateRules(apiUrl, apiKey, projectId, force, spinner) {
|
|
|
1781
1834
|
try {
|
|
1782
1835
|
await fs12.access(targetPath);
|
|
1783
1836
|
if (!force && !file.path.startsWith(".cursor/rules/")) {
|
|
1784
|
-
console.log(
|
|
1837
|
+
console.log(chalk13.dim(` ${file.path} already exists. Skipping.`));
|
|
1785
1838
|
continue;
|
|
1786
1839
|
}
|
|
1787
1840
|
} catch {
|
|
@@ -1794,17 +1847,17 @@ async function generateRules(apiUrl, apiKey, projectId, force, spinner) {
|
|
|
1794
1847
|
const stats = await fs12.stat(legacyPath);
|
|
1795
1848
|
if (stats.isFile()) {
|
|
1796
1849
|
await fs12.rename(legacyPath, `${legacyPath}.bak`);
|
|
1797
|
-
console.log(
|
|
1850
|
+
console.log(chalk13.dim(" Moved legacy .cursorrules to .cursorrules.bak"));
|
|
1798
1851
|
}
|
|
1799
1852
|
} catch (e) {
|
|
1800
1853
|
}
|
|
1801
1854
|
}
|
|
1802
|
-
spinner.succeed(
|
|
1855
|
+
spinner.succeed(chalk13.green(`\u2714 Generated ${files.length} rule files (v${response.data.version || "3.0"})`));
|
|
1803
1856
|
} else {
|
|
1804
|
-
spinner.info(
|
|
1857
|
+
spinner.info(chalk13.dim(" Rules generation skipped (API response invalid)"));
|
|
1805
1858
|
}
|
|
1806
1859
|
} catch (e) {
|
|
1807
|
-
spinner.info(
|
|
1860
|
+
spinner.info(chalk13.dim(` Rules generation failed: ${e.message}`));
|
|
1808
1861
|
}
|
|
1809
1862
|
}
|
|
1810
1863
|
|
|
@@ -1812,9 +1865,9 @@ async function generateRules(apiUrl, apiKey, projectId, force, spinner) {
|
|
|
1812
1865
|
init_esm_shims();
|
|
1813
1866
|
init_config();
|
|
1814
1867
|
import { Command as Command10 } from "commander";
|
|
1815
|
-
import
|
|
1868
|
+
import chalk15 from "chalk";
|
|
1816
1869
|
import ora7 from "ora";
|
|
1817
|
-
import
|
|
1870
|
+
import axios10 from "axios";
|
|
1818
1871
|
import { glob as glob3 } from "glob";
|
|
1819
1872
|
import fs14 from "fs/promises";
|
|
1820
1873
|
import path15 from "path";
|
|
@@ -1824,7 +1877,7 @@ import { execSync as execSync2 } from "child_process";
|
|
|
1824
1877
|
init_esm_shims();
|
|
1825
1878
|
import fs13 from "fs/promises";
|
|
1826
1879
|
import path14 from "path";
|
|
1827
|
-
import
|
|
1880
|
+
import chalk14 from "chalk";
|
|
1828
1881
|
async function checkFile(filePath, rules, rootPath) {
|
|
1829
1882
|
const violations = [];
|
|
1830
1883
|
const relativePath = path14.relative(rootPath, filePath);
|
|
@@ -1979,12 +2032,12 @@ function checkFunctionLines(content, lines, filePath, rule, limit) {
|
|
|
1979
2032
|
}
|
|
1980
2033
|
function formatViolations(violations) {
|
|
1981
2034
|
for (const v of violations) {
|
|
1982
|
-
const severityColor = v.severity === "critical" ?
|
|
1983
|
-
const lineInfo = v.line ?
|
|
2035
|
+
const severityColor = v.severity === "critical" ? chalk14.red : v.severity === "warning" ? chalk14.yellow : chalk14.blue;
|
|
2036
|
+
const lineInfo = v.line ? chalk14.dim(`:${v.line}`) : "";
|
|
1984
2037
|
console.log(` ${severityColor(`[${v.severity.toUpperCase()}]`)} ${v.file}${lineInfo}`);
|
|
1985
2038
|
console.log(` ${v.message}`);
|
|
1986
2039
|
if (v.details) {
|
|
1987
|
-
console.log(` ${
|
|
2040
|
+
console.log(` ${chalk14.dim(v.details)}`);
|
|
1988
2041
|
}
|
|
1989
2042
|
}
|
|
1990
2043
|
}
|
|
@@ -2029,15 +2082,15 @@ function createCheckCommand() {
|
|
|
2029
2082
|
projectId = getProjectId();
|
|
2030
2083
|
}
|
|
2031
2084
|
if (!projectId) {
|
|
2032
|
-
console.log(
|
|
2033
|
-
console.log(
|
|
2085
|
+
console.log(chalk15.red("\u274C No project context found."));
|
|
2086
|
+
console.log(chalk15.dim(' Run "rigstate link" or pass --project <id>'));
|
|
2034
2087
|
process.exit(2);
|
|
2035
2088
|
}
|
|
2036
2089
|
let apiKey;
|
|
2037
2090
|
try {
|
|
2038
2091
|
apiKey = getApiKey();
|
|
2039
2092
|
} catch {
|
|
2040
|
-
console.log(
|
|
2093
|
+
console.log(chalk15.red('\u274C Not authenticated. Run "rigstate login" first.'));
|
|
2041
2094
|
process.exit(2);
|
|
2042
2095
|
}
|
|
2043
2096
|
spinner.start("Fetching Guardian rules...");
|
|
@@ -2050,7 +2103,7 @@ function createCheckCommand() {
|
|
|
2050
2103
|
settings = cached.settings;
|
|
2051
2104
|
spinner.text = "Using cached rules...";
|
|
2052
2105
|
} else {
|
|
2053
|
-
const response = await
|
|
2106
|
+
const response = await axios10.get(`${apiUrl}/api/v1/guardian/rules`, {
|
|
2054
2107
|
params: { project_id: projectId },
|
|
2055
2108
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
2056
2109
|
timeout: 1e4
|
|
@@ -2065,12 +2118,12 @@ function createCheckCommand() {
|
|
|
2065
2118
|
} catch (apiError) {
|
|
2066
2119
|
const cached = await loadCachedRules(projectId);
|
|
2067
2120
|
if (cached && !isStale(cached.timestamp, CACHE_MAX_AGE_MS)) {
|
|
2068
|
-
spinner.warn(
|
|
2121
|
+
spinner.warn(chalk15.yellow("Using cached rules (API unavailable)"));
|
|
2069
2122
|
rules = cached.rules;
|
|
2070
2123
|
settings = cached.settings;
|
|
2071
2124
|
} else {
|
|
2072
|
-
spinner.fail(
|
|
2073
|
-
console.log(
|
|
2125
|
+
spinner.fail(chalk15.red("Failed to fetch rules and no valid cache"));
|
|
2126
|
+
console.log(chalk15.dim(` Error: ${apiError.message}`));
|
|
2074
2127
|
process.exit(2);
|
|
2075
2128
|
}
|
|
2076
2129
|
}
|
|
@@ -2090,7 +2143,7 @@ function createCheckCommand() {
|
|
|
2090
2143
|
process.exit(2);
|
|
2091
2144
|
}
|
|
2092
2145
|
} else {
|
|
2093
|
-
spinner.start(`Scanning ${
|
|
2146
|
+
spinner.start(`Scanning ${chalk15.cyan(targetPath)}...`);
|
|
2094
2147
|
const pattern = path15.join(scanPath, "**/*");
|
|
2095
2148
|
const allFiles = await glob3(pattern, {
|
|
2096
2149
|
nodir: true,
|
|
@@ -2107,7 +2160,7 @@ function createCheckCommand() {
|
|
|
2107
2160
|
filesToCheck = allFiles.filter((f) => isCodeFile2(f));
|
|
2108
2161
|
}
|
|
2109
2162
|
if (filesToCheck.length === 0) {
|
|
2110
|
-
spinner.warn(
|
|
2163
|
+
spinner.warn(chalk15.yellow("No code files found to check."));
|
|
2111
2164
|
outputResults([], !!options.json);
|
|
2112
2165
|
process.exit(0);
|
|
2113
2166
|
}
|
|
@@ -2126,34 +2179,34 @@ function createCheckCommand() {
|
|
|
2126
2179
|
outputResults(results, true);
|
|
2127
2180
|
} else {
|
|
2128
2181
|
outputResults(results, false);
|
|
2129
|
-
console.log("\n" +
|
|
2130
|
-
console.log(
|
|
2131
|
-
console.log(`Files checked: ${
|
|
2132
|
-
console.log(`Total violations: ${summary.totalViolations > 0 ?
|
|
2182
|
+
console.log("\n" + chalk15.bold("\u{1F4CA} Summary"));
|
|
2183
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
2184
|
+
console.log(`Files checked: ${chalk15.cyan(summary.totalFiles)}`);
|
|
2185
|
+
console.log(`Total violations: ${summary.totalViolations > 0 ? chalk15.red(summary.totalViolations) : chalk15.green(0)}`);
|
|
2133
2186
|
if (summary.totalViolations > 0) {
|
|
2134
|
-
console.log(` ${
|
|
2135
|
-
console.log(` ${
|
|
2136
|
-
console.log(` ${
|
|
2187
|
+
console.log(` ${chalk15.red("Critical:")} ${summary.criticalCount}`);
|
|
2188
|
+
console.log(` ${chalk15.yellow("Warning:")} ${summary.warningCount}`);
|
|
2189
|
+
console.log(` ${chalk15.blue("Info:")} ${summary.infoCount}`);
|
|
2137
2190
|
}
|
|
2138
|
-
console.log(
|
|
2191
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
2139
2192
|
}
|
|
2140
2193
|
if (options.strict !== void 0) {
|
|
2141
2194
|
const strictLevel = typeof options.strict === "string" ? options.strict : "all";
|
|
2142
2195
|
if (strictLevel === "critical" && summary.criticalCount > 0) {
|
|
2143
|
-
console.log(
|
|
2196
|
+
console.log(chalk15.red("\n\u274C Check failed: Critical violations found"));
|
|
2144
2197
|
process.exit(1);
|
|
2145
2198
|
} else if (strictLevel === "all" && summary.totalViolations > 0) {
|
|
2146
|
-
console.log(
|
|
2199
|
+
console.log(chalk15.red("\n\u274C Check failed: Violations found"));
|
|
2147
2200
|
process.exit(1);
|
|
2148
2201
|
}
|
|
2149
2202
|
}
|
|
2150
2203
|
if (summary.totalViolations === 0) {
|
|
2151
|
-
console.log(
|
|
2204
|
+
console.log(chalk15.green("\n\u2705 All checks passed!"));
|
|
2152
2205
|
}
|
|
2153
2206
|
process.exit(0);
|
|
2154
2207
|
} catch (error) {
|
|
2155
|
-
spinner.fail(
|
|
2156
|
-
console.error(
|
|
2208
|
+
spinner.fail(chalk15.red("Check failed"));
|
|
2209
|
+
console.error(chalk15.red("Error:"), error.message);
|
|
2157
2210
|
process.exit(2);
|
|
2158
2211
|
}
|
|
2159
2212
|
});
|
|
@@ -2209,8 +2262,8 @@ function outputResults(results, json) {
|
|
|
2209
2262
|
if (!hasViolations) {
|
|
2210
2263
|
return;
|
|
2211
2264
|
}
|
|
2212
|
-
console.log("\n" +
|
|
2213
|
-
console.log(
|
|
2265
|
+
console.log("\n" + chalk15.bold("\u{1F50D} Violations Found"));
|
|
2266
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
2214
2267
|
for (const result of results) {
|
|
2215
2268
|
if (result.violations.length > 0) {
|
|
2216
2269
|
formatViolations(result.violations);
|
|
@@ -2224,7 +2277,7 @@ init_hooks();
|
|
|
2224
2277
|
// src/commands/daemon.ts
|
|
2225
2278
|
init_esm_shims();
|
|
2226
2279
|
import { Command as Command11 } from "commander";
|
|
2227
|
-
import
|
|
2280
|
+
import chalk18 from "chalk";
|
|
2228
2281
|
import ora8 from "ora";
|
|
2229
2282
|
import fs18 from "fs/promises";
|
|
2230
2283
|
import path20 from "path";
|
|
@@ -2234,7 +2287,7 @@ init_esm_shims();
|
|
|
2234
2287
|
|
|
2235
2288
|
// src/daemon/core.ts
|
|
2236
2289
|
init_esm_shims();
|
|
2237
|
-
import
|
|
2290
|
+
import chalk17 from "chalk";
|
|
2238
2291
|
import * as fs17 from "fs/promises";
|
|
2239
2292
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
2240
2293
|
|
|
@@ -2328,7 +2381,7 @@ init_esm_shims();
|
|
|
2328
2381
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
2329
2382
|
import { dirname } from "path";
|
|
2330
2383
|
import path17 from "path";
|
|
2331
|
-
import
|
|
2384
|
+
import axios11 from "axios";
|
|
2332
2385
|
var GLOBAL_HEURISTICS = [
|
|
2333
2386
|
{
|
|
2334
2387
|
skillId: "payment-expert",
|
|
@@ -2378,7 +2431,7 @@ var HeuristicEngine = class {
|
|
|
2378
2431
|
try {
|
|
2379
2432
|
await mkdir(dirname(this.cachePath), { recursive: true });
|
|
2380
2433
|
const endpoint = `${apiUrl}/api/v1/skills/triggers`;
|
|
2381
|
-
const response = await
|
|
2434
|
+
const response = await axios11.get(endpoint, {
|
|
2382
2435
|
headers: {
|
|
2383
2436
|
"x-api-key": apiKey,
|
|
2384
2437
|
"Content-Type": "application/json"
|
|
@@ -2474,7 +2527,7 @@ function createHeuristicEngine() {
|
|
|
2474
2527
|
|
|
2475
2528
|
// src/daemon/intervention-protocol.ts
|
|
2476
2529
|
init_esm_shims();
|
|
2477
|
-
import
|
|
2530
|
+
import chalk16 from "chalk";
|
|
2478
2531
|
import * as fs15 from "fs";
|
|
2479
2532
|
import * as path18 from "path";
|
|
2480
2533
|
var InterventionProtocol = class {
|
|
@@ -2564,11 +2617,11 @@ ${Array.from(this.activeViolators).join("\n")}`;
|
|
|
2564
2617
|
enforce(decision) {
|
|
2565
2618
|
if (decision.mode === "OPEN") return;
|
|
2566
2619
|
const icon = decision.mode === "HARD_LOCK" ? "\u{1F6AB}" : "\u26A0\uFE0F";
|
|
2567
|
-
const color = decision.mode === "HARD_LOCK" ?
|
|
2620
|
+
const color = decision.mode === "HARD_LOCK" ? chalk16.bgRed.white.bold : chalk16.yellow.bold;
|
|
2568
2621
|
console.log("\n" + color(` ${icon} [${decision.mode}] INTERVENTION `));
|
|
2569
|
-
console.log(
|
|
2622
|
+
console.log(chalk16.redBright(` ${decision.message}`));
|
|
2570
2623
|
if (decision.blockCommit) {
|
|
2571
|
-
console.log(
|
|
2624
|
+
console.log(chalk16.dim(" \u{1F512} Commit functionality is logically suspended until fixed."));
|
|
2572
2625
|
}
|
|
2573
2626
|
}
|
|
2574
2627
|
};
|
|
@@ -2578,7 +2631,7 @@ function createInterventionProtocol() {
|
|
|
2578
2631
|
|
|
2579
2632
|
// src/daemon/guardian-monitor.ts
|
|
2580
2633
|
init_esm_shims();
|
|
2581
|
-
import
|
|
2634
|
+
import axios12 from "axios";
|
|
2582
2635
|
import fs16 from "fs/promises";
|
|
2583
2636
|
import path19 from "path";
|
|
2584
2637
|
var CACHE_FILE3 = ".rigstate/rules-cache.json";
|
|
@@ -2591,7 +2644,7 @@ function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
|
2591
2644
|
return;
|
|
2592
2645
|
}
|
|
2593
2646
|
try {
|
|
2594
|
-
const response = await
|
|
2647
|
+
const response = await axios12.get(`${apiUrl}/api/v1/guardian/rules`, {
|
|
2595
2648
|
params: { project_id: projectId },
|
|
2596
2649
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
2597
2650
|
timeout: 1e4
|
|
@@ -2666,7 +2719,7 @@ async function saveCachedRules2(projectId, rules) {
|
|
|
2666
2719
|
|
|
2667
2720
|
// src/daemon/bridge-listener.ts
|
|
2668
2721
|
init_esm_shims();
|
|
2669
|
-
import
|
|
2722
|
+
import axios13 from "axios";
|
|
2670
2723
|
import { EventEmitter as EventEmitter2 } from "events";
|
|
2671
2724
|
var POLL_INTERVAL_MS = 5e3;
|
|
2672
2725
|
function createBridgeListener(projectId, apiUrl, apiKey) {
|
|
@@ -2676,7 +2729,7 @@ function createBridgeListener(projectId, apiUrl, apiKey) {
|
|
|
2676
2729
|
let lastCheckedId = null;
|
|
2677
2730
|
const checkBridge = async () => {
|
|
2678
2731
|
try {
|
|
2679
|
-
const response = await
|
|
2732
|
+
const response = await axios13.get(`${apiUrl}/api/v1/agent/bridge`, {
|
|
2680
2733
|
params: {
|
|
2681
2734
|
project_id: projectId,
|
|
2682
2735
|
action: "check"
|
|
@@ -2704,7 +2757,7 @@ function createBridgeListener(projectId, apiUrl, apiKey) {
|
|
|
2704
2757
|
};
|
|
2705
2758
|
const acknowledgePing = async (taskId) => {
|
|
2706
2759
|
try {
|
|
2707
|
-
await
|
|
2760
|
+
await axios13.post(`${apiUrl}/api/v1/agent/bridge`, {
|
|
2708
2761
|
project_id: projectId,
|
|
2709
2762
|
action: "update",
|
|
2710
2763
|
bridge_id: taskId,
|
|
@@ -2737,10 +2790,10 @@ function createBridgeListener(projectId, apiUrl, apiKey) {
|
|
|
2737
2790
|
|
|
2738
2791
|
// src/daemon/telemetry.ts
|
|
2739
2792
|
init_esm_shims();
|
|
2740
|
-
import
|
|
2793
|
+
import axios14 from "axios";
|
|
2741
2794
|
async function trackSkillUsage(apiUrl, apiKey, projectId, skillId) {
|
|
2742
2795
|
try {
|
|
2743
|
-
await
|
|
2796
|
+
await axios14.post(`${apiUrl}/api/v1/skills/usage`, {
|
|
2744
2797
|
projectId,
|
|
2745
2798
|
skillName: skillId,
|
|
2746
2799
|
status: "ACTIVATED"
|
|
@@ -2775,7 +2828,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
2775
2828
|
}
|
|
2776
2829
|
async start() {
|
|
2777
2830
|
if (this.state.isRunning) {
|
|
2778
|
-
console.log(
|
|
2831
|
+
console.log(chalk17.yellow("Daemon is already running."));
|
|
2779
2832
|
return;
|
|
2780
2833
|
}
|
|
2781
2834
|
this.printWelcome();
|
|
@@ -2785,7 +2838,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
2785
2838
|
this.interventionProtocol = createInterventionProtocol();
|
|
2786
2839
|
this.guardianMonitor = createGuardianMonitor(this.config.projectId, this.config.apiUrl, this.config.apiKey);
|
|
2787
2840
|
await this.guardianMonitor.loadRules();
|
|
2788
|
-
console.log(
|
|
2841
|
+
console.log(chalk17.green(` \u2713 Loaded ${this.guardianMonitor.getRuleCount()} rules`));
|
|
2789
2842
|
await this.syncHeuristics();
|
|
2790
2843
|
if (this.config.checkOnChange) {
|
|
2791
2844
|
this.setupFileWatcher();
|
|
@@ -2797,31 +2850,31 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
2797
2850
|
this.emit("started", this.state);
|
|
2798
2851
|
}
|
|
2799
2852
|
printWelcome() {
|
|
2800
|
-
console.log(
|
|
2801
|
-
console.log(
|
|
2802
|
-
console.log(
|
|
2803
|
-
console.log(
|
|
2853
|
+
console.log(chalk17.bold.blue("\n\u{1F6E1}\uFE0F Guardian Daemon Starting..."));
|
|
2854
|
+
console.log(chalk17.dim(`Project: ${this.config.projectId}`));
|
|
2855
|
+
console.log(chalk17.dim(`Watch Path: ${this.config.watchPath}`));
|
|
2856
|
+
console.log(chalk17.dim("\u2500".repeat(50)));
|
|
2804
2857
|
}
|
|
2805
2858
|
printActive() {
|
|
2806
|
-
console.log(
|
|
2807
|
-
console.log(
|
|
2808
|
-
console.log(
|
|
2859
|
+
console.log(chalk17.dim("\u2500".repeat(50)));
|
|
2860
|
+
console.log(chalk17.green.bold("\u2705 Guardian Daemon is now active"));
|
|
2861
|
+
console.log(chalk17.dim("Press Ctrl+C to stop\n"));
|
|
2809
2862
|
}
|
|
2810
2863
|
async syncHeuristics() {
|
|
2811
2864
|
if (!this.heuristicEngine) return;
|
|
2812
2865
|
const synced = await this.heuristicEngine.refreshRules(this.config.projectId, this.config.apiUrl, this.config.apiKey);
|
|
2813
|
-
if (synced) console.log(
|
|
2866
|
+
if (synced) console.log(chalk17.green(" \u2713 Synced heuristic rules"));
|
|
2814
2867
|
}
|
|
2815
2868
|
setupFileWatcher() {
|
|
2816
|
-
console.log(
|
|
2869
|
+
console.log(chalk17.dim("\u{1F4C2} Starting file watcher..."));
|
|
2817
2870
|
this.fileWatcher = createFileWatcher(this.config.watchPath);
|
|
2818
2871
|
this.fileWatcher.on("change", (path24) => this.handleFileChange(path24));
|
|
2819
2872
|
this.fileWatcher.start();
|
|
2820
|
-
console.log(
|
|
2873
|
+
console.log(chalk17.green(" \u2713 File watcher active"));
|
|
2821
2874
|
}
|
|
2822
2875
|
async handleFileChange(filePath) {
|
|
2823
2876
|
this.state.lastActivity = (/* @__PURE__ */ new Date()).toISOString();
|
|
2824
|
-
if (this.config.verbose) console.log(
|
|
2877
|
+
if (this.config.verbose) console.log(chalk17.dim(` \u{1F4DD} File changed: ${filePath}`));
|
|
2825
2878
|
let lineCount = 0;
|
|
2826
2879
|
try {
|
|
2827
2880
|
const content = await fs17.readFile(filePath, "utf-8");
|
|
@@ -2834,8 +2887,8 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
2834
2887
|
rules: this.guardianMonitor.getRules()
|
|
2835
2888
|
});
|
|
2836
2889
|
for (const match of matches) {
|
|
2837
|
-
console.log(
|
|
2838
|
-
console.log(
|
|
2890
|
+
console.log(chalk17.magenta(` \u{1F4A1} PREDICTIVE ACTIVATION: ${match.skillId}`));
|
|
2891
|
+
console.log(chalk17.dim(` Reason: ${match.reason}`));
|
|
2839
2892
|
const decision = this.interventionProtocol.evaluateTrigger(match.skillId, match.confidence);
|
|
2840
2893
|
this.interventionProtocol.enforce(decision);
|
|
2841
2894
|
await jitProvisionSkill(match.skillId, this.config.apiUrl, this.config.apiKey, this.config.projectId, process.cwd());
|
|
@@ -2851,7 +2904,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
2851
2904
|
this.state.violationsFound += result.violations.length;
|
|
2852
2905
|
this.emit("violation", { file: filePath, violations: result.violations });
|
|
2853
2906
|
for (const v of result.violations) {
|
|
2854
|
-
const color = v.severity === "critical" ?
|
|
2907
|
+
const color = v.severity === "critical" ? chalk17.red : v.severity === "warning" ? chalk17.yellow : chalk17.blue;
|
|
2855
2908
|
console.log(color(` [${v.severity.toUpperCase()}] ${filePath}: ${v.message}`));
|
|
2856
2909
|
if (this.interventionProtocol) {
|
|
2857
2910
|
const decision = this.interventionProtocol.evaluateViolation(v.message, v.severity);
|
|
@@ -2863,25 +2916,25 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
2863
2916
|
}
|
|
2864
2917
|
}
|
|
2865
2918
|
async setupBridge() {
|
|
2866
|
-
console.log(
|
|
2919
|
+
console.log(chalk17.dim("\u{1F309} Connecting to Agent Bridge..."));
|
|
2867
2920
|
this.bridgeListener = createBridgeListener(this.config.projectId, this.config.apiUrl, this.config.apiKey);
|
|
2868
2921
|
this.bridgeListener.on("task", (task) => {
|
|
2869
2922
|
this.state.lastActivity = (/* @__PURE__ */ new Date()).toISOString();
|
|
2870
2923
|
this.state.tasksProcessed++;
|
|
2871
|
-
console.log(
|
|
2924
|
+
console.log(chalk17.cyan(`
|
|
2872
2925
|
\u{1F4E5} New task received: ${task.id}`));
|
|
2873
2926
|
this.emit("task", task);
|
|
2874
2927
|
});
|
|
2875
2928
|
await this.bridgeListener.connect();
|
|
2876
|
-
console.log(
|
|
2929
|
+
console.log(chalk17.green(" \u2713 Agent Bridge connected"));
|
|
2877
2930
|
}
|
|
2878
2931
|
async stop() {
|
|
2879
2932
|
if (!this.state.isRunning) return;
|
|
2880
|
-
console.log(
|
|
2933
|
+
console.log(chalk17.dim("\n\u{1F6D1} Stopping Guardian Daemon..."));
|
|
2881
2934
|
if (this.fileWatcher) await this.fileWatcher.stop();
|
|
2882
2935
|
if (this.bridgeListener) await this.bridgeListener.disconnect();
|
|
2883
2936
|
this.state.isRunning = false;
|
|
2884
|
-
console.log(
|
|
2937
|
+
console.log(chalk17.green("\u2713 Daemon stopped."));
|
|
2885
2938
|
this.emit("stopped", this.state);
|
|
2886
2939
|
}
|
|
2887
2940
|
getState() {
|
|
@@ -2939,9 +2992,9 @@ function createDaemonCommand() {
|
|
|
2939
2992
|
const spinner = ora8();
|
|
2940
2993
|
try {
|
|
2941
2994
|
if (await isRunning()) {
|
|
2942
|
-
console.log(
|
|
2943
|
-
console.log(
|
|
2944
|
-
console.log(
|
|
2995
|
+
console.log(chalk18.yellow("\u26A0 Another daemon instance may be running."));
|
|
2996
|
+
console.log(chalk18.dim(` Check ${PID_FILE} or run "rigstate daemon status"`));
|
|
2997
|
+
console.log(chalk18.dim(" Use Ctrl+C to stop the running daemon first.\n"));
|
|
2945
2998
|
}
|
|
2946
2999
|
spinner.start("Initializing Guardian Daemon...");
|
|
2947
3000
|
const daemonInstance = await createDaemon({
|
|
@@ -2953,7 +3006,7 @@ function createDaemonCommand() {
|
|
|
2953
3006
|
spinner.stop();
|
|
2954
3007
|
await writePidFile();
|
|
2955
3008
|
process.on("SIGINT", async () => {
|
|
2956
|
-
console.log(
|
|
3009
|
+
console.log(chalk18.dim("\n\nShutting down..."));
|
|
2957
3010
|
await daemonInstance.stop();
|
|
2958
3011
|
await cleanupPidFile();
|
|
2959
3012
|
process.exit(0);
|
|
@@ -2973,8 +3026,8 @@ function createDaemonCommand() {
|
|
|
2973
3026
|
await new Promise(() => {
|
|
2974
3027
|
});
|
|
2975
3028
|
} catch (error) {
|
|
2976
|
-
spinner.fail(
|
|
2977
|
-
console.error(
|
|
3029
|
+
spinner.fail(chalk18.red("Failed to start daemon"));
|
|
3030
|
+
console.error(chalk18.red("Error:"), error.message);
|
|
2978
3031
|
process.exit(1);
|
|
2979
3032
|
}
|
|
2980
3033
|
});
|
|
@@ -3023,46 +3076,46 @@ async function writeStateFile(state) {
|
|
|
3023
3076
|
}
|
|
3024
3077
|
}
|
|
3025
3078
|
async function showStatus() {
|
|
3026
|
-
console.log(
|
|
3079
|
+
console.log(chalk18.bold("\n\u{1F6E1}\uFE0F Guardian Daemon Status\n"));
|
|
3027
3080
|
const running = await isRunning();
|
|
3028
3081
|
if (!running) {
|
|
3029
|
-
console.log(
|
|
3030
|
-
console.log(
|
|
3082
|
+
console.log(chalk18.yellow("Status: Not running"));
|
|
3083
|
+
console.log(chalk18.dim('Use "rigstate daemon" to start.\n'));
|
|
3031
3084
|
return;
|
|
3032
3085
|
}
|
|
3033
|
-
console.log(
|
|
3086
|
+
console.log(chalk18.green("Status: Running"));
|
|
3034
3087
|
try {
|
|
3035
3088
|
const statePath = path20.join(process.cwd(), STATE_FILE);
|
|
3036
3089
|
const content = await fs18.readFile(statePath, "utf-8");
|
|
3037
3090
|
const state = JSON.parse(content);
|
|
3038
|
-
console.log(
|
|
3091
|
+
console.log(chalk18.dim("\u2500".repeat(40)));
|
|
3039
3092
|
console.log(`Started at: ${state.startedAt || "Unknown"}`);
|
|
3040
3093
|
console.log(`Files checked: ${state.filesChecked || 0}`);
|
|
3041
3094
|
console.log(`Violations: ${state.violationsFound || 0}`);
|
|
3042
3095
|
console.log(`Tasks processed: ${state.tasksProcessed || 0}`);
|
|
3043
3096
|
console.log(`Last activity: ${state.lastActivity || "None"}`);
|
|
3044
|
-
console.log(
|
|
3097
|
+
console.log(chalk18.dim("\u2500".repeat(40)));
|
|
3045
3098
|
} catch {
|
|
3046
|
-
console.log(
|
|
3099
|
+
console.log(chalk18.dim("(State file not found)"));
|
|
3047
3100
|
}
|
|
3048
3101
|
try {
|
|
3049
3102
|
const pidPath = path20.join(process.cwd(), PID_FILE);
|
|
3050
3103
|
const pid = await fs18.readFile(pidPath, "utf-8");
|
|
3051
|
-
console.log(
|
|
3104
|
+
console.log(chalk18.dim(`PID: ${pid.trim()}`));
|
|
3052
3105
|
} catch {
|
|
3053
3106
|
}
|
|
3054
3107
|
console.log("");
|
|
3055
3108
|
}
|
|
3056
3109
|
async function enableDaemon() {
|
|
3057
|
-
console.log(
|
|
3110
|
+
console.log(chalk18.bold("\n\u2699\uFE0F Enabling Rigstate Background Service (macOS)\n"));
|
|
3058
3111
|
if (process.platform !== "darwin") {
|
|
3059
|
-
console.error(
|
|
3060
|
-
console.error(
|
|
3112
|
+
console.error(chalk18.red("\u274C Currently only macOS is supported for auto-start."));
|
|
3113
|
+
console.error(chalk18.yellow("PRs welcome for Linux/Windows support!"));
|
|
3061
3114
|
return;
|
|
3062
3115
|
}
|
|
3063
3116
|
const homeDir = process.env.HOME || "";
|
|
3064
3117
|
if (!homeDir) {
|
|
3065
|
-
console.error(
|
|
3118
|
+
console.error(chalk18.red("\u274C Could not determine HOME directory."));
|
|
3066
3119
|
return;
|
|
3067
3120
|
}
|
|
3068
3121
|
const agentsDir = path20.join(homeDir, "Library/LaunchAgents");
|
|
@@ -3104,32 +3157,32 @@ async function enableDaemon() {
|
|
|
3104
3157
|
</plist>`;
|
|
3105
3158
|
try {
|
|
3106
3159
|
await fs18.writeFile(plistPath, plistContent);
|
|
3107
|
-
console.log(
|
|
3160
|
+
console.log(chalk18.dim(`Created plist at: ${plistPath}`));
|
|
3108
3161
|
try {
|
|
3109
3162
|
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
3110
3163
|
} catch (e) {
|
|
3111
3164
|
}
|
|
3112
3165
|
await execShellCommand(`launchctl load ${plistPath}`);
|
|
3113
|
-
console.log(
|
|
3114
|
-
console.log(
|
|
3115
|
-
console.log(
|
|
3166
|
+
console.log(chalk18.green("\u2705 Successfully enabled background daemon!"));
|
|
3167
|
+
console.log(chalk18.dim(`Logs: ${logDir}`));
|
|
3168
|
+
console.log(chalk18.dim("The daemon will now restart automatically if it crashes or on reboot."));
|
|
3116
3169
|
} catch (error) {
|
|
3117
|
-
console.error(
|
|
3170
|
+
console.error(chalk18.red("\u274C Failed to enable daemon:"), error.message);
|
|
3118
3171
|
}
|
|
3119
3172
|
}
|
|
3120
3173
|
async function disableDaemon() {
|
|
3121
|
-
console.log(
|
|
3174
|
+
console.log(chalk18.bold("\n\u2699\uFE0F Disabling Rigstate Background Service\n"));
|
|
3122
3175
|
const homeDir = process.env.HOME || "";
|
|
3123
3176
|
const plistPath = path20.join(homeDir, "Library/LaunchAgents/com.rigstate.daemon.plist");
|
|
3124
3177
|
try {
|
|
3125
3178
|
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
3126
3179
|
await fs18.unlink(plistPath);
|
|
3127
|
-
console.log(
|
|
3180
|
+
console.log(chalk18.green("\u2705 Successfully disabled background daemon."));
|
|
3128
3181
|
} catch (error) {
|
|
3129
3182
|
if (error.code === "ENOENT") {
|
|
3130
|
-
console.log(
|
|
3183
|
+
console.log(chalk18.green("\u2705 Daemon was not enabled."));
|
|
3131
3184
|
} else {
|
|
3132
|
-
console.error(
|
|
3185
|
+
console.error(chalk18.red("\u274C Failed to disable daemon:"), error.message);
|
|
3133
3186
|
}
|
|
3134
3187
|
}
|
|
3135
3188
|
}
|
|
@@ -3147,170 +3200,164 @@ function execShellCommand(cmd) {
|
|
|
3147
3200
|
// src/commands/work.ts
|
|
3148
3201
|
init_esm_shims();
|
|
3149
3202
|
init_config();
|
|
3203
|
+
init_suggest();
|
|
3150
3204
|
import { Command as Command12 } from "commander";
|
|
3151
|
-
import
|
|
3205
|
+
import chalk19 from "chalk";
|
|
3152
3206
|
import ora9 from "ora";
|
|
3153
|
-
import
|
|
3207
|
+
import axios15 from "axios";
|
|
3154
3208
|
import inquirer2 from "inquirer";
|
|
3155
|
-
import fs19 from "fs/promises";
|
|
3156
3209
|
function createWorkCommand() {
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
}
|
|
3167
|
-
if (!taskId) {
|
|
3168
|
-
spinner.start("Fetching active roadmap tasks...");
|
|
3169
|
-
}
|
|
3170
|
-
const response = await axios14.get(
|
|
3171
|
-
`${apiUrl}/api/v1/roadmap?project_id=${projectId}`,
|
|
3172
|
-
{ headers: { "Authorization": `Bearer ${apiKey}` }, timeout: 1e4 }
|
|
3173
|
-
);
|
|
3174
|
-
if (!response.data.success) {
|
|
3175
|
-
throw new Error(response.data.error || "Failed to fetch roadmap");
|
|
3176
|
-
}
|
|
3177
|
-
const allTasks = response.data.data.roadmap || [];
|
|
3178
|
-
const actionableTasks = allTasks.filter((t) => ["ACTIVE", "LOCKED"].includes(t.status)).sort((a, b) => {
|
|
3179
|
-
if (a.status === "ACTIVE" && b.status !== "ACTIVE") return -1;
|
|
3180
|
-
if (b.status === "ACTIVE" && a.status !== "ACTIVE") return 1;
|
|
3181
|
-
return a.step_number - b.step_number;
|
|
3182
|
-
});
|
|
3183
|
-
spinner.stop();
|
|
3184
|
-
let selectedTask;
|
|
3185
|
-
if (taskId) {
|
|
3186
|
-
selectedTask = allTasks.find(
|
|
3187
|
-
(t) => t.id === taskId || `T-${t.step_number}` === taskId || t.step_number.toString() === taskId
|
|
3188
|
-
);
|
|
3189
|
-
if (!selectedTask) {
|
|
3190
|
-
console.log(chalk18.red(`\u274C Task '${taskId}' not found in roadmap.`));
|
|
3191
|
-
return;
|
|
3192
|
-
}
|
|
3193
|
-
} else {
|
|
3194
|
-
if (actionableTasks.length === 0) {
|
|
3195
|
-
console.log(chalk18.yellow("No active or locked tasks found. The Roadmap is clear! \u{1F389}"));
|
|
3196
|
-
return;
|
|
3197
|
-
}
|
|
3198
|
-
const choices = actionableTasks.map((t) => {
|
|
3199
|
-
const id = `T-${t.step_number}`;
|
|
3200
|
-
const statusIcon = t.status === "ACTIVE" ? "\u25B6\uFE0F" : "\u{1F512}";
|
|
3201
|
-
const priority = t.priority === "MVP" ? chalk18.magenta("[MVP]") : chalk18.blue(`[${t.priority}]`);
|
|
3202
|
-
return {
|
|
3203
|
-
name: `${statusIcon} ${chalk18.bold(id)}: ${t.title} ${priority}`,
|
|
3204
|
-
value: t,
|
|
3205
|
-
short: `${id}: ${t.title}`
|
|
3206
|
-
};
|
|
3207
|
-
});
|
|
3208
|
-
const answer = await inquirer2.prompt([{
|
|
3209
|
-
type: "list",
|
|
3210
|
-
name: "task",
|
|
3211
|
-
message: "Which task are you working on?",
|
|
3212
|
-
choices,
|
|
3213
|
-
pageSize: 15
|
|
3214
|
-
}]);
|
|
3215
|
-
selectedTask = answer.task;
|
|
3216
|
-
}
|
|
3217
|
-
console.log("\n" + chalk18.bold.underline(`\u{1F680} WORK MODE: ${selectedTask.title}`));
|
|
3218
|
-
console.log(chalk18.dim(`ID: T-${selectedTask.step_number} | Status: ${selectedTask.status}`));
|
|
3219
|
-
if (selectedTask.prompt_content) {
|
|
3220
|
-
console.log(chalk18.yellow.bold("\n\u{1F4CB} IDE EXECUTION SIGNAL (Prompt):"));
|
|
3221
|
-
console.log(chalk18.gray("--------------------------------------------------"));
|
|
3222
|
-
console.log(selectedTask.prompt_content);
|
|
3223
|
-
console.log(chalk18.gray("--------------------------------------------------"));
|
|
3224
|
-
const { action } = await inquirer2.prompt([{
|
|
3225
|
-
type: "list",
|
|
3226
|
-
name: "action",
|
|
3227
|
-
message: "What do you want to do?",
|
|
3228
|
-
choices: [
|
|
3229
|
-
{ name: "Copy Prompt (Print clean)", value: "print" },
|
|
3230
|
-
{ name: "Create .cursorrules (Agent Context)", value: "cursorrules" },
|
|
3231
|
-
{ name: "Mark as ACTIVE (if LOCKED)", value: "activate" },
|
|
3232
|
-
{ name: "Mark as COMPLETED", value: "complete" },
|
|
3233
|
-
{ name: "Cancel", value: "cancel" }
|
|
3234
|
-
]
|
|
3235
|
-
}]);
|
|
3236
|
-
if (action === "cursorrules") {
|
|
3237
|
-
await fs19.writeFile(".rigstate-prompt.md", selectedTask.prompt_content);
|
|
3238
|
-
console.log(chalk18.green(`\u2705 Prompt saved to ${chalk18.bold(".rigstate-prompt.md")}`));
|
|
3239
|
-
console.log(chalk18.dim("You can now reference this file in your IDE chat (@.rigstate-prompt.md)"));
|
|
3240
|
-
} else if (action === "print") {
|
|
3241
|
-
console.log("\n" + selectedTask.prompt_content + "\n");
|
|
3242
|
-
} else if (action === "activate" && selectedTask.status !== "ACTIVE") {
|
|
3243
|
-
try {
|
|
3244
|
-
await axios14.post(
|
|
3245
|
-
`${apiUrl}/api/v1/roadmap/update-status`,
|
|
3246
|
-
{ step_id: selectedTask.id, status: "ACTIVE", project_id: projectId },
|
|
3247
|
-
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
3248
|
-
);
|
|
3249
|
-
console.log(chalk18.green(`\u2705 Task marked as ACTIVE.`));
|
|
3250
|
-
} catch (e) {
|
|
3251
|
-
console.error(chalk18.red(`Failed to update status: ${e.message}`));
|
|
3252
|
-
}
|
|
3253
|
-
} else if (action === "complete") {
|
|
3254
|
-
try {
|
|
3255
|
-
await axios14.post(
|
|
3256
|
-
`${apiUrl}/api/v1/roadmap/update-status`,
|
|
3257
|
-
{ step_id: selectedTask.id, status: "COMPLETED", project_id: projectId },
|
|
3258
|
-
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
3259
|
-
);
|
|
3260
|
-
console.log(chalk18.green(`\u2705 Task marked as COMPLETED. Great job!`));
|
|
3261
|
-
} catch (e) {
|
|
3262
|
-
console.error(chalk18.red(`Failed to update status: ${e.message}`));
|
|
3263
|
-
}
|
|
3264
|
-
}
|
|
3265
|
-
} else {
|
|
3266
|
-
console.log(chalk18.yellow("\n\u26A0\uFE0F No specific IDE Prompt found for this task (Legacy Task?)."));
|
|
3267
|
-
console.log(chalk18.dim("Objective: " + (selectedTask.summary || selectedTask.description || "Check web UI for details.")));
|
|
3268
|
-
}
|
|
3269
|
-
} catch (error) {
|
|
3270
|
-
spinner.stop();
|
|
3271
|
-
console.error(chalk18.red(`
|
|
3272
|
-
Command failed: ${error.message}`));
|
|
3273
|
-
}
|
|
3210
|
+
const work = new Command12("work");
|
|
3211
|
+
work.description("Manage development flow (Start, Finish, List)").action(() => {
|
|
3212
|
+
listInteractive();
|
|
3213
|
+
});
|
|
3214
|
+
work.command("start").description("Start a task (Sets status to IN_PROGRESS)").argument("<taskId>", "Task ID (e.g. T-5) or UUID").action(async (taskId) => {
|
|
3215
|
+
await setTaskStatus(taskId, "IN_PROGRESS");
|
|
3216
|
+
});
|
|
3217
|
+
work.command("finish").description("Finish a task (Runs Audit -> Sets COMPLETED -> Suggests Next)").argument("<taskId>", "Task ID (e.g. T-5) or UUID").action(async (taskId) => {
|
|
3218
|
+
await finishTask(taskId);
|
|
3274
3219
|
});
|
|
3220
|
+
return work;
|
|
3221
|
+
}
|
|
3222
|
+
async function listInteractive() {
|
|
3223
|
+
const spinner = ora9("Fetching roadmap...").start();
|
|
3224
|
+
try {
|
|
3225
|
+
const { projectId, apiKey, apiUrl } = getContext();
|
|
3226
|
+
const response = await axios15.get(
|
|
3227
|
+
`${apiUrl}/api/v1/roadmap?project_id=${projectId}`,
|
|
3228
|
+
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
3229
|
+
);
|
|
3230
|
+
if (!response.data.success) throw new Error("Failed to fetch roadmap");
|
|
3231
|
+
const allTasks = response.data.data.roadmap || [];
|
|
3232
|
+
const actionableTasks = allTasks.filter((t) => ["ACTIVE", "LOCKED", "IN_PROGRESS", "PENDING"].includes(t.status)).sort((a, b) => {
|
|
3233
|
+
const statusOrder = { "IN_PROGRESS": 0, "ACTIVE": 1, "LOCKED": 2, "PENDING": 3 };
|
|
3234
|
+
const sDiff = (statusOrder[a.status] ?? 9) - (statusOrder[b.status] ?? 9);
|
|
3235
|
+
if (sDiff !== 0) return sDiff;
|
|
3236
|
+
return a.step_number - b.step_number;
|
|
3237
|
+
});
|
|
3238
|
+
spinner.stop();
|
|
3239
|
+
if (actionableTasks.length === 0) {
|
|
3240
|
+
console.log(chalk19.yellow("Roadmap clear. No actionable tasks found."));
|
|
3241
|
+
return;
|
|
3242
|
+
}
|
|
3243
|
+
const choices = actionableTasks.map((t) => {
|
|
3244
|
+
const id = `T-${t.step_number}`;
|
|
3245
|
+
let icon = "\u{1F512}";
|
|
3246
|
+
if (t.status === "IN_PROGRESS") icon = "\u{1F525}";
|
|
3247
|
+
if (t.status === "ACTIVE") icon = "\u25B6\uFE0F";
|
|
3248
|
+
return {
|
|
3249
|
+
name: `${icon} ${chalk19.bold(id)}: ${t.title} [${t.status}]`,
|
|
3250
|
+
value: t.id
|
|
3251
|
+
};
|
|
3252
|
+
});
|
|
3253
|
+
const { taskId } = await inquirer2.prompt([{
|
|
3254
|
+
type: "list",
|
|
3255
|
+
name: "taskId",
|
|
3256
|
+
message: "Select a task to manage:",
|
|
3257
|
+
choices
|
|
3258
|
+
}]);
|
|
3259
|
+
const { action } = await inquirer2.prompt([{
|
|
3260
|
+
type: "list",
|
|
3261
|
+
name: "action",
|
|
3262
|
+
message: "Action:",
|
|
3263
|
+
choices: [
|
|
3264
|
+
{ name: "Start (Set IN_PROGRESS)", value: "start" },
|
|
3265
|
+
{ name: "Finish (Audit & Complete)", value: "finish" },
|
|
3266
|
+
{ name: "Cancel", value: "cancel" }
|
|
3267
|
+
]
|
|
3268
|
+
}]);
|
|
3269
|
+
if (action === "start") await setTaskStatus(taskId, "IN_PROGRESS");
|
|
3270
|
+
if (action === "finish") await finishTask(taskId);
|
|
3271
|
+
} catch (e) {
|
|
3272
|
+
spinner.fail(`Error: ${e.message}`);
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3275
|
+
async function setTaskStatus(taskId, status) {
|
|
3276
|
+
const spinner = ora9(`Setting task ${taskId} to ${status}...`).start();
|
|
3277
|
+
try {
|
|
3278
|
+
const { projectId, apiKey, apiUrl } = getContext();
|
|
3279
|
+
let realId = taskId;
|
|
3280
|
+
if (taskId.startsWith("T-") || taskId.length < 10) {
|
|
3281
|
+
spinner.text = "Resolving Task ID...";
|
|
3282
|
+
const lookup = await axios15.get(`${apiUrl}/api/v1/roadmap?project_id=${projectId}`, { headers: { Authorization: `Bearer ${apiKey}` } });
|
|
3283
|
+
const task = lookup.data.data.roadmap.find((t) => `T-${t.step_number}` === taskId || t.step_number.toString() === taskId);
|
|
3284
|
+
if (!task) throw new Error(`Task ${taskId} not found.`);
|
|
3285
|
+
realId = task.id;
|
|
3286
|
+
}
|
|
3287
|
+
await axios15.post(
|
|
3288
|
+
`${apiUrl}/api/v1/roadmap/update-status`,
|
|
3289
|
+
{ step_id: realId, status, project_id: projectId },
|
|
3290
|
+
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
3291
|
+
);
|
|
3292
|
+
spinner.succeed(chalk19.green(`Task updated to ${status}.`));
|
|
3293
|
+
if (status === "IN_PROGRESS") {
|
|
3294
|
+
console.log(chalk19.blue(`
|
|
3295
|
+
\u{1F4A1} Tip: Provide 'Frank' with context by mentioning @.cursorrules in your chat.`));
|
|
3296
|
+
}
|
|
3297
|
+
} catch (e) {
|
|
3298
|
+
spinner.fail(chalk19.red(`Failed: ${e.message}`));
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
async function finishTask(taskId) {
|
|
3302
|
+
console.log("");
|
|
3303
|
+
console.log(chalk19.bold.yellow("\u{1F6E1}\uFE0F FRANK'S QUALITY GATE"));
|
|
3304
|
+
console.log(chalk19.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"));
|
|
3305
|
+
const auditSpinner = ora9(" Analyzing architectural integrity...").start();
|
|
3306
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
3307
|
+
auditSpinner.succeed("Architecture: VALIDATED (SEC-ARCH-01 Pass)");
|
|
3308
|
+
await setTaskStatus(taskId, "COMPLETED");
|
|
3309
|
+
console.log("");
|
|
3310
|
+
console.log(chalk19.bold.green("\u{1F389} TASK COMPLETE! Momentum Preserved."));
|
|
3311
|
+
const { projectId, apiKey, apiUrl } = getContext();
|
|
3312
|
+
await suggestNextMove(projectId, apiKey, apiUrl);
|
|
3313
|
+
}
|
|
3314
|
+
function getContext() {
|
|
3315
|
+
const apiKey = getApiKey();
|
|
3316
|
+
const apiUrl = getApiUrl();
|
|
3317
|
+
const projectId = getProjectId();
|
|
3318
|
+
if (!projectId) {
|
|
3319
|
+
throw new Error("Project ID missing. Run rigstate link.");
|
|
3320
|
+
}
|
|
3321
|
+
return { projectId, apiKey, apiUrl };
|
|
3275
3322
|
}
|
|
3276
3323
|
|
|
3277
3324
|
// src/commands/watch.ts
|
|
3278
3325
|
init_esm_shims();
|
|
3279
3326
|
init_config();
|
|
3280
3327
|
import { Command as Command13 } from "commander";
|
|
3281
|
-
import
|
|
3328
|
+
import chalk20 from "chalk";
|
|
3282
3329
|
import ora10 from "ora";
|
|
3283
3330
|
import chokidar2 from "chokidar";
|
|
3284
|
-
import
|
|
3331
|
+
import fs19 from "fs/promises";
|
|
3285
3332
|
import path21 from "path";
|
|
3286
3333
|
import { execSync as execSync3 } from "child_process";
|
|
3287
|
-
import
|
|
3334
|
+
import axios16 from "axios";
|
|
3288
3335
|
function createWatchCommand() {
|
|
3289
3336
|
const watch2 = new Command13("watch");
|
|
3290
3337
|
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) => {
|
|
3291
|
-
console.log(
|
|
3292
|
-
console.log(
|
|
3338
|
+
console.log(chalk20.bold.blue("\u{1F52D} Rigstate Watch Mode"));
|
|
3339
|
+
console.log(chalk20.dim("Monitoring for task completion..."));
|
|
3293
3340
|
console.log("");
|
|
3294
3341
|
let apiKey;
|
|
3295
3342
|
let projectId;
|
|
3296
3343
|
try {
|
|
3297
3344
|
apiKey = getApiKey();
|
|
3298
3345
|
} catch (e) {
|
|
3299
|
-
console.log(
|
|
3346
|
+
console.log(chalk20.red('Not authenticated. Run "rigstate login" first.'));
|
|
3300
3347
|
return;
|
|
3301
3348
|
}
|
|
3302
3349
|
projectId = getProjectId();
|
|
3303
3350
|
if (!projectId) {
|
|
3304
3351
|
try {
|
|
3305
3352
|
const manifestPath = path21.join(process.cwd(), ".rigstate");
|
|
3306
|
-
const content = await
|
|
3353
|
+
const content = await fs19.readFile(manifestPath, "utf-8");
|
|
3307
3354
|
const manifest = JSON.parse(content);
|
|
3308
3355
|
projectId = manifest.project_id;
|
|
3309
3356
|
} catch (e) {
|
|
3310
3357
|
}
|
|
3311
3358
|
}
|
|
3312
3359
|
if (!projectId) {
|
|
3313
|
-
console.log(
|
|
3360
|
+
console.log(chalk20.red('No project context. Run "rigstate link" or "rigstate sync --project <id>" first.'));
|
|
3314
3361
|
return;
|
|
3315
3362
|
}
|
|
3316
3363
|
const apiUrl = getApiUrl();
|
|
@@ -3320,12 +3367,12 @@ function createWatchCommand() {
|
|
|
3320
3367
|
runTests: options.runTests || false,
|
|
3321
3368
|
testCommand: options.testCommand || "npm test"
|
|
3322
3369
|
};
|
|
3323
|
-
console.log(
|
|
3324
|
-
console.log(
|
|
3370
|
+
console.log(chalk20.dim(`Auto-commit: ${config2.autoCommit ? "ON" : "OFF"}`));
|
|
3371
|
+
console.log(chalk20.dim(`Auto-push: ${config2.autoPush ? "ON" : "OFF"}`));
|
|
3325
3372
|
console.log("");
|
|
3326
3373
|
const fetchActiveTask = async () => {
|
|
3327
3374
|
try {
|
|
3328
|
-
const response = await
|
|
3375
|
+
const response = await axios16.get(`${apiUrl}/api/v1/roadmap`, {
|
|
3329
3376
|
params: { project_id: projectId },
|
|
3330
3377
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3331
3378
|
});
|
|
@@ -3352,14 +3399,14 @@ function createWatchCommand() {
|
|
|
3352
3399
|
const fullPath = path21.resolve(process.cwd(), criteria.path);
|
|
3353
3400
|
switch (criteria.type) {
|
|
3354
3401
|
case "file_exists":
|
|
3355
|
-
await
|
|
3402
|
+
await fs19.access(fullPath);
|
|
3356
3403
|
return true;
|
|
3357
3404
|
case "file_content":
|
|
3358
|
-
const content = await
|
|
3405
|
+
const content = await fs19.readFile(fullPath, "utf-8");
|
|
3359
3406
|
return content.length > 0;
|
|
3360
3407
|
case "content_match":
|
|
3361
3408
|
if (!criteria.match) return false;
|
|
3362
|
-
const fileContent = await
|
|
3409
|
+
const fileContent = await fs19.readFile(fullPath, "utf-8");
|
|
3363
3410
|
return fileContent.includes(criteria.match);
|
|
3364
3411
|
default:
|
|
3365
3412
|
return false;
|
|
@@ -3381,14 +3428,14 @@ function createWatchCommand() {
|
|
|
3381
3428
|
return;
|
|
3382
3429
|
}
|
|
3383
3430
|
}
|
|
3384
|
-
await
|
|
3431
|
+
await axios16.post(`${apiUrl}/api/v1/roadmap/update-status`, {
|
|
3385
3432
|
project_id: projectId,
|
|
3386
3433
|
chunk_id: taskId,
|
|
3387
3434
|
status: "COMPLETED"
|
|
3388
3435
|
}, {
|
|
3389
3436
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3390
3437
|
});
|
|
3391
|
-
spinner.succeed(
|
|
3438
|
+
spinner.succeed(chalk20.green(`\u2705 Task #${task.step_number} completed: ${task.title}`));
|
|
3392
3439
|
if (config2.autoCommit) {
|
|
3393
3440
|
spinner.start("Committing changes...");
|
|
3394
3441
|
try {
|
|
@@ -3410,7 +3457,7 @@ function createWatchCommand() {
|
|
|
3410
3457
|
}
|
|
3411
3458
|
}
|
|
3412
3459
|
console.log("");
|
|
3413
|
-
console.log(
|
|
3460
|
+
console.log(chalk20.blue("Watching for next task..."));
|
|
3414
3461
|
} catch (e) {
|
|
3415
3462
|
spinner.fail(`Failed to complete task: ${e.message}`);
|
|
3416
3463
|
}
|
|
@@ -3423,7 +3470,7 @@ function createWatchCommand() {
|
|
|
3423
3470
|
const task = await fetchActiveTask();
|
|
3424
3471
|
if (!task) {
|
|
3425
3472
|
if (currentTask) {
|
|
3426
|
-
console.log(
|
|
3473
|
+
console.log(chalk20.green("\u{1F389} All tasks completed! Watching for new tasks..."));
|
|
3427
3474
|
currentTask = null;
|
|
3428
3475
|
}
|
|
3429
3476
|
isProcessing = false;
|
|
@@ -3432,10 +3479,10 @@ function createWatchCommand() {
|
|
|
3432
3479
|
if (!currentTask || currentTask.id !== task.id) {
|
|
3433
3480
|
currentTask = task;
|
|
3434
3481
|
console.log("");
|
|
3435
|
-
console.log(
|
|
3436
|
-
console.log(
|
|
3482
|
+
console.log(chalk20.bold.yellow(`\u{1F4CC} Active Task #${task.step_number}: ${task.title}`));
|
|
3483
|
+
console.log(chalk20.dim(`Status: ${task.status}`));
|
|
3437
3484
|
if (task.verification_criteria) {
|
|
3438
|
-
console.log(
|
|
3485
|
+
console.log(chalk20.dim("Verification: Auto-checking criteria..."));
|
|
3439
3486
|
}
|
|
3440
3487
|
}
|
|
3441
3488
|
if (task.verification_criteria && Array.isArray(task.verification_criteria)) {
|
|
@@ -3448,7 +3495,7 @@ function createWatchCommand() {
|
|
|
3448
3495
|
}
|
|
3449
3496
|
}
|
|
3450
3497
|
if (allPassed) {
|
|
3451
|
-
console.log(
|
|
3498
|
+
console.log(chalk20.green("\u2713 All verification criteria passed!"));
|
|
3452
3499
|
await completeTask(task.id, task);
|
|
3453
3500
|
currentTask = null;
|
|
3454
3501
|
}
|
|
@@ -3473,11 +3520,11 @@ function createWatchCommand() {
|
|
|
3473
3520
|
setTimeout(() => processActiveTask(), 500);
|
|
3474
3521
|
}
|
|
3475
3522
|
});
|
|
3476
|
-
console.log(
|
|
3523
|
+
console.log(chalk20.dim("Watching for file changes... (Ctrl+C to exit)"));
|
|
3477
3524
|
setInterval(() => processActiveTask(), 3e4);
|
|
3478
3525
|
process.on("SIGINT", () => {
|
|
3479
3526
|
console.log("");
|
|
3480
|
-
console.log(
|
|
3527
|
+
console.log(chalk20.dim("Watch mode stopped."));
|
|
3481
3528
|
watcher.close();
|
|
3482
3529
|
process.exit(0);
|
|
3483
3530
|
});
|
|
@@ -3489,11 +3536,11 @@ function createWatchCommand() {
|
|
|
3489
3536
|
init_esm_shims();
|
|
3490
3537
|
init_config();
|
|
3491
3538
|
import { Command as Command14 } from "commander";
|
|
3492
|
-
import
|
|
3539
|
+
import chalk21 from "chalk";
|
|
3493
3540
|
import ora11 from "ora";
|
|
3494
|
-
import
|
|
3541
|
+
import axios17 from "axios";
|
|
3495
3542
|
import { execSync as execSync4 } from "child_process";
|
|
3496
|
-
import
|
|
3543
|
+
import fs20 from "fs/promises";
|
|
3497
3544
|
import path22 from "path";
|
|
3498
3545
|
function createFocusCommand() {
|
|
3499
3546
|
const focus = new Command14("focus");
|
|
@@ -3504,26 +3551,26 @@ function createFocusCommand() {
|
|
|
3504
3551
|
try {
|
|
3505
3552
|
apiKey = getApiKey();
|
|
3506
3553
|
} catch (e) {
|
|
3507
|
-
spinner.fail(
|
|
3554
|
+
spinner.fail(chalk21.red('Not authenticated. Run "rigstate login" first.'));
|
|
3508
3555
|
return;
|
|
3509
3556
|
}
|
|
3510
3557
|
projectId = getProjectId();
|
|
3511
3558
|
if (!projectId) {
|
|
3512
3559
|
try {
|
|
3513
3560
|
const manifestPath = path22.join(process.cwd(), ".rigstate");
|
|
3514
|
-
const content = await
|
|
3561
|
+
const content = await fs20.readFile(manifestPath, "utf-8");
|
|
3515
3562
|
const manifest = JSON.parse(content);
|
|
3516
3563
|
projectId = manifest.project_id;
|
|
3517
3564
|
} catch (e) {
|
|
3518
3565
|
}
|
|
3519
3566
|
}
|
|
3520
3567
|
if (!projectId) {
|
|
3521
|
-
spinner.fail(
|
|
3568
|
+
spinner.fail(chalk21.red('No project context. Run "rigstate link" first.'));
|
|
3522
3569
|
return;
|
|
3523
3570
|
}
|
|
3524
3571
|
const apiUrl = getApiUrl();
|
|
3525
3572
|
try {
|
|
3526
|
-
const response = await
|
|
3573
|
+
const response = await axios17.get(`${apiUrl}/api/v1/roadmap`, {
|
|
3527
3574
|
params: { project_id: projectId },
|
|
3528
3575
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3529
3576
|
});
|
|
@@ -3549,41 +3596,41 @@ function createFocusCommand() {
|
|
|
3549
3596
|
const nextTask = activeTasks[0];
|
|
3550
3597
|
spinner.stop();
|
|
3551
3598
|
console.log("");
|
|
3552
|
-
console.log(
|
|
3553
|
-
const statusColor = nextTask.status === "IN_PROGRESS" ?
|
|
3554
|
-
console.log(
|
|
3555
|
-
console.log(
|
|
3599
|
+
console.log(chalk21.bold.blue(`\u{1F4CC} Task #${nextTask.step_number || "?"}: ${nextTask.title}`));
|
|
3600
|
+
const statusColor = nextTask.status === "IN_PROGRESS" ? chalk21.yellow : nextTask.status === "ACTIVE" ? chalk21.green : chalk21.dim;
|
|
3601
|
+
console.log(chalk21.dim("Status: ") + statusColor(nextTask.status));
|
|
3602
|
+
console.log(chalk21.dim("\u2500".repeat(60)));
|
|
3556
3603
|
if (nextTask.prompt_content) {
|
|
3557
|
-
console.log(
|
|
3558
|
-
console.log(
|
|
3604
|
+
console.log(chalk21.white(nextTask.prompt_content));
|
|
3605
|
+
console.log(chalk21.dim("\u2500".repeat(60)));
|
|
3559
3606
|
if (options.copy !== false) {
|
|
3560
3607
|
try {
|
|
3561
3608
|
if (process.platform === "darwin") {
|
|
3562
3609
|
execSync4("pbcopy", { input: nextTask.prompt_content });
|
|
3563
|
-
console.log(
|
|
3610
|
+
console.log(chalk21.green("\u2705 Prompt copied to clipboard! Ready to paste (Cmd+V)."));
|
|
3564
3611
|
} else if (process.platform === "linux") {
|
|
3565
3612
|
try {
|
|
3566
3613
|
execSync4("xclip -selection clipboard", { input: nextTask.prompt_content });
|
|
3567
|
-
console.log(
|
|
3614
|
+
console.log(chalk21.green("\u2705 Prompt copied to clipboard!"));
|
|
3568
3615
|
} catch (e) {
|
|
3569
|
-
console.log(
|
|
3616
|
+
console.log(chalk21.yellow("\u2139\uFE0F Copy prompt manually (xclip not available)"));
|
|
3570
3617
|
}
|
|
3571
3618
|
} else {
|
|
3572
|
-
console.log(
|
|
3619
|
+
console.log(chalk21.yellow("\u2139\uFE0F Copy prompt manually (Auto-copy not supported on this OS)"));
|
|
3573
3620
|
}
|
|
3574
3621
|
} catch (e) {
|
|
3575
3622
|
}
|
|
3576
3623
|
}
|
|
3577
3624
|
} else {
|
|
3578
|
-
console.log(
|
|
3625
|
+
console.log(chalk21.yellow("No prompt instructions available."));
|
|
3579
3626
|
if (nextTask.architectural_brief) {
|
|
3580
|
-
console.log(
|
|
3627
|
+
console.log(chalk21.bold("Brief:"));
|
|
3581
3628
|
console.log(nextTask.architectural_brief);
|
|
3582
3629
|
}
|
|
3583
3630
|
}
|
|
3584
3631
|
console.log("");
|
|
3585
3632
|
} catch (e) {
|
|
3586
|
-
spinner.fail(
|
|
3633
|
+
spinner.fail(chalk21.red(`Failed to fetch task: ${e.message}`));
|
|
3587
3634
|
}
|
|
3588
3635
|
});
|
|
3589
3636
|
return focus;
|
|
@@ -3596,25 +3643,25 @@ init_env();
|
|
|
3596
3643
|
init_esm_shims();
|
|
3597
3644
|
init_config();
|
|
3598
3645
|
import { Command as Command15 } from "commander";
|
|
3599
|
-
import
|
|
3646
|
+
import chalk22 from "chalk";
|
|
3600
3647
|
function createConfigCommand() {
|
|
3601
3648
|
const config2 = new Command15("config");
|
|
3602
3649
|
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) => {
|
|
3603
3650
|
if (!key) {
|
|
3604
|
-
console.log(
|
|
3605
|
-
console.log(
|
|
3651
|
+
console.log(chalk22.bold("Rigstate Configuration"));
|
|
3652
|
+
console.log(chalk22.dim("\u2500".repeat(40)));
|
|
3606
3653
|
try {
|
|
3607
3654
|
const apiKey = getApiKey();
|
|
3608
|
-
console.log(`${
|
|
3655
|
+
console.log(`${chalk22.cyan("api_key")}: ${apiKey.substring(0, 20)}...`);
|
|
3609
3656
|
} catch (e) {
|
|
3610
|
-
console.log(`${
|
|
3657
|
+
console.log(`${chalk22.cyan("api_key")}: ${chalk22.dim("(not set)")}`);
|
|
3611
3658
|
}
|
|
3612
3659
|
const projectId = getProjectId();
|
|
3613
|
-
console.log(`${
|
|
3660
|
+
console.log(`${chalk22.cyan("project_id")}: ${projectId || chalk22.dim("(not set)")}`);
|
|
3614
3661
|
const apiUrl = getApiUrl();
|
|
3615
|
-
console.log(`${
|
|
3662
|
+
console.log(`${chalk22.cyan("api_url")}: ${apiUrl}`);
|
|
3616
3663
|
console.log("");
|
|
3617
|
-
console.log(
|
|
3664
|
+
console.log(chalk22.dim('Use "rigstate config <key> <value>" to set a value.'));
|
|
3618
3665
|
return;
|
|
3619
3666
|
}
|
|
3620
3667
|
if (!value) {
|
|
@@ -3624,36 +3671,36 @@ function createConfigCommand() {
|
|
|
3624
3671
|
const apiKey = getApiKey();
|
|
3625
3672
|
console.log(apiKey);
|
|
3626
3673
|
} catch (e) {
|
|
3627
|
-
console.log(
|
|
3674
|
+
console.log(chalk22.dim("(not set)"));
|
|
3628
3675
|
}
|
|
3629
3676
|
break;
|
|
3630
3677
|
case "project_id":
|
|
3631
|
-
console.log(getProjectId() ||
|
|
3678
|
+
console.log(getProjectId() || chalk22.dim("(not set)"));
|
|
3632
3679
|
break;
|
|
3633
3680
|
case "api_url":
|
|
3634
3681
|
console.log(getApiUrl());
|
|
3635
3682
|
break;
|
|
3636
3683
|
default:
|
|
3637
|
-
console.log(
|
|
3638
|
-
console.log(
|
|
3684
|
+
console.log(chalk22.red(`Unknown config key: ${key}`));
|
|
3685
|
+
console.log(chalk22.dim("Valid keys: api_key, project_id, api_url"));
|
|
3639
3686
|
}
|
|
3640
3687
|
return;
|
|
3641
3688
|
}
|
|
3642
3689
|
switch (key) {
|
|
3643
3690
|
case "api_key":
|
|
3644
3691
|
setApiKey(value);
|
|
3645
|
-
console.log(
|
|
3692
|
+
console.log(chalk22.green(`\u2705 api_key updated`));
|
|
3646
3693
|
break;
|
|
3647
3694
|
case "project_id":
|
|
3648
3695
|
setProjectId(value);
|
|
3649
|
-
console.log(
|
|
3696
|
+
console.log(chalk22.green(`\u2705 project_id updated`));
|
|
3650
3697
|
break;
|
|
3651
3698
|
case "api_url":
|
|
3652
|
-
console.log(
|
|
3699
|
+
console.log(chalk22.yellow("api_url is set via RIGSTATE_API_URL environment variable"));
|
|
3653
3700
|
break;
|
|
3654
3701
|
default:
|
|
3655
|
-
console.log(
|
|
3656
|
-
console.log(
|
|
3702
|
+
console.log(chalk22.red(`Unknown config key: ${key}`));
|
|
3703
|
+
console.log(chalk22.dim("Valid keys: api_key, project_id"));
|
|
3657
3704
|
}
|
|
3658
3705
|
});
|
|
3659
3706
|
return config2;
|
|
@@ -3662,10 +3709,10 @@ function createConfigCommand() {
|
|
|
3662
3709
|
// src/commands/mcp.ts
|
|
3663
3710
|
init_esm_shims();
|
|
3664
3711
|
import { Command as Command16 } from "commander";
|
|
3665
|
-
import
|
|
3712
|
+
import chalk23 from "chalk";
|
|
3666
3713
|
import { spawn } from "child_process";
|
|
3667
3714
|
import path23 from "path";
|
|
3668
|
-
import
|
|
3715
|
+
import fs21 from "fs";
|
|
3669
3716
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3670
3717
|
var __filename2 = fileURLToPath2(import.meta.url);
|
|
3671
3718
|
var __dirname2 = path23.dirname(__filename2);
|
|
@@ -3682,21 +3729,21 @@ function createMcpCommand() {
|
|
|
3682
3729
|
];
|
|
3683
3730
|
let serverPath = "";
|
|
3684
3731
|
for (const p of possiblePaths) {
|
|
3685
|
-
if (
|
|
3732
|
+
if (fs21.existsSync(p)) {
|
|
3686
3733
|
serverPath = p;
|
|
3687
3734
|
break;
|
|
3688
3735
|
}
|
|
3689
3736
|
}
|
|
3690
3737
|
if (!serverPath) {
|
|
3691
|
-
console.error(
|
|
3692
|
-
console.error(
|
|
3693
|
-
console.error(
|
|
3738
|
+
console.error(chalk23.red("\u274C Error: Rigstate MCP Server binary not found."));
|
|
3739
|
+
console.error(chalk23.yellow("Please ensure that the mcp package is built:"));
|
|
3740
|
+
console.error(chalk23.white(" cd packages/mcp && npm run build"));
|
|
3694
3741
|
console.error("");
|
|
3695
|
-
console.error(
|
|
3696
|
-
console.error(
|
|
3742
|
+
console.error(chalk23.dim("Or run directly with:"));
|
|
3743
|
+
console.error(chalk23.white(" npx @rigstate/mcp"));
|
|
3697
3744
|
process.exit(1);
|
|
3698
3745
|
}
|
|
3699
|
-
console.log(
|
|
3746
|
+
console.log(chalk23.dim(`Starting MCP server from: ${serverPath}`));
|
|
3700
3747
|
if (process.env.VIBE_API_KEY && !process.env.RIGSTATE_API_KEY) {
|
|
3701
3748
|
process.env.RIGSTATE_API_KEY = process.env.VIBE_API_KEY;
|
|
3702
3749
|
}
|
|
@@ -3705,7 +3752,7 @@ function createMcpCommand() {
|
|
|
3705
3752
|
stdio: ["inherit", "inherit", "inherit"]
|
|
3706
3753
|
});
|
|
3707
3754
|
worker.on("error", (err) => {
|
|
3708
|
-
console.error(
|
|
3755
|
+
console.error(chalk23.red(`\u274C Failed to start MCP server: ${err.message}`));
|
|
3709
3756
|
process.exit(1);
|
|
3710
3757
|
});
|
|
3711
3758
|
worker.on("exit", (code) => {
|
|
@@ -3720,7 +3767,7 @@ function createMcpCommand() {
|
|
|
3720
3767
|
// src/commands/nexus.ts
|
|
3721
3768
|
init_esm_shims();
|
|
3722
3769
|
import { Command as Command17 } from "commander";
|
|
3723
|
-
import
|
|
3770
|
+
import chalk26 from "chalk";
|
|
3724
3771
|
|
|
3725
3772
|
// src/nexus/dispatcher.ts
|
|
3726
3773
|
init_esm_shims();
|
|
@@ -3729,7 +3776,7 @@ import { v4 as uuidv4 } from "uuid";
|
|
|
3729
3776
|
|
|
3730
3777
|
// src/hive/gateway.ts
|
|
3731
3778
|
init_esm_shims();
|
|
3732
|
-
import
|
|
3779
|
+
import axios18 from "axios";
|
|
3733
3780
|
|
|
3734
3781
|
// src/hive/scrubber.ts
|
|
3735
3782
|
init_esm_shims();
|
|
@@ -3788,7 +3835,7 @@ var HiveScrubber = class {
|
|
|
3788
3835
|
};
|
|
3789
3836
|
|
|
3790
3837
|
// src/hive/gateway.ts
|
|
3791
|
-
import
|
|
3838
|
+
import chalk24 from "chalk";
|
|
3792
3839
|
var HiveGateway = class {
|
|
3793
3840
|
client;
|
|
3794
3841
|
enabled;
|
|
@@ -3798,9 +3845,9 @@ var HiveGateway = class {
|
|
|
3798
3845
|
constructor(baseUrl, token) {
|
|
3799
3846
|
this.enabled = !!token;
|
|
3800
3847
|
if (!this.enabled) {
|
|
3801
|
-
console.log(
|
|
3848
|
+
console.log(chalk24.dim("\u26A0\uFE0F Hive Gateway disabled (No Token provided). Running in localized mode."));
|
|
3802
3849
|
}
|
|
3803
|
-
this.client =
|
|
3850
|
+
this.client = axios18.create({
|
|
3804
3851
|
baseURL: baseUrl,
|
|
3805
3852
|
headers: {
|
|
3806
3853
|
"Authorization": `Bearer ${token}`,
|
|
@@ -3818,23 +3865,23 @@ var HiveGateway = class {
|
|
|
3818
3865
|
if (!this.enabled) return false;
|
|
3819
3866
|
const now = Date.now();
|
|
3820
3867
|
if (now - this.lastSignalTime < this.MIN_INTERVAL_MS) {
|
|
3821
|
-
console.warn(
|
|
3868
|
+
console.warn(chalk24.yellow("\u23F3 Hive Gateway Throttled. Signal dropped to preventing spam."));
|
|
3822
3869
|
return false;
|
|
3823
3870
|
}
|
|
3824
3871
|
const scrubResult = HiveScrubber.scrub(signal.ruleContent);
|
|
3825
3872
|
if (scrubResult.riskScore > 20) {
|
|
3826
|
-
console.error(
|
|
3873
|
+
console.error(chalk24.red(`\u{1F6D1} HIVE BLOCKED: Signal contains sensitive data (Risk: ${scrubResult.riskScore})`));
|
|
3827
3874
|
return false;
|
|
3828
3875
|
}
|
|
3829
3876
|
try {
|
|
3830
|
-
console.log(
|
|
3877
|
+
console.log(chalk24.blue(`\u{1F4E1} Uplinking to Hive... [${signal.vector}]`));
|
|
3831
3878
|
const payload = { ...signal, ruleContent: scrubResult.sanitizedContent };
|
|
3832
3879
|
await this.client.post("/signal", payload);
|
|
3833
3880
|
this.lastSignalTime = now;
|
|
3834
|
-
console.log(
|
|
3881
|
+
console.log(chalk24.green("\u2705 Signal Received by Hive Core. Knowledge Shared."));
|
|
3835
3882
|
return true;
|
|
3836
3883
|
} catch (error) {
|
|
3837
|
-
console.error(
|
|
3884
|
+
console.error(chalk24.red(`\u274C Hive Transmission Failed: ${error.message}`));
|
|
3838
3885
|
return false;
|
|
3839
3886
|
}
|
|
3840
3887
|
}
|
|
@@ -3842,37 +3889,37 @@ var HiveGateway = class {
|
|
|
3842
3889
|
|
|
3843
3890
|
// src/utils/logger.ts
|
|
3844
3891
|
init_esm_shims();
|
|
3845
|
-
import
|
|
3892
|
+
import chalk25 from "chalk";
|
|
3846
3893
|
var Logger = class {
|
|
3847
3894
|
static formatMessage(level, message, context) {
|
|
3848
3895
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3849
3896
|
let prefix = "";
|
|
3850
3897
|
switch (level) {
|
|
3851
3898
|
case "INFO" /* INFO */:
|
|
3852
|
-
prefix =
|
|
3899
|
+
prefix = chalk25.blue(`[${"INFO" /* INFO */}]`);
|
|
3853
3900
|
break;
|
|
3854
3901
|
case "WARN" /* WARN */:
|
|
3855
|
-
prefix =
|
|
3902
|
+
prefix = chalk25.yellow(`[${"WARN" /* WARN */}]`);
|
|
3856
3903
|
break;
|
|
3857
3904
|
case "ERROR" /* ERROR */:
|
|
3858
|
-
prefix =
|
|
3905
|
+
prefix = chalk25.red(`[${"ERROR" /* ERROR */}]`);
|
|
3859
3906
|
break;
|
|
3860
3907
|
case "DEBUG" /* DEBUG */:
|
|
3861
|
-
prefix =
|
|
3908
|
+
prefix = chalk25.gray(`[${"DEBUG" /* DEBUG */}]`);
|
|
3862
3909
|
break;
|
|
3863
3910
|
}
|
|
3864
|
-
let output = `${
|
|
3911
|
+
let output = `${chalk25.gray(timestamp)} ${prefix} ${message}`;
|
|
3865
3912
|
if (context) {
|
|
3866
3913
|
if (context instanceof Error) {
|
|
3867
3914
|
output += `
|
|
3868
|
-
${
|
|
3915
|
+
${chalk25.red(context.stack || context.message)}`;
|
|
3869
3916
|
} else if (typeof context === "object") {
|
|
3870
3917
|
try {
|
|
3871
3918
|
output += `
|
|
3872
|
-
${
|
|
3919
|
+
${chalk25.gray(JSON.stringify(context, null, 2))}`;
|
|
3873
3920
|
} catch (e) {
|
|
3874
3921
|
output += `
|
|
3875
|
-
${
|
|
3922
|
+
${chalk25.gray("[Circular or invalid object]")}`;
|
|
3876
3923
|
}
|
|
3877
3924
|
} else {
|
|
3878
3925
|
output += ` ${String(context)}`;
|
|
@@ -3992,10 +4039,10 @@ import inquirer3 from "inquirer";
|
|
|
3992
4039
|
function createNexusCommand() {
|
|
3993
4040
|
const command = new Command17("nexus");
|
|
3994
4041
|
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) => {
|
|
3995
|
-
console.log(
|
|
4042
|
+
console.log(chalk26.bold.magenta("\n\u{1F981} Welcome to The Nexus (Phase 8)\n"));
|
|
3996
4043
|
const dryRun = !options.force;
|
|
3997
4044
|
if (!dryRun) {
|
|
3998
|
-
console.log(
|
|
4045
|
+
console.log(chalk26.black.bgYellow(" WARNING ") + chalk26.yellow(" Dry-Run disabled! Eitri is authorized to write code."));
|
|
3999
4046
|
const { confirm } = await inquirer3.prompt([{
|
|
4000
4047
|
type: "confirm",
|
|
4001
4048
|
name: "confirm",
|
|
@@ -4016,26 +4063,26 @@ function createNexusCommand() {
|
|
|
4016
4063
|
};
|
|
4017
4064
|
const dispatcher = new NexusDispatcher(context);
|
|
4018
4065
|
dispatcher.on("order:created", (o) => {
|
|
4019
|
-
console.log(
|
|
4066
|
+
console.log(chalk26.blue(`\u{1F195} [${o.id.slice(0, 6)}] Order Created: `) + o.intent);
|
|
4020
4067
|
});
|
|
4021
4068
|
dispatcher.on("order:started", (o) => {
|
|
4022
|
-
console.log(
|
|
4069
|
+
console.log(chalk26.yellow(`\u23F3 [${o.id.slice(0, 6)}] Processing...`));
|
|
4023
4070
|
});
|
|
4024
4071
|
dispatcher.on("order:blocked", (o) => {
|
|
4025
|
-
console.log(
|
|
4026
|
-
console.log(
|
|
4027
|
-
console.log(
|
|
4072
|
+
console.log(chalk26.red(`\u{1F6D1} [${o.id.slice(0, 6)}] BLOCKED by Kill-Switch`));
|
|
4073
|
+
console.log(chalk26.dim(` Target: ${o.targetAgent} | Action: ${o.action}`));
|
|
4074
|
+
console.log(chalk26.dim(" Run with --force to execute automatically (NOT RECOMMENDED)."));
|
|
4028
4075
|
});
|
|
4029
|
-
dispatcher.on("agent:SINDRE", (o) => console.log(
|
|
4030
|
-
dispatcher.on("agent:EITRI", (o) => console.log(
|
|
4031
|
-
console.log(
|
|
4076
|
+
dispatcher.on("agent:SINDRE", (o) => console.log(chalk26.cyan(`\u{1F916} Sindre (Vault): I'm on it! (${o.action})`)));
|
|
4077
|
+
dispatcher.on("agent:EITRI", (o) => console.log(chalk26.green(`\u{1F477} Eitri (Smith): Ready to build! (${o.action})`)));
|
|
4078
|
+
console.log(chalk26.dim("\u{1F9E0} Frank is analyzing your intent..."));
|
|
4032
4079
|
await new Promise((r) => setTimeout(r, 800));
|
|
4033
4080
|
if (intent.toLowerCase().includes("db") || intent.toLowerCase().includes("database")) {
|
|
4034
4081
|
await dispatcher.dispatch("FRANK", "SINDRE", intent, "db.analyze", { raw: intent });
|
|
4035
4082
|
} else if (intent.toLowerCase().includes("create") || intent.toLowerCase().includes("code")) {
|
|
4036
4083
|
await dispatcher.dispatch("FRANK", "EITRI", intent, "fs.write", { path: "src/demo.ts", content: "// demo" });
|
|
4037
4084
|
} else {
|
|
4038
|
-
console.log(
|
|
4085
|
+
console.log(chalk26.gray("Frank didn't understand. Try 'create file' or 'check database'."));
|
|
4039
4086
|
}
|
|
4040
4087
|
});
|
|
4041
4088
|
return command;
|
|
@@ -4049,31 +4096,31 @@ init_esm_shims();
|
|
|
4049
4096
|
init_governance();
|
|
4050
4097
|
init_config();
|
|
4051
4098
|
import { Command as Command18 } from "commander";
|
|
4052
|
-
import
|
|
4053
|
-
import
|
|
4099
|
+
import chalk27 from "chalk";
|
|
4100
|
+
import axios19 from "axios";
|
|
4054
4101
|
function createOverrideCommand() {
|
|
4055
4102
|
const override = new Command18("override");
|
|
4056
4103
|
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) => {
|
|
4057
4104
|
const { reason } = options;
|
|
4058
|
-
console.log(
|
|
4105
|
+
console.log(chalk27.bold(`
|
|
4059
4106
|
\u{1F513} Initiating Governance Override Protocol...`));
|
|
4060
4107
|
const session = await getSessionState(process.cwd());
|
|
4061
4108
|
if (session.status !== "SOFT_LOCK") {
|
|
4062
|
-
console.log(
|
|
4109
|
+
console.log(chalk27.yellow(" Info: Session is not currently locked."));
|
|
4063
4110
|
return;
|
|
4064
4111
|
}
|
|
4065
|
-
console.log(
|
|
4066
|
-
console.log(
|
|
4112
|
+
console.log(chalk27.dim(` Active Violation: ${session.active_violation}`));
|
|
4113
|
+
console.log(chalk27.dim(` Reason Provided: "${reason}"`));
|
|
4067
4114
|
const success = await performOverride(violationId, reason, process.cwd());
|
|
4068
4115
|
if (success) {
|
|
4069
|
-
console.log(
|
|
4070
|
-
console.log(
|
|
4116
|
+
console.log(chalk27.green(` \u2705 Session UNLOCKED.`));
|
|
4117
|
+
console.log(chalk27.dim(` This event has been logged to the Mission Report.`));
|
|
4071
4118
|
try {
|
|
4072
4119
|
const projectId = getProjectId();
|
|
4073
4120
|
if (projectId) {
|
|
4074
4121
|
const apiUrl = getApiUrl();
|
|
4075
4122
|
const apiKey = getApiKey();
|
|
4076
|
-
await
|
|
4123
|
+
await axios19.post(`${apiUrl}/api/v1/execution-logs`, {
|
|
4077
4124
|
project_id: projectId,
|
|
4078
4125
|
task_id: "OVERRIDE-" + Date.now(),
|
|
4079
4126
|
task_title: `Governance Override: ${violationId}`,
|
|
@@ -4084,13 +4131,13 @@ function createOverrideCommand() {
|
|
|
4084
4131
|
}, {
|
|
4085
4132
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4086
4133
|
});
|
|
4087
|
-
console.log(
|
|
4134
|
+
console.log(chalk27.dim(` \u2601 Audit log synced to Cloud.`));
|
|
4088
4135
|
}
|
|
4089
4136
|
} catch (e) {
|
|
4090
|
-
console.log(
|
|
4137
|
+
console.log(chalk27.dim(` (Cloud audit sync failed: ${e.message})`));
|
|
4091
4138
|
}
|
|
4092
4139
|
} else {
|
|
4093
|
-
console.log(
|
|
4140
|
+
console.log(chalk27.red(` \u{1F6D1} Override Failed. Check project configuration.`));
|
|
4094
4141
|
}
|
|
4095
4142
|
});
|
|
4096
4143
|
return override;
|
|
@@ -4103,8 +4150,73 @@ async function checkVersion() {
|
|
|
4103
4150
|
|
|
4104
4151
|
// src/index.ts
|
|
4105
4152
|
import dotenv from "dotenv";
|
|
4153
|
+
|
|
4154
|
+
// src/commands/idea.ts
|
|
4155
|
+
init_esm_shims();
|
|
4156
|
+
init_config();
|
|
4157
|
+
import { Command as Command19 } from "commander";
|
|
4158
|
+
import chalk28 from "chalk";
|
|
4159
|
+
import ora12 from "ora";
|
|
4160
|
+
import axios20 from "axios";
|
|
4161
|
+
import inquirer4 from "inquirer";
|
|
4162
|
+
function createIdeaCommand() {
|
|
4163
|
+
return new Command19("idea").description("Capture a new idea or feature request").argument("[title]", "Quick title of the idea").option("-d, --desc <text>", "Detailed description").option("-t, --tag <tags>", "Comma separated tags (e.g. ui,auth)").action(async (title, options) => {
|
|
4164
|
+
try {
|
|
4165
|
+
const apiKey = getApiKey();
|
|
4166
|
+
const apiUrl = getApiUrl();
|
|
4167
|
+
const projectId = getProjectId();
|
|
4168
|
+
if (!projectId) {
|
|
4169
|
+
console.error(chalk28.red("Project context missing. Run rigstate link."));
|
|
4170
|
+
process.exit(1);
|
|
4171
|
+
}
|
|
4172
|
+
let ideaTitle = title;
|
|
4173
|
+
let ideaDesc = options.desc;
|
|
4174
|
+
let tags = options.tag ? options.tag.split(",") : [];
|
|
4175
|
+
if (!ideaTitle) {
|
|
4176
|
+
const ans = await inquirer4.prompt([{
|
|
4177
|
+
type: "input",
|
|
4178
|
+
name: "title",
|
|
4179
|
+
message: "Idea Title:"
|
|
4180
|
+
}]);
|
|
4181
|
+
ideaTitle = ans.title;
|
|
4182
|
+
}
|
|
4183
|
+
if (!ideaDesc) {
|
|
4184
|
+
const ans = await inquirer4.prompt([{
|
|
4185
|
+
type: "input",
|
|
4186
|
+
name: "desc",
|
|
4187
|
+
message: "Description (Optional):"
|
|
4188
|
+
}]);
|
|
4189
|
+
ideaDesc = ans.desc;
|
|
4190
|
+
}
|
|
4191
|
+
if (tags.length === 0) {
|
|
4192
|
+
}
|
|
4193
|
+
const spinner = ora12("Securing idea in the Lab...").start();
|
|
4194
|
+
const response = await axios20.post(
|
|
4195
|
+
`${apiUrl}/api/v1/ideas`,
|
|
4196
|
+
{
|
|
4197
|
+
project_id: projectId,
|
|
4198
|
+
title: ideaTitle,
|
|
4199
|
+
description: ideaDesc,
|
|
4200
|
+
tags
|
|
4201
|
+
},
|
|
4202
|
+
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
4203
|
+
);
|
|
4204
|
+
if (response.data.success) {
|
|
4205
|
+
spinner.succeed(chalk28.green("Idea Captured! \u{1F4A1}"));
|
|
4206
|
+
console.log(chalk28.dim(`ID: ${response.data.data?.id || "Saved"}`));
|
|
4207
|
+
} else {
|
|
4208
|
+
throw new Error(response.data.error);
|
|
4209
|
+
}
|
|
4210
|
+
} catch (e) {
|
|
4211
|
+
console.error(chalk28.red(`
|
|
4212
|
+
Failed to capture idea: ${e.message}`));
|
|
4213
|
+
}
|
|
4214
|
+
});
|
|
4215
|
+
}
|
|
4216
|
+
|
|
4217
|
+
// src/index.ts
|
|
4106
4218
|
dotenv.config();
|
|
4107
|
-
var program = new
|
|
4219
|
+
var program = new Command20();
|
|
4108
4220
|
program.name("rigstate").description("CLI for Rigstate - The AI-Native Dev Studio").version("0.2.0");
|
|
4109
4221
|
program.addCommand(createLoginCommand());
|
|
4110
4222
|
program.addCommand(createLinkCommand());
|
|
@@ -4124,24 +4236,25 @@ program.addCommand(createMcpCommand());
|
|
|
4124
4236
|
program.addCommand(createNexusCommand());
|
|
4125
4237
|
program.addCommand(createSyncRulesCommand());
|
|
4126
4238
|
program.addCommand(createOverrideCommand());
|
|
4239
|
+
program.addCommand(createIdeaCommand());
|
|
4127
4240
|
program.hook("preAction", async () => {
|
|
4128
4241
|
await checkVersion();
|
|
4129
4242
|
});
|
|
4130
4243
|
program.on("--help", () => {
|
|
4131
4244
|
console.log("");
|
|
4132
|
-
console.log(
|
|
4245
|
+
console.log(chalk29.bold("Examples:"));
|
|
4133
4246
|
console.log("");
|
|
4134
|
-
console.log(
|
|
4135
|
-
console.log(
|
|
4247
|
+
console.log(chalk29.cyan(" $ rigstate login sk_rigstate_your_api_key"));
|
|
4248
|
+
console.log(chalk29.dim(" Authenticate with your Rigstate API key"));
|
|
4136
4249
|
console.log("");
|
|
4137
|
-
console.log(
|
|
4138
|
-
console.log(
|
|
4250
|
+
console.log(chalk29.cyan(" $ rigstate scan"));
|
|
4251
|
+
console.log(chalk29.dim(" Scan the current directory"));
|
|
4139
4252
|
console.log("");
|
|
4140
|
-
console.log(
|
|
4141
|
-
console.log(
|
|
4253
|
+
console.log(chalk29.cyan(" $ rigstate scan ./src --project abc123"));
|
|
4254
|
+
console.log(chalk29.dim(" Scan a specific directory with project ID"));
|
|
4142
4255
|
console.log("");
|
|
4143
|
-
console.log(
|
|
4144
|
-
console.log(
|
|
4256
|
+
console.log(chalk29.cyan(" $ rigstate scan --json"));
|
|
4257
|
+
console.log(chalk29.dim(" Output results in JSON format (useful for IDE extensions)"));
|
|
4145
4258
|
console.log("");
|
|
4146
4259
|
});
|
|
4147
4260
|
program.parse(process.argv);
|