@rigstate/cli 0.7.37 → 0.7.39
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/.rigstate/memories/2585b51e-f576-4c0c-b69d-2daaaa427bf4.json +18 -0
- package/.rigstate/memories/739c72cd-d1a7-49a7-901c-8f2a9db9e4ca.json +17 -0
- package/.rigstate/memories/bd30d910-dd03-42d7-8eee-8306a5536ca1.json +18 -0
- package/dist/index.cjs +376 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +376 -53
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/ask.ts +100 -0
- package/src/commands/genesis.ts +41 -5
- package/src/commands/remember.ts +67 -0
- package/src/index.ts +4 -0
- package/src/utils/memory-store.ts +183 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "2585b51e-f576-4c0c-b69d-2daaaa427bf4",
|
|
3
|
+
"title": "Bruk aldri 'any' i @rigstate/shared typer. Alt skal være Zod...",
|
|
4
|
+
"content": "Bruk aldri 'any' i @rigstate/shared typer. Alt skal være Zod-validert.",
|
|
5
|
+
"category": "LESSON",
|
|
6
|
+
"source": "USER",
|
|
7
|
+
"tags": [
|
|
8
|
+
"typescript",
|
|
9
|
+
"zod",
|
|
10
|
+
"shared"
|
|
11
|
+
],
|
|
12
|
+
"importance": 7,
|
|
13
|
+
"project_id": "bb9f8445-39fd-438c-8ab6-8057f5514395",
|
|
14
|
+
"confidence": 1,
|
|
15
|
+
"created_at": "2026-02-19T23:55:34.637Z",
|
|
16
|
+
"updated_at": "2026-02-19T23:55:34.637Z",
|
|
17
|
+
"expires_at": null
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "739c72cd-d1a7-49a7-901c-8f2a9db9e4ca",
|
|
3
|
+
"title": "Monorepo-struktur: packages/shared er Hjernen, packages/cli ...",
|
|
4
|
+
"content": "Monorepo-struktur: packages/shared er Hjernen, packages/cli er Agenten, apps/web er Grensesnittet",
|
|
5
|
+
"category": "PATTERN",
|
|
6
|
+
"source": "USER",
|
|
7
|
+
"tags": [
|
|
8
|
+
"monorepo",
|
|
9
|
+
"architecture"
|
|
10
|
+
],
|
|
11
|
+
"importance": 8,
|
|
12
|
+
"project_id": "bb9f8445-39fd-438c-8ab6-8057f5514395",
|
|
13
|
+
"confidence": 1,
|
|
14
|
+
"created_at": "2026-02-19T23:55:29.585Z",
|
|
15
|
+
"updated_at": "2026-02-19T23:55:29.585Z",
|
|
16
|
+
"expires_at": null
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "bd30d910-dd03-42d7-8eee-8306a5536ca1",
|
|
3
|
+
"title": "Vi valgte Supabase for real-time subscriptions, RLS og edge ...",
|
|
4
|
+
"content": "Vi valgte Supabase for real-time subscriptions, RLS og edge functions",
|
|
5
|
+
"category": "ADR",
|
|
6
|
+
"source": "USER",
|
|
7
|
+
"tags": [
|
|
8
|
+
"supabase",
|
|
9
|
+
"database",
|
|
10
|
+
"architecture"
|
|
11
|
+
],
|
|
12
|
+
"importance": 9,
|
|
13
|
+
"project_id": "bb9f8445-39fd-438c-8ab6-8057f5514395",
|
|
14
|
+
"confidence": 1,
|
|
15
|
+
"created_at": "2026-02-19T23:55:23.715Z",
|
|
16
|
+
"updated_at": "2026-02-19T23:55:23.715Z",
|
|
17
|
+
"expires_at": null
|
|
18
|
+
}
|
package/dist/index.cjs
CHANGED
|
@@ -410,19 +410,19 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false, versi
|
|
|
410
410
|
}
|
|
411
411
|
const files = syncResponse.data.data.files;
|
|
412
412
|
if (files && Array.isArray(files)) {
|
|
413
|
-
const
|
|
414
|
-
const
|
|
413
|
+
const fs27 = await import("fs/promises");
|
|
414
|
+
const path29 = await import("path");
|
|
415
415
|
for (const file of files) {
|
|
416
|
-
const filePath =
|
|
417
|
-
await
|
|
418
|
-
await
|
|
416
|
+
const filePath = path29.join(process.cwd(), file.path);
|
|
417
|
+
await fs27.mkdir(path29.dirname(filePath), { recursive: true });
|
|
418
|
+
await fs27.writeFile(filePath, file.content, "utf-8");
|
|
419
419
|
}
|
|
420
420
|
console.log(import_chalk4.default.dim(` \u{1F4BE} Wrote ${files.length} rule files to local .cursor/rules/`));
|
|
421
421
|
try {
|
|
422
|
-
const masterPath =
|
|
422
|
+
const masterPath = path29.join(process.cwd(), ".cursorrules");
|
|
423
423
|
let masterContent = "";
|
|
424
424
|
try {
|
|
425
|
-
masterContent = await
|
|
425
|
+
masterContent = await fs27.readFile(masterPath, "utf-8");
|
|
426
426
|
} catch {
|
|
427
427
|
masterContent = "";
|
|
428
428
|
}
|
|
@@ -451,7 +451,7 @@ ${END_MARKER}`;
|
|
|
451
451
|
|
|
452
452
|
${governanceBlock}` : governanceBlock;
|
|
453
453
|
}
|
|
454
|
-
await
|
|
454
|
+
await fs27.writeFile(masterPath, newContent, "utf-8");
|
|
455
455
|
console.log(import_chalk4.default.dim(" \u{1F4DC} Updated master .cursorrules (Constitution enforced)"));
|
|
456
456
|
} catch (e) {
|
|
457
457
|
console.warn(import_chalk4.default.yellow(` \u26A0\uFE0F Could not update .cursorrules: ${e.message}`));
|
|
@@ -511,7 +511,7 @@ __export(genesis_exports, {
|
|
|
511
511
|
triggerGenesis: () => triggerGenesis
|
|
512
512
|
});
|
|
513
513
|
function createGenesisCommand() {
|
|
514
|
-
return new import_commander4.Command("genesis").description("Initialize project foundation (Phase 0). Detects stack and injects foundation steps.").option("--force", "Re-run genesis even if already initialized (use with caution)").option("--status", "Check genesis status without triggering").option("--project-id <id>", "Override project ID (defaults to linked project)").action(async (options) => {
|
|
514
|
+
return new import_commander4.Command("genesis").description("Initialize project foundation (Phase 0). Detects stack and injects foundation steps.").option("--force", "Re-run genesis even if already initialized (use with caution)").option("--simulate", "Dry-run: Calculate plan without modifying database").option("--status", "Check genesis status without triggering").option("--project-id <id>", "Override project ID (defaults to linked project)").action(async (options) => {
|
|
515
515
|
const apiKey = getApiKey();
|
|
516
516
|
const apiUrl = getApiUrl();
|
|
517
517
|
const projectId = options.projectId || getProjectId();
|
|
@@ -526,7 +526,7 @@ function createGenesisCommand() {
|
|
|
526
526
|
if (options.status) {
|
|
527
527
|
await checkGenesisStatus(projectId, apiKey, apiUrl);
|
|
528
528
|
} else {
|
|
529
|
-
await triggerGenesis(projectId, apiKey, apiUrl, options.force ?? false);
|
|
529
|
+
await triggerGenesis(projectId, apiKey, apiUrl, options.force ?? false, options.simulate ?? false);
|
|
530
530
|
}
|
|
531
531
|
});
|
|
532
532
|
}
|
|
@@ -586,10 +586,15 @@ async function checkGenesisStatus(projectId, apiKey, apiUrl) {
|
|
|
586
586
|
return { complete: false, stepCount: 0 };
|
|
587
587
|
}
|
|
588
588
|
}
|
|
589
|
-
async function triggerGenesis(projectId, apiKey, apiUrl, force = false) {
|
|
589
|
+
async function triggerGenesis(projectId, apiKey, apiUrl, force = false, simulate = false) {
|
|
590
590
|
console.log("");
|
|
591
|
-
|
|
592
|
-
|
|
591
|
+
if (simulate) {
|
|
592
|
+
console.log(import_chalk5.default.bold.magenta("\u{1F52E} GENESIS SIMULATION"));
|
|
593
|
+
console.log(import_chalk5.default.dim("Dry-run: Calculating plan without executing changes..."));
|
|
594
|
+
} else {
|
|
595
|
+
console.log(import_chalk5.default.bold.blue("\u{1F3D7}\uFE0F GENESIS PROTOCOL"));
|
|
596
|
+
console.log(import_chalk5.default.dim("Initializing project foundation..."));
|
|
597
|
+
}
|
|
593
598
|
console.log("");
|
|
594
599
|
const spinner = (0, import_ora3.default)("Detecting tech stack...").start();
|
|
595
600
|
try {
|
|
@@ -618,7 +623,7 @@ async function triggerGenesis(projectId, apiKey, apiUrl, force = false) {
|
|
|
618
623
|
}
|
|
619
624
|
const response = await import_axios3.default.post(
|
|
620
625
|
`${apiUrl}/api/v1/genesis`,
|
|
621
|
-
{ project_id: projectId, force },
|
|
626
|
+
{ project_id: projectId, force, simulate },
|
|
622
627
|
{
|
|
623
628
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
624
629
|
timeout: 6e4
|
|
@@ -643,6 +648,28 @@ async function triggerGenesis(projectId, apiKey, apiUrl, force = false) {
|
|
|
643
648
|
return false;
|
|
644
649
|
}
|
|
645
650
|
const { data } = response.data;
|
|
651
|
+
if (response.data.simulation) {
|
|
652
|
+
console.log(import_chalk5.default.bold.magenta("\u{1F52E} SIMULATION RESULTS"));
|
|
653
|
+
console.log(import_chalk5.default.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"));
|
|
654
|
+
console.log(`${import_chalk5.default.bold("Project:")} ${import_chalk5.default.cyan(data.project_name)}`);
|
|
655
|
+
console.log(`${import_chalk5.default.bold("Stack:")} ${import_chalk5.default.magenta(data.template)}`);
|
|
656
|
+
console.log(`${import_chalk5.default.bold("Will Create:")} ${import_chalk5.default.white(data.steps_created)} foundation steps`);
|
|
657
|
+
if (data.existing_steps_shifted > 0) {
|
|
658
|
+
console.log(`${import_chalk5.default.bold("Will Shift:")} ${import_chalk5.default.yellow(`${data.existing_steps_shifted} existing steps down`)}`);
|
|
659
|
+
}
|
|
660
|
+
console.log("");
|
|
661
|
+
console.log(import_chalk5.default.bold("\u{1F4CB} Planner Preview:"));
|
|
662
|
+
data.steps.forEach((step) => {
|
|
663
|
+
const stepNum = step.step_number;
|
|
664
|
+
console.log(` ${step.icon || "\u{1F539}"} ${import_chalk5.default.bold(`T-${stepNum}`)}: ${step.title}`);
|
|
665
|
+
if (step.verification_path) {
|
|
666
|
+
console.log(` ${import_chalk5.default.dim(`Verify: ${step.verification_path}`)}`);
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
console.log("");
|
|
670
|
+
console.log(import_chalk5.default.dim("To execute this plan, run without --simulate."));
|
|
671
|
+
return true;
|
|
672
|
+
}
|
|
646
673
|
console.log(import_chalk5.default.bold.green("\u2705 GENESIS COMPLETE"));
|
|
647
674
|
console.log(import_chalk5.default.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"));
|
|
648
675
|
console.log(`${import_chalk5.default.bold("Project:")} ${import_chalk5.default.cyan(data.project_name)}`);
|
|
@@ -1132,7 +1159,7 @@ var require_package = __commonJS({
|
|
|
1132
1159
|
"package.json"(exports2, module2) {
|
|
1133
1160
|
module2.exports = {
|
|
1134
1161
|
name: "@rigstate/cli",
|
|
1135
|
-
version: "0.7.
|
|
1162
|
+
version: "0.7.38",
|
|
1136
1163
|
description: "Rigstate CLI - Code audit, sync and supervision tool",
|
|
1137
1164
|
type: "module",
|
|
1138
1165
|
main: "./dist/index.js",
|
|
@@ -1189,8 +1216,8 @@ var require_package = __commonJS({
|
|
|
1189
1216
|
|
|
1190
1217
|
// src/index.ts
|
|
1191
1218
|
init_cjs_shims();
|
|
1192
|
-
var
|
|
1193
|
-
var
|
|
1219
|
+
var import_commander27 = require("commander");
|
|
1220
|
+
var import_chalk39 = __toESM(require("chalk"), 1);
|
|
1194
1221
|
|
|
1195
1222
|
// src/commands/login.ts
|
|
1196
1223
|
init_cjs_shims();
|
|
@@ -1358,9 +1385,9 @@ function createLinkCommand() {
|
|
|
1358
1385
|
});
|
|
1359
1386
|
}
|
|
1360
1387
|
async function hardenGitIgnore(cwd) {
|
|
1361
|
-
const
|
|
1362
|
-
const
|
|
1363
|
-
const ignorePath =
|
|
1388
|
+
const fs27 = await import("fs/promises");
|
|
1389
|
+
const path29 = await import("path");
|
|
1390
|
+
const ignorePath = path29.join(cwd, ".gitignore");
|
|
1364
1391
|
const REQUIRED_IGNORES = [
|
|
1365
1392
|
"# Rigstate - Runtime Artifacts (Do not commit)",
|
|
1366
1393
|
".rigstate/ACTIVE_VIOLATIONS.md",
|
|
@@ -1375,7 +1402,7 @@ async function hardenGitIgnore(cwd) {
|
|
|
1375
1402
|
try {
|
|
1376
1403
|
let content = "";
|
|
1377
1404
|
try {
|
|
1378
|
-
content = await
|
|
1405
|
+
content = await fs27.readFile(ignorePath, "utf-8");
|
|
1379
1406
|
} catch {
|
|
1380
1407
|
content = "";
|
|
1381
1408
|
}
|
|
@@ -1383,7 +1410,7 @@ async function hardenGitIgnore(cwd) {
|
|
|
1383
1410
|
if (missing.length > 0) {
|
|
1384
1411
|
console.log(import_chalk7.default.dim(" Configuring .gitignore for Rigstate safety..."));
|
|
1385
1412
|
const toAppend = "\n\n" + REQUIRED_IGNORES.join("\n") + "\n";
|
|
1386
|
-
await
|
|
1413
|
+
await fs27.writeFile(ignorePath, content + toAppend, "utf-8");
|
|
1387
1414
|
console.log(import_chalk7.default.green(" \u2714 .gitignore updated (Artifacts protected)"));
|
|
1388
1415
|
} else {
|
|
1389
1416
|
console.log(import_chalk7.default.green(" \u2714 .gitignore already hardened"));
|
|
@@ -1393,21 +1420,21 @@ async function hardenGitIgnore(cwd) {
|
|
|
1393
1420
|
}
|
|
1394
1421
|
}
|
|
1395
1422
|
async function installHooks(cwd) {
|
|
1396
|
-
const
|
|
1397
|
-
const
|
|
1423
|
+
const fs27 = await import("fs/promises");
|
|
1424
|
+
const path29 = await import("path");
|
|
1398
1425
|
try {
|
|
1399
|
-
await
|
|
1426
|
+
await fs27.access(path29.join(cwd, ".git"));
|
|
1400
1427
|
} catch {
|
|
1401
1428
|
console.log(import_chalk7.default.dim(" (Not a git repository, skipping hooks)"));
|
|
1402
1429
|
return;
|
|
1403
1430
|
}
|
|
1404
|
-
const hooksDir =
|
|
1431
|
+
const hooksDir = path29.join(cwd, ".husky");
|
|
1405
1432
|
try {
|
|
1406
|
-
const preCommitPath =
|
|
1433
|
+
const preCommitPath = path29.join(cwd, ".git/hooks/pre-commit");
|
|
1407
1434
|
let shouldInstall = false;
|
|
1408
1435
|
try {
|
|
1409
|
-
await
|
|
1410
|
-
const content = await
|
|
1436
|
+
await fs27.access(preCommitPath);
|
|
1437
|
+
const content = await fs27.readFile(preCommitPath, "utf-8");
|
|
1411
1438
|
if (content.includes("rigstate")) {
|
|
1412
1439
|
console.log(import_chalk7.default.green(" \u2714 Git hooks already active"));
|
|
1413
1440
|
} else {
|
|
@@ -1431,12 +1458,12 @@ echo "\u{1F6E1}\uFE0F Running Guardian checks..."
|
|
|
1431
1458
|
rigstate check --staged --strict=critical
|
|
1432
1459
|
exit $?
|
|
1433
1460
|
`;
|
|
1434
|
-
await
|
|
1461
|
+
await fs27.mkdir(path29.dirname(preCommitPath), { recursive: true });
|
|
1435
1462
|
if (await fileExists(preCommitPath)) {
|
|
1436
|
-
const existing = await
|
|
1437
|
-
await
|
|
1463
|
+
const existing = await fs27.readFile(preCommitPath, "utf-8");
|
|
1464
|
+
await fs27.writeFile(preCommitPath, existing + "\n\n" + PRE_COMMIT_SCRIPT2.replace("#!/bin/sh\n", ""), { mode: 493 });
|
|
1438
1465
|
} else {
|
|
1439
|
-
await
|
|
1466
|
+
await fs27.writeFile(preCommitPath, PRE_COMMIT_SCRIPT2, { mode: 493 });
|
|
1440
1467
|
}
|
|
1441
1468
|
console.log(import_chalk7.default.green(" \u2714 Applied Guardian protection (git-hooks)"));
|
|
1442
1469
|
}
|
|
@@ -1444,10 +1471,10 @@ exit $?
|
|
|
1444
1471
|
console.log(import_chalk7.default.dim(" (Skipped hooks: " + e.message + ")"));
|
|
1445
1472
|
}
|
|
1446
1473
|
}
|
|
1447
|
-
async function fileExists(
|
|
1448
|
-
const
|
|
1474
|
+
async function fileExists(path29) {
|
|
1475
|
+
const fs27 = await import("fs/promises");
|
|
1449
1476
|
try {
|
|
1450
|
-
await
|
|
1477
|
+
await fs27.access(path29);
|
|
1451
1478
|
return true;
|
|
1452
1479
|
} catch {
|
|
1453
1480
|
return false;
|
|
@@ -3497,7 +3524,7 @@ var KnowledgeHarvester = class extends import_events3.EventEmitter {
|
|
|
3497
3524
|
pollInterval: 100
|
|
3498
3525
|
}
|
|
3499
3526
|
});
|
|
3500
|
-
this.watcher.on("add", (
|
|
3527
|
+
this.watcher.on("add", (path29) => this.handleFileEvent(path29, "add")).on("change", (path29) => this.handleFileEvent(path29, "change"));
|
|
3501
3528
|
this.isReady = true;
|
|
3502
3529
|
}
|
|
3503
3530
|
async stop() {
|
|
@@ -3689,7 +3716,7 @@ var GuardianDaemon = class extends import_events4.EventEmitter {
|
|
|
3689
3716
|
setupFileWatcher() {
|
|
3690
3717
|
Logger.info("Starting file watcher...");
|
|
3691
3718
|
this.fileWatcher = createFileWatcher(this.config.watchPath);
|
|
3692
|
-
this.fileWatcher.on("change", (
|
|
3719
|
+
this.fileWatcher.on("change", (path29) => this.handleFileChange(path29));
|
|
3693
3720
|
this.fileWatcher.start();
|
|
3694
3721
|
Logger.info("File watcher active");
|
|
3695
3722
|
}
|
|
@@ -5392,16 +5419,310 @@ Council session aborted: ${e.message}`));
|
|
|
5392
5419
|
});
|
|
5393
5420
|
}
|
|
5394
5421
|
function sleep(ms) {
|
|
5395
|
-
return new Promise((
|
|
5422
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
5396
5423
|
}
|
|
5397
5424
|
|
|
5398
5425
|
// src/index.ts
|
|
5399
5426
|
init_genesis();
|
|
5427
|
+
|
|
5428
|
+
// src/commands/remember.ts
|
|
5429
|
+
init_cjs_shims();
|
|
5430
|
+
var import_commander25 = require("commander");
|
|
5431
|
+
var import_chalk37 = __toESM(require("chalk"), 1);
|
|
5432
|
+
|
|
5433
|
+
// src/utils/memory-store.ts
|
|
5434
|
+
init_cjs_shims();
|
|
5435
|
+
var fs26 = __toESM(require("fs"), 1);
|
|
5436
|
+
var path28 = __toESM(require("path"), 1);
|
|
5437
|
+
var import_crypto2 = require("crypto");
|
|
5438
|
+
var MEMORIES_DIR = ".rigstate/memories";
|
|
5439
|
+
function getMemoriesDir() {
|
|
5440
|
+
const dir = path28.resolve(process.cwd(), MEMORIES_DIR);
|
|
5441
|
+
if (!fs26.existsSync(dir)) {
|
|
5442
|
+
fs26.mkdirSync(dir, { recursive: true });
|
|
5443
|
+
}
|
|
5444
|
+
return dir;
|
|
5445
|
+
}
|
|
5446
|
+
function saveMemory(input) {
|
|
5447
|
+
const dir = getMemoriesDir();
|
|
5448
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5449
|
+
const memory = {
|
|
5450
|
+
id: (0, import_crypto2.randomUUID)(),
|
|
5451
|
+
...input,
|
|
5452
|
+
title: input.title,
|
|
5453
|
+
content: input.content,
|
|
5454
|
+
category: input.category || "CONTEXT",
|
|
5455
|
+
source: input.source || "USER",
|
|
5456
|
+
tags: input.tags || [],
|
|
5457
|
+
importance: input.importance || 5,
|
|
5458
|
+
confidence: input.confidence || 1,
|
|
5459
|
+
created_at: now,
|
|
5460
|
+
updated_at: now,
|
|
5461
|
+
expires_at: input.expires_at || null
|
|
5462
|
+
};
|
|
5463
|
+
const filename = `${memory.id}.json`;
|
|
5464
|
+
const filepath = path28.join(dir, filename);
|
|
5465
|
+
fs26.writeFileSync(filepath, JSON.stringify(memory, null, 2), "utf-8");
|
|
5466
|
+
return memory;
|
|
5467
|
+
}
|
|
5468
|
+
function loadAllMemories() {
|
|
5469
|
+
const dir = getMemoriesDir();
|
|
5470
|
+
const files = fs26.readdirSync(dir).filter((f) => f.endsWith(".json"));
|
|
5471
|
+
const memories = [];
|
|
5472
|
+
for (const file of files) {
|
|
5473
|
+
try {
|
|
5474
|
+
const raw = fs26.readFileSync(path28.join(dir, file), "utf-8");
|
|
5475
|
+
memories.push(JSON.parse(raw));
|
|
5476
|
+
} catch {
|
|
5477
|
+
}
|
|
5478
|
+
}
|
|
5479
|
+
return memories;
|
|
5480
|
+
}
|
|
5481
|
+
function searchMemories(query, limit = 5) {
|
|
5482
|
+
const memories = loadAllMemories();
|
|
5483
|
+
const tokens = tokenize(query);
|
|
5484
|
+
if (tokens.length === 0) return [];
|
|
5485
|
+
const results = [];
|
|
5486
|
+
for (const memory of memories) {
|
|
5487
|
+
if (memory.expires_at && new Date(memory.expires_at) < /* @__PURE__ */ new Date()) {
|
|
5488
|
+
continue;
|
|
5489
|
+
}
|
|
5490
|
+
let score = 0;
|
|
5491
|
+
const matchedFields = [];
|
|
5492
|
+
const titleTokens = tokenize(memory.title);
|
|
5493
|
+
const titleMatches = tokens.filter((t) => titleTokens.includes(t)).length;
|
|
5494
|
+
if (titleMatches > 0) {
|
|
5495
|
+
score += titleMatches * 3;
|
|
5496
|
+
matchedFields.push("title");
|
|
5497
|
+
}
|
|
5498
|
+
const contentLower = memory.content.toLowerCase();
|
|
5499
|
+
const contentMatches = tokens.filter((t) => contentLower.includes(t)).length;
|
|
5500
|
+
if (contentMatches > 0) {
|
|
5501
|
+
score += contentMatches * 1;
|
|
5502
|
+
matchedFields.push("content");
|
|
5503
|
+
}
|
|
5504
|
+
const tagLower = memory.tags.map((t) => t.toLowerCase());
|
|
5505
|
+
const tagMatches = tokens.filter((t) => tagLower.includes(t)).length;
|
|
5506
|
+
if (tagMatches > 0) {
|
|
5507
|
+
score += tagMatches * 4;
|
|
5508
|
+
matchedFields.push("tags");
|
|
5509
|
+
}
|
|
5510
|
+
if (tokens.includes(memory.category.toLowerCase())) {
|
|
5511
|
+
score += 2;
|
|
5512
|
+
matchedFields.push("category");
|
|
5513
|
+
}
|
|
5514
|
+
score *= memory.importance / 5;
|
|
5515
|
+
if (score > 0) {
|
|
5516
|
+
results.push({ memory, score, matchedFields });
|
|
5517
|
+
}
|
|
5518
|
+
}
|
|
5519
|
+
return results.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5520
|
+
}
|
|
5521
|
+
function getMemoryStats() {
|
|
5522
|
+
const memories = loadAllMemories();
|
|
5523
|
+
const byCategory = {};
|
|
5524
|
+
for (const m of memories) {
|
|
5525
|
+
byCategory[m.category] = (byCategory[m.category] || 0) + 1;
|
|
5526
|
+
}
|
|
5527
|
+
return { total: memories.length, byCategory };
|
|
5528
|
+
}
|
|
5529
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
5530
|
+
"the",
|
|
5531
|
+
"a",
|
|
5532
|
+
"an",
|
|
5533
|
+
"is",
|
|
5534
|
+
"are",
|
|
5535
|
+
"was",
|
|
5536
|
+
"were",
|
|
5537
|
+
"in",
|
|
5538
|
+
"on",
|
|
5539
|
+
"at",
|
|
5540
|
+
"to",
|
|
5541
|
+
"for",
|
|
5542
|
+
"of",
|
|
5543
|
+
"with",
|
|
5544
|
+
"by",
|
|
5545
|
+
"from",
|
|
5546
|
+
"and",
|
|
5547
|
+
"or",
|
|
5548
|
+
"not",
|
|
5549
|
+
"this",
|
|
5550
|
+
"that",
|
|
5551
|
+
"it",
|
|
5552
|
+
"we",
|
|
5553
|
+
"you",
|
|
5554
|
+
"they",
|
|
5555
|
+
"my",
|
|
5556
|
+
"our",
|
|
5557
|
+
"your",
|
|
5558
|
+
"its",
|
|
5559
|
+
"his",
|
|
5560
|
+
"her",
|
|
5561
|
+
"how",
|
|
5562
|
+
"what",
|
|
5563
|
+
"why",
|
|
5564
|
+
"when",
|
|
5565
|
+
"where",
|
|
5566
|
+
"which",
|
|
5567
|
+
"who",
|
|
5568
|
+
"do",
|
|
5569
|
+
"does",
|
|
5570
|
+
"did",
|
|
5571
|
+
"has",
|
|
5572
|
+
"have",
|
|
5573
|
+
"had",
|
|
5574
|
+
"be",
|
|
5575
|
+
"been",
|
|
5576
|
+
"being",
|
|
5577
|
+
"will",
|
|
5578
|
+
"would",
|
|
5579
|
+
"can",
|
|
5580
|
+
"could",
|
|
5581
|
+
"should",
|
|
5582
|
+
"shall",
|
|
5583
|
+
"may",
|
|
5584
|
+
"might",
|
|
5585
|
+
"must",
|
|
5586
|
+
"vi",
|
|
5587
|
+
"er",
|
|
5588
|
+
"var",
|
|
5589
|
+
"har",
|
|
5590
|
+
"den",
|
|
5591
|
+
"det",
|
|
5592
|
+
"en",
|
|
5593
|
+
"et",
|
|
5594
|
+
"og",
|
|
5595
|
+
"i",
|
|
5596
|
+
"p\xE5",
|
|
5597
|
+
"til",
|
|
5598
|
+
"fra",
|
|
5599
|
+
"med",
|
|
5600
|
+
"som",
|
|
5601
|
+
"om",
|
|
5602
|
+
"for",
|
|
5603
|
+
"av",
|
|
5604
|
+
"ikke",
|
|
5605
|
+
"hvorfor",
|
|
5606
|
+
"hvordan",
|
|
5607
|
+
"hva",
|
|
5608
|
+
"n\xE5r",
|
|
5609
|
+
"hvor"
|
|
5610
|
+
]);
|
|
5611
|
+
function tokenize(text) {
|
|
5612
|
+
return text.toLowerCase().replace(/[^a-zA-Z0-9æøåÆØÅ\s]/g, " ").split(/\s+/).filter((t) => t.length > 1 && !STOP_WORDS.has(t));
|
|
5613
|
+
}
|
|
5614
|
+
|
|
5615
|
+
// src/commands/remember.ts
|
|
5616
|
+
init_config();
|
|
5617
|
+
function createRememberCommand() {
|
|
5618
|
+
return new import_commander25.Command("remember").description("Save a memory to the local knowledge base (.rigstate/memories/)").argument("<text>", "The memory content to save").option("-t, --title <title>", "Title for the memory (defaults to first 60 chars of text)").option("-c, --category <category>", "Category: ADR, DECISION, LESSON, CONTEXT, INSTRUCTION, PATTERN, GOTCHA", "CONTEXT").option("--tags <tags>", 'Comma-separated tags (e.g. "supabase,architecture")').option("-i, --importance <n>", "Importance 1-10 (default: 5)", "5").option("--source <source>", "Source: USER, AGENT, COUNCIL, GOVERNANCE, HARVEST, IMPORT", "USER").action(async (text, options) => {
|
|
5619
|
+
try {
|
|
5620
|
+
const projectId = getProjectId();
|
|
5621
|
+
const title = options.title || text.substring(0, 60) + (text.length > 60 ? "..." : "");
|
|
5622
|
+
const tags = options.tags ? options.tags.split(",").map((t) => t.trim()) : [];
|
|
5623
|
+
const importance = Math.min(10, Math.max(1, parseInt(options.importance, 10) || 5));
|
|
5624
|
+
const memory = saveMemory({
|
|
5625
|
+
title,
|
|
5626
|
+
content: text,
|
|
5627
|
+
category: options.category || "CONTEXT",
|
|
5628
|
+
source: options.source || "USER",
|
|
5629
|
+
tags,
|
|
5630
|
+
importance,
|
|
5631
|
+
project_id: projectId || void 0
|
|
5632
|
+
});
|
|
5633
|
+
console.log("");
|
|
5634
|
+
console.log(import_chalk37.default.bold.green("\u{1F9E0} Memory Saved"));
|
|
5635
|
+
console.log(import_chalk37.default.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"));
|
|
5636
|
+
console.log(`${import_chalk37.default.bold("ID:")} ${import_chalk37.default.dim(memory.id)}`);
|
|
5637
|
+
console.log(`${import_chalk37.default.bold("Title:")} ${import_chalk37.default.cyan(memory.title)}`);
|
|
5638
|
+
console.log(`${import_chalk37.default.bold("Category:")} ${import_chalk37.default.magenta(memory.category)}`);
|
|
5639
|
+
console.log(`${import_chalk37.default.bold("Importance:")} ${"\u2B50".repeat(Math.min(5, Math.ceil(importance / 2)))} (${importance}/10)`);
|
|
5640
|
+
if (tags.length > 0) {
|
|
5641
|
+
console.log(`${import_chalk37.default.bold("Tags:")} ${tags.map((t) => import_chalk37.default.yellow(`#${t}`)).join(" ")}`);
|
|
5642
|
+
}
|
|
5643
|
+
console.log(import_chalk37.default.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"));
|
|
5644
|
+
const stats = getMemoryStats();
|
|
5645
|
+
console.log(import_chalk37.default.dim(`Total memories: ${stats.total}`));
|
|
5646
|
+
console.log("");
|
|
5647
|
+
} catch (err) {
|
|
5648
|
+
console.error(import_chalk37.default.red(`\u274C Failed to save memory: ${err.message}`));
|
|
5649
|
+
process.exit(1);
|
|
5650
|
+
}
|
|
5651
|
+
});
|
|
5652
|
+
}
|
|
5653
|
+
|
|
5654
|
+
// src/commands/ask.ts
|
|
5655
|
+
init_cjs_shims();
|
|
5656
|
+
var import_commander26 = require("commander");
|
|
5657
|
+
var import_chalk38 = __toESM(require("chalk"), 1);
|
|
5658
|
+
function createAskCommand() {
|
|
5659
|
+
return new import_commander26.Command("ask").description("Search local memories instantly (<10ms, offline)").argument("<query>", "Natural language query to search memories").option("-n, --limit <n>", "Maximum results to return", "5").action(async (query, options) => {
|
|
5660
|
+
const limit = parseInt(options.limit, 10) || 5;
|
|
5661
|
+
const startTime = performance.now();
|
|
5662
|
+
const results = searchMemories(query, limit);
|
|
5663
|
+
const elapsed = (performance.now() - startTime).toFixed(1);
|
|
5664
|
+
console.log("");
|
|
5665
|
+
if (results.length === 0) {
|
|
5666
|
+
const stats2 = getMemoryStats();
|
|
5667
|
+
console.log(import_chalk38.default.yellow(`\u{1F50D} No memories found for: "${query}"`));
|
|
5668
|
+
console.log(import_chalk38.default.dim(` Searched ${stats2.total} memories in ${elapsed}ms.`));
|
|
5669
|
+
if (stats2.total === 0) {
|
|
5670
|
+
console.log("");
|
|
5671
|
+
console.log(import_chalk38.default.dim(" No memories yet. Start with:"));
|
|
5672
|
+
console.log(import_chalk38.default.white(' rigstate remember "We chose Supabase for real-time and RLS"'));
|
|
5673
|
+
}
|
|
5674
|
+
console.log("");
|
|
5675
|
+
return;
|
|
5676
|
+
}
|
|
5677
|
+
console.log(import_chalk38.default.bold(`\u{1F9E0} ${results.length} memor${results.length === 1 ? "y" : "ies"} found`) + import_chalk38.default.dim(` (${elapsed}ms)`));
|
|
5678
|
+
console.log(import_chalk38.default.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"));
|
|
5679
|
+
for (const { memory, score, matchedFields } of results) {
|
|
5680
|
+
const categoryColor = getCategoryColor(memory.category);
|
|
5681
|
+
const stars = "\u2B50".repeat(Math.min(5, Math.ceil((memory.importance || 5) / 2)));
|
|
5682
|
+
console.log("");
|
|
5683
|
+
console.log(` ${categoryColor(memory.category)} ${import_chalk38.default.bold(memory.title)} ${import_chalk38.default.dim(`[${stars}]`)}`);
|
|
5684
|
+
const preview = memory.content.length > 120 ? memory.content.substring(0, 120) + "..." : memory.content;
|
|
5685
|
+
console.log(` ${import_chalk38.default.white(preview)}`);
|
|
5686
|
+
if (memory.tags && memory.tags.length > 0) {
|
|
5687
|
+
console.log(` ${memory.tags.map((t) => import_chalk38.default.yellow(`#${t}`)).join(" ")}`);
|
|
5688
|
+
}
|
|
5689
|
+
const meta = [
|
|
5690
|
+
import_chalk38.default.dim(`score:${score.toFixed(1)}`),
|
|
5691
|
+
import_chalk38.default.dim(`matched:${matchedFields.join(",")}`),
|
|
5692
|
+
import_chalk38.default.dim(`source:${memory.source}`)
|
|
5693
|
+
];
|
|
5694
|
+
if (memory.created_at) {
|
|
5695
|
+
const date = new Date(memory.created_at).toLocaleDateString("nb-NO");
|
|
5696
|
+
meta.push(import_chalk38.default.dim(`date:${date}`));
|
|
5697
|
+
}
|
|
5698
|
+
console.log(` ${meta.join(" ")}`);
|
|
5699
|
+
}
|
|
5700
|
+
console.log("");
|
|
5701
|
+
console.log(import_chalk38.default.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"));
|
|
5702
|
+
const stats = getMemoryStats();
|
|
5703
|
+
console.log(import_chalk38.default.dim(`Searched ${stats.total} memories in ${elapsed}ms`));
|
|
5704
|
+
console.log("");
|
|
5705
|
+
});
|
|
5706
|
+
}
|
|
5707
|
+
function getCategoryColor(category) {
|
|
5708
|
+
const colors = {
|
|
5709
|
+
"ADR": import_chalk38.default.bgBlue.white,
|
|
5710
|
+
"DECISION": import_chalk38.default.bgCyan.black,
|
|
5711
|
+
"LESSON": import_chalk38.default.bgYellow.black,
|
|
5712
|
+
"CONTEXT": import_chalk38.default.bgGreen.black,
|
|
5713
|
+
"INSTRUCTION": import_chalk38.default.bgMagenta.white,
|
|
5714
|
+
"PATTERN": import_chalk38.default.bgWhite.black,
|
|
5715
|
+
"GOTCHA": import_chalk38.default.bgRed.white
|
|
5716
|
+
};
|
|
5717
|
+
return colors[category] || import_chalk38.default.dim;
|
|
5718
|
+
}
|
|
5719
|
+
|
|
5720
|
+
// src/index.ts
|
|
5400
5721
|
init_version();
|
|
5401
5722
|
var import_dotenv = __toESM(require("dotenv"), 1);
|
|
5402
5723
|
var pkg = require_package();
|
|
5403
5724
|
import_dotenv.default.config();
|
|
5404
|
-
var program = new
|
|
5725
|
+
var program = new import_commander27.Command();
|
|
5405
5726
|
program.name("rigstate").description("CLI for Rigstate - The AI-Native Dev Studio").version(pkg.version);
|
|
5406
5727
|
program.addCommand(createLoginCommand());
|
|
5407
5728
|
program.addCommand(createLinkCommand());
|
|
@@ -5427,30 +5748,32 @@ program.addCommand(createRoadmapCommand());
|
|
|
5427
5748
|
program.addCommand(createCouncilCommand());
|
|
5428
5749
|
program.addCommand(createPlanCommand());
|
|
5429
5750
|
program.addCommand(createGenesisCommand());
|
|
5751
|
+
program.addCommand(createRememberCommand());
|
|
5752
|
+
program.addCommand(createAskCommand());
|
|
5430
5753
|
program.hook("preAction", async () => {
|
|
5431
5754
|
await checkVersion();
|
|
5432
5755
|
});
|
|
5433
5756
|
program.on("--help", () => {
|
|
5434
5757
|
console.log("");
|
|
5435
|
-
console.log(
|
|
5758
|
+
console.log(import_chalk39.default.bold("Examples:"));
|
|
5436
5759
|
console.log("");
|
|
5437
|
-
console.log(
|
|
5438
|
-
console.log(
|
|
5760
|
+
console.log(import_chalk39.default.cyan(" $ rigstate login sk_rigstate_your_api_key"));
|
|
5761
|
+
console.log(import_chalk39.default.dim(" Authenticate with your Rigstate API key"));
|
|
5439
5762
|
console.log("");
|
|
5440
|
-
console.log(
|
|
5441
|
-
console.log(
|
|
5763
|
+
console.log(import_chalk39.default.cyan(" $ rigstate scan"));
|
|
5764
|
+
console.log(import_chalk39.default.dim(" Scan the current directory"));
|
|
5442
5765
|
console.log("");
|
|
5443
|
-
console.log(
|
|
5444
|
-
console.log(
|
|
5766
|
+
console.log(import_chalk39.default.cyan(" $ rigstate genesis"));
|
|
5767
|
+
console.log(import_chalk39.default.dim(" Initialize project foundation (auto-detects stack)"));
|
|
5445
5768
|
console.log("");
|
|
5446
|
-
console.log(
|
|
5447
|
-
console.log(
|
|
5769
|
+
console.log(import_chalk39.default.cyan(" $ rigstate genesis --status"));
|
|
5770
|
+
console.log(import_chalk39.default.dim(" Check genesis status without triggering"));
|
|
5448
5771
|
console.log("");
|
|
5449
|
-
console.log(
|
|
5450
|
-
console.log(
|
|
5772
|
+
console.log(import_chalk39.default.cyan(" $ rigstate scan ./src --project abc123"));
|
|
5773
|
+
console.log(import_chalk39.default.dim(" Scan a specific directory with project ID"));
|
|
5451
5774
|
console.log("");
|
|
5452
|
-
console.log(
|
|
5453
|
-
console.log(
|
|
5775
|
+
console.log(import_chalk39.default.cyan(" $ rigstate scan --json"));
|
|
5776
|
+
console.log(import_chalk39.default.dim(" Output results in JSON format (useful for IDE extensions)"));
|
|
5454
5777
|
console.log("");
|
|
5455
5778
|
});
|
|
5456
5779
|
program.parse(process.argv);
|