@rigstate/cli 0.7.34 → 0.7.35
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 +812 -712
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +851 -752
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/commands/env.ts +3 -6
- package/src/commands/focus.ts +3 -6
- package/src/commands/init.ts +4 -5
- package/src/commands/link.ts +8 -18
- package/src/commands/plan.ts +20 -3
- package/src/commands/sync.ts +7 -12
- package/src/commands/watch.ts +3 -7
- package/src/utils/config.ts +79 -4
- package/src/utils/manifest.ts +56 -5
package/dist/index.js
CHANGED
|
@@ -63,7 +63,28 @@ __export(config_exports, {
|
|
|
63
63
|
setProjectId: () => setProjectId
|
|
64
64
|
});
|
|
65
65
|
import Conf from "conf";
|
|
66
|
+
import chalk from "chalk";
|
|
67
|
+
import fs from "fs";
|
|
68
|
+
import path2 from "path";
|
|
66
69
|
function getApiKey() {
|
|
70
|
+
try {
|
|
71
|
+
const cwd = process.cwd();
|
|
72
|
+
const manifestPaths = [
|
|
73
|
+
path2.join(cwd, ".rigstate", "identity.json"),
|
|
74
|
+
path2.join(cwd, ".rigstate")
|
|
75
|
+
];
|
|
76
|
+
for (const manifestPath of manifestPaths) {
|
|
77
|
+
if (fs.existsSync(manifestPath) && fs.statSync(manifestPath).isFile()) {
|
|
78
|
+
const content = fs.readFileSync(manifestPath, "utf-8");
|
|
79
|
+
const manifest = JSON.parse(content);
|
|
80
|
+
if (manifest.api_key) return manifest.api_key;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} catch (e) {
|
|
84
|
+
}
|
|
85
|
+
if (process.env.RIGSTATE_API_KEY) {
|
|
86
|
+
return process.env.RIGSTATE_API_KEY;
|
|
87
|
+
}
|
|
67
88
|
const apiKey = config.get("apiKey");
|
|
68
89
|
if (!apiKey) {
|
|
69
90
|
throw new Error(
|
|
@@ -76,12 +97,54 @@ function setApiKey(key) {
|
|
|
76
97
|
config.set("apiKey", key);
|
|
77
98
|
}
|
|
78
99
|
function getProjectId() {
|
|
79
|
-
|
|
100
|
+
try {
|
|
101
|
+
const cwd = process.cwd();
|
|
102
|
+
const manifestPaths = [
|
|
103
|
+
path2.join(cwd, ".rigstate", "identity.json"),
|
|
104
|
+
path2.join(cwd, ".rigstate")
|
|
105
|
+
];
|
|
106
|
+
for (const manifestPath of manifestPaths) {
|
|
107
|
+
if (fs.existsSync(manifestPath) && fs.statSync(manifestPath).isFile()) {
|
|
108
|
+
const content = fs.readFileSync(manifestPath, "utf-8");
|
|
109
|
+
const manifest = JSON.parse(content);
|
|
110
|
+
if (manifest.project_id) {
|
|
111
|
+
console.log(chalk.dim(` [Auth] Context: Project ID ${manifest.project_id.substring(0, 8)}... (from ${path2.basename(manifestPath)})`));
|
|
112
|
+
return manifest.project_id;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} catch (e) {
|
|
117
|
+
console.log(chalk.red(` [Error] Failed to read context: ${e.message}`));
|
|
118
|
+
}
|
|
119
|
+
if (process.env.RIGSTATE_PROJECT_ID) {
|
|
120
|
+
console.log(chalk.dim(` [Auth] Context: Project ID ${process.env.RIGSTATE_PROJECT_ID.substring(0, 8)}... (from ENV)`));
|
|
121
|
+
return process.env.RIGSTATE_PROJECT_ID;
|
|
122
|
+
}
|
|
123
|
+
const globalId = config.get("projectId");
|
|
124
|
+
if (globalId) {
|
|
125
|
+
console.log(chalk.dim(` [Auth] Context: Project ID ${globalId.substring(0, 8)}... (from GLOBAL CONFIG)`));
|
|
126
|
+
}
|
|
127
|
+
return globalId;
|
|
80
128
|
}
|
|
81
129
|
function setProjectId(projectId) {
|
|
82
130
|
config.set("projectId", projectId);
|
|
83
131
|
}
|
|
84
132
|
function getApiUrl() {
|
|
133
|
+
try {
|
|
134
|
+
const cwd = process.cwd();
|
|
135
|
+
const manifestPaths = [
|
|
136
|
+
path2.join(cwd, ".rigstate", "identity.json"),
|
|
137
|
+
path2.join(cwd, ".rigstate")
|
|
138
|
+
];
|
|
139
|
+
for (const manifestPath of manifestPaths) {
|
|
140
|
+
if (fs.existsSync(manifestPath) && fs.statSync(manifestPath).isFile()) {
|
|
141
|
+
const content = fs.readFileSync(manifestPath, "utf-8");
|
|
142
|
+
const manifest = JSON.parse(content);
|
|
143
|
+
if (manifest.api_url) return manifest.api_url;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch (e) {
|
|
147
|
+
}
|
|
85
148
|
if (process.env.RIGSTATE_API_URL) {
|
|
86
149
|
return process.env.RIGSTATE_API_URL;
|
|
87
150
|
}
|
|
@@ -111,6 +174,65 @@ var init_config = __esm({
|
|
|
111
174
|
}
|
|
112
175
|
});
|
|
113
176
|
|
|
177
|
+
// src/utils/manifest.ts
|
|
178
|
+
var manifest_exports = {};
|
|
179
|
+
__export(manifest_exports, {
|
|
180
|
+
loadManifest: () => loadManifest,
|
|
181
|
+
saveManifest: () => saveManifest
|
|
182
|
+
});
|
|
183
|
+
import fs2 from "fs/promises";
|
|
184
|
+
import fsSync from "fs";
|
|
185
|
+
import path3 from "path";
|
|
186
|
+
async function loadManifest() {
|
|
187
|
+
const cwd = process.cwd();
|
|
188
|
+
const manifestPaths = [
|
|
189
|
+
path3.join(cwd, ".rigstate", "identity.json"),
|
|
190
|
+
path3.join(cwd, ".rigstate")
|
|
191
|
+
];
|
|
192
|
+
for (const p of manifestPaths) {
|
|
193
|
+
try {
|
|
194
|
+
if (fsSync.existsSync(p) && fsSync.statSync(p).isFile()) {
|
|
195
|
+
const content = await fs2.readFile(p, "utf-8");
|
|
196
|
+
const data = JSON.parse(content);
|
|
197
|
+
return {
|
|
198
|
+
project_id: data.project?.id || data.project_id,
|
|
199
|
+
api_url: data.api_url,
|
|
200
|
+
linked_at: data.linked_at || data.project?.created_at,
|
|
201
|
+
api_key: data.api_key
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
} catch (e) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
async function saveManifest(data) {
|
|
211
|
+
const cwd = process.cwd();
|
|
212
|
+
const rigstatePath = path3.join(cwd, ".rigstate");
|
|
213
|
+
let targetFile = rigstatePath;
|
|
214
|
+
try {
|
|
215
|
+
const stats = await fs2.stat(rigstatePath);
|
|
216
|
+
if (stats.isDirectory()) {
|
|
217
|
+
targetFile = path3.join(rigstatePath, "identity.json");
|
|
218
|
+
}
|
|
219
|
+
} catch (e) {
|
|
220
|
+
}
|
|
221
|
+
const existing = await loadManifest() || {};
|
|
222
|
+
const merged = { ...existing, ...data };
|
|
223
|
+
if (targetFile.endsWith("identity.json")) {
|
|
224
|
+
await fs2.mkdir(rigstatePath, { recursive: true });
|
|
225
|
+
}
|
|
226
|
+
await fs2.writeFile(targetFile, JSON.stringify(merged, null, 2), "utf-8");
|
|
227
|
+
return targetFile;
|
|
228
|
+
}
|
|
229
|
+
var init_manifest = __esm({
|
|
230
|
+
"src/utils/manifest.ts"() {
|
|
231
|
+
"use strict";
|
|
232
|
+
init_esm_shims();
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
114
236
|
// src/commands/env.ts
|
|
115
237
|
var env_exports = {};
|
|
116
238
|
__export(env_exports, {
|
|
@@ -118,17 +240,17 @@ __export(env_exports, {
|
|
|
118
240
|
syncEnv: () => syncEnv
|
|
119
241
|
});
|
|
120
242
|
import { Command as Command2 } from "commander";
|
|
121
|
-
import
|
|
243
|
+
import chalk3 from "chalk";
|
|
122
244
|
import ora from "ora";
|
|
123
|
-
import
|
|
124
|
-
import
|
|
245
|
+
import fs3 from "fs/promises";
|
|
246
|
+
import path4 from "path";
|
|
125
247
|
import axios from "axios";
|
|
126
248
|
async function syncEnv(projectId, apiKey, apiUrl, silent = false) {
|
|
127
249
|
if (!silent) {
|
|
128
250
|
console.log("");
|
|
129
|
-
console.log(
|
|
130
|
-
console.log(
|
|
131
|
-
console.log(
|
|
251
|
+
console.log(chalk3.bold.yellow("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
252
|
+
console.log(chalk3.bold.yellow("\u2551") + chalk3.bold.white(" \u{1F6E1}\uFE0F RIGSTATE SOVEREIGN VAULT SYNC \u{1F6E1}\uFE0F ") + chalk3.bold.yellow("\u2551"));
|
|
253
|
+
console.log(chalk3.bold.yellow("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
132
254
|
console.log("");
|
|
133
255
|
}
|
|
134
256
|
const spinner = ora("Fetching secrets from Vault...").start();
|
|
@@ -145,15 +267,15 @@ async function syncEnv(projectId, apiKey, apiUrl, silent = false) {
|
|
|
145
267
|
const secretCount = response.data.data.count || 0;
|
|
146
268
|
if (secretCount === 0) {
|
|
147
269
|
spinner.info("No secrets found in Vault for this project.");
|
|
148
|
-
if (!silent) console.log(
|
|
270
|
+
if (!silent) console.log(chalk3.dim(" Add secrets via the Rigstate web interface."));
|
|
149
271
|
return true;
|
|
150
272
|
}
|
|
151
|
-
spinner.succeed(`Retrieved ${
|
|
152
|
-
const envFile =
|
|
273
|
+
spinner.succeed(`Retrieved ${chalk3.bold(secretCount)} secret(s)`);
|
|
274
|
+
const envFile = path4.resolve(process.cwd(), ".env.local");
|
|
153
275
|
let existingContent = "";
|
|
154
276
|
let existingKeys = /* @__PURE__ */ new Set();
|
|
155
277
|
try {
|
|
156
|
-
existingContent = await
|
|
278
|
+
existingContent = await fs3.readFile(envFile, "utf-8");
|
|
157
279
|
existingContent.split("\n").forEach((line) => {
|
|
158
280
|
const match = line.match(/^([A-Z_][A-Z0-9_]*)=/);
|
|
159
281
|
if (match) existingKeys.add(match[1]);
|
|
@@ -185,25 +307,25 @@ async function syncEnv(projectId, apiKey, apiUrl, silent = false) {
|
|
|
185
307
|
"# ==========================================",
|
|
186
308
|
""
|
|
187
309
|
].join("\n");
|
|
188
|
-
await
|
|
310
|
+
await fs3.writeFile(envFile, header + vaultContent + "\n");
|
|
189
311
|
spinner.succeed("Written to .env.local");
|
|
190
312
|
if (!silent) {
|
|
191
313
|
console.log("");
|
|
192
|
-
console.log(
|
|
314
|
+
console.log(chalk3.bold.green("\u2705 Environment synchronized successfully"));
|
|
193
315
|
console.log("");
|
|
194
|
-
console.log(
|
|
195
|
-
console.log(
|
|
196
|
-
console.log(
|
|
197
|
-
console.log(
|
|
316
|
+
console.log(chalk3.dim(" Summary:"));
|
|
317
|
+
console.log(chalk3.green(` + ${newCount} new`));
|
|
318
|
+
console.log(chalk3.yellow(` ~ ${updatedCount} updated`));
|
|
319
|
+
console.log(chalk3.dim(` = ${unchangedCount} unchanged`));
|
|
198
320
|
console.log("");
|
|
199
|
-
console.log(
|
|
200
|
-
console.log(
|
|
201
|
-
console.log(
|
|
321
|
+
console.log(chalk3.bold.yellow("\u26A0\uFE0F Security Reminder:"));
|
|
322
|
+
console.log(chalk3.dim(" - Never commit .env.local to version control."));
|
|
323
|
+
console.log(chalk3.dim(" - Ensure .gitignore includes .env.local"));
|
|
202
324
|
console.log("");
|
|
203
325
|
}
|
|
204
326
|
return true;
|
|
205
327
|
} catch (e) {
|
|
206
|
-
spinner.fail(
|
|
328
|
+
spinner.fail(chalk3.red(`Failed to fetch secrets: ${e.message}`));
|
|
207
329
|
return false;
|
|
208
330
|
}
|
|
209
331
|
}
|
|
@@ -215,21 +337,17 @@ function createEnvPullCommand() {
|
|
|
215
337
|
try {
|
|
216
338
|
apiKey = getApiKey();
|
|
217
339
|
} catch (e) {
|
|
218
|
-
console.error(
|
|
340
|
+
console.error(chalk3.red('Not authenticated. Run "rigstate login" first.'));
|
|
219
341
|
return;
|
|
220
342
|
}
|
|
221
343
|
projectId = getProjectId();
|
|
222
344
|
if (!projectId) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const manifest = JSON.parse(content);
|
|
227
|
-
projectId = manifest.project_id;
|
|
228
|
-
} catch (e) {
|
|
229
|
-
}
|
|
345
|
+
const { loadManifest: loadManifest2 } = await Promise.resolve().then(() => (init_manifest(), manifest_exports));
|
|
346
|
+
const manifest = await loadManifest2();
|
|
347
|
+
if (manifest?.project_id) projectId = manifest.project_id;
|
|
230
348
|
}
|
|
231
349
|
if (!projectId) {
|
|
232
|
-
console.error(
|
|
350
|
+
console.error(chalk3.red('No project context. Run "rigstate link" first.'));
|
|
233
351
|
return;
|
|
234
352
|
}
|
|
235
353
|
const apiUrl = getApiUrl();
|
|
@@ -264,7 +382,7 @@ __export(sync_rules_exports, {
|
|
|
264
382
|
syncProjectRules: () => syncProjectRules
|
|
265
383
|
});
|
|
266
384
|
import { Command as Command3 } from "commander";
|
|
267
|
-
import
|
|
385
|
+
import chalk4 from "chalk";
|
|
268
386
|
import ora2 from "ora";
|
|
269
387
|
import axios2 from "axios";
|
|
270
388
|
async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false, version = CLI_VERSION) {
|
|
@@ -282,7 +400,7 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false, versi
|
|
|
282
400
|
const project = projectRes.data.data.projects[0];
|
|
283
401
|
spinner.text = `Syncing rules for ${project.name}...`;
|
|
284
402
|
if (dryRun) {
|
|
285
|
-
spinner.succeed(
|
|
403
|
+
spinner.succeed(chalk4.yellow(` [DRY-RUN] Would sync: ${project.name}`));
|
|
286
404
|
return true;
|
|
287
405
|
}
|
|
288
406
|
const syncResponse = await axios2.post(`${apiUrl}/api/v1/rules/sync`, {
|
|
@@ -292,9 +410,9 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false, versi
|
|
|
292
410
|
});
|
|
293
411
|
if (syncResponse.data.success) {
|
|
294
412
|
if (syncResponse.data.data.github_synced) {
|
|
295
|
-
spinner.succeed(
|
|
413
|
+
spinner.succeed(chalk4.green(` \u2705 ${project.name} [${project.id}] \u2192 GitHub synced`));
|
|
296
414
|
} else {
|
|
297
|
-
spinner.info(
|
|
415
|
+
spinner.info(chalk4.blue(` \u2139\uFE0F ${project.name} [${project.id}] \u2192 Rules generated (no GitHub)`));
|
|
298
416
|
}
|
|
299
417
|
const files = syncResponse.data.data.files;
|
|
300
418
|
if (files && Array.isArray(files)) {
|
|
@@ -305,7 +423,7 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false, versi
|
|
|
305
423
|
await fs26.mkdir(path29.dirname(filePath), { recursive: true });
|
|
306
424
|
await fs26.writeFile(filePath, file.content, "utf-8");
|
|
307
425
|
}
|
|
308
|
-
console.log(
|
|
426
|
+
console.log(chalk4.dim(` \u{1F4BE} Wrote ${files.length} rule files to local .cursor/rules/`));
|
|
309
427
|
try {
|
|
310
428
|
const masterPath = path29.join(process.cwd(), ".cursorrules");
|
|
311
429
|
let masterContent = "";
|
|
@@ -340,20 +458,20 @@ ${END_MARKER}`;
|
|
|
340
458
|
${governanceBlock}` : governanceBlock;
|
|
341
459
|
}
|
|
342
460
|
await fs26.writeFile(masterPath, newContent, "utf-8");
|
|
343
|
-
console.log(
|
|
461
|
+
console.log(chalk4.dim(" \u{1F4DC} Updated master .cursorrules (Constitution enforced)"));
|
|
344
462
|
} catch (e) {
|
|
345
|
-
console.warn(
|
|
463
|
+
console.warn(chalk4.yellow(` \u26A0\uFE0F Could not update .cursorrules: ${e.message}`));
|
|
346
464
|
}
|
|
347
465
|
}
|
|
348
466
|
console.log("");
|
|
349
|
-
console.log(
|
|
350
|
-
console.log(
|
|
467
|
+
console.log(chalk4.cyan("\u{1F6E1}\uFE0F Frank Protocol v1.0 has been injected into the rules engine."));
|
|
468
|
+
console.log(chalk4.dim(" All new chats will now boot with mandatory governance checks."));
|
|
351
469
|
} else {
|
|
352
|
-
spinner.warn(
|
|
470
|
+
spinner.warn(chalk4.yellow(` \u26A0\uFE0F ${project.name} \u2192 ${syncResponse.data.error || "Unknown error"}`));
|
|
353
471
|
success = false;
|
|
354
472
|
}
|
|
355
473
|
} catch (e) {
|
|
356
|
-
spinner.fail(
|
|
474
|
+
spinner.fail(chalk4.red(`Sync failed: ${e.message}`));
|
|
357
475
|
success = false;
|
|
358
476
|
}
|
|
359
477
|
return success;
|
|
@@ -365,14 +483,14 @@ function createSyncRulesCommand() {
|
|
|
365
483
|
try {
|
|
366
484
|
apiKey = getApiKey();
|
|
367
485
|
} catch (e) {
|
|
368
|
-
console.error(
|
|
486
|
+
console.error(chalk4.red('Not authenticated. Run "rigstate login" first.'));
|
|
369
487
|
return;
|
|
370
488
|
}
|
|
371
489
|
const apiUrl = getApiUrl();
|
|
372
490
|
if (options.project) {
|
|
373
491
|
await syncProjectRules(options.project, apiKey, apiUrl, options.dryRun);
|
|
374
492
|
} else {
|
|
375
|
-
console.log(
|
|
493
|
+
console.log(chalk4.yellow("Use --project <id> for now. (Mass sync logic awaiting migration)"));
|
|
376
494
|
}
|
|
377
495
|
});
|
|
378
496
|
return syncRules;
|
|
@@ -391,7 +509,7 @@ var suggest_exports = {};
|
|
|
391
509
|
__export(suggest_exports, {
|
|
392
510
|
suggestNextMove: () => suggestNextMove
|
|
393
511
|
});
|
|
394
|
-
import
|
|
512
|
+
import chalk5 from "chalk";
|
|
395
513
|
import axios3 from "axios";
|
|
396
514
|
async function suggestNextMove(projectId, apiKey, apiUrl) {
|
|
397
515
|
try {
|
|
@@ -411,18 +529,18 @@ async function suggestNextMove(projectId, apiKey, apiUrl) {
|
|
|
411
529
|
if (tasks.length === 0) return;
|
|
412
530
|
const nextTask = tasks[0];
|
|
413
531
|
console.log("");
|
|
414
|
-
console.log(
|
|
415
|
-
console.log(
|
|
416
|
-
console.log(`${
|
|
417
|
-
console.log(`${
|
|
532
|
+
console.log(chalk5.bold("\u{1F3AF} TACTICAL INTELLIGENCE"));
|
|
533
|
+
console.log(chalk5.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
534
|
+
console.log(`${chalk5.bold("Active Phase:")} Implementation`);
|
|
535
|
+
console.log(`${chalk5.bold("Next Mission:")} ${chalk5.cyan(nextTask.title)}`);
|
|
418
536
|
if (nextTask.role) {
|
|
419
|
-
console.log(`${
|
|
537
|
+
console.log(`${chalk5.bold("Required Role:")} ${chalk5.magenta(nextTask.role)}`);
|
|
420
538
|
}
|
|
421
539
|
console.log("");
|
|
422
|
-
console.log(
|
|
423
|
-
console.log(
|
|
424
|
-
console.log(
|
|
425
|
-
console.log(
|
|
540
|
+
console.log(chalk5.yellow("SUGGESTED NEXT MOVE:"));
|
|
541
|
+
console.log(chalk5.white(`> rigstate work start ${nextTask.id} `) + chalk5.dim("(Start this task)"));
|
|
542
|
+
console.log(chalk5.white(`> rigstate chat "How do I solve T-${nextTask.step_number}?" `) + chalk5.dim("(Ask Architect)"));
|
|
543
|
+
console.log(chalk5.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
426
544
|
console.log("");
|
|
427
545
|
} catch (e) {
|
|
428
546
|
}
|
|
@@ -442,9 +560,9 @@ __export(skills_provisioner_exports, {
|
|
|
442
560
|
provisionSkills: () => provisionSkills
|
|
443
561
|
});
|
|
444
562
|
import axios6 from "axios";
|
|
445
|
-
import
|
|
446
|
-
import
|
|
447
|
-
import
|
|
563
|
+
import fs8 from "fs/promises";
|
|
564
|
+
import path9 from "path";
|
|
565
|
+
import chalk9 from "chalk";
|
|
448
566
|
async function provisionSkills(apiUrl, apiKey, projectId, rootDir) {
|
|
449
567
|
const skills = [];
|
|
450
568
|
try {
|
|
@@ -466,18 +584,18 @@ async function provisionSkills(apiUrl, apiKey, projectId, rootDir) {
|
|
|
466
584
|
}
|
|
467
585
|
} catch (e) {
|
|
468
586
|
const msg = e.response?.data?.error || e.message;
|
|
469
|
-
console.log(
|
|
587
|
+
console.log(chalk9.dim(` (Skills API not available: ${msg}, using core library)`));
|
|
470
588
|
}
|
|
471
589
|
if (skills.length === 0) {
|
|
472
590
|
const { getRigstateStandardSkills } = await import("@rigstate/rules-engine");
|
|
473
591
|
const coreSkills = getRigstateStandardSkills();
|
|
474
592
|
skills.push(...coreSkills);
|
|
475
593
|
}
|
|
476
|
-
const skillsDir =
|
|
477
|
-
await
|
|
594
|
+
const skillsDir = path9.join(rootDir, ".agent", "skills");
|
|
595
|
+
await fs8.mkdir(skillsDir, { recursive: true });
|
|
478
596
|
for (const skill of skills) {
|
|
479
|
-
const skillDir =
|
|
480
|
-
await
|
|
597
|
+
const skillDir = path9.join(skillsDir, skill.name);
|
|
598
|
+
await fs8.mkdir(skillDir, { recursive: true });
|
|
481
599
|
const skillContent = `---
|
|
482
600
|
name: ${skill.name}
|
|
483
601
|
description: ${skill.description}
|
|
@@ -490,10 +608,10 @@ ${skill.content}
|
|
|
490
608
|
|
|
491
609
|
---
|
|
492
610
|
*Provisioned by Rigstate CLI. Do not modify manually.*`;
|
|
493
|
-
const skillPath =
|
|
494
|
-
await
|
|
611
|
+
const skillPath = path9.join(skillDir, "SKILL.md");
|
|
612
|
+
await fs8.writeFile(skillPath, skillContent, "utf-8");
|
|
495
613
|
}
|
|
496
|
-
console.log(
|
|
614
|
+
console.log(chalk9.green(` \u2705 Provisioned ${skills.length} skill(s) to .agent/skills/`));
|
|
497
615
|
return skills;
|
|
498
616
|
}
|
|
499
617
|
function generateSkillsDiscoveryBlock(skills) {
|
|
@@ -508,16 +626,16 @@ ${skillBlocks}
|
|
|
508
626
|
</available_skills>`;
|
|
509
627
|
}
|
|
510
628
|
async function jitProvisionSkill(skillId, apiUrl, apiKey, projectId, rootDir) {
|
|
511
|
-
const rulesPath =
|
|
629
|
+
const rulesPath = path9.join(rootDir, ".cursorrules");
|
|
512
630
|
let rulesContent = "";
|
|
513
631
|
try {
|
|
514
|
-
rulesContent = await
|
|
632
|
+
rulesContent = await fs8.readFile(rulesPath, "utf-8");
|
|
515
633
|
} catch (e) {
|
|
516
634
|
return false;
|
|
517
635
|
}
|
|
518
636
|
const isProvisioned = rulesContent.includes(`<name>${skillId}</name>`) || rulesContent.includes(`.agent/skills/${skillId}`);
|
|
519
637
|
if (isProvisioned) return false;
|
|
520
|
-
console.log(
|
|
638
|
+
console.log(chalk9.yellow(` \u26A1 JIT PROVISIONING: Injecting ${skillId}...`));
|
|
521
639
|
try {
|
|
522
640
|
const skills = await provisionSkills(apiUrl, apiKey, projectId, rootDir);
|
|
523
641
|
const skillsBlock = generateSkillsDiscoveryBlock(skills);
|
|
@@ -532,10 +650,10 @@ async function jitProvisionSkill(skillId, apiUrl, apiKey, projectId, rootDir) {
|
|
|
532
650
|
rulesContent = rulesContent.slice(0, insertPoint + 3) + "\n\n" + skillsBlock + "\n" + rulesContent.slice(insertPoint + 3);
|
|
533
651
|
}
|
|
534
652
|
}
|
|
535
|
-
await
|
|
653
|
+
await fs8.writeFile(rulesPath, rulesContent, "utf-8");
|
|
536
654
|
return true;
|
|
537
655
|
} catch (e) {
|
|
538
|
-
console.log(
|
|
656
|
+
console.log(chalk9.red(` Failed to provision skill: ${e.message}`));
|
|
539
657
|
return false;
|
|
540
658
|
}
|
|
541
659
|
}
|
|
@@ -556,13 +674,13 @@ __export(governance_exports, {
|
|
|
556
674
|
performOverride: () => performOverride,
|
|
557
675
|
setSoftLock: () => setSoftLock
|
|
558
676
|
});
|
|
559
|
-
import
|
|
560
|
-
import
|
|
561
|
-
import
|
|
677
|
+
import fs9 from "fs/promises";
|
|
678
|
+
import path10 from "path";
|
|
679
|
+
import chalk10 from "chalk";
|
|
562
680
|
async function getGovernanceConfig(rootDir = process.cwd()) {
|
|
563
681
|
try {
|
|
564
|
-
const configPath =
|
|
565
|
-
const content = await
|
|
682
|
+
const configPath = path10.join(rootDir, "rigstate.config.json");
|
|
683
|
+
const content = await fs9.readFile(configPath, "utf-8");
|
|
566
684
|
const userConfig = JSON.parse(content);
|
|
567
685
|
return {
|
|
568
686
|
governance: {
|
|
@@ -576,37 +694,37 @@ async function getGovernanceConfig(rootDir = process.cwd()) {
|
|
|
576
694
|
}
|
|
577
695
|
async function getSessionState(rootDir = process.cwd()) {
|
|
578
696
|
try {
|
|
579
|
-
const sessionPath =
|
|
580
|
-
const content = await
|
|
697
|
+
const sessionPath = path10.join(rootDir, ".rigstate", "session.json");
|
|
698
|
+
const content = await fs9.readFile(sessionPath, "utf-8");
|
|
581
699
|
return JSON.parse(content);
|
|
582
700
|
} catch (e) {
|
|
583
701
|
return DEFAULT_SESSION;
|
|
584
702
|
}
|
|
585
703
|
}
|
|
586
704
|
async function setSoftLock(reason, violationId, rootDir = process.cwd()) {
|
|
587
|
-
const sessionPath =
|
|
705
|
+
const sessionPath = path10.join(rootDir, ".rigstate", "session.json");
|
|
588
706
|
const state = {
|
|
589
707
|
status: "SOFT_LOCK",
|
|
590
708
|
active_violation: violationId,
|
|
591
709
|
lock_reason: reason,
|
|
592
710
|
last_updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
593
711
|
};
|
|
594
|
-
await
|
|
595
|
-
await
|
|
712
|
+
await fs9.mkdir(path10.dirname(sessionPath), { recursive: true });
|
|
713
|
+
await fs9.writeFile(sessionPath, JSON.stringify(state, null, 2), "utf-8");
|
|
596
714
|
}
|
|
597
715
|
async function clearSoftLock(rootDir = process.cwd()) {
|
|
598
|
-
const sessionPath =
|
|
716
|
+
const sessionPath = path10.join(rootDir, ".rigstate", "session.json");
|
|
599
717
|
const state = {
|
|
600
718
|
...DEFAULT_SESSION,
|
|
601
719
|
last_updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
602
720
|
};
|
|
603
|
-
await
|
|
604
|
-
await
|
|
721
|
+
await fs9.mkdir(path10.dirname(sessionPath), { recursive: true });
|
|
722
|
+
await fs9.writeFile(sessionPath, JSON.stringify(state, null, 2), "utf-8");
|
|
605
723
|
}
|
|
606
724
|
async function performOverride(violationId, reason, rootDir = process.cwd()) {
|
|
607
725
|
const config2 = await getGovernanceConfig(rootDir);
|
|
608
726
|
if (!config2.governance.allow_overrides) {
|
|
609
|
-
console.log(
|
|
727
|
+
console.log(chalk10.red("\u274C Overrides are disabled for this project."));
|
|
610
728
|
return false;
|
|
611
729
|
}
|
|
612
730
|
await clearSoftLock(rootDir);
|
|
@@ -643,22 +761,22 @@ var watchdog_exports = {};
|
|
|
643
761
|
__export(watchdog_exports, {
|
|
644
762
|
runGuardianWatchdog: () => runGuardianWatchdog
|
|
645
763
|
});
|
|
646
|
-
import
|
|
647
|
-
import
|
|
648
|
-
import
|
|
764
|
+
import fs10 from "fs/promises";
|
|
765
|
+
import path11 from "path";
|
|
766
|
+
import chalk11 from "chalk";
|
|
649
767
|
import axios7 from "axios";
|
|
650
768
|
async function countLines(filePath) {
|
|
651
769
|
try {
|
|
652
|
-
const content = await
|
|
770
|
+
const content = await fs10.readFile(filePath, "utf-8");
|
|
653
771
|
return content.split("\n").length;
|
|
654
772
|
} catch (e) {
|
|
655
773
|
return 0;
|
|
656
774
|
}
|
|
657
775
|
}
|
|
658
776
|
async function getFiles(dir, extension) {
|
|
659
|
-
const entries = await
|
|
777
|
+
const entries = await fs10.readdir(dir, { withFileTypes: true });
|
|
660
778
|
const files = await Promise.all(entries.map(async (entry) => {
|
|
661
|
-
const res =
|
|
779
|
+
const res = path11.resolve(dir, entry.name);
|
|
662
780
|
if (entry.isDirectory()) {
|
|
663
781
|
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === ".next" || entry.name === "dist") return [];
|
|
664
782
|
return getFiles(res, extension);
|
|
@@ -686,8 +804,8 @@ async function fetchRulesFromApi(projectId) {
|
|
|
686
804
|
}
|
|
687
805
|
} catch (error) {
|
|
688
806
|
try {
|
|
689
|
-
const cachePath =
|
|
690
|
-
const content = await
|
|
807
|
+
const cachePath = path11.join(process.cwd(), CACHE_FILE);
|
|
808
|
+
const content = await fs10.readFile(cachePath, "utf-8");
|
|
691
809
|
const cached = JSON.parse(content);
|
|
692
810
|
if (cached.settings) {
|
|
693
811
|
return {
|
|
@@ -706,7 +824,7 @@ async function fetchRulesFromApi(projectId) {
|
|
|
706
824
|
};
|
|
707
825
|
}
|
|
708
826
|
async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
709
|
-
console.log(
|
|
827
|
+
console.log(chalk11.bold("\n\u{1F6E1}\uFE0F Active Guardian Watchdog Initiated..."));
|
|
710
828
|
let lmax = settings.lmax || DEFAULT_LMAX;
|
|
711
829
|
let lmaxWarning = settings.lmax_warning || DEFAULT_LMAX_WARNING;
|
|
712
830
|
let ruleSource = settings.lmax ? "Settings (Passed)" : "Default";
|
|
@@ -716,47 +834,47 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
716
834
|
lmaxWarning = apiRules.lmaxWarning;
|
|
717
835
|
ruleSource = apiRules.source;
|
|
718
836
|
}
|
|
719
|
-
console.log(
|
|
837
|
+
console.log(chalk11.dim(`Governance Rules: L_max=${lmax}, L_max_warning=${lmaxWarning}, Source: ${ruleSource}`));
|
|
720
838
|
const targetExtensions = [".ts", ".tsx"];
|
|
721
839
|
let scanTarget = rootPath;
|
|
722
|
-
const webSrc =
|
|
840
|
+
const webSrc = path11.join(rootPath, "apps", "web", "src");
|
|
723
841
|
try {
|
|
724
|
-
await
|
|
842
|
+
await fs10.access(webSrc);
|
|
725
843
|
scanTarget = webSrc;
|
|
726
844
|
} catch {
|
|
727
845
|
}
|
|
728
|
-
console.log(
|
|
846
|
+
console.log(chalk11.dim(`Scanning target: ${path11.relative(process.cwd(), scanTarget)}`));
|
|
729
847
|
const files = await getFiles(scanTarget, targetExtensions);
|
|
730
848
|
let violations = 0;
|
|
731
849
|
let warnings = 0;
|
|
732
850
|
const results = [];
|
|
733
851
|
for (const file of files) {
|
|
734
852
|
const lines = await countLines(file);
|
|
735
|
-
const relPath =
|
|
853
|
+
const relPath = path11.relative(rootPath, file);
|
|
736
854
|
if (lines > lmax) {
|
|
737
855
|
results.push({ file: relPath, lines, status: "VIOLATION" });
|
|
738
856
|
violations++;
|
|
739
|
-
console.log(
|
|
857
|
+
console.log(chalk11.red(`[VIOLATION] ${relPath}: ${lines} lines (Limit: ${lmax})`));
|
|
740
858
|
} else if (lines > lmaxWarning) {
|
|
741
859
|
results.push({ file: relPath, lines, status: "WARNING" });
|
|
742
860
|
warnings++;
|
|
743
|
-
console.log(
|
|
861
|
+
console.log(chalk11.yellow(`[WARNING] ${relPath}: ${lines} lines (Threshold: ${lmaxWarning})`));
|
|
744
862
|
}
|
|
745
863
|
}
|
|
746
864
|
if (violations === 0 && warnings === 0) {
|
|
747
|
-
console.log(
|
|
865
|
+
console.log(chalk11.green(`\u2714 All ${files.length} files are within governance limits.`));
|
|
748
866
|
} else {
|
|
749
|
-
console.log("\n" +
|
|
750
|
-
console.log(
|
|
751
|
-
console.log(
|
|
867
|
+
console.log("\n" + chalk11.bold("Summary:"));
|
|
868
|
+
console.log(chalk11.red(`Violations: ${violations}`));
|
|
869
|
+
console.log(chalk11.yellow(`Warnings: ${warnings}`));
|
|
752
870
|
const { getGovernanceConfig: getGovernanceConfig2, setSoftLock: setSoftLock2, InterventionLevel: InterventionLevel2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
753
871
|
const { governance } = await getGovernanceConfig2(rootPath);
|
|
754
|
-
console.log(
|
|
872
|
+
console.log(chalk11.dim(`Intervention Level: ${InterventionLevel2[governance.intervention_level] || "UNKNOWN"} (${governance.intervention_level})`));
|
|
755
873
|
if (violations > 0) {
|
|
756
|
-
console.log(
|
|
874
|
+
console.log(chalk11.red.bold("\nCRITICAL: Governance violations detected. Immediate refactoring required."));
|
|
757
875
|
if (governance.intervention_level >= InterventionLevel2.SENTINEL) {
|
|
758
|
-
console.log(
|
|
759
|
-
console.log(
|
|
876
|
+
console.log(chalk11.red.bold("\u{1F6D1} SENTINEL MODE: Session SOFT_LOCKED until resolved."));
|
|
877
|
+
console.log(chalk11.red(' Run "rigstate override <id> --reason \\"...\\"" if this is an emergency.'));
|
|
760
878
|
await setSoftLock2("Sentinel Mode: Governance Violations Detected", "ARC-VIOLATION", rootPath);
|
|
761
879
|
}
|
|
762
880
|
}
|
|
@@ -779,9 +897,9 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
779
897
|
}, {
|
|
780
898
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
781
899
|
});
|
|
782
|
-
console.log(
|
|
900
|
+
console.log(chalk11.dim("\u2714 Violations synced to Rigstate Cloud."));
|
|
783
901
|
} catch (e) {
|
|
784
|
-
console.log(
|
|
902
|
+
console.log(chalk11.dim("\u26A0 Cloud sync skipped: " + (e.message || "Unknown")));
|
|
785
903
|
}
|
|
786
904
|
}
|
|
787
905
|
}
|
|
@@ -1735,32 +1853,32 @@ var require_package = __commonJS({
|
|
|
1735
1853
|
// src/index.ts
|
|
1736
1854
|
init_esm_shims();
|
|
1737
1855
|
import { Command as Command24 } from "commander";
|
|
1738
|
-
import
|
|
1856
|
+
import chalk36 from "chalk";
|
|
1739
1857
|
|
|
1740
1858
|
// src/commands/login.ts
|
|
1741
1859
|
init_esm_shims();
|
|
1742
1860
|
init_config();
|
|
1743
1861
|
import { Command } from "commander";
|
|
1744
|
-
import
|
|
1862
|
+
import chalk2 from "chalk";
|
|
1745
1863
|
function createLoginCommand() {
|
|
1746
1864
|
return new Command("login").description("Authenticate with your Rigstate API key").argument("<api-key>", "Your Rigstate API key (starts with sk_)").action(async (apiKey) => {
|
|
1747
1865
|
try {
|
|
1748
1866
|
if (!apiKey || !apiKey.startsWith("sk_rigstate_")) {
|
|
1749
|
-
console.error(
|
|
1750
|
-
console.error(
|
|
1867
|
+
console.error(chalk2.red("\u274C Invalid API key format"));
|
|
1868
|
+
console.error(chalk2.dim('API keys must start with "sk_rigstate_"'));
|
|
1751
1869
|
process.exit(1);
|
|
1752
1870
|
}
|
|
1753
1871
|
setApiKey(apiKey);
|
|
1754
|
-
console.log(
|
|
1872
|
+
console.log(chalk2.green("\u2705 Successfully logged in!"));
|
|
1755
1873
|
console.log(
|
|
1756
|
-
|
|
1874
|
+
chalk2.dim(
|
|
1757
1875
|
`
|
|
1758
1876
|
Your API key has been securely stored. You can now use "rigstate scan" to audit your code.`
|
|
1759
1877
|
)
|
|
1760
1878
|
);
|
|
1761
|
-
console.log(
|
|
1762
|
-
console.log(
|
|
1763
|
-
console.log(
|
|
1879
|
+
console.log(chalk2.bold("\n\u{1F916} Cursor MCP Configuration"));
|
|
1880
|
+
console.log(chalk2.dim("Copy and paste this into Cursor Settings -> Features -> MCP:"));
|
|
1881
|
+
console.log(chalk2.cyan(`
|
|
1764
1882
|
{
|
|
1765
1883
|
"mcpServers": {
|
|
1766
1884
|
"rigstate": {
|
|
@@ -1777,7 +1895,7 @@ Your API key has been securely stored. You can now use "rigstate scan" to audit
|
|
|
1777
1895
|
}`));
|
|
1778
1896
|
} catch (error) {
|
|
1779
1897
|
console.error(
|
|
1780
|
-
|
|
1898
|
+
chalk2.red("\u274C Login failed:"),
|
|
1781
1899
|
error instanceof Error ? error.message : "Unknown error"
|
|
1782
1900
|
);
|
|
1783
1901
|
process.exit(1);
|
|
@@ -1789,24 +1907,24 @@ Your API key has been securely stored. You can now use "rigstate scan" to audit
|
|
|
1789
1907
|
init_esm_shims();
|
|
1790
1908
|
init_config();
|
|
1791
1909
|
import { Command as Command4 } from "commander";
|
|
1792
|
-
import
|
|
1793
|
-
import
|
|
1794
|
-
import
|
|
1910
|
+
import fs4 from "fs/promises";
|
|
1911
|
+
import path5 from "path";
|
|
1912
|
+
import chalk6 from "chalk";
|
|
1795
1913
|
import os from "os";
|
|
1796
1914
|
function createLinkCommand() {
|
|
1797
1915
|
return new Command4("link").description("Link current directory to a Rigstate project").argument("[projectId]", "Project ID to link").action(async (projectId) => {
|
|
1798
1916
|
try {
|
|
1799
|
-
const globalPath =
|
|
1800
|
-
const globalData = await
|
|
1917
|
+
const globalPath = path5.join(os.homedir(), ".rigstate", "config.json");
|
|
1918
|
+
const globalData = await fs4.readFile(globalPath, "utf-8").catch(() => null);
|
|
1801
1919
|
if (globalData) {
|
|
1802
1920
|
const config2 = JSON.parse(globalData);
|
|
1803
|
-
const
|
|
1804
|
-
if (config2.overrides && config2.overrides[
|
|
1805
|
-
const overrideId = config2.overrides[
|
|
1806
|
-
console.warn(
|
|
1921
|
+
const cwd2 = process.cwd();
|
|
1922
|
+
if (config2.overrides && config2.overrides[cwd2]) {
|
|
1923
|
+
const overrideId = config2.overrides[cwd2];
|
|
1924
|
+
console.warn(chalk6.yellow(`Global override detected. Enforcing project ID: ${overrideId}`));
|
|
1807
1925
|
if (!projectId) projectId = overrideId;
|
|
1808
1926
|
else if (projectId !== overrideId) {
|
|
1809
|
-
console.warn(
|
|
1927
|
+
console.warn(chalk6.red(`Ignoring provided ID ${projectId}. Using override.`));
|
|
1810
1928
|
projectId = overrideId;
|
|
1811
1929
|
}
|
|
1812
1930
|
}
|
|
@@ -1820,16 +1938,16 @@ function createLinkCommand() {
|
|
|
1820
1938
|
const apiKey = getApiKey();
|
|
1821
1939
|
const apiUrl = getApiUrl();
|
|
1822
1940
|
if (!apiKey) {
|
|
1823
|
-
console.error(
|
|
1941
|
+
console.error(chalk6.red('Not authenticated. Please run "rigstate login" or provide a Project ID.'));
|
|
1824
1942
|
process.exit(1);
|
|
1825
1943
|
}
|
|
1826
|
-
console.log(
|
|
1944
|
+
console.log(chalk6.dim("Fetching your projects..."));
|
|
1827
1945
|
const axios24 = (await import("axios")).default;
|
|
1828
1946
|
const response = await axios24.get(`${apiUrl}/api/v1/projects`, {
|
|
1829
1947
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1830
1948
|
});
|
|
1831
1949
|
if (!response.data.success || !response.data.data.projects?.length) {
|
|
1832
|
-
console.error(
|
|
1950
|
+
console.error(chalk6.yellow("No projects found. Create one at https://app.rigstate.com"));
|
|
1833
1951
|
process.exit(1);
|
|
1834
1952
|
}
|
|
1835
1953
|
const choices = response.data.data.projects.map((p) => ({
|
|
@@ -1844,54 +1962,49 @@ function createLinkCommand() {
|
|
|
1844
1962
|
}]);
|
|
1845
1963
|
projectId = answer.id;
|
|
1846
1964
|
} catch (e) {
|
|
1847
|
-
console.error(
|
|
1965
|
+
console.error(chalk6.red(`Failed to fetch projects: ${e.message}`));
|
|
1848
1966
|
console.error("Please provide project ID manually: rigstate link <id>");
|
|
1849
1967
|
process.exit(1);
|
|
1850
1968
|
}
|
|
1851
1969
|
}
|
|
1852
|
-
const
|
|
1853
|
-
const content = {
|
|
1854
|
-
project_id: projectId,
|
|
1855
|
-
linked_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1856
|
-
};
|
|
1857
|
-
const currentUrl = getApiUrl();
|
|
1858
|
-
if (currentUrl !== "https://app.rigstate.com") {
|
|
1859
|
-
content.api_url = currentUrl;
|
|
1860
|
-
}
|
|
1970
|
+
const cwd = process.cwd();
|
|
1861
1971
|
try {
|
|
1862
|
-
await
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1972
|
+
const { saveManifest: saveManifest2 } = await Promise.resolve().then(() => (init_manifest(), manifest_exports));
|
|
1973
|
+
const targetFile = await saveManifest2({
|
|
1974
|
+
project_id: projectId,
|
|
1975
|
+
linked_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1976
|
+
api_url: getApiUrl() !== "https://app.rigstate.com" ? getApiUrl() : void 0
|
|
1977
|
+
});
|
|
1978
|
+
console.log(chalk6.green(`\u2714 Linked to project ID: ${projectId}`));
|
|
1979
|
+
console.log(chalk6.dim(`Created local identity manifest at ${path5.relative(cwd, targetFile)}`));
|
|
1866
1980
|
console.log("");
|
|
1867
|
-
console.log(
|
|
1981
|
+
console.log(chalk6.bold("\u{1F916} Rigstate Automation Detected"));
|
|
1868
1982
|
console.log("");
|
|
1869
|
-
const { getApiKey: _getApiKey, getApiUrl: _getApiUrl } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
1870
1983
|
const apiKey = getApiKey();
|
|
1871
1984
|
const apiUrl = getApiUrl();
|
|
1872
1985
|
if (apiKey) {
|
|
1873
|
-
console.log(
|
|
1986
|
+
console.log(chalk6.blue("\u{1F510} Checking Vault for secrets..."));
|
|
1874
1987
|
const { syncEnv: syncEnv2 } = await Promise.resolve().then(() => (init_env(), env_exports));
|
|
1875
1988
|
await syncEnv2(projectId, apiKey, apiUrl, true);
|
|
1876
|
-
console.log(
|
|
1989
|
+
console.log(chalk6.blue("\u{1F9E0} Syncing neural instructions..."));
|
|
1877
1990
|
const { syncProjectRules: syncProjectRules2 } = await Promise.resolve().then(() => (init_sync_rules(), sync_rules_exports));
|
|
1878
1991
|
await syncProjectRules2(projectId, apiKey, apiUrl);
|
|
1879
|
-
console.log(
|
|
1992
|
+
console.log(chalk6.blue("\u{1F6E1}\uFE0F Injecting Guardian hooks & Safety nets..."));
|
|
1880
1993
|
await installHooks(process.cwd());
|
|
1881
1994
|
await hardenGitIgnore(process.cwd());
|
|
1882
1995
|
console.log("");
|
|
1883
|
-
console.log(
|
|
1996
|
+
console.log(chalk6.bold.green("\u{1F680} Link Complete! Your environment is ready."));
|
|
1884
1997
|
const { suggestNextMove: suggestNextMove2 } = await Promise.resolve().then(() => (init_suggest(), suggest_exports));
|
|
1885
1998
|
await suggestNextMove2(projectId, apiKey, apiUrl);
|
|
1886
1999
|
} else {
|
|
1887
2000
|
console.log("");
|
|
1888
|
-
console.log(
|
|
2001
|
+
console.log(chalk6.bold.green("\u{1F680} Link Complete!"));
|
|
1889
2002
|
}
|
|
1890
2003
|
} catch (error) {
|
|
1891
2004
|
if (error.message?.includes("Not authenticated")) {
|
|
1892
|
-
console.warn(
|
|
2005
|
+
console.warn(chalk6.yellow('\u26A0\uFE0F Not authenticated. Run "rigstate login" to enable automation features.'));
|
|
1893
2006
|
} else {
|
|
1894
|
-
console.error(
|
|
2007
|
+
console.error(chalk6.red(`Failed to link project: ${error.message}`));
|
|
1895
2008
|
}
|
|
1896
2009
|
}
|
|
1897
2010
|
});
|
|
@@ -1920,15 +2033,15 @@ async function hardenGitIgnore(cwd) {
|
|
|
1920
2033
|
}
|
|
1921
2034
|
const missing = REQUIRED_IGNORES.filter((line) => !content.includes(line) && !line.startsWith("#"));
|
|
1922
2035
|
if (missing.length > 0) {
|
|
1923
|
-
console.log(
|
|
2036
|
+
console.log(chalk6.dim(" Configuring .gitignore for Rigstate safety..."));
|
|
1924
2037
|
const toAppend = "\n\n" + REQUIRED_IGNORES.join("\n") + "\n";
|
|
1925
2038
|
await fs26.writeFile(ignorePath, content + toAppend, "utf-8");
|
|
1926
|
-
console.log(
|
|
2039
|
+
console.log(chalk6.green(" \u2714 .gitignore updated (Artifacts protected)"));
|
|
1927
2040
|
} else {
|
|
1928
|
-
console.log(
|
|
2041
|
+
console.log(chalk6.green(" \u2714 .gitignore already hardened"));
|
|
1929
2042
|
}
|
|
1930
2043
|
} catch (e) {
|
|
1931
|
-
console.warn(
|
|
2044
|
+
console.warn(chalk6.yellow(` Could not update .gitignore: ${e.message}`));
|
|
1932
2045
|
}
|
|
1933
2046
|
}
|
|
1934
2047
|
async function installHooks(cwd) {
|
|
@@ -1937,7 +2050,7 @@ async function installHooks(cwd) {
|
|
|
1937
2050
|
try {
|
|
1938
2051
|
await fs26.access(path29.join(cwd, ".git"));
|
|
1939
2052
|
} catch {
|
|
1940
|
-
console.log(
|
|
2053
|
+
console.log(chalk6.dim(" (Not a git repository, skipping hooks)"));
|
|
1941
2054
|
return;
|
|
1942
2055
|
}
|
|
1943
2056
|
const hooksDir = path29.join(cwd, ".husky");
|
|
@@ -1948,7 +2061,7 @@ async function installHooks(cwd) {
|
|
|
1948
2061
|
await fs26.access(preCommitPath);
|
|
1949
2062
|
const content = await fs26.readFile(preCommitPath, "utf-8");
|
|
1950
2063
|
if (content.includes("rigstate")) {
|
|
1951
|
-
console.log(
|
|
2064
|
+
console.log(chalk6.green(" \u2714 Git hooks already active"));
|
|
1952
2065
|
} else {
|
|
1953
2066
|
shouldInstall = true;
|
|
1954
2067
|
}
|
|
@@ -1977,10 +2090,10 @@ exit $?
|
|
|
1977
2090
|
} else {
|
|
1978
2091
|
await fs26.writeFile(preCommitPath, PRE_COMMIT_SCRIPT2, { mode: 493 });
|
|
1979
2092
|
}
|
|
1980
|
-
console.log(
|
|
2093
|
+
console.log(chalk6.green(" \u2714 Applied Guardian protection (git-hooks)"));
|
|
1981
2094
|
}
|
|
1982
2095
|
} catch (e) {
|
|
1983
|
-
console.log(
|
|
2096
|
+
console.log(chalk6.dim(" (Skipped hooks: " + e.message + ")"));
|
|
1984
2097
|
}
|
|
1985
2098
|
}
|
|
1986
2099
|
async function fileExists(path29) {
|
|
@@ -1997,21 +2110,21 @@ async function fileExists(path29) {
|
|
|
1997
2110
|
init_esm_shims();
|
|
1998
2111
|
init_config();
|
|
1999
2112
|
import { Command as Command5 } from "commander";
|
|
2000
|
-
import
|
|
2113
|
+
import chalk7 from "chalk";
|
|
2001
2114
|
import ora3 from "ora";
|
|
2002
2115
|
import axios4 from "axios";
|
|
2003
2116
|
import { glob } from "glob";
|
|
2004
|
-
import
|
|
2005
|
-
import
|
|
2117
|
+
import fs6 from "fs/promises";
|
|
2118
|
+
import path7 from "path";
|
|
2006
2119
|
|
|
2007
2120
|
// src/utils/files.ts
|
|
2008
2121
|
init_esm_shims();
|
|
2009
|
-
import
|
|
2010
|
-
import
|
|
2122
|
+
import fs5 from "fs/promises";
|
|
2123
|
+
import path6 from "path";
|
|
2011
2124
|
async function readGitignore(dir) {
|
|
2012
|
-
const gitignorePath =
|
|
2125
|
+
const gitignorePath = path6.join(dir, ".gitignore");
|
|
2013
2126
|
try {
|
|
2014
|
-
const content = await
|
|
2127
|
+
const content = await fs5.readFile(gitignorePath, "utf-8");
|
|
2015
2128
|
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
2016
2129
|
} catch (error) {
|
|
2017
2130
|
return [];
|
|
@@ -2073,7 +2186,7 @@ function isCodeFile(filePath) {
|
|
|
2073
2186
|
".vue",
|
|
2074
2187
|
".svelte"
|
|
2075
2188
|
];
|
|
2076
|
-
const ext =
|
|
2189
|
+
const ext = path6.extname(filePath).toLowerCase();
|
|
2077
2190
|
return codeExtensions.includes(ext);
|
|
2078
2191
|
}
|
|
2079
2192
|
|
|
@@ -2087,26 +2200,26 @@ function createScanCommand() {
|
|
|
2087
2200
|
const projectId = options.project || getProjectId();
|
|
2088
2201
|
if (!projectId) {
|
|
2089
2202
|
console.warn(
|
|
2090
|
-
|
|
2203
|
+
chalk7.yellow(
|
|
2091
2204
|
"\u26A0\uFE0F No project ID specified. Use --project <id> or set a default."
|
|
2092
2205
|
)
|
|
2093
2206
|
);
|
|
2094
2207
|
}
|
|
2095
|
-
const scanPath =
|
|
2096
|
-
spinner.start(`Scanning ${
|
|
2208
|
+
const scanPath = path7.resolve(process.cwd(), targetPath);
|
|
2209
|
+
spinner.start(`Scanning ${chalk7.cyan(scanPath)}...`);
|
|
2097
2210
|
const gitignorePatterns = await readGitignore(scanPath);
|
|
2098
|
-
const pattern =
|
|
2211
|
+
const pattern = path7.join(scanPath, "**/*");
|
|
2099
2212
|
const allFiles = await glob(pattern, {
|
|
2100
2213
|
nodir: true,
|
|
2101
2214
|
dot: false,
|
|
2102
2215
|
ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**", "**/build/**"]
|
|
2103
2216
|
});
|
|
2104
2217
|
const codeFiles = allFiles.filter((file) => {
|
|
2105
|
-
const relativePath =
|
|
2218
|
+
const relativePath = path7.relative(scanPath, file);
|
|
2106
2219
|
return isCodeFile(file) && !shouldIgnore(relativePath, gitignorePatterns);
|
|
2107
2220
|
});
|
|
2108
2221
|
if (codeFiles.length === 0) {
|
|
2109
|
-
spinner.warn(
|
|
2222
|
+
spinner.warn(chalk7.yellow("No code files found to scan."));
|
|
2110
2223
|
return;
|
|
2111
2224
|
}
|
|
2112
2225
|
spinner.text = `Found ${codeFiles.length} files. Scanning...`;
|
|
@@ -2115,10 +2228,10 @@ function createScanCommand() {
|
|
|
2115
2228
|
const severityCounts = {};
|
|
2116
2229
|
for (let i = 0; i < codeFiles.length; i++) {
|
|
2117
2230
|
const filePath = codeFiles[i];
|
|
2118
|
-
const relativePath =
|
|
2231
|
+
const relativePath = path7.relative(scanPath, filePath);
|
|
2119
2232
|
spinner.text = `Scanning ${i + 1}/${codeFiles.length}: ${relativePath}`;
|
|
2120
2233
|
try {
|
|
2121
|
-
const content = await
|
|
2234
|
+
const content = await fs6.readFile(filePath, "utf-8");
|
|
2122
2235
|
const response = await axios4.post(
|
|
2123
2236
|
`${apiUrl}/api/v1/audit`,
|
|
2124
2237
|
{
|
|
@@ -2154,15 +2267,15 @@ function createScanCommand() {
|
|
|
2154
2267
|
}
|
|
2155
2268
|
} catch (fileError) {
|
|
2156
2269
|
if (axios4.isAxiosError(fileError)) {
|
|
2157
|
-
console.warn(
|
|
2270
|
+
console.warn(chalk7.yellow(`
|
|
2158
2271
|
\u26A0\uFE0F Skipping ${relativePath}: ${fileError.message}`));
|
|
2159
2272
|
} else {
|
|
2160
|
-
console.warn(
|
|
2273
|
+
console.warn(chalk7.yellow(`
|
|
2161
2274
|
\u26A0\uFE0F Error reading ${relativePath}`));
|
|
2162
2275
|
}
|
|
2163
2276
|
}
|
|
2164
2277
|
}
|
|
2165
|
-
spinner.succeed(
|
|
2278
|
+
spinner.succeed(chalk7.green("\u2705 Scan completed!"));
|
|
2166
2279
|
const aggregatedResponse = {
|
|
2167
2280
|
results,
|
|
2168
2281
|
summary: {
|
|
@@ -2177,21 +2290,21 @@ function createScanCommand() {
|
|
|
2177
2290
|
printPrettyResults(aggregatedResponse);
|
|
2178
2291
|
}
|
|
2179
2292
|
} catch (error) {
|
|
2180
|
-
spinner.fail(
|
|
2293
|
+
spinner.fail(chalk7.red("\u274C Scan failed"));
|
|
2181
2294
|
if (axios4.isAxiosError(error)) {
|
|
2182
2295
|
if (error.response) {
|
|
2183
|
-
console.error(
|
|
2296
|
+
console.error(chalk7.red("API Error:"), error.response.data);
|
|
2184
2297
|
} else if (error.request) {
|
|
2185
2298
|
console.error(
|
|
2186
|
-
|
|
2299
|
+
chalk7.red("Network Error:"),
|
|
2187
2300
|
"Could not reach the API. Is the server running?"
|
|
2188
2301
|
);
|
|
2189
2302
|
} else {
|
|
2190
|
-
console.error(
|
|
2303
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2191
2304
|
}
|
|
2192
2305
|
} else {
|
|
2193
2306
|
console.error(
|
|
2194
|
-
|
|
2307
|
+
chalk7.red("Error:"),
|
|
2195
2308
|
error instanceof Error ? error.message : "Unknown error"
|
|
2196
2309
|
);
|
|
2197
2310
|
}
|
|
@@ -2201,10 +2314,10 @@ function createScanCommand() {
|
|
|
2201
2314
|
}
|
|
2202
2315
|
function printPrettyResults(data) {
|
|
2203
2316
|
const { results, summary } = data;
|
|
2204
|
-
console.log("\n" +
|
|
2205
|
-
console.log(
|
|
2206
|
-
console.log(`Total Files Scanned: ${
|
|
2207
|
-
console.log(`Total Issues Found: ${
|
|
2317
|
+
console.log("\n" + chalk7.bold("\u{1F4CA} Scan Summary"));
|
|
2318
|
+
console.log(chalk7.dim("\u2500".repeat(60)));
|
|
2319
|
+
console.log(`Total Files Scanned: ${chalk7.cyan(summary.total_files)}`);
|
|
2320
|
+
console.log(`Total Issues Found: ${chalk7.yellow(summary.total_issues)}`);
|
|
2208
2321
|
if (summary.by_severity) {
|
|
2209
2322
|
console.log("\nIssues by Severity:");
|
|
2210
2323
|
Object.entries(summary.by_severity).forEach(([severity, count]) => {
|
|
@@ -2213,39 +2326,39 @@ function printPrettyResults(data) {
|
|
|
2213
2326
|
});
|
|
2214
2327
|
}
|
|
2215
2328
|
if (results && results.length > 0) {
|
|
2216
|
-
console.log("\n" +
|
|
2217
|
-
console.log(
|
|
2329
|
+
console.log("\n" + chalk7.bold("\u{1F50D} Detailed Results"));
|
|
2330
|
+
console.log(chalk7.dim("\u2500".repeat(60)));
|
|
2218
2331
|
results.forEach((result) => {
|
|
2219
2332
|
if (result.issues && result.issues.length > 0) {
|
|
2220
2333
|
console.log(`
|
|
2221
|
-
${
|
|
2334
|
+
${chalk7.bold(result.file_path)}`);
|
|
2222
2335
|
result.issues.forEach((issue) => {
|
|
2223
2336
|
const severityColor = getSeverityColor(issue.severity);
|
|
2224
|
-
const lineInfo = issue.line ?
|
|
2337
|
+
const lineInfo = issue.line ? chalk7.dim(`:${issue.line}`) : "";
|
|
2225
2338
|
console.log(
|
|
2226
2339
|
` ${severityColor(`[${issue.severity.toUpperCase()}]`)} ${issue.type}${lineInfo}`
|
|
2227
2340
|
);
|
|
2228
|
-
console.log(` ${
|
|
2341
|
+
console.log(` ${chalk7.dim(issue.message)}`);
|
|
2229
2342
|
});
|
|
2230
2343
|
}
|
|
2231
2344
|
});
|
|
2232
2345
|
}
|
|
2233
|
-
console.log("\n" +
|
|
2346
|
+
console.log("\n" + chalk7.dim("\u2500".repeat(60)));
|
|
2234
2347
|
}
|
|
2235
2348
|
function getSeverityColor(severity) {
|
|
2236
2349
|
switch (severity.toLowerCase()) {
|
|
2237
2350
|
case "critical":
|
|
2238
|
-
return
|
|
2351
|
+
return chalk7.red.bold;
|
|
2239
2352
|
case "high":
|
|
2240
|
-
return
|
|
2353
|
+
return chalk7.red;
|
|
2241
2354
|
case "medium":
|
|
2242
|
-
return
|
|
2355
|
+
return chalk7.yellow;
|
|
2243
2356
|
case "low":
|
|
2244
|
-
return
|
|
2357
|
+
return chalk7.blue;
|
|
2245
2358
|
case "info":
|
|
2246
|
-
return
|
|
2359
|
+
return chalk7.gray;
|
|
2247
2360
|
default:
|
|
2248
|
-
return
|
|
2361
|
+
return chalk7.white;
|
|
2249
2362
|
}
|
|
2250
2363
|
}
|
|
2251
2364
|
|
|
@@ -2253,12 +2366,12 @@ function getSeverityColor(severity) {
|
|
|
2253
2366
|
init_esm_shims();
|
|
2254
2367
|
init_config();
|
|
2255
2368
|
import { Command as Command6 } from "commander";
|
|
2256
|
-
import
|
|
2369
|
+
import chalk8 from "chalk";
|
|
2257
2370
|
import ora4 from "ora";
|
|
2258
2371
|
import axios5 from "axios";
|
|
2259
2372
|
import { glob as glob2 } from "glob";
|
|
2260
|
-
import
|
|
2261
|
-
import
|
|
2373
|
+
import fs7 from "fs/promises";
|
|
2374
|
+
import path8 from "path";
|
|
2262
2375
|
import inquirer from "inquirer";
|
|
2263
2376
|
import * as Diff from "diff";
|
|
2264
2377
|
function createFixCommand() {
|
|
@@ -2269,31 +2382,31 @@ function createFixCommand() {
|
|
|
2269
2382
|
const apiUrl = getApiUrl();
|
|
2270
2383
|
const projectId = options.project || getProjectId();
|
|
2271
2384
|
if (!projectId) {
|
|
2272
|
-
console.log(
|
|
2385
|
+
console.log(chalk8.yellow("\u26A0\uFE0F Project ID is required for fixing. Using default or pass --project <id>"));
|
|
2273
2386
|
}
|
|
2274
|
-
const scanPath =
|
|
2387
|
+
const scanPath = path8.resolve(process.cwd(), targetPath);
|
|
2275
2388
|
const gitignorePatterns = await readGitignore(scanPath);
|
|
2276
|
-
const pattern =
|
|
2389
|
+
const pattern = path8.join(scanPath, "**/*");
|
|
2277
2390
|
const allFiles = await glob2(pattern, { nodir: true, dot: false, ignore: ["**/node_modules/**", "**/.git/**"] });
|
|
2278
2391
|
const codeFiles = allFiles.filter((file) => {
|
|
2279
|
-
const relativePath =
|
|
2392
|
+
const relativePath = path8.relative(scanPath, file);
|
|
2280
2393
|
return isCodeFile(file) && !shouldIgnore(relativePath, gitignorePatterns);
|
|
2281
2394
|
});
|
|
2282
2395
|
if (codeFiles.length === 0) {
|
|
2283
|
-
console.log(
|
|
2396
|
+
console.log(chalk8.yellow("No code files found."));
|
|
2284
2397
|
return;
|
|
2285
2398
|
}
|
|
2286
|
-
console.log(
|
|
2399
|
+
console.log(chalk8.bold(`
|
|
2287
2400
|
\u{1F9E0} Rigstate Fix Mode`));
|
|
2288
|
-
console.log(
|
|
2401
|
+
console.log(chalk8.dim(`Scanning ${codeFiles.length} files with Project Context...
|
|
2289
2402
|
`));
|
|
2290
2403
|
let fixedCount = 0;
|
|
2291
2404
|
for (let i = 0; i < codeFiles.length; i++) {
|
|
2292
2405
|
const filePath = codeFiles[i];
|
|
2293
|
-
const relativePath =
|
|
2406
|
+
const relativePath = path8.relative(scanPath, filePath);
|
|
2294
2407
|
spinner.start(`Analyzing ${relativePath}...`);
|
|
2295
2408
|
try {
|
|
2296
|
-
const content = await
|
|
2409
|
+
const content = await fs7.readFile(filePath, "utf-8");
|
|
2297
2410
|
const response = await axios5.post(
|
|
2298
2411
|
`${apiUrl}/api/v1/audit`,
|
|
2299
2412
|
{ content, file_path: relativePath, project_id: projectId },
|
|
@@ -2304,22 +2417,22 @@ function createFixCommand() {
|
|
|
2304
2417
|
if (fixableIssues.length > 0) {
|
|
2305
2418
|
spinner.stop();
|
|
2306
2419
|
console.log(`
|
|
2307
|
-
${
|
|
2420
|
+
${chalk8.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
2308
2421
|
for (const issue of fixableIssues) {
|
|
2309
|
-
console.log(
|
|
2422
|
+
console.log(chalk8.red(`
|
|
2310
2423
|
[${issue.type}] ${issue.title}`));
|
|
2311
|
-
console.log(
|
|
2424
|
+
console.log(chalk8.dim(issue.suggestion || issue.message));
|
|
2312
2425
|
const diff = Diff.createTwoFilesPatch(relativePath, relativePath, content, issue.fixed_content, "Current", "Fixed");
|
|
2313
2426
|
console.log("\n" + diff.split("\n").slice(0, 15).join("\n") + (diff.split("\n").length > 15 ? "\n..." : ""));
|
|
2314
2427
|
const { apply } = await inquirer.prompt([{
|
|
2315
2428
|
type: "confirm",
|
|
2316
2429
|
name: "apply",
|
|
2317
|
-
message: `Apply this fix to ${
|
|
2430
|
+
message: `Apply this fix to ${chalk8.cyan(relativePath)}?`,
|
|
2318
2431
|
default: true
|
|
2319
2432
|
}]);
|
|
2320
2433
|
if (apply) {
|
|
2321
|
-
await
|
|
2322
|
-
console.log(
|
|
2434
|
+
await fs7.writeFile(filePath, issue.fixed_content);
|
|
2435
|
+
console.log(chalk8.green(`\u2705 Fixed applied!`));
|
|
2323
2436
|
fixedCount++;
|
|
2324
2437
|
if (issue.related_step_id) {
|
|
2325
2438
|
const { completeStep } = await inquirer.prompt([{
|
|
@@ -2335,15 +2448,15 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
2335
2448
|
{ step_id: issue.related_step_id, status: "COMPLETED", project_id: projectId },
|
|
2336
2449
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
2337
2450
|
);
|
|
2338
|
-
console.log(
|
|
2451
|
+
console.log(chalk8.green(`\u{1F680} Roadmap updated! Mission Control is in sync.`));
|
|
2339
2452
|
} catch (err) {
|
|
2340
|
-
console.error(
|
|
2453
|
+
console.error(chalk8.yellow(`Failed to update roadmap: ${err.message}`));
|
|
2341
2454
|
}
|
|
2342
2455
|
}
|
|
2343
2456
|
}
|
|
2344
2457
|
break;
|
|
2345
2458
|
} else {
|
|
2346
|
-
console.log(
|
|
2459
|
+
console.log(chalk8.dim("Skipped."));
|
|
2347
2460
|
}
|
|
2348
2461
|
}
|
|
2349
2462
|
} else {
|
|
@@ -2353,11 +2466,11 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
2353
2466
|
}
|
|
2354
2467
|
}
|
|
2355
2468
|
spinner.stop();
|
|
2356
|
-
console.log(
|
|
2469
|
+
console.log(chalk8.bold.green(`
|
|
2357
2470
|
|
|
2358
2471
|
\u{1F680} Fix session complete!`));
|
|
2359
2472
|
console.log(`Frank fixed ${fixedCount} detected issues.`);
|
|
2360
|
-
console.log(
|
|
2473
|
+
console.log(chalk8.dim(`Run 'rigstate scan' to verify remaining issues.`));
|
|
2361
2474
|
} catch (error) {
|
|
2362
2475
|
spinner.fail("Fix session failed");
|
|
2363
2476
|
console.error(error.message);
|
|
@@ -2369,11 +2482,11 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
2369
2482
|
init_esm_shims();
|
|
2370
2483
|
init_config();
|
|
2371
2484
|
import { Command as Command7 } from "commander";
|
|
2372
|
-
import
|
|
2485
|
+
import chalk12 from "chalk";
|
|
2373
2486
|
import ora5 from "ora";
|
|
2374
2487
|
import axios8 from "axios";
|
|
2375
|
-
import
|
|
2376
|
-
import
|
|
2488
|
+
import fs11 from "fs/promises";
|
|
2489
|
+
import path12 from "path";
|
|
2377
2490
|
function createSyncCommand() {
|
|
2378
2491
|
const sync = new Command7("sync");
|
|
2379
2492
|
sync.description("Synchronize local state with Rigstate Cloud").option("-p, --project <id>", "Specify Project ID (saves to config automatically)").action(async (options) => {
|
|
@@ -2388,13 +2501,9 @@ function createSyncCommand() {
|
|
|
2388
2501
|
}
|
|
2389
2502
|
let projectId = options.project;
|
|
2390
2503
|
if (!projectId) {
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
const manifest = JSON.parse(manifestContent);
|
|
2395
|
-
if (manifest.project_id) projectId = manifest.project_id;
|
|
2396
|
-
} catch (e) {
|
|
2397
|
-
}
|
|
2504
|
+
const { loadManifest: loadManifest2 } = await Promise.resolve().then(() => (init_manifest(), manifest_exports));
|
|
2505
|
+
const manifest = await loadManifest2();
|
|
2506
|
+
if (manifest?.project_id) projectId = manifest.project_id;
|
|
2398
2507
|
}
|
|
2399
2508
|
if (!projectId) projectId = getProjectId();
|
|
2400
2509
|
if (options.project) {
|
|
@@ -2414,31 +2523,30 @@ function createSyncCommand() {
|
|
|
2414
2523
|
}
|
|
2415
2524
|
const { roadmap, project } = response.data.data;
|
|
2416
2525
|
const timestamp = response.data.timestamp;
|
|
2417
|
-
const targetPath =
|
|
2526
|
+
const targetPath = path12.join(process.cwd(), "roadmap.json");
|
|
2418
2527
|
const fileContent = JSON.stringify({
|
|
2419
2528
|
project,
|
|
2420
2529
|
last_synced: timestamp,
|
|
2421
2530
|
roadmap
|
|
2422
2531
|
}, null, 2);
|
|
2423
|
-
await
|
|
2532
|
+
await fs11.writeFile(targetPath, fileContent, "utf-8");
|
|
2424
2533
|
try {
|
|
2425
|
-
const
|
|
2426
|
-
|
|
2534
|
+
const { saveManifest: saveManifest2 } = await Promise.resolve().then(() => (init_manifest(), manifest_exports));
|
|
2535
|
+
await saveManifest2({
|
|
2427
2536
|
project_id: projectId,
|
|
2428
|
-
|
|
2429
|
-
|
|
2537
|
+
linked_at: timestamp,
|
|
2538
|
+
// Using timestamp as linked_at for consistency
|
|
2430
2539
|
api_url: apiUrl
|
|
2431
|
-
};
|
|
2432
|
-
await fs9.writeFile(manifestPath, JSON.stringify(manifestContent, null, 2), "utf-8");
|
|
2540
|
+
});
|
|
2433
2541
|
} catch (e) {
|
|
2434
2542
|
}
|
|
2435
|
-
console.log(
|
|
2543
|
+
console.log(chalk12.bold("\n\u{1F9E0} Agent Skills Provisioning..."));
|
|
2436
2544
|
try {
|
|
2437
2545
|
const { provisionSkills: provisionSkills2, generateSkillsDiscoveryBlock: generateSkillsDiscoveryBlock2 } = await Promise.resolve().then(() => (init_skills_provisioner(), skills_provisioner_exports));
|
|
2438
2546
|
const skills = await provisionSkills2(apiUrl, apiKey, projectId, process.cwd());
|
|
2439
|
-
const cursorRulesPath =
|
|
2547
|
+
const cursorRulesPath = path12.join(process.cwd(), ".cursorrules");
|
|
2440
2548
|
try {
|
|
2441
|
-
let rulesContent = await
|
|
2549
|
+
let rulesContent = await fs11.readFile(cursorRulesPath, "utf-8");
|
|
2442
2550
|
const skillsBlock = generateSkillsDiscoveryBlock2(skills);
|
|
2443
2551
|
if (rulesContent.includes("<available_skills>")) {
|
|
2444
2552
|
rulesContent = rulesContent.replace(
|
|
@@ -2451,17 +2559,17 @@ function createSyncCommand() {
|
|
|
2451
2559
|
rulesContent = rulesContent.slice(0, insertPoint + 3) + "\n\n" + skillsBlock + "\n" + rulesContent.slice(insertPoint + 3);
|
|
2452
2560
|
}
|
|
2453
2561
|
}
|
|
2454
|
-
await
|
|
2455
|
-
console.log(
|
|
2562
|
+
await fs11.writeFile(cursorRulesPath, rulesContent, "utf-8");
|
|
2563
|
+
console.log(chalk12.dim(` Updated .cursorrules with skills discovery block`));
|
|
2456
2564
|
} catch (e) {
|
|
2457
2565
|
}
|
|
2458
2566
|
} catch (e) {
|
|
2459
|
-
console.log(
|
|
2567
|
+
console.log(chalk12.yellow(` \u26A0 Skills provisioning skipped: ${e.message}`));
|
|
2460
2568
|
}
|
|
2461
2569
|
try {
|
|
2462
|
-
const logPath =
|
|
2570
|
+
const logPath = path12.join(process.cwd(), ".rigstate", "logs", "last_execution.json");
|
|
2463
2571
|
try {
|
|
2464
|
-
const logContent = await
|
|
2572
|
+
const logContent = await fs11.readFile(logPath, "utf-8");
|
|
2465
2573
|
const logData = JSON.parse(logContent);
|
|
2466
2574
|
if (logData.task_summary) {
|
|
2467
2575
|
await axios8.post(`${apiUrl}/api/v1/execution-logs`, {
|
|
@@ -2471,8 +2579,8 @@ function createSyncCommand() {
|
|
|
2471
2579
|
}, {
|
|
2472
2580
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2473
2581
|
});
|
|
2474
|
-
await
|
|
2475
|
-
console.log(
|
|
2582
|
+
await fs11.unlink(logPath);
|
|
2583
|
+
console.log(chalk12.dim(`\u2714 Mission Report uploaded.`));
|
|
2476
2584
|
}
|
|
2477
2585
|
} catch (e) {
|
|
2478
2586
|
if (e.code !== "ENOENT") {
|
|
@@ -2480,12 +2588,12 @@ function createSyncCommand() {
|
|
|
2480
2588
|
}
|
|
2481
2589
|
} catch (e) {
|
|
2482
2590
|
}
|
|
2483
|
-
spinner.succeed(
|
|
2484
|
-
console.log(
|
|
2591
|
+
spinner.succeed(chalk12.green(`Synced ${roadmap.length} roadmap steps for project "${project}"`));
|
|
2592
|
+
console.log(chalk12.dim(`Local files updated: roadmap.json`));
|
|
2485
2593
|
const { runGuardianWatchdog: runGuardianWatchdog2 } = await Promise.resolve().then(() => (init_watchdog(), watchdog_exports));
|
|
2486
2594
|
const settings = response.data.data.settings || {};
|
|
2487
2595
|
await runGuardianWatchdog2(process.cwd(), settings, projectId);
|
|
2488
|
-
console.log(
|
|
2596
|
+
console.log(chalk12.bold("\n\u{1F4E1} Agent Bridge Heartbeat..."));
|
|
2489
2597
|
try {
|
|
2490
2598
|
const bridgeResponse = await axios8.get(`${apiUrl}/api/v1/agent/bridge`, {
|
|
2491
2599
|
params: { project_id: projectId },
|
|
@@ -2496,10 +2604,10 @@ function createSyncCommand() {
|
|
|
2496
2604
|
const pending = tasks.filter((t) => t.status === "PENDING");
|
|
2497
2605
|
const approved = tasks.filter((t) => t.status === "APPROVED");
|
|
2498
2606
|
if (pending.length > 0 || approved.length > 0) {
|
|
2499
|
-
console.log(
|
|
2500
|
-
console.log(
|
|
2607
|
+
console.log(chalk12.yellow(`\u26A0 Bridge Alert: ${pending.length} pending, ${approved.length} approved tasks found.`));
|
|
2608
|
+
console.log(chalk12.dim('Run "rigstate fix" to process these tasks or ensure your IDE MCP server is active.'));
|
|
2501
2609
|
} else {
|
|
2502
|
-
console.log(
|
|
2610
|
+
console.log(chalk12.green("\u2714 Heartbeat healthy. No pending bridge tasks."));
|
|
2503
2611
|
}
|
|
2504
2612
|
const pings = pending.filter((t) => t.proposal?.startsWith("ping"));
|
|
2505
2613
|
for (const ping of pings) {
|
|
@@ -2510,25 +2618,25 @@ function createSyncCommand() {
|
|
|
2510
2618
|
}, {
|
|
2511
2619
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2512
2620
|
});
|
|
2513
|
-
console.log(
|
|
2621
|
+
console.log(chalk12.cyan(`\u{1F3D3} Pong! Acknowledged heartbeat signal [${ping.id}]`));
|
|
2514
2622
|
}
|
|
2515
2623
|
}
|
|
2516
2624
|
} catch (e) {
|
|
2517
|
-
console.log(
|
|
2625
|
+
console.log(chalk12.yellow(`\u26A0 Could not verify Bridge status: ${e.message}`));
|
|
2518
2626
|
}
|
|
2519
2627
|
if (options.project) {
|
|
2520
|
-
console.log(
|
|
2628
|
+
console.log(chalk12.blue(`Project context saved. Future commands will use this project.`));
|
|
2521
2629
|
}
|
|
2522
2630
|
try {
|
|
2523
|
-
const migrationDir =
|
|
2524
|
-
const files = await
|
|
2631
|
+
const migrationDir = path12.join(process.cwd(), "supabase", "migrations");
|
|
2632
|
+
const files = await fs11.readdir(migrationDir);
|
|
2525
2633
|
const sqlFiles = files.filter((f) => f.endsWith(".sql")).sort();
|
|
2526
2634
|
if (sqlFiles.length > 0) {
|
|
2527
2635
|
const latestMigration = sqlFiles[sqlFiles.length - 1];
|
|
2528
|
-
console.log(
|
|
2636
|
+
console.log(chalk12.dim(`
|
|
2529
2637
|
\u{1F6E1} Migration Guard:`));
|
|
2530
|
-
console.log(
|
|
2531
|
-
console.log(
|
|
2638
|
+
console.log(chalk12.dim(` Latest Local: ${latestMigration}`));
|
|
2639
|
+
console.log(chalk12.yellow(` \u26A0 Ensure DB schema matches this version. CLI cannot verify Remote RLS policies directly.`));
|
|
2532
2640
|
}
|
|
2533
2641
|
} catch (e) {
|
|
2534
2642
|
}
|
|
@@ -2540,15 +2648,15 @@ function createSyncCommand() {
|
|
|
2540
2648
|
);
|
|
2541
2649
|
if (vaultResponse.data.success) {
|
|
2542
2650
|
const vaultContent = vaultResponse.data.data.content || "";
|
|
2543
|
-
const localEnvPath =
|
|
2651
|
+
const localEnvPath = path12.join(process.cwd(), ".env.local");
|
|
2544
2652
|
let localContent = "";
|
|
2545
2653
|
try {
|
|
2546
|
-
localContent = await
|
|
2654
|
+
localContent = await fs11.readFile(localEnvPath, "utf-8");
|
|
2547
2655
|
} catch (e) {
|
|
2548
2656
|
}
|
|
2549
2657
|
if (vaultContent.trim() !== localContent.trim()) {
|
|
2550
|
-
console.log(
|
|
2551
|
-
console.log(
|
|
2658
|
+
console.log(chalk12.bold("\n\u{1F510} Sovereign Foundation (Vault):"));
|
|
2659
|
+
console.log(chalk12.yellow(" Status: Drift Detected / Update Available"));
|
|
2552
2660
|
const { syncVault } = await import("inquirer").then((m) => m.default.prompt([{
|
|
2553
2661
|
type: "confirm",
|
|
2554
2662
|
name: "syncVault",
|
|
@@ -2556,25 +2664,25 @@ function createSyncCommand() {
|
|
|
2556
2664
|
default: false
|
|
2557
2665
|
}]));
|
|
2558
2666
|
if (syncVault) {
|
|
2559
|
-
await
|
|
2560
|
-
console.log(
|
|
2667
|
+
await fs11.writeFile(localEnvPath, vaultContent, "utf-8");
|
|
2668
|
+
console.log(chalk12.green(" \u2705 .env.local synchronized with Vault."));
|
|
2561
2669
|
} else {
|
|
2562
|
-
console.log(
|
|
2670
|
+
console.log(chalk12.dim(" Skipped vault sync."));
|
|
2563
2671
|
}
|
|
2564
2672
|
} else {
|
|
2565
|
-
console.log(
|
|
2673
|
+
console.log(chalk12.dim("\n\u{1F510} Sovereign Foundation: Synced."));
|
|
2566
2674
|
}
|
|
2567
2675
|
}
|
|
2568
2676
|
} catch (e) {
|
|
2569
2677
|
}
|
|
2570
|
-
console.log(
|
|
2678
|
+
console.log(chalk12.dim("\n\u{1F6E1}\uFE0F System Integrity Check..."));
|
|
2571
2679
|
await checkSystemIntegrity(apiUrl, apiKey, projectId);
|
|
2572
2680
|
} catch (error) {
|
|
2573
2681
|
if (axios8.isAxiosError(error)) {
|
|
2574
2682
|
const message = error.response?.data?.error || error.message;
|
|
2575
|
-
spinner.fail(
|
|
2683
|
+
spinner.fail(chalk12.red(`Sync failed: ${message}`));
|
|
2576
2684
|
} else {
|
|
2577
|
-
spinner.fail(
|
|
2685
|
+
spinner.fail(chalk12.red("Sync failed: " + (error.message || "Unknown error")));
|
|
2578
2686
|
}
|
|
2579
2687
|
}
|
|
2580
2688
|
});
|
|
@@ -2590,65 +2698,50 @@ async function checkSystemIntegrity(apiUrl, apiKey, projectId) {
|
|
|
2590
2698
|
const { migrations, rls, guardian_violations } = response.data.data;
|
|
2591
2699
|
if (migrations) {
|
|
2592
2700
|
if (migrations.in_sync) {
|
|
2593
|
-
console.log(
|
|
2701
|
+
console.log(chalk12.green(` \u2705 Migrations synced (${migrations.count} versions)`));
|
|
2594
2702
|
} else {
|
|
2595
|
-
console.log(
|
|
2703
|
+
console.log(chalk12.red(` \u{1F6D1} CRITICAL: DB Schema out of sync! ${migrations.missing?.length || 0} migrations not applied.`));
|
|
2596
2704
|
if (migrations.missing?.length > 0) {
|
|
2597
|
-
console.log(
|
|
2705
|
+
console.log(chalk12.dim(` Missing: ${migrations.missing.slice(0, 3).join(", ")}${migrations.missing.length > 3 ? "..." : ""}`));
|
|
2598
2706
|
}
|
|
2599
|
-
console.log(
|
|
2707
|
+
console.log(chalk12.yellow(` Run 'supabase db push' or apply migrations immediately.`));
|
|
2600
2708
|
}
|
|
2601
2709
|
}
|
|
2602
2710
|
if (rls) {
|
|
2603
2711
|
if (rls.all_secured) {
|
|
2604
|
-
console.log(
|
|
2712
|
+
console.log(chalk12.green(` \u2705 RLS Audit Passed (${rls.table_count} tables secured)`));
|
|
2605
2713
|
} else {
|
|
2606
|
-
console.log(
|
|
2714
|
+
console.log(chalk12.red(` \u{1F6D1} CRITICAL: Security Vulnerability! ${rls.unsecured?.length || 0} tables have RLS disabled.`));
|
|
2607
2715
|
rls.unsecured?.forEach((table) => {
|
|
2608
|
-
console.log(
|
|
2716
|
+
console.log(chalk12.red(` - ${table}`));
|
|
2609
2717
|
});
|
|
2610
|
-
console.log(
|
|
2718
|
+
console.log(chalk12.yellow(' Enable RLS immediately: ALTER TABLE "table" ENABLE ROW LEVEL SECURITY;'));
|
|
2611
2719
|
}
|
|
2612
2720
|
}
|
|
2613
2721
|
if (guardian_violations) {
|
|
2614
2722
|
if (guardian_violations.count === 0) {
|
|
2615
|
-
console.log(
|
|
2723
|
+
console.log(chalk12.green(" \u2705 Guardian: No active violations"));
|
|
2616
2724
|
} else {
|
|
2617
|
-
console.log(
|
|
2618
|
-
console.log(
|
|
2725
|
+
console.log(chalk12.yellow(` \u26A0\uFE0F Guardian: ${guardian_violations.count} active violations`));
|
|
2726
|
+
console.log(chalk12.dim(' Run "rigstate check" for details.'));
|
|
2619
2727
|
}
|
|
2620
2728
|
}
|
|
2621
2729
|
}
|
|
2622
2730
|
} catch (e) {
|
|
2623
|
-
console.log(
|
|
2731
|
+
console.log(chalk12.dim(" (System integrity check skipped - API endpoint not available)"));
|
|
2624
2732
|
}
|
|
2625
2733
|
}
|
|
2626
2734
|
|
|
2627
2735
|
// src/commands/init.ts
|
|
2628
2736
|
init_esm_shims();
|
|
2737
|
+
init_manifest();
|
|
2738
|
+
init_config();
|
|
2629
2739
|
import { Command as Command8 } from "commander";
|
|
2630
|
-
import
|
|
2631
|
-
import
|
|
2632
|
-
import
|
|
2740
|
+
import chalk13 from "chalk";
|
|
2741
|
+
import fs12 from "fs/promises";
|
|
2742
|
+
import path13 from "path";
|
|
2633
2743
|
import ora6 from "ora";
|
|
2634
2744
|
import { execSync } from "child_process";
|
|
2635
|
-
|
|
2636
|
-
// src/utils/manifest.ts
|
|
2637
|
-
init_esm_shims();
|
|
2638
|
-
import fs10 from "fs/promises";
|
|
2639
|
-
import path11 from "path";
|
|
2640
|
-
async function loadManifest() {
|
|
2641
|
-
try {
|
|
2642
|
-
const manifestPath = path11.join(process.cwd(), ".rigstate");
|
|
2643
|
-
const content = await fs10.readFile(manifestPath, "utf-8");
|
|
2644
|
-
return JSON.parse(content);
|
|
2645
|
-
} catch {
|
|
2646
|
-
return null;
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
|
|
2650
|
-
// src/commands/init.ts
|
|
2651
|
-
init_config();
|
|
2652
2745
|
import axios9 from "axios";
|
|
2653
2746
|
function createInitCommand() {
|
|
2654
2747
|
return new Command8("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) => {
|
|
@@ -2657,7 +2750,7 @@ function createInitCommand() {
|
|
|
2657
2750
|
try {
|
|
2658
2751
|
apiKey = getApiKey();
|
|
2659
2752
|
} catch (e) {
|
|
2660
|
-
spinner.fail(
|
|
2753
|
+
spinner.fail(chalk13.red('Not authenticated. Run "rigstate login" first.'));
|
|
2661
2754
|
return;
|
|
2662
2755
|
}
|
|
2663
2756
|
const apiUrl = getApiUrl();
|
|
@@ -2754,7 +2847,7 @@ function createInitCommand() {
|
|
|
2754
2847
|
selectedOrgId = orgId;
|
|
2755
2848
|
}
|
|
2756
2849
|
if (!selectedOrgId) {
|
|
2757
|
-
console.log(
|
|
2850
|
+
console.log(chalk13.yellow("No organization available. Please create the project via the Rigstate dashboard."));
|
|
2758
2851
|
return;
|
|
2759
2852
|
}
|
|
2760
2853
|
spinner.start("Creating new project...");
|
|
@@ -2766,13 +2859,13 @@ function createInitCommand() {
|
|
|
2766
2859
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2767
2860
|
});
|
|
2768
2861
|
if (!createResponse.data.success) {
|
|
2769
|
-
spinner.fail(
|
|
2862
|
+
spinner.fail(chalk13.red("Failed to create project: " + createResponse.data.error));
|
|
2770
2863
|
return;
|
|
2771
2864
|
}
|
|
2772
2865
|
projectId = createResponse.data.data.project.id;
|
|
2773
|
-
spinner.succeed(
|
|
2866
|
+
spinner.succeed(chalk13.green(`Created new project: ${newName}`));
|
|
2774
2867
|
} catch (e) {
|
|
2775
|
-
spinner.fail(
|
|
2868
|
+
spinner.fail(chalk13.red("Project creation API not available. Please create via dashboard."));
|
|
2776
2869
|
return;
|
|
2777
2870
|
}
|
|
2778
2871
|
} else {
|
|
@@ -2782,28 +2875,27 @@ function createInitCommand() {
|
|
|
2782
2875
|
spinner.start(`Linking to project ID: ${projectId}...`);
|
|
2783
2876
|
}
|
|
2784
2877
|
setProjectId(projectId);
|
|
2785
|
-
const
|
|
2786
|
-
|
|
2878
|
+
const { saveManifest: saveManifest2 } = await Promise.resolve().then(() => (init_manifest(), manifest_exports));
|
|
2879
|
+
await saveManifest2({
|
|
2787
2880
|
project_id: projectId,
|
|
2788
|
-
|
|
2881
|
+
linked_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2789
2882
|
api_url: apiUrl
|
|
2790
|
-
};
|
|
2791
|
-
await fs11.writeFile(manifestPath, JSON.stringify(manifestContent, null, 2), "utf-8");
|
|
2883
|
+
});
|
|
2792
2884
|
try {
|
|
2793
|
-
await
|
|
2885
|
+
await fs12.access(".git");
|
|
2794
2886
|
} catch {
|
|
2795
2887
|
spinner.text = "Initializing git repository...";
|
|
2796
2888
|
execSync("git init", { stdio: "ignore" });
|
|
2797
2889
|
}
|
|
2798
|
-
spinner.succeed(
|
|
2890
|
+
spinner.succeed(chalk13.green(`\u2705 Linked to project: ${projectId}`));
|
|
2799
2891
|
await generateRules(apiUrl, apiKey, projectId, options.force, spinner);
|
|
2800
2892
|
console.log("");
|
|
2801
|
-
console.log(
|
|
2802
|
-
console.log(
|
|
2803
|
-
console.log(
|
|
2804
|
-
console.log(
|
|
2893
|
+
console.log(chalk13.blue("Next steps:"));
|
|
2894
|
+
console.log(chalk13.dim(" rigstate sync - Sync roadmap and context"));
|
|
2895
|
+
console.log(chalk13.dim(" rigstate watch - Start development loop"));
|
|
2896
|
+
console.log(chalk13.dim(" rigstate focus - Get current task"));
|
|
2805
2897
|
} catch (e) {
|
|
2806
|
-
spinner.fail(
|
|
2898
|
+
spinner.fail(chalk13.red("Initialization failed: " + e.message));
|
|
2807
2899
|
}
|
|
2808
2900
|
});
|
|
2809
2901
|
}
|
|
@@ -2818,67 +2910,68 @@ async function generateRules(apiUrl, apiKey, projectId, force, spinner) {
|
|
|
2818
2910
|
if (response.data.success || response.data.files) {
|
|
2819
2911
|
const files = response.data.files || [];
|
|
2820
2912
|
if (files.length === 0 && response.data.rules) {
|
|
2821
|
-
const rulesPath =
|
|
2822
|
-
await
|
|
2823
|
-
spinner.succeed(
|
|
2913
|
+
const rulesPath = path13.join(process.cwd(), ".cursorrules");
|
|
2914
|
+
await fs12.writeFile(rulesPath, response.data.rules, "utf-8");
|
|
2915
|
+
spinner.succeed(chalk13.green("\u2714 Generated .cursorrules (legacy mode)"));
|
|
2824
2916
|
return;
|
|
2825
2917
|
}
|
|
2826
2918
|
for (const file of files) {
|
|
2827
|
-
const targetPath =
|
|
2828
|
-
const targetDir =
|
|
2829
|
-
await
|
|
2919
|
+
const targetPath = path13.join(process.cwd(), file.path);
|
|
2920
|
+
const targetDir = path13.dirname(targetPath);
|
|
2921
|
+
await fs12.mkdir(targetDir, { recursive: true });
|
|
2830
2922
|
try {
|
|
2831
|
-
await
|
|
2923
|
+
await fs12.access(targetPath);
|
|
2832
2924
|
if (!force && !file.path.startsWith(".cursor/rules/")) {
|
|
2833
|
-
console.log(
|
|
2925
|
+
console.log(chalk13.dim(` ${file.path} already exists. Skipping.`));
|
|
2834
2926
|
continue;
|
|
2835
2927
|
}
|
|
2836
2928
|
} catch {
|
|
2837
2929
|
}
|
|
2838
|
-
await
|
|
2930
|
+
await fs12.writeFile(targetPath, file.content, "utf-8");
|
|
2839
2931
|
}
|
|
2840
2932
|
if (files.length > 0) {
|
|
2841
|
-
const legacyPath =
|
|
2933
|
+
const legacyPath = path13.join(process.cwd(), ".cursorrules");
|
|
2842
2934
|
try {
|
|
2843
|
-
const stats = await
|
|
2935
|
+
const stats = await fs12.stat(legacyPath);
|
|
2844
2936
|
if (stats.isFile()) {
|
|
2845
|
-
await
|
|
2846
|
-
console.log(
|
|
2937
|
+
await fs12.rename(legacyPath, `${legacyPath}.bak`);
|
|
2938
|
+
console.log(chalk13.dim(" Moved legacy .cursorrules to .cursorrules.bak"));
|
|
2847
2939
|
}
|
|
2848
2940
|
} catch (e) {
|
|
2849
2941
|
}
|
|
2850
2942
|
}
|
|
2851
|
-
spinner.succeed(
|
|
2943
|
+
spinner.succeed(chalk13.green(`\u2714 Generated ${files.length} rule files (v${response.data.version || "3.0"})`));
|
|
2852
2944
|
} else {
|
|
2853
|
-
spinner.info(
|
|
2945
|
+
spinner.info(chalk13.dim(" Rules generation skipped (API response invalid)"));
|
|
2854
2946
|
}
|
|
2855
2947
|
} catch (e) {
|
|
2856
|
-
spinner.info(
|
|
2948
|
+
spinner.info(chalk13.dim(` Rules generation failed: ${e.message}`));
|
|
2857
2949
|
}
|
|
2858
2950
|
}
|
|
2859
2951
|
|
|
2860
2952
|
// src/commands/check.ts
|
|
2861
2953
|
init_esm_shims();
|
|
2862
2954
|
init_config();
|
|
2955
|
+
init_manifest();
|
|
2863
2956
|
import { Command as Command9 } from "commander";
|
|
2864
|
-
import
|
|
2957
|
+
import chalk15 from "chalk";
|
|
2865
2958
|
import ora7 from "ora";
|
|
2866
2959
|
import axios10 from "axios";
|
|
2867
2960
|
import { glob as glob3 } from "glob";
|
|
2868
|
-
import
|
|
2869
|
-
import
|
|
2961
|
+
import fs14 from "fs/promises";
|
|
2962
|
+
import path15 from "path";
|
|
2870
2963
|
import { execSync as execSync2 } from "child_process";
|
|
2871
2964
|
|
|
2872
2965
|
// src/utils/rule-engine.ts
|
|
2873
2966
|
init_esm_shims();
|
|
2874
|
-
import
|
|
2875
|
-
import
|
|
2876
|
-
import
|
|
2967
|
+
import fs13 from "fs/promises";
|
|
2968
|
+
import path14 from "path";
|
|
2969
|
+
import chalk14 from "chalk";
|
|
2877
2970
|
async function checkFile(filePath, rules, rootPath) {
|
|
2878
2971
|
const violations = [];
|
|
2879
|
-
const relativePath =
|
|
2972
|
+
const relativePath = path14.relative(rootPath, filePath);
|
|
2880
2973
|
try {
|
|
2881
|
-
const content = await
|
|
2974
|
+
const content = await fs13.readFile(filePath, "utf-8");
|
|
2882
2975
|
const lines = content.split("\n");
|
|
2883
2976
|
for (const rule of rules) {
|
|
2884
2977
|
const ruleViolations = await evaluateRule(rule, content, lines, relativePath);
|
|
@@ -2969,7 +3062,7 @@ async function evaluateRule(rule, content, lines, filePath) {
|
|
|
2969
3062
|
case "NAMING_CONVENTION": {
|
|
2970
3063
|
const value = rule.value;
|
|
2971
3064
|
const pattern = new RegExp(value.pattern);
|
|
2972
|
-
const fileName =
|
|
3065
|
+
const fileName = path14.basename(filePath);
|
|
2973
3066
|
if (filePath.includes(value.context) && !pattern.test(fileName)) {
|
|
2974
3067
|
violations.push({
|
|
2975
3068
|
file: filePath,
|
|
@@ -3028,12 +3121,12 @@ function checkFunctionLines(content, lines, filePath, rule, limit) {
|
|
|
3028
3121
|
}
|
|
3029
3122
|
function formatViolations(violations) {
|
|
3030
3123
|
for (const v of violations) {
|
|
3031
|
-
const severityColor = v.severity === "critical" ?
|
|
3032
|
-
const lineInfo = v.line ?
|
|
3124
|
+
const severityColor = v.severity === "critical" ? chalk14.red : v.severity === "warning" ? chalk14.yellow : chalk14.blue;
|
|
3125
|
+
const lineInfo = v.line ? chalk14.dim(`:${v.line}`) : "";
|
|
3033
3126
|
console.log(` ${severityColor(`[${v.severity.toUpperCase()}]`)} ${v.file}${lineInfo}`);
|
|
3034
3127
|
console.log(` ${v.message}`);
|
|
3035
3128
|
if (v.details) {
|
|
3036
|
-
console.log(` ${
|
|
3129
|
+
console.log(` ${chalk14.dim(v.details)}`);
|
|
3037
3130
|
}
|
|
3038
3131
|
}
|
|
3039
3132
|
}
|
|
@@ -3078,15 +3171,15 @@ function createCheckCommand() {
|
|
|
3078
3171
|
projectId = getProjectId();
|
|
3079
3172
|
}
|
|
3080
3173
|
if (!projectId) {
|
|
3081
|
-
console.log(
|
|
3082
|
-
console.log(
|
|
3174
|
+
console.log(chalk15.red("\u274C No project context found."));
|
|
3175
|
+
console.log(chalk15.dim(' Run "rigstate link" or pass --project <id>'));
|
|
3083
3176
|
process.exit(2);
|
|
3084
3177
|
}
|
|
3085
3178
|
let apiKey;
|
|
3086
3179
|
try {
|
|
3087
3180
|
apiKey = getApiKey();
|
|
3088
3181
|
} catch {
|
|
3089
|
-
console.log(
|
|
3182
|
+
console.log(chalk15.red('\u274C Not authenticated. Run "rigstate login" first.'));
|
|
3090
3183
|
process.exit(2);
|
|
3091
3184
|
}
|
|
3092
3185
|
spinner.start("Fetching Guardian rules...");
|
|
@@ -3114,17 +3207,17 @@ function createCheckCommand() {
|
|
|
3114
3207
|
} catch (apiError) {
|
|
3115
3208
|
const cached = await loadCachedRules(projectId);
|
|
3116
3209
|
if (cached && !isStale(cached.timestamp, CACHE_MAX_AGE_MS)) {
|
|
3117
|
-
spinner.warn(
|
|
3210
|
+
spinner.warn(chalk15.yellow("Using cached rules (API unavailable)"));
|
|
3118
3211
|
rules = cached.rules;
|
|
3119
3212
|
settings = cached.settings;
|
|
3120
3213
|
} else {
|
|
3121
|
-
spinner.fail(
|
|
3122
|
-
console.log(
|
|
3214
|
+
spinner.fail(chalk15.red("Failed to fetch rules and no valid cache"));
|
|
3215
|
+
console.log(chalk15.dim(` Error: ${apiError.message}`));
|
|
3123
3216
|
process.exit(2);
|
|
3124
3217
|
}
|
|
3125
3218
|
}
|
|
3126
3219
|
spinner.succeed(`Loaded ${rules.length} Guardian rules`);
|
|
3127
|
-
const scanPath =
|
|
3220
|
+
const scanPath = path15.resolve(process.cwd(), targetPath);
|
|
3128
3221
|
let filesToCheck;
|
|
3129
3222
|
if (options.staged) {
|
|
3130
3223
|
spinner.start("Getting staged files...");
|
|
@@ -3133,14 +3226,14 @@ function createCheckCommand() {
|
|
|
3133
3226
|
encoding: "utf-8",
|
|
3134
3227
|
cwd: process.cwd()
|
|
3135
3228
|
});
|
|
3136
|
-
filesToCheck = stagedOutput.split("\n").filter((f) => f.trim()).filter((f) => isCodeFile2(f)).map((f) =>
|
|
3229
|
+
filesToCheck = stagedOutput.split("\n").filter((f) => f.trim()).filter((f) => isCodeFile2(f)).map((f) => path15.resolve(process.cwd(), f));
|
|
3137
3230
|
} catch {
|
|
3138
3231
|
spinner.fail("Not a git repository or no staged files");
|
|
3139
3232
|
process.exit(2);
|
|
3140
3233
|
}
|
|
3141
3234
|
} else {
|
|
3142
|
-
spinner.start(`Scanning ${
|
|
3143
|
-
const pattern =
|
|
3235
|
+
spinner.start(`Scanning ${chalk15.cyan(targetPath)}...`);
|
|
3236
|
+
const pattern = path15.join(scanPath, "**/*");
|
|
3144
3237
|
const allFiles = await glob3(pattern, {
|
|
3145
3238
|
nodir: true,
|
|
3146
3239
|
dot: false,
|
|
@@ -3156,7 +3249,7 @@ function createCheckCommand() {
|
|
|
3156
3249
|
filesToCheck = allFiles.filter((f) => isCodeFile2(f));
|
|
3157
3250
|
}
|
|
3158
3251
|
if (filesToCheck.length === 0) {
|
|
3159
|
-
spinner.warn(
|
|
3252
|
+
spinner.warn(chalk15.yellow("No code files found to check."));
|
|
3160
3253
|
outputResults([], !!options.json);
|
|
3161
3254
|
process.exit(0);
|
|
3162
3255
|
}
|
|
@@ -3165,7 +3258,7 @@ function createCheckCommand() {
|
|
|
3165
3258
|
const results = [];
|
|
3166
3259
|
for (let i = 0; i < filesToCheck.length; i++) {
|
|
3167
3260
|
const file = filesToCheck[i];
|
|
3168
|
-
spinner.text = `Checking ${i + 1}/${filesToCheck.length}: ${
|
|
3261
|
+
spinner.text = `Checking ${i + 1}/${filesToCheck.length}: ${path15.basename(file)}`;
|
|
3169
3262
|
const result = await checkFile(file, rules, process.cwd());
|
|
3170
3263
|
results.push(result);
|
|
3171
3264
|
}
|
|
@@ -3175,47 +3268,47 @@ function createCheckCommand() {
|
|
|
3175
3268
|
outputResults(results, true);
|
|
3176
3269
|
} else {
|
|
3177
3270
|
outputResults(results, false);
|
|
3178
|
-
console.log("\n" +
|
|
3179
|
-
console.log(
|
|
3180
|
-
console.log(`Files checked: ${
|
|
3181
|
-
console.log(`Total violations: ${summary.totalViolations > 0 ?
|
|
3271
|
+
console.log("\n" + chalk15.bold("\u{1F4CA} Summary"));
|
|
3272
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
3273
|
+
console.log(`Files checked: ${chalk15.cyan(summary.totalFiles)}`);
|
|
3274
|
+
console.log(`Total violations: ${summary.totalViolations > 0 ? chalk15.red(summary.totalViolations) : chalk15.green(0)}`);
|
|
3182
3275
|
if (summary.totalViolations > 0) {
|
|
3183
|
-
console.log(` ${
|
|
3184
|
-
console.log(` ${
|
|
3185
|
-
console.log(` ${
|
|
3276
|
+
console.log(` ${chalk15.red("Critical:")} ${summary.criticalCount}`);
|
|
3277
|
+
console.log(` ${chalk15.yellow("Warning:")} ${summary.warningCount}`);
|
|
3278
|
+
console.log(` ${chalk15.blue("Info:")} ${summary.infoCount}`);
|
|
3186
3279
|
}
|
|
3187
|
-
console.log(
|
|
3280
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
3188
3281
|
}
|
|
3189
3282
|
if (options.strict !== void 0) {
|
|
3190
3283
|
const strictLevel = typeof options.strict === "string" ? options.strict : "all";
|
|
3191
3284
|
if (strictLevel === "critical" && summary.criticalCount > 0) {
|
|
3192
|
-
console.log(
|
|
3285
|
+
console.log(chalk15.red("\n\u274C Check failed: Critical violations found"));
|
|
3193
3286
|
process.exit(1);
|
|
3194
3287
|
} else if (strictLevel === "all" && summary.totalViolations > 0) {
|
|
3195
|
-
console.log(
|
|
3288
|
+
console.log(chalk15.red("\n\u274C Check failed: Violations found"));
|
|
3196
3289
|
process.exit(1);
|
|
3197
3290
|
}
|
|
3198
3291
|
}
|
|
3199
3292
|
if (summary.totalViolations === 0) {
|
|
3200
|
-
console.log(
|
|
3293
|
+
console.log(chalk15.green("\n\u2705 All checks passed!"));
|
|
3201
3294
|
}
|
|
3202
3295
|
process.exit(0);
|
|
3203
3296
|
} catch (error) {
|
|
3204
|
-
spinner.fail(
|
|
3205
|
-
console.error(
|
|
3297
|
+
spinner.fail(chalk15.red("Check failed"));
|
|
3298
|
+
console.error(chalk15.red("Error:"), error.message);
|
|
3206
3299
|
process.exit(2);
|
|
3207
3300
|
}
|
|
3208
3301
|
});
|
|
3209
3302
|
}
|
|
3210
3303
|
function isCodeFile2(filePath) {
|
|
3211
3304
|
const codeExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
3212
|
-
const ext =
|
|
3305
|
+
const ext = path15.extname(filePath).toLowerCase();
|
|
3213
3306
|
return codeExtensions.includes(ext);
|
|
3214
3307
|
}
|
|
3215
3308
|
async function loadCachedRules(projectId) {
|
|
3216
3309
|
try {
|
|
3217
|
-
const cachePath =
|
|
3218
|
-
const content = await
|
|
3310
|
+
const cachePath = path15.join(process.cwd(), CACHE_FILE2);
|
|
3311
|
+
const content = await fs14.readFile(cachePath, "utf-8");
|
|
3219
3312
|
const cached = JSON.parse(content);
|
|
3220
3313
|
if (cached.projectId !== projectId) {
|
|
3221
3314
|
return null;
|
|
@@ -3227,16 +3320,16 @@ async function loadCachedRules(projectId) {
|
|
|
3227
3320
|
}
|
|
3228
3321
|
async function saveCachedRules(projectId, rules, settings) {
|
|
3229
3322
|
try {
|
|
3230
|
-
const cacheDir =
|
|
3231
|
-
await
|
|
3323
|
+
const cacheDir = path15.join(process.cwd(), ".rigstate");
|
|
3324
|
+
await fs14.mkdir(cacheDir, { recursive: true });
|
|
3232
3325
|
const cached = {
|
|
3233
3326
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3234
3327
|
projectId,
|
|
3235
3328
|
rules,
|
|
3236
3329
|
settings
|
|
3237
3330
|
};
|
|
3238
|
-
await
|
|
3239
|
-
|
|
3331
|
+
await fs14.writeFile(
|
|
3332
|
+
path15.join(cacheDir, "rules-cache.json"),
|
|
3240
3333
|
JSON.stringify(cached, null, 2)
|
|
3241
3334
|
);
|
|
3242
3335
|
} catch {
|
|
@@ -3258,8 +3351,8 @@ function outputResults(results, json) {
|
|
|
3258
3351
|
if (!hasViolations) {
|
|
3259
3352
|
return;
|
|
3260
3353
|
}
|
|
3261
|
-
console.log("\n" +
|
|
3262
|
-
console.log(
|
|
3354
|
+
console.log("\n" + chalk15.bold("\u{1F50D} Violations Found"));
|
|
3355
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
3263
3356
|
for (const result of results) {
|
|
3264
3357
|
if (result.violations.length > 0) {
|
|
3265
3358
|
formatViolations(result.violations);
|
|
@@ -3270,9 +3363,9 @@ function outputResults(results, json) {
|
|
|
3270
3363
|
// src/commands/hooks.ts
|
|
3271
3364
|
init_esm_shims();
|
|
3272
3365
|
import { Command as Command10 } from "commander";
|
|
3273
|
-
import
|
|
3274
|
-
import
|
|
3275
|
-
import
|
|
3366
|
+
import chalk16 from "chalk";
|
|
3367
|
+
import fs15 from "fs/promises";
|
|
3368
|
+
import path16 from "path";
|
|
3276
3369
|
var PRE_COMMIT_SCRIPT = `#!/bin/sh
|
|
3277
3370
|
# Rigstate Guardian Pre-commit Hook
|
|
3278
3371
|
# Installed by: rigstate hooks install
|
|
@@ -3301,23 +3394,23 @@ function createHooksCommand() {
|
|
|
3301
3394
|
const hooks = new Command10("hooks").description("Manage git hooks for Guardian integration");
|
|
3302
3395
|
hooks.command("install").description("Install pre-commit hook to run Guardian checks").option("--strict [level]", 'Strict level: "all" or "critical" (default)', "critical").action(async (options) => {
|
|
3303
3396
|
try {
|
|
3304
|
-
const gitDir =
|
|
3397
|
+
const gitDir = path16.join(process.cwd(), ".git");
|
|
3305
3398
|
try {
|
|
3306
|
-
await
|
|
3399
|
+
await fs15.access(gitDir);
|
|
3307
3400
|
} catch {
|
|
3308
|
-
console.log(
|
|
3309
|
-
console.log(
|
|
3401
|
+
console.log(chalk16.red("\u274C Not a git repository."));
|
|
3402
|
+
console.log(chalk16.dim(' Initialize with "git init" first.'));
|
|
3310
3403
|
process.exit(1);
|
|
3311
3404
|
}
|
|
3312
|
-
const hooksDir =
|
|
3313
|
-
await
|
|
3314
|
-
const preCommitPath =
|
|
3405
|
+
const hooksDir = path16.join(gitDir, "hooks");
|
|
3406
|
+
await fs15.mkdir(hooksDir, { recursive: true });
|
|
3407
|
+
const preCommitPath = path16.join(hooksDir, "pre-commit");
|
|
3315
3408
|
let existingContent = "";
|
|
3316
3409
|
try {
|
|
3317
|
-
existingContent = await
|
|
3410
|
+
existingContent = await fs15.readFile(preCommitPath, "utf-8");
|
|
3318
3411
|
if (existingContent.includes("rigstate")) {
|
|
3319
|
-
console.log(
|
|
3320
|
-
console.log(
|
|
3412
|
+
console.log(chalk16.yellow("\u26A0 Rigstate pre-commit hook already installed."));
|
|
3413
|
+
console.log(chalk16.dim(' Use "rigstate hooks uninstall" to remove first.'));
|
|
3321
3414
|
return;
|
|
3322
3415
|
}
|
|
3323
3416
|
} catch {
|
|
@@ -3328,34 +3421,34 @@ function createHooksCommand() {
|
|
|
3328
3421
|
}
|
|
3329
3422
|
if (existingContent && !existingContent.includes("rigstate")) {
|
|
3330
3423
|
const combinedScript = existingContent + "\n\n" + script.replace("#!/bin/sh\n", "");
|
|
3331
|
-
await
|
|
3332
|
-
console.log(
|
|
3424
|
+
await fs15.writeFile(preCommitPath, combinedScript, { mode: 493 });
|
|
3425
|
+
console.log(chalk16.green("\u2705 Rigstate hook appended to existing pre-commit."));
|
|
3333
3426
|
} else {
|
|
3334
|
-
await
|
|
3335
|
-
console.log(
|
|
3427
|
+
await fs15.writeFile(preCommitPath, script, { mode: 493 });
|
|
3428
|
+
console.log(chalk16.green("\u2705 Pre-commit hook installed!"));
|
|
3336
3429
|
}
|
|
3337
|
-
console.log(
|
|
3338
|
-
console.log(
|
|
3430
|
+
console.log(chalk16.dim(` Path: ${preCommitPath}`));
|
|
3431
|
+
console.log(chalk16.dim(` Strict level: ${options.strict}`));
|
|
3339
3432
|
console.log("");
|
|
3340
|
-
console.log(
|
|
3341
|
-
console.log(
|
|
3433
|
+
console.log(chalk16.cyan("Guardian will now check your code before each commit."));
|
|
3434
|
+
console.log(chalk16.dim('Use "rigstate hooks uninstall" to remove the hook.'));
|
|
3342
3435
|
} catch (error) {
|
|
3343
|
-
console.error(
|
|
3436
|
+
console.error(chalk16.red("Failed to install hook:"), error.message);
|
|
3344
3437
|
process.exit(1);
|
|
3345
3438
|
}
|
|
3346
3439
|
});
|
|
3347
3440
|
hooks.command("uninstall").description("Remove Rigstate pre-commit hook").action(async () => {
|
|
3348
3441
|
try {
|
|
3349
|
-
const preCommitPath =
|
|
3442
|
+
const preCommitPath = path16.join(process.cwd(), ".git", "hooks", "pre-commit");
|
|
3350
3443
|
try {
|
|
3351
|
-
const content = await
|
|
3444
|
+
const content = await fs15.readFile(preCommitPath, "utf-8");
|
|
3352
3445
|
if (!content.includes("rigstate")) {
|
|
3353
|
-
console.log(
|
|
3446
|
+
console.log(chalk16.yellow("\u26A0 No Rigstate hook found in pre-commit."));
|
|
3354
3447
|
return;
|
|
3355
3448
|
}
|
|
3356
3449
|
if (content.includes("# Rigstate Guardian Pre-commit Hook") && content.trim().split("\n").filter((l) => l && !l.startsWith("#")).length <= 4) {
|
|
3357
|
-
await
|
|
3358
|
-
console.log(
|
|
3450
|
+
await fs15.unlink(preCommitPath);
|
|
3451
|
+
console.log(chalk16.green("\u2705 Pre-commit hook removed."));
|
|
3359
3452
|
} else {
|
|
3360
3453
|
const lines = content.split("\n");
|
|
3361
3454
|
const filteredLines = [];
|
|
@@ -3373,14 +3466,14 @@ function createHooksCommand() {
|
|
|
3373
3466
|
filteredLines.push(line);
|
|
3374
3467
|
}
|
|
3375
3468
|
}
|
|
3376
|
-
await
|
|
3377
|
-
console.log(
|
|
3469
|
+
await fs15.writeFile(preCommitPath, filteredLines.join("\n"), { mode: 493 });
|
|
3470
|
+
console.log(chalk16.green("\u2705 Rigstate section removed from pre-commit hook."));
|
|
3378
3471
|
}
|
|
3379
3472
|
} catch {
|
|
3380
|
-
console.log(
|
|
3473
|
+
console.log(chalk16.yellow("\u26A0 No pre-commit hook found."));
|
|
3381
3474
|
}
|
|
3382
3475
|
} catch (error) {
|
|
3383
|
-
console.error(
|
|
3476
|
+
console.error(chalk16.red("Failed to uninstall hook:"), error.message);
|
|
3384
3477
|
process.exit(1);
|
|
3385
3478
|
}
|
|
3386
3479
|
});
|
|
@@ -3390,40 +3483,40 @@ function createHooksCommand() {
|
|
|
3390
3483
|
// src/commands/daemon.ts
|
|
3391
3484
|
init_esm_shims();
|
|
3392
3485
|
import { Command as Command11 } from "commander";
|
|
3393
|
-
import
|
|
3486
|
+
import chalk22 from "chalk";
|
|
3394
3487
|
import ora8 from "ora";
|
|
3395
|
-
import
|
|
3396
|
-
import
|
|
3488
|
+
import fs21 from "fs/promises";
|
|
3489
|
+
import path24 from "path";
|
|
3397
3490
|
|
|
3398
3491
|
// src/daemon/factory.ts
|
|
3399
3492
|
init_esm_shims();
|
|
3400
3493
|
|
|
3401
3494
|
// src/daemon/core.ts
|
|
3402
3495
|
init_esm_shims();
|
|
3403
|
-
import
|
|
3404
|
-
import * as
|
|
3405
|
-
import
|
|
3496
|
+
import chalk20 from "chalk";
|
|
3497
|
+
import * as fs19 from "fs/promises";
|
|
3498
|
+
import path22 from "path";
|
|
3406
3499
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
3407
3500
|
|
|
3408
3501
|
// src/daemon/file-watcher.ts
|
|
3409
3502
|
init_esm_shims();
|
|
3410
3503
|
import * as chokidar from "chokidar";
|
|
3411
|
-
import
|
|
3504
|
+
import path17 from "path";
|
|
3412
3505
|
import { EventEmitter } from "events";
|
|
3413
3506
|
var CODE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
3414
3507
|
function isCodeFile3(filePath) {
|
|
3415
|
-
const ext =
|
|
3508
|
+
const ext = path17.extname(filePath).toLowerCase();
|
|
3416
3509
|
return CODE_EXTENSIONS.includes(ext);
|
|
3417
3510
|
}
|
|
3418
3511
|
function createFileWatcher(watchPath) {
|
|
3419
3512
|
const emitter = new EventEmitter();
|
|
3420
3513
|
let watcher = null;
|
|
3421
3514
|
emitter.start = () => {
|
|
3422
|
-
const absolutePath =
|
|
3515
|
+
const absolutePath = path17.resolve(process.cwd(), watchPath);
|
|
3423
3516
|
watcher = chokidar.watch(absolutePath, {
|
|
3424
3517
|
ignored: (pathStr) => {
|
|
3425
|
-
const relativePath =
|
|
3426
|
-
const segments = relativePath.split(
|
|
3518
|
+
const relativePath = path17.relative(process.cwd(), pathStr);
|
|
3519
|
+
const segments = relativePath.split(path17.sep);
|
|
3427
3520
|
const ignoreDirs = [
|
|
3428
3521
|
"node_modules",
|
|
3429
3522
|
".git",
|
|
@@ -3455,7 +3548,7 @@ function createFileWatcher(watchPath) {
|
|
|
3455
3548
|
if (segments.some((segment) => ignoreDirs.includes(segment))) {
|
|
3456
3549
|
return true;
|
|
3457
3550
|
}
|
|
3458
|
-
const isFile = !!
|
|
3551
|
+
const isFile = !!path17.extname(pathStr);
|
|
3459
3552
|
if (isFile && !isCodeFile3(pathStr)) {
|
|
3460
3553
|
return true;
|
|
3461
3554
|
}
|
|
@@ -3478,17 +3571,17 @@ function createFileWatcher(watchPath) {
|
|
|
3478
3571
|
});
|
|
3479
3572
|
watcher.on("change", (filePath) => {
|
|
3480
3573
|
if (isCodeFile3(filePath)) {
|
|
3481
|
-
emitter.emit("change",
|
|
3574
|
+
emitter.emit("change", path17.relative(process.cwd(), filePath));
|
|
3482
3575
|
}
|
|
3483
3576
|
});
|
|
3484
3577
|
watcher.on("add", (filePath) => {
|
|
3485
3578
|
if (isCodeFile3(filePath)) {
|
|
3486
|
-
emitter.emit("add",
|
|
3579
|
+
emitter.emit("add", path17.relative(process.cwd(), filePath));
|
|
3487
3580
|
}
|
|
3488
3581
|
});
|
|
3489
3582
|
watcher.on("unlink", (filePath) => {
|
|
3490
3583
|
if (isCodeFile3(filePath)) {
|
|
3491
|
-
emitter.emit("unlink",
|
|
3584
|
+
emitter.emit("unlink", path17.relative(process.cwd(), filePath));
|
|
3492
3585
|
}
|
|
3493
3586
|
});
|
|
3494
3587
|
watcher.on("error", (error) => {
|
|
@@ -3511,7 +3604,7 @@ function createFileWatcher(watchPath) {
|
|
|
3511
3604
|
init_esm_shims();
|
|
3512
3605
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
3513
3606
|
import { dirname } from "path";
|
|
3514
|
-
import
|
|
3607
|
+
import path18 from "path";
|
|
3515
3608
|
import axios11 from "axios";
|
|
3516
3609
|
var GLOBAL_HEURISTICS = [
|
|
3517
3610
|
{
|
|
@@ -3543,7 +3636,7 @@ var HeuristicEngine = class {
|
|
|
3543
3636
|
rules = [];
|
|
3544
3637
|
cachePath;
|
|
3545
3638
|
constructor() {
|
|
3546
|
-
this.cachePath =
|
|
3639
|
+
this.cachePath = path18.join(process.cwd(), ".rigstate", "cache", "heuristics.json");
|
|
3547
3640
|
this.loadRules();
|
|
3548
3641
|
}
|
|
3549
3642
|
async loadRules() {
|
|
@@ -3658,9 +3751,9 @@ function createHeuristicEngine() {
|
|
|
3658
3751
|
|
|
3659
3752
|
// src/daemon/intervention-protocol.ts
|
|
3660
3753
|
init_esm_shims();
|
|
3661
|
-
import
|
|
3662
|
-
import * as
|
|
3663
|
-
import * as
|
|
3754
|
+
import chalk17 from "chalk";
|
|
3755
|
+
import * as fs16 from "fs";
|
|
3756
|
+
import * as path19 from "path";
|
|
3664
3757
|
var InterventionProtocol = class {
|
|
3665
3758
|
activeViolators = /* @__PURE__ */ new Set();
|
|
3666
3759
|
/**
|
|
@@ -3683,18 +3776,18 @@ var InterventionProtocol = class {
|
|
|
3683
3776
|
}
|
|
3684
3777
|
syncLockFile() {
|
|
3685
3778
|
try {
|
|
3686
|
-
const lockDir =
|
|
3687
|
-
if (!
|
|
3688
|
-
const lockPath =
|
|
3779
|
+
const lockDir = path19.join(process.cwd(), ".rigstate");
|
|
3780
|
+
if (!fs16.existsSync(lockDir)) fs16.mkdirSync(lockDir, { recursive: true });
|
|
3781
|
+
const lockPath = path19.join(lockDir, "guardian.lock");
|
|
3689
3782
|
if (this.activeViolators.size > 0) {
|
|
3690
3783
|
const content = `HARD_LOCK_ACTIVE
|
|
3691
3784
|
Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
3692
3785
|
|
|
3693
3786
|
Blocking Files:
|
|
3694
3787
|
${Array.from(this.activeViolators).join("\n")}`;
|
|
3695
|
-
|
|
3788
|
+
fs16.writeFileSync(lockPath, content, "utf-8");
|
|
3696
3789
|
} else {
|
|
3697
|
-
if (
|
|
3790
|
+
if (fs16.existsSync(lockPath)) fs16.unlinkSync(lockPath);
|
|
3698
3791
|
}
|
|
3699
3792
|
} catch (e) {
|
|
3700
3793
|
console.error("Failed to sync guardian lock file:", e);
|
|
@@ -3748,11 +3841,11 @@ ${Array.from(this.activeViolators).join("\n")}`;
|
|
|
3748
3841
|
enforce(decision) {
|
|
3749
3842
|
if (decision.mode === "OPEN") return;
|
|
3750
3843
|
const icon = decision.mode === "HARD_LOCK" ? "\u{1F6AB}" : "\u26A0\uFE0F";
|
|
3751
|
-
const color = decision.mode === "HARD_LOCK" ?
|
|
3844
|
+
const color = decision.mode === "HARD_LOCK" ? chalk17.bgRed.white.bold : chalk17.yellow.bold;
|
|
3752
3845
|
console.log("\n" + color(` ${icon} [${decision.mode}] INTERVENTION `));
|
|
3753
|
-
console.log(
|
|
3846
|
+
console.log(chalk17.redBright(` ${decision.message}`));
|
|
3754
3847
|
if (decision.blockCommit) {
|
|
3755
|
-
console.log(
|
|
3848
|
+
console.log(chalk17.dim(" \u{1F512} Commit functionality is logically suspended until fixed."));
|
|
3756
3849
|
}
|
|
3757
3850
|
}
|
|
3758
3851
|
};
|
|
@@ -3763,9 +3856,9 @@ function createInterventionProtocol() {
|
|
|
3763
3856
|
// src/daemon/guardian-monitor.ts
|
|
3764
3857
|
init_esm_shims();
|
|
3765
3858
|
import axios12 from "axios";
|
|
3766
|
-
import
|
|
3767
|
-
import
|
|
3768
|
-
import
|
|
3859
|
+
import chalk18 from "chalk";
|
|
3860
|
+
import fs17 from "fs/promises";
|
|
3861
|
+
import path20 from "path";
|
|
3769
3862
|
var CACHE_FILE3 = ".rigstate/rules-cache.json";
|
|
3770
3863
|
var CACHE_TTL_MS2 = 5 * 60 * 1e3;
|
|
3771
3864
|
function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
@@ -3790,7 +3883,7 @@ function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
|
3790
3883
|
} catch (error) {
|
|
3791
3884
|
if (apiUrl.includes("localhost") || apiUrl.includes("127.0.0.1")) {
|
|
3792
3885
|
const cloudUrl = "https://app.rigstate.com";
|
|
3793
|
-
console.log(
|
|
3886
|
+
console.log(chalk18.blue(` \u2601\uFE0F Local API not found. Attempting Cloud Fallback (${cloudUrl})...`));
|
|
3794
3887
|
try {
|
|
3795
3888
|
const cloudResponse = await axios12.get(`${cloudUrl}/api/v1/guardian/rules`, {
|
|
3796
3889
|
params: { project_id: projectId },
|
|
@@ -3799,22 +3892,22 @@ function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
|
3799
3892
|
});
|
|
3800
3893
|
if (cloudResponse.data.success && cloudResponse.data.data.rules) {
|
|
3801
3894
|
rules = cloudResponse.data.data.rules;
|
|
3802
|
-
console.log(
|
|
3895
|
+
console.log(chalk18.green(` \u2705 Successfully loaded rules from Rigstate Cloud!`));
|
|
3803
3896
|
lastFetch = Date.now();
|
|
3804
3897
|
await saveCachedRules2(projectId, rules);
|
|
3805
3898
|
return;
|
|
3806
3899
|
}
|
|
3807
3900
|
} catch (cloudError) {
|
|
3808
|
-
console.error(
|
|
3901
|
+
console.error(chalk18.red(` \u274C Cloud Fallback failed: ${cloudError.message}`));
|
|
3809
3902
|
}
|
|
3810
3903
|
}
|
|
3811
|
-
console.error(
|
|
3904
|
+
console.error(chalk18.red(` \u26A0\uFE0F Failed to fetch rules from API: ${error.message}`));
|
|
3812
3905
|
if (error.response) {
|
|
3813
|
-
console.error(
|
|
3906
|
+
console.error(chalk18.red(` Status: ${error.response.status} - ${JSON.stringify(error.response.data)}`));
|
|
3814
3907
|
}
|
|
3815
3908
|
const cached = await loadCachedRules2(projectId);
|
|
3816
3909
|
if (cached) {
|
|
3817
|
-
console.log(
|
|
3910
|
+
console.log(chalk18.yellow(" \u2139\uFE0F Using cached rules as fallback"));
|
|
3818
3911
|
rules = cached.rules;
|
|
3819
3912
|
lastFetch = Date.now();
|
|
3820
3913
|
return;
|
|
@@ -3831,7 +3924,7 @@ function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
|
3831
3924
|
passed: true
|
|
3832
3925
|
};
|
|
3833
3926
|
}
|
|
3834
|
-
const absolutePath =
|
|
3927
|
+
const absolutePath = path20.resolve(process.cwd(), filePath);
|
|
3835
3928
|
return checkFile(absolutePath, rules, process.cwd());
|
|
3836
3929
|
};
|
|
3837
3930
|
const getRuleCount = () => rules.length;
|
|
@@ -3845,8 +3938,8 @@ function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
|
3845
3938
|
}
|
|
3846
3939
|
async function loadCachedRules2(projectId) {
|
|
3847
3940
|
try {
|
|
3848
|
-
const cachePath =
|
|
3849
|
-
const content = await
|
|
3941
|
+
const cachePath = path20.join(process.cwd(), CACHE_FILE3);
|
|
3942
|
+
const content = await fs17.readFile(cachePath, "utf-8");
|
|
3850
3943
|
const cached = JSON.parse(content);
|
|
3851
3944
|
if (cached.projectId !== projectId) {
|
|
3852
3945
|
return null;
|
|
@@ -3858,16 +3951,16 @@ async function loadCachedRules2(projectId) {
|
|
|
3858
3951
|
}
|
|
3859
3952
|
async function saveCachedRules2(projectId, rules) {
|
|
3860
3953
|
try {
|
|
3861
|
-
const cacheDir =
|
|
3862
|
-
await
|
|
3954
|
+
const cacheDir = path20.join(process.cwd(), ".rigstate");
|
|
3955
|
+
await fs17.mkdir(cacheDir, { recursive: true });
|
|
3863
3956
|
const cached = {
|
|
3864
3957
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3865
3958
|
projectId,
|
|
3866
3959
|
rules,
|
|
3867
3960
|
settings: { lmax: 400, lmax_warning: 350 }
|
|
3868
3961
|
};
|
|
3869
|
-
await
|
|
3870
|
-
|
|
3962
|
+
await fs17.writeFile(
|
|
3963
|
+
path20.join(cacheDir, "rules-cache.json"),
|
|
3871
3964
|
JSON.stringify(cached, null, 2)
|
|
3872
3965
|
);
|
|
3873
3966
|
} catch {
|
|
@@ -3967,37 +4060,37 @@ init_sync_rules();
|
|
|
3967
4060
|
|
|
3968
4061
|
// src/utils/logger.ts
|
|
3969
4062
|
init_esm_shims();
|
|
3970
|
-
import
|
|
4063
|
+
import chalk19 from "chalk";
|
|
3971
4064
|
var Logger = class {
|
|
3972
4065
|
static formatMessage(level, message, context) {
|
|
3973
4066
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3974
4067
|
let prefix = "";
|
|
3975
4068
|
switch (level) {
|
|
3976
4069
|
case "INFO" /* INFO */:
|
|
3977
|
-
prefix =
|
|
4070
|
+
prefix = chalk19.blue(`[${"INFO" /* INFO */}]`);
|
|
3978
4071
|
break;
|
|
3979
4072
|
case "WARN" /* WARN */:
|
|
3980
|
-
prefix =
|
|
4073
|
+
prefix = chalk19.yellow(`[${"WARN" /* WARN */}]`);
|
|
3981
4074
|
break;
|
|
3982
4075
|
case "ERROR" /* ERROR */:
|
|
3983
|
-
prefix =
|
|
4076
|
+
prefix = chalk19.red(`[${"ERROR" /* ERROR */}]`);
|
|
3984
4077
|
break;
|
|
3985
4078
|
case "DEBUG" /* DEBUG */:
|
|
3986
|
-
prefix =
|
|
4079
|
+
prefix = chalk19.gray(`[${"DEBUG" /* DEBUG */}]`);
|
|
3987
4080
|
break;
|
|
3988
4081
|
}
|
|
3989
|
-
let output = `${
|
|
4082
|
+
let output = `${chalk19.gray(timestamp)} ${prefix} ${message}`;
|
|
3990
4083
|
if (context) {
|
|
3991
4084
|
if (context instanceof Error) {
|
|
3992
4085
|
output += `
|
|
3993
|
-
${
|
|
4086
|
+
${chalk19.red(context.stack || context.message)}`;
|
|
3994
4087
|
} else if (typeof context === "object") {
|
|
3995
4088
|
try {
|
|
3996
4089
|
output += `
|
|
3997
|
-
${
|
|
4090
|
+
${chalk19.gray(JSON.stringify(context, null, 2))}`;
|
|
3998
4091
|
} catch (e) {
|
|
3999
4092
|
output += `
|
|
4000
|
-
${
|
|
4093
|
+
${chalk19.gray("[Circular or invalid object]")}`;
|
|
4001
4094
|
}
|
|
4002
4095
|
} else {
|
|
4003
4096
|
output += ` ${String(context)}`;
|
|
@@ -4025,8 +4118,8 @@ ${chalk18.gray("[Circular or invalid object]")}`;
|
|
|
4025
4118
|
init_esm_shims();
|
|
4026
4119
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
4027
4120
|
import chokidar2 from "chokidar";
|
|
4028
|
-
import
|
|
4029
|
-
import
|
|
4121
|
+
import path21 from "path";
|
|
4122
|
+
import fs18 from "fs/promises";
|
|
4030
4123
|
import crypto from "crypto";
|
|
4031
4124
|
import axios15 from "axios";
|
|
4032
4125
|
var KnowledgeHarvester = class extends EventEmitter3 {
|
|
@@ -4044,8 +4137,8 @@ var KnowledgeHarvester = class extends EventEmitter3 {
|
|
|
4044
4137
|
}
|
|
4045
4138
|
async start() {
|
|
4046
4139
|
await this.loadHashes();
|
|
4047
|
-
const rulesPath =
|
|
4048
|
-
const watchPattern =
|
|
4140
|
+
const rulesPath = path21.join(this.config.watchPath, ".cursor", "rules");
|
|
4141
|
+
const watchPattern = path21.join(rulesPath, "**", "*.mdc");
|
|
4049
4142
|
Logger.debug(`\u{1F33E} Harvester watching: ${watchPattern}`);
|
|
4050
4143
|
this.watcher = chokidar2.watch(watchPattern, {
|
|
4051
4144
|
persistent: true,
|
|
@@ -4066,7 +4159,7 @@ var KnowledgeHarvester = class extends EventEmitter3 {
|
|
|
4066
4159
|
}
|
|
4067
4160
|
}
|
|
4068
4161
|
async handleFileEvent(filePath, event) {
|
|
4069
|
-
const fileName =
|
|
4162
|
+
const fileName = path21.basename(filePath);
|
|
4070
4163
|
if (this.IGNORED_PREFIXES.some((prefix) => fileName.startsWith(prefix))) {
|
|
4071
4164
|
return;
|
|
4072
4165
|
}
|
|
@@ -4082,27 +4175,27 @@ var KnowledgeHarvester = class extends EventEmitter3 {
|
|
|
4082
4175
|
if (this.processingQueue.has(filePath)) return;
|
|
4083
4176
|
this.processingQueue.add(filePath);
|
|
4084
4177
|
try {
|
|
4085
|
-
const content = await
|
|
4178
|
+
const content = await fs18.readFile(filePath, "utf-8");
|
|
4086
4179
|
const currentHash = this.computeHash(content);
|
|
4087
4180
|
if (this.ruleHashes.get(filePath) === currentHash) {
|
|
4088
|
-
Logger.debug(`Skipping ${
|
|
4181
|
+
Logger.debug(`Skipping ${path21.basename(filePath)} (unchanged hash)`);
|
|
4089
4182
|
return;
|
|
4090
4183
|
}
|
|
4091
4184
|
if (content.length < 20) {
|
|
4092
|
-
Logger.debug(`Skipping ${
|
|
4185
|
+
Logger.debug(`Skipping ${path21.basename(filePath)} (too short)`);
|
|
4093
4186
|
return;
|
|
4094
4187
|
}
|
|
4095
4188
|
await this.submitSignal(filePath, content);
|
|
4096
4189
|
this.ruleHashes.set(filePath, currentHash);
|
|
4097
4190
|
} catch (error) {
|
|
4098
|
-
Logger.warn(`Harvester failed to process ${
|
|
4191
|
+
Logger.warn(`Harvester failed to process ${path21.basename(filePath)}: ${error.message}`);
|
|
4099
4192
|
} finally {
|
|
4100
4193
|
this.processingQueue.delete(filePath);
|
|
4101
4194
|
}
|
|
4102
4195
|
}
|
|
4103
4196
|
async submitSignal(filePath, content) {
|
|
4104
|
-
const title =
|
|
4105
|
-
const relativePath =
|
|
4197
|
+
const title = path21.basename(filePath, ".mdc");
|
|
4198
|
+
const relativePath = path21.relative(process.cwd(), filePath);
|
|
4106
4199
|
Logger.info(`\u{1F33E} Harvesting new knowledge: ${title}`);
|
|
4107
4200
|
try {
|
|
4108
4201
|
const descriptionMatch = content.match(/description:\s*(.*)/);
|
|
@@ -4136,14 +4229,14 @@ var KnowledgeHarvester = class extends EventEmitter3 {
|
|
|
4136
4229
|
}
|
|
4137
4230
|
}
|
|
4138
4231
|
async loadHashes() {
|
|
4139
|
-
const rulesPath =
|
|
4232
|
+
const rulesPath = path21.join(this.config.watchPath, ".cursor", "rules");
|
|
4140
4233
|
try {
|
|
4141
|
-
await
|
|
4142
|
-
const files = await
|
|
4234
|
+
await fs18.mkdir(rulesPath, { recursive: true });
|
|
4235
|
+
const files = await fs18.readdir(rulesPath);
|
|
4143
4236
|
for (const file of files) {
|
|
4144
4237
|
if (file.endsWith(".mdc")) {
|
|
4145
|
-
const fullPath =
|
|
4146
|
-
const content = await
|
|
4238
|
+
const fullPath = path21.join(rulesPath, file);
|
|
4239
|
+
const content = await fs18.readFile(fullPath, "utf-8");
|
|
4147
4240
|
this.ruleHashes.set(fullPath, this.computeHash(content));
|
|
4148
4241
|
}
|
|
4149
4242
|
}
|
|
@@ -4180,7 +4273,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4180
4273
|
}
|
|
4181
4274
|
async start() {
|
|
4182
4275
|
if (this.state.isRunning) {
|
|
4183
|
-
console.log(
|
|
4276
|
+
console.log(chalk20.yellow("Daemon is already running."));
|
|
4184
4277
|
return;
|
|
4185
4278
|
}
|
|
4186
4279
|
this.printWelcome();
|
|
@@ -4212,8 +4305,8 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4212
4305
|
try {
|
|
4213
4306
|
await this.setupBridge();
|
|
4214
4307
|
} catch (e) {
|
|
4215
|
-
console.error(
|
|
4216
|
-
console.log(
|
|
4308
|
+
console.error(chalk20.yellow(` \u26A0\uFE0F Agent Bridge connection failed: ${e.message}`));
|
|
4309
|
+
console.log(chalk20.dim(" (Daemon will continue with local monitoring only)"));
|
|
4217
4310
|
}
|
|
4218
4311
|
}
|
|
4219
4312
|
this.printActive();
|
|
@@ -4229,16 +4322,16 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4229
4322
|
}
|
|
4230
4323
|
}
|
|
4231
4324
|
printWelcome() {
|
|
4232
|
-
console.log(
|
|
4233
|
-
console.log(
|
|
4234
|
-
console.log(
|
|
4235
|
-
console.log(
|
|
4236
|
-
console.log(
|
|
4325
|
+
console.log(chalk20.bold.blue("\n\u{1F6E1}\uFE0F Guardian Daemon Starting..."));
|
|
4326
|
+
console.log(chalk20.dim(`Project: ${this.config.projectId}`));
|
|
4327
|
+
console.log(chalk20.dim(`API URL: ${this.config.apiUrl}`));
|
|
4328
|
+
console.log(chalk20.dim(`Watch Path: ${this.config.watchPath}`));
|
|
4329
|
+
console.log(chalk20.dim("\u2500".repeat(50)));
|
|
4237
4330
|
}
|
|
4238
4331
|
printActive() {
|
|
4239
|
-
console.log(
|
|
4240
|
-
console.log(
|
|
4241
|
-
console.log(
|
|
4332
|
+
console.log(chalk20.dim("\u2500".repeat(50)));
|
|
4333
|
+
console.log(chalk20.green.bold("\u2705 Guardian Daemon is now active"));
|
|
4334
|
+
console.log(chalk20.dim("Press Ctrl+C to stop\n"));
|
|
4242
4335
|
}
|
|
4243
4336
|
async syncHeuristics() {
|
|
4244
4337
|
if (!this.heuristicEngine) return;
|
|
@@ -4261,7 +4354,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4261
4354
|
}
|
|
4262
4355
|
async getLineCount(filePath) {
|
|
4263
4356
|
try {
|
|
4264
|
-
const content = await
|
|
4357
|
+
const content = await fs19.readFile(filePath, "utf-8");
|
|
4265
4358
|
return content.split("\n").length;
|
|
4266
4359
|
} catch (e) {
|
|
4267
4360
|
return 0;
|
|
@@ -4298,7 +4391,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4298
4391
|
}
|
|
4299
4392
|
}
|
|
4300
4393
|
async updateViolationReport(violations) {
|
|
4301
|
-
const reportPath =
|
|
4394
|
+
const reportPath = path22.join(process.cwd(), ".rigstate", "ACTIVE_VIOLATIONS.md");
|
|
4302
4395
|
const allViolations = Array.from(this.violationsMap.entries());
|
|
4303
4396
|
const totalCount = allViolations.reduce((acc, [, v]) => acc + v.length, 0);
|
|
4304
4397
|
let content = `# \u{1F6E1}\uFE0F Guardian Status: ${totalCount > 0 ? "\u26A0\uFE0F ATTENTION" : "\u2705 PASS"}
|
|
@@ -4314,7 +4407,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4314
4407
|
} else {
|
|
4315
4408
|
content += "### \u{1F6A8} Active Violations\n\n";
|
|
4316
4409
|
for (const [file, fileViolations] of allViolations) {
|
|
4317
|
-
const relPath =
|
|
4410
|
+
const relPath = path22.relative(process.cwd(), file);
|
|
4318
4411
|
content += `#### \u{1F4C4} ${relPath}
|
|
4319
4412
|
`;
|
|
4320
4413
|
for (const v of fileViolations) {
|
|
@@ -4326,7 +4419,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4326
4419
|
content += "\n---\n*Rigstate Daemon is watching. Fix violations to clear this report.*";
|
|
4327
4420
|
}
|
|
4328
4421
|
try {
|
|
4329
|
-
await
|
|
4422
|
+
await fs19.writeFile(reportPath, content, "utf-8");
|
|
4330
4423
|
} catch (e) {
|
|
4331
4424
|
}
|
|
4332
4425
|
}
|
|
@@ -4346,27 +4439,27 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4346
4439
|
}
|
|
4347
4440
|
}
|
|
4348
4441
|
async setupBridge() {
|
|
4349
|
-
console.log(
|
|
4442
|
+
console.log(chalk20.dim("\u{1F309} Connecting to Agent Bridge..."));
|
|
4350
4443
|
this.bridgeListener = createBridgeListener(this.config.projectId, this.config.apiUrl, this.config.apiKey);
|
|
4351
4444
|
this.bridgeListener.on("task", (task) => {
|
|
4352
4445
|
this.state.lastActivity = (/* @__PURE__ */ new Date()).toISOString();
|
|
4353
4446
|
this.state.tasksProcessed++;
|
|
4354
|
-
console.log(
|
|
4447
|
+
console.log(chalk20.cyan(`
|
|
4355
4448
|
\u{1F4E5} New task received: ${task.id}`));
|
|
4356
4449
|
this.emit("task", task);
|
|
4357
4450
|
});
|
|
4358
4451
|
await this.bridgeListener.connect();
|
|
4359
|
-
console.log(
|
|
4452
|
+
console.log(chalk20.green(" \u2713 Agent Bridge connected"));
|
|
4360
4453
|
}
|
|
4361
4454
|
async stop() {
|
|
4362
4455
|
if (!this.state.isRunning) return;
|
|
4363
|
-
console.log(
|
|
4456
|
+
console.log(chalk20.dim("\n\u{1F6D1} Stopping Guardian Daemon..."));
|
|
4364
4457
|
if (this.fileWatcher) await this.fileWatcher.stop();
|
|
4365
4458
|
if (this.bridgeListener) await this.bridgeListener.disconnect();
|
|
4366
4459
|
if (this.harvester) await this.harvester.stop();
|
|
4367
4460
|
if (this.syncInterval) clearInterval(this.syncInterval);
|
|
4368
4461
|
this.state.isRunning = false;
|
|
4369
|
-
console.log(
|
|
4462
|
+
console.log(chalk20.green("\u2713 Daemon stopped."));
|
|
4370
4463
|
this.emit("stopped", this.state);
|
|
4371
4464
|
}
|
|
4372
4465
|
getState() {
|
|
@@ -4376,6 +4469,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4376
4469
|
|
|
4377
4470
|
// src/daemon/factory.ts
|
|
4378
4471
|
init_config();
|
|
4472
|
+
init_manifest();
|
|
4379
4473
|
async function createDaemon(options) {
|
|
4380
4474
|
const apiUrl = getApiUrl();
|
|
4381
4475
|
let projectId = options.project;
|
|
@@ -4405,9 +4499,9 @@ async function createDaemon(options) {
|
|
|
4405
4499
|
|
|
4406
4500
|
// src/utils/service-manager.ts
|
|
4407
4501
|
init_esm_shims();
|
|
4408
|
-
import
|
|
4409
|
-
import
|
|
4410
|
-
import
|
|
4502
|
+
import chalk21 from "chalk";
|
|
4503
|
+
import fs20 from "fs/promises";
|
|
4504
|
+
import path23 from "path";
|
|
4411
4505
|
import { execSync as execSync3 } from "child_process";
|
|
4412
4506
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4413
4507
|
async function execShellCommand(cmd) {
|
|
@@ -4419,22 +4513,22 @@ async function execShellCommand(cmd) {
|
|
|
4419
4513
|
}
|
|
4420
4514
|
}
|
|
4421
4515
|
async function enableDaemon() {
|
|
4422
|
-
console.log(
|
|
4516
|
+
console.log(chalk21.bold("\n\u2699\uFE0F Enabling Rigstate Background Service (macOS)\n"));
|
|
4423
4517
|
if (process.platform !== "darwin") {
|
|
4424
|
-
console.error(
|
|
4425
|
-
console.error(
|
|
4518
|
+
console.error(chalk21.red("\u274C Currently only macOS is supported for auto-start."));
|
|
4519
|
+
console.error(chalk21.yellow("PRs welcome for Linux/Windows support!"));
|
|
4426
4520
|
return;
|
|
4427
4521
|
}
|
|
4428
4522
|
const homeDir = process.env.HOME || "";
|
|
4429
4523
|
if (!homeDir) {
|
|
4430
|
-
console.error(
|
|
4524
|
+
console.error(chalk21.red("\u274C Could not determine HOME directory."));
|
|
4431
4525
|
return;
|
|
4432
4526
|
}
|
|
4433
|
-
const agentsDir =
|
|
4434
|
-
const logDir =
|
|
4435
|
-
const plistPath =
|
|
4436
|
-
await
|
|
4437
|
-
await
|
|
4527
|
+
const agentsDir = path23.join(homeDir, "Library/LaunchAgents");
|
|
4528
|
+
const logDir = path23.join(homeDir, ".rigstate/logs");
|
|
4529
|
+
const plistPath = path23.join(agentsDir, "com.rigstate.daemon.plist");
|
|
4530
|
+
await fs20.mkdir(agentsDir, { recursive: true });
|
|
4531
|
+
await fs20.mkdir(logDir, { recursive: true });
|
|
4438
4532
|
const scriptPath = fileURLToPath2(import.meta.url);
|
|
4439
4533
|
const nodePath = process.execPath;
|
|
4440
4534
|
const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -4453,9 +4547,9 @@ async function enableDaemon() {
|
|
|
4453
4547
|
<key>WorkingDirectory</key>
|
|
4454
4548
|
<string>${process.cwd()}</string>
|
|
4455
4549
|
<key>StandardOutPath</key>
|
|
4456
|
-
<string>${
|
|
4550
|
+
<string>${path23.join(logDir, "daemon.out.log")}</string>
|
|
4457
4551
|
<key>StandardErrorPath</key>
|
|
4458
|
-
<string>${
|
|
4552
|
+
<string>${path23.join(logDir, "daemon.err.log")}</string>
|
|
4459
4553
|
<key>RunAtLoad</key>
|
|
4460
4554
|
<true/>
|
|
4461
4555
|
<key>KeepAlive</key>
|
|
@@ -4468,33 +4562,33 @@ async function enableDaemon() {
|
|
|
4468
4562
|
</dict>
|
|
4469
4563
|
</plist>`;
|
|
4470
4564
|
try {
|
|
4471
|
-
await
|
|
4472
|
-
console.log(
|
|
4565
|
+
await fs20.writeFile(plistPath, plistContent);
|
|
4566
|
+
console.log(chalk21.dim(`Created plist at: ${plistPath}`));
|
|
4473
4567
|
try {
|
|
4474
4568
|
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
4475
4569
|
} catch (e) {
|
|
4476
4570
|
}
|
|
4477
4571
|
await execShellCommand(`launchctl load ${plistPath}`);
|
|
4478
|
-
console.log(
|
|
4479
|
-
console.log(
|
|
4480
|
-
console.log(
|
|
4572
|
+
console.log(chalk21.green("\u2705 Successfully enabled background daemon!"));
|
|
4573
|
+
console.log(chalk21.dim(`Logs: ${logDir}`));
|
|
4574
|
+
console.log(chalk21.dim("The daemon will now restart automatically if it crashes or on reboot."));
|
|
4481
4575
|
} catch (error) {
|
|
4482
|
-
console.error(
|
|
4576
|
+
console.error(chalk21.red("\u274C Failed to enable daemon:"), error.message);
|
|
4483
4577
|
}
|
|
4484
4578
|
}
|
|
4485
4579
|
async function disableDaemon() {
|
|
4486
|
-
console.log(
|
|
4580
|
+
console.log(chalk21.bold("\n\u2699\uFE0F Disabling Rigstate Background Service\n"));
|
|
4487
4581
|
const homeDir = process.env.HOME || "";
|
|
4488
|
-
const plistPath =
|
|
4582
|
+
const plistPath = path23.join(homeDir, "Library/LaunchAgents/com.rigstate.daemon.plist");
|
|
4489
4583
|
try {
|
|
4490
4584
|
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
4491
|
-
await
|
|
4492
|
-
console.log(
|
|
4585
|
+
await fs20.unlink(plistPath);
|
|
4586
|
+
console.log(chalk21.green("\u2705 Successfully disabled background daemon."));
|
|
4493
4587
|
} catch (error) {
|
|
4494
4588
|
if (error.code === "ENOENT") {
|
|
4495
|
-
console.log(
|
|
4589
|
+
console.log(chalk21.green("\u2705 Daemon was not enabled."));
|
|
4496
4590
|
} else {
|
|
4497
|
-
console.error(
|
|
4591
|
+
console.error(chalk21.red("\u274C Failed to disable daemon:"), error.message);
|
|
4498
4592
|
}
|
|
4499
4593
|
}
|
|
4500
4594
|
}
|
|
@@ -4519,17 +4613,17 @@ function createDaemonCommand() {
|
|
|
4519
4613
|
}
|
|
4520
4614
|
const spinner = ora8();
|
|
4521
4615
|
try {
|
|
4522
|
-
const pidPath =
|
|
4616
|
+
const pidPath = path24.join(process.cwd(), PID_FILE);
|
|
4523
4617
|
try {
|
|
4524
|
-
const content = await
|
|
4618
|
+
const content = await fs21.readFile(pidPath, "utf-8");
|
|
4525
4619
|
const pid = parseInt(content.trim(), 10);
|
|
4526
4620
|
try {
|
|
4527
4621
|
process.kill(pid, 0);
|
|
4528
|
-
console.log(
|
|
4529
|
-
console.log(
|
|
4622
|
+
console.log(chalk22.yellow("\u26A0 Another daemon instance is active (PID " + pid + ")."));
|
|
4623
|
+
console.log(chalk22.dim(` Run "rigstate daemon status" for details or Ctrl+C to stop.
|
|
4530
4624
|
`));
|
|
4531
4625
|
} catch {
|
|
4532
|
-
await
|
|
4626
|
+
await fs21.unlink(pidPath).catch(() => {
|
|
4533
4627
|
});
|
|
4534
4628
|
}
|
|
4535
4629
|
} catch {
|
|
@@ -4544,7 +4638,7 @@ function createDaemonCommand() {
|
|
|
4544
4638
|
spinner.stop();
|
|
4545
4639
|
await writePidFile();
|
|
4546
4640
|
process.on("SIGINT", async () => {
|
|
4547
|
-
console.log(
|
|
4641
|
+
console.log(chalk22.dim("\n\nShutting down..."));
|
|
4548
4642
|
await daemonInstance.stop();
|
|
4549
4643
|
await cleanupPidFile();
|
|
4550
4644
|
process.exit(0);
|
|
@@ -4564,8 +4658,8 @@ function createDaemonCommand() {
|
|
|
4564
4658
|
await new Promise(() => {
|
|
4565
4659
|
});
|
|
4566
4660
|
} catch (error) {
|
|
4567
|
-
spinner.fail(
|
|
4568
|
-
console.error(
|
|
4661
|
+
spinner.fail(chalk22.red("Failed to start daemon"));
|
|
4662
|
+
console.error(chalk22.red("Error:"), error.message);
|
|
4569
4663
|
process.exit(1);
|
|
4570
4664
|
}
|
|
4571
4665
|
});
|
|
@@ -4573,14 +4667,14 @@ function createDaemonCommand() {
|
|
|
4573
4667
|
}
|
|
4574
4668
|
async function isRunning() {
|
|
4575
4669
|
try {
|
|
4576
|
-
const pidPath =
|
|
4577
|
-
const content = await
|
|
4670
|
+
const pidPath = path24.join(process.cwd(), PID_FILE);
|
|
4671
|
+
const content = await fs21.readFile(pidPath, "utf-8");
|
|
4578
4672
|
const pid = parseInt(content.trim(), 10);
|
|
4579
4673
|
try {
|
|
4580
4674
|
process.kill(pid, 0);
|
|
4581
4675
|
return true;
|
|
4582
4676
|
} catch {
|
|
4583
|
-
await
|
|
4677
|
+
await fs21.unlink(pidPath);
|
|
4584
4678
|
return false;
|
|
4585
4679
|
}
|
|
4586
4680
|
} catch {
|
|
@@ -4589,57 +4683,57 @@ async function isRunning() {
|
|
|
4589
4683
|
}
|
|
4590
4684
|
async function writePidFile() {
|
|
4591
4685
|
try {
|
|
4592
|
-
const dir =
|
|
4593
|
-
await
|
|
4594
|
-
await
|
|
4686
|
+
const dir = path24.join(process.cwd(), ".rigstate");
|
|
4687
|
+
await fs21.mkdir(dir, { recursive: true });
|
|
4688
|
+
await fs21.writeFile(path24.join(dir, "daemon.pid"), process.pid.toString());
|
|
4595
4689
|
} catch {
|
|
4596
4690
|
}
|
|
4597
4691
|
}
|
|
4598
4692
|
async function cleanupPidFile() {
|
|
4599
4693
|
try {
|
|
4600
|
-
await
|
|
4601
|
-
await
|
|
4694
|
+
await fs21.unlink(path24.join(process.cwd(), PID_FILE));
|
|
4695
|
+
await fs21.unlink(path24.join(process.cwd(), STATE_FILE));
|
|
4602
4696
|
} catch {
|
|
4603
4697
|
}
|
|
4604
4698
|
}
|
|
4605
4699
|
async function writeStateFile(state) {
|
|
4606
4700
|
try {
|
|
4607
|
-
const dir =
|
|
4608
|
-
await
|
|
4609
|
-
await
|
|
4610
|
-
|
|
4701
|
+
const dir = path24.join(process.cwd(), ".rigstate");
|
|
4702
|
+
await fs21.mkdir(dir, { recursive: true });
|
|
4703
|
+
await fs21.writeFile(
|
|
4704
|
+
path24.join(dir, "daemon.state.json"),
|
|
4611
4705
|
JSON.stringify(state, null, 2)
|
|
4612
4706
|
);
|
|
4613
4707
|
} catch {
|
|
4614
4708
|
}
|
|
4615
4709
|
}
|
|
4616
4710
|
async function showStatus() {
|
|
4617
|
-
console.log(
|
|
4711
|
+
console.log(chalk22.bold("\n\u{1F6E1}\uFE0F Guardian Daemon Status\n"));
|
|
4618
4712
|
const running = await isRunning();
|
|
4619
4713
|
if (!running) {
|
|
4620
|
-
console.log(
|
|
4621
|
-
console.log(
|
|
4714
|
+
console.log(chalk22.yellow("Status: Not running"));
|
|
4715
|
+
console.log(chalk22.dim('Use "rigstate daemon" to start.\n'));
|
|
4622
4716
|
return;
|
|
4623
4717
|
}
|
|
4624
|
-
console.log(
|
|
4718
|
+
console.log(chalk22.green("Status: Running"));
|
|
4625
4719
|
try {
|
|
4626
|
-
const statePath =
|
|
4627
|
-
const content = await
|
|
4720
|
+
const statePath = path24.join(process.cwd(), STATE_FILE);
|
|
4721
|
+
const content = await fs21.readFile(statePath, "utf-8");
|
|
4628
4722
|
const state = JSON.parse(content);
|
|
4629
|
-
console.log(
|
|
4723
|
+
console.log(chalk22.dim("\u2500".repeat(40)));
|
|
4630
4724
|
console.log(`Started at: ${state.startedAt || "Unknown"}`);
|
|
4631
4725
|
console.log(`Files checked: ${state.filesChecked || 0}`);
|
|
4632
4726
|
console.log(`Violations: ${state.violationsFound || 0}`);
|
|
4633
4727
|
console.log(`Tasks processed: ${state.tasksProcessed || 0}`);
|
|
4634
4728
|
console.log(`Last activity: ${state.lastActivity || "None"}`);
|
|
4635
|
-
console.log(
|
|
4729
|
+
console.log(chalk22.dim("\u2500".repeat(40)));
|
|
4636
4730
|
} catch {
|
|
4637
|
-
console.log(
|
|
4731
|
+
console.log(chalk22.dim("(State file not found)"));
|
|
4638
4732
|
}
|
|
4639
4733
|
try {
|
|
4640
|
-
const pidPath =
|
|
4641
|
-
const pid = await
|
|
4642
|
-
console.log(
|
|
4734
|
+
const pidPath = path24.join(process.cwd(), PID_FILE);
|
|
4735
|
+
const pid = await fs21.readFile(pidPath, "utf-8");
|
|
4736
|
+
console.log(chalk22.dim(`PID: ${pid.trim()}`));
|
|
4643
4737
|
} catch {
|
|
4644
4738
|
}
|
|
4645
4739
|
console.log("");
|
|
@@ -4650,7 +4744,7 @@ init_esm_shims();
|
|
|
4650
4744
|
init_config();
|
|
4651
4745
|
init_suggest();
|
|
4652
4746
|
import { Command as Command13 } from "commander";
|
|
4653
|
-
import
|
|
4747
|
+
import chalk24 from "chalk";
|
|
4654
4748
|
import ora10 from "ora";
|
|
4655
4749
|
import axios17 from "axios";
|
|
4656
4750
|
import inquirer3 from "inquirer";
|
|
@@ -4659,11 +4753,11 @@ import inquirer3 from "inquirer";
|
|
|
4659
4753
|
init_esm_shims();
|
|
4660
4754
|
init_config();
|
|
4661
4755
|
import { Command as Command12 } from "commander";
|
|
4662
|
-
import
|
|
4756
|
+
import chalk23 from "chalk";
|
|
4663
4757
|
import ora9 from "ora";
|
|
4664
4758
|
import axios16 from "axios";
|
|
4665
|
-
import
|
|
4666
|
-
import
|
|
4759
|
+
import fs22 from "fs/promises";
|
|
4760
|
+
import path25 from "path";
|
|
4667
4761
|
import inquirer2 from "inquirer";
|
|
4668
4762
|
function createPlanCommand() {
|
|
4669
4763
|
const plan = new Command12("plan");
|
|
@@ -4721,7 +4815,7 @@ async function executePlan(taskId) {
|
|
|
4721
4815
|
taskDescription = task.description;
|
|
4722
4816
|
}
|
|
4723
4817
|
spinner.start("Generating Context for Frank...");
|
|
4724
|
-
const contextPath =
|
|
4818
|
+
const contextPath = path25.join(process.cwd(), ".rigstate", "CURRENT_CONTEXT.md");
|
|
4725
4819
|
const contextContent = `
|
|
4726
4820
|
# \u{1F3AF} Active Mission: ${taskTitle}
|
|
4727
4821
|
**ID:** ${taskId}
|
|
@@ -4736,10 +4830,10 @@ ${taskDescription}
|
|
|
4736
4830
|
|
|
4737
4831
|
*Generated by Rigstate CLI at ${(/* @__PURE__ */ new Date()).toLocaleString()}*
|
|
4738
4832
|
`;
|
|
4739
|
-
await
|
|
4740
|
-
await
|
|
4741
|
-
const planPath =
|
|
4742
|
-
const planExists = await
|
|
4833
|
+
await fs22.mkdir(path25.dirname(contextPath), { recursive: true });
|
|
4834
|
+
await fs22.writeFile(contextPath, contextContent.trim());
|
|
4835
|
+
const planPath = path25.join(process.cwd(), "IMPLEMENTATION_PLAN.md");
|
|
4836
|
+
const planExists = await fs22.stat(planPath).then(() => true).catch(() => false);
|
|
4743
4837
|
if (!planExists) {
|
|
4744
4838
|
const planTemplate = `
|
|
4745
4839
|
# \u{1F4CB} Implementation Plan: ${taskTitle}
|
|
@@ -4758,23 +4852,38 @@ ${taskDescription}
|
|
|
4758
4852
|
## 4. \u{1F680} Execution
|
|
4759
4853
|
[Frank: Log your progress here]
|
|
4760
4854
|
`;
|
|
4761
|
-
await
|
|
4762
|
-
spinner.succeed(
|
|
4855
|
+
await fs22.writeFile(planPath, planTemplate.trim());
|
|
4856
|
+
spinner.succeed(chalk23.green("Created new IMPLEMENTATION_PLAN.md"));
|
|
4763
4857
|
} else {
|
|
4764
|
-
spinner.info(
|
|
4858
|
+
spinner.info(chalk23.yellow("IMPLEMENTATION_PLAN.md already exists. Preserving it."));
|
|
4859
|
+
}
|
|
4860
|
+
try {
|
|
4861
|
+
spinner.start("\u{1F4E1} Signaling Frank to start drafting...");
|
|
4862
|
+
await axios16.post(`${apiUrl}/api/v1/agent/bridge`, {
|
|
4863
|
+
project_id: projectId,
|
|
4864
|
+
task_id: realId,
|
|
4865
|
+
status: "APPROVED",
|
|
4866
|
+
proposal: `draft_plan:${taskId}`,
|
|
4867
|
+
summary: `Requesting implementation plan for ${taskTitle}`
|
|
4868
|
+
}, {
|
|
4869
|
+
headers: { "Authorization": `Bearer ${apiKey}` }
|
|
4870
|
+
});
|
|
4871
|
+
spinner.succeed("Signal sent to Agent Bridge.");
|
|
4872
|
+
} catch (e) {
|
|
4873
|
+
spinner.info(chalk23.dim("Agent Bridge signal skipped (non-critical)."));
|
|
4765
4874
|
}
|
|
4766
4875
|
console.log("");
|
|
4767
|
-
console.log(
|
|
4768
|
-
console.log(
|
|
4769
|
-
console.log(`1. Context loaded into: ${
|
|
4770
|
-
console.log(`2. Plan template ready: ${
|
|
4876
|
+
console.log(chalk23.bold.blue("\u{1F680} Planning Mode Activated"));
|
|
4877
|
+
console.log(chalk23.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"));
|
|
4878
|
+
console.log(`1. Context loaded into: ${chalk23.bold(".rigstate/CURRENT_CONTEXT.md")}`);
|
|
4879
|
+
console.log(`2. Plan template ready: ${chalk23.bold("IMPLEMENTATION_PLAN.md")}`);
|
|
4771
4880
|
console.log("");
|
|
4772
|
-
console.log(
|
|
4773
|
-
console.log(
|
|
4774
|
-
console.log(
|
|
4881
|
+
console.log(chalk23.green("\u2728 FRANK IS ON IT!"));
|
|
4882
|
+
console.log(chalk23.dim(" He has received the bridge signal and will begin drafting shortly."));
|
|
4883
|
+
console.log(chalk23.dim(" No further manual steps required once he wakes up."));
|
|
4775
4884
|
console.log("");
|
|
4776
4885
|
} catch (e) {
|
|
4777
|
-
spinner.fail(
|
|
4886
|
+
spinner.fail(chalk23.red(`Planning failed: ${e.message}`));
|
|
4778
4887
|
}
|
|
4779
4888
|
}
|
|
4780
4889
|
function getContext() {
|
|
@@ -4819,7 +4928,7 @@ async function listInteractive() {
|
|
|
4819
4928
|
});
|
|
4820
4929
|
spinner.stop();
|
|
4821
4930
|
if (actionableTasks.length === 0) {
|
|
4822
|
-
console.log(
|
|
4931
|
+
console.log(chalk24.yellow("Roadmap clear. No actionable tasks found."));
|
|
4823
4932
|
return;
|
|
4824
4933
|
}
|
|
4825
4934
|
const choices = actionableTasks.map((t) => {
|
|
@@ -4828,7 +4937,7 @@ async function listInteractive() {
|
|
|
4828
4937
|
if (t.status === "IN_PROGRESS") icon = "\u{1F525}";
|
|
4829
4938
|
if (t.status === "ACTIVE") icon = "\u25B6\uFE0F";
|
|
4830
4939
|
return {
|
|
4831
|
-
name: `${icon} ${
|
|
4940
|
+
name: `${icon} ${chalk24.bold(id)}: ${t.title} [${t.status}]`,
|
|
4832
4941
|
value: t.id
|
|
4833
4942
|
};
|
|
4834
4943
|
});
|
|
@@ -4875,25 +4984,25 @@ async function setTaskStatus(taskId, status) {
|
|
|
4875
4984
|
{ step_id: realId, status, project_id: projectId },
|
|
4876
4985
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
4877
4986
|
);
|
|
4878
|
-
spinner.succeed(
|
|
4987
|
+
spinner.succeed(chalk24.green(`Task updated to ${status}.`));
|
|
4879
4988
|
if (status === "IN_PROGRESS") {
|
|
4880
|
-
console.log(
|
|
4989
|
+
console.log(chalk24.blue(`
|
|
4881
4990
|
\u{1F4A1} Tip: Provide 'Frank' with context by mentioning @.cursorrules in your chat.`));
|
|
4882
4991
|
}
|
|
4883
4992
|
} catch (e) {
|
|
4884
|
-
spinner.fail(
|
|
4993
|
+
spinner.fail(chalk24.red(`Failed: ${e.message}`));
|
|
4885
4994
|
}
|
|
4886
4995
|
}
|
|
4887
4996
|
async function finishTask(taskId) {
|
|
4888
4997
|
console.log("");
|
|
4889
|
-
console.log(
|
|
4890
|
-
console.log(
|
|
4998
|
+
console.log(chalk24.bold.yellow("\u{1F6E1}\uFE0F FRANK'S QUALITY GATE"));
|
|
4999
|
+
console.log(chalk24.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"));
|
|
4891
5000
|
const auditSpinner = ora10(" Analyzing architectural integrity...").start();
|
|
4892
5001
|
await new Promise((r) => setTimeout(r, 1500));
|
|
4893
5002
|
auditSpinner.succeed("Architecture: VALIDATED (SEC-ARCH-01 Pass)");
|
|
4894
5003
|
await setTaskStatus(taskId, "COMPLETED");
|
|
4895
5004
|
console.log("");
|
|
4896
|
-
console.log(
|
|
5005
|
+
console.log(chalk24.bold.green("\u{1F389} TASK COMPLETE! Momentum Preserved."));
|
|
4897
5006
|
const { projectId, apiKey, apiUrl } = getContext2();
|
|
4898
5007
|
await suggestNextMove(projectId, apiKey, apiUrl);
|
|
4899
5008
|
}
|
|
@@ -4911,39 +5020,35 @@ function getContext2() {
|
|
|
4911
5020
|
init_esm_shims();
|
|
4912
5021
|
init_config();
|
|
4913
5022
|
import { Command as Command14 } from "commander";
|
|
4914
|
-
import
|
|
5023
|
+
import chalk25 from "chalk";
|
|
4915
5024
|
import ora11 from "ora";
|
|
4916
5025
|
import chokidar3 from "chokidar";
|
|
4917
|
-
import
|
|
4918
|
-
import
|
|
5026
|
+
import fs23 from "fs/promises";
|
|
5027
|
+
import path26 from "path";
|
|
4919
5028
|
import { execSync as execSync4 } from "child_process";
|
|
4920
5029
|
import axios18 from "axios";
|
|
4921
5030
|
function createWatchCommand() {
|
|
4922
5031
|
const watch2 = new Command14("watch");
|
|
4923
5032
|
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) => {
|
|
4924
|
-
console.log(
|
|
4925
|
-
console.log(
|
|
5033
|
+
console.log(chalk25.bold.blue("\u{1F52D} Rigstate Watch Mode"));
|
|
5034
|
+
console.log(chalk25.dim("Monitoring for task completion..."));
|
|
4926
5035
|
console.log("");
|
|
4927
5036
|
let apiKey;
|
|
4928
5037
|
let projectId;
|
|
4929
5038
|
try {
|
|
4930
5039
|
apiKey = getApiKey();
|
|
4931
5040
|
} catch (e) {
|
|
4932
|
-
console.log(
|
|
5041
|
+
console.log(chalk25.red('Not authenticated. Run "rigstate login" first.'));
|
|
4933
5042
|
return;
|
|
4934
5043
|
}
|
|
4935
5044
|
projectId = getProjectId();
|
|
4936
5045
|
if (!projectId) {
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
const manifest = JSON.parse(content);
|
|
4941
|
-
projectId = manifest.project_id;
|
|
4942
|
-
} catch (e) {
|
|
4943
|
-
}
|
|
5046
|
+
const { loadManifest: loadManifest2 } = await Promise.resolve().then(() => (init_manifest(), manifest_exports));
|
|
5047
|
+
const manifest = await loadManifest2();
|
|
5048
|
+
if (manifest?.project_id) projectId = manifest.project_id;
|
|
4944
5049
|
}
|
|
4945
5050
|
if (!projectId) {
|
|
4946
|
-
console.log(
|
|
5051
|
+
console.log(chalk25.red('No project context. Run "rigstate link" or "rigstate sync --project <id>" first.'));
|
|
4947
5052
|
return;
|
|
4948
5053
|
}
|
|
4949
5054
|
const apiUrl = getApiUrl();
|
|
@@ -4953,8 +5058,8 @@ function createWatchCommand() {
|
|
|
4953
5058
|
runTests: options.runTests || false,
|
|
4954
5059
|
testCommand: options.testCommand || "npm test"
|
|
4955
5060
|
};
|
|
4956
|
-
console.log(
|
|
4957
|
-
console.log(
|
|
5061
|
+
console.log(chalk25.dim(`Auto-commit: ${config2.autoCommit ? "ON" : "OFF"}`));
|
|
5062
|
+
console.log(chalk25.dim(`Auto-push: ${config2.autoPush ? "ON" : "OFF"}`));
|
|
4958
5063
|
console.log("");
|
|
4959
5064
|
const fetchActiveTask = async () => {
|
|
4960
5065
|
try {
|
|
@@ -4982,17 +5087,17 @@ function createWatchCommand() {
|
|
|
4982
5087
|
};
|
|
4983
5088
|
const checkCriteria = async (criteria) => {
|
|
4984
5089
|
try {
|
|
4985
|
-
const fullPath =
|
|
5090
|
+
const fullPath = path26.resolve(process.cwd(), criteria.path);
|
|
4986
5091
|
switch (criteria.type) {
|
|
4987
5092
|
case "file_exists":
|
|
4988
|
-
await
|
|
5093
|
+
await fs23.access(fullPath);
|
|
4989
5094
|
return true;
|
|
4990
5095
|
case "file_content":
|
|
4991
|
-
const content = await
|
|
5096
|
+
const content = await fs23.readFile(fullPath, "utf-8");
|
|
4992
5097
|
return content.length > 0;
|
|
4993
5098
|
case "content_match":
|
|
4994
5099
|
if (!criteria.match) return false;
|
|
4995
|
-
const fileContent = await
|
|
5100
|
+
const fileContent = await fs23.readFile(fullPath, "utf-8");
|
|
4996
5101
|
return fileContent.includes(criteria.match);
|
|
4997
5102
|
default:
|
|
4998
5103
|
return false;
|
|
@@ -5021,7 +5126,7 @@ function createWatchCommand() {
|
|
|
5021
5126
|
}, {
|
|
5022
5127
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
5023
5128
|
});
|
|
5024
|
-
spinner.succeed(
|
|
5129
|
+
spinner.succeed(chalk25.green(`\u2705 Task #${task.step_number} completed: ${task.title}`));
|
|
5025
5130
|
if (config2.autoCommit) {
|
|
5026
5131
|
spinner.start("Committing changes...");
|
|
5027
5132
|
try {
|
|
@@ -5043,7 +5148,7 @@ function createWatchCommand() {
|
|
|
5043
5148
|
}
|
|
5044
5149
|
}
|
|
5045
5150
|
console.log("");
|
|
5046
|
-
console.log(
|
|
5151
|
+
console.log(chalk25.blue("Watching for next task..."));
|
|
5047
5152
|
} catch (e) {
|
|
5048
5153
|
spinner.fail(`Failed to complete task: ${e.message}`);
|
|
5049
5154
|
}
|
|
@@ -5056,7 +5161,7 @@ function createWatchCommand() {
|
|
|
5056
5161
|
const task = await fetchActiveTask();
|
|
5057
5162
|
if (!task) {
|
|
5058
5163
|
if (currentTask) {
|
|
5059
|
-
console.log(
|
|
5164
|
+
console.log(chalk25.green("\u{1F389} All tasks completed! Watching for new tasks..."));
|
|
5060
5165
|
currentTask = null;
|
|
5061
5166
|
}
|
|
5062
5167
|
isProcessing = false;
|
|
@@ -5065,10 +5170,10 @@ function createWatchCommand() {
|
|
|
5065
5170
|
if (!currentTask || currentTask.id !== task.id) {
|
|
5066
5171
|
currentTask = task;
|
|
5067
5172
|
console.log("");
|
|
5068
|
-
console.log(
|
|
5069
|
-
console.log(
|
|
5173
|
+
console.log(chalk25.bold.yellow(`\u{1F4CC} Active Task #${task.step_number}: ${task.title}`));
|
|
5174
|
+
console.log(chalk25.dim(`Status: ${task.status}`));
|
|
5070
5175
|
if (task.verification_criteria) {
|
|
5071
|
-
console.log(
|
|
5176
|
+
console.log(chalk25.dim("Verification: Auto-checking criteria..."));
|
|
5072
5177
|
}
|
|
5073
5178
|
}
|
|
5074
5179
|
if (task.verification_criteria && Array.isArray(task.verification_criteria)) {
|
|
@@ -5081,7 +5186,7 @@ function createWatchCommand() {
|
|
|
5081
5186
|
}
|
|
5082
5187
|
}
|
|
5083
5188
|
if (allPassed) {
|
|
5084
|
-
console.log(
|
|
5189
|
+
console.log(chalk25.green("\u2713 All verification criteria passed!"));
|
|
5085
5190
|
await completeTask(task.id, task);
|
|
5086
5191
|
currentTask = null;
|
|
5087
5192
|
}
|
|
@@ -5106,11 +5211,11 @@ function createWatchCommand() {
|
|
|
5106
5211
|
setTimeout(() => processActiveTask(), 500);
|
|
5107
5212
|
}
|
|
5108
5213
|
});
|
|
5109
|
-
console.log(
|
|
5214
|
+
console.log(chalk25.dim("Watching for file changes... (Ctrl+C to exit)"));
|
|
5110
5215
|
setInterval(() => processActiveTask(), 3e4);
|
|
5111
5216
|
process.on("SIGINT", () => {
|
|
5112
5217
|
console.log("");
|
|
5113
|
-
console.log(
|
|
5218
|
+
console.log(chalk25.dim("Watch mode stopped."));
|
|
5114
5219
|
watcher.close();
|
|
5115
5220
|
process.exit(0);
|
|
5116
5221
|
});
|
|
@@ -5122,12 +5227,10 @@ function createWatchCommand() {
|
|
|
5122
5227
|
init_esm_shims();
|
|
5123
5228
|
init_config();
|
|
5124
5229
|
import { Command as Command15 } from "commander";
|
|
5125
|
-
import
|
|
5230
|
+
import chalk26 from "chalk";
|
|
5126
5231
|
import ora12 from "ora";
|
|
5127
5232
|
import axios19 from "axios";
|
|
5128
5233
|
import { execSync as execSync5 } from "child_process";
|
|
5129
|
-
import fs23 from "fs/promises";
|
|
5130
|
-
import path26 from "path";
|
|
5131
5234
|
function createFocusCommand() {
|
|
5132
5235
|
const focus = new Command15("focus");
|
|
5133
5236
|
focus.alias("task").description("Get the next active roadmap task and copy its prompt to clipboard").option("--no-copy", "Do not copy to clipboard").action(async (options) => {
|
|
@@ -5137,21 +5240,17 @@ function createFocusCommand() {
|
|
|
5137
5240
|
try {
|
|
5138
5241
|
apiKey = getApiKey();
|
|
5139
5242
|
} catch (e) {
|
|
5140
|
-
spinner.fail(
|
|
5243
|
+
spinner.fail(chalk26.red('Not authenticated. Run "rigstate login" first.'));
|
|
5141
5244
|
return;
|
|
5142
5245
|
}
|
|
5143
5246
|
projectId = getProjectId();
|
|
5144
5247
|
if (!projectId) {
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
const manifest = JSON.parse(content);
|
|
5149
|
-
projectId = manifest.project_id;
|
|
5150
|
-
} catch (e) {
|
|
5151
|
-
}
|
|
5248
|
+
const { loadManifest: loadManifest2 } = await Promise.resolve().then(() => (init_manifest(), manifest_exports));
|
|
5249
|
+
const manifest = await loadManifest2();
|
|
5250
|
+
if (manifest?.project_id) projectId = manifest.project_id;
|
|
5152
5251
|
}
|
|
5153
5252
|
if (!projectId) {
|
|
5154
|
-
spinner.fail(
|
|
5253
|
+
spinner.fail(chalk26.red('No project context. Run "rigstate link" first.'));
|
|
5155
5254
|
return;
|
|
5156
5255
|
}
|
|
5157
5256
|
const apiUrl = getApiUrl();
|
|
@@ -5182,41 +5281,41 @@ function createFocusCommand() {
|
|
|
5182
5281
|
const nextTask = activeTasks[0];
|
|
5183
5282
|
spinner.stop();
|
|
5184
5283
|
console.log("");
|
|
5185
|
-
console.log(
|
|
5186
|
-
const statusColor = nextTask.status === "IN_PROGRESS" ?
|
|
5187
|
-
console.log(
|
|
5188
|
-
console.log(
|
|
5284
|
+
console.log(chalk26.bold.blue(`\u{1F4CC} Task #${nextTask.step_number || "?"}: ${nextTask.title}`));
|
|
5285
|
+
const statusColor = nextTask.status === "IN_PROGRESS" ? chalk26.yellow : nextTask.status === "ACTIVE" ? chalk26.green : chalk26.dim;
|
|
5286
|
+
console.log(chalk26.dim("Status: ") + statusColor(nextTask.status));
|
|
5287
|
+
console.log(chalk26.dim("\u2500".repeat(60)));
|
|
5189
5288
|
if (nextTask.prompt_content) {
|
|
5190
|
-
console.log(
|
|
5191
|
-
console.log(
|
|
5289
|
+
console.log(chalk26.white(nextTask.prompt_content));
|
|
5290
|
+
console.log(chalk26.dim("\u2500".repeat(60)));
|
|
5192
5291
|
if (options.copy !== false) {
|
|
5193
5292
|
try {
|
|
5194
5293
|
if (process.platform === "darwin") {
|
|
5195
5294
|
execSync5("pbcopy", { input: nextTask.prompt_content });
|
|
5196
|
-
console.log(
|
|
5295
|
+
console.log(chalk26.green("\u2705 Prompt copied to clipboard! Ready to paste (Cmd+V)."));
|
|
5197
5296
|
} else if (process.platform === "linux") {
|
|
5198
5297
|
try {
|
|
5199
5298
|
execSync5("xclip -selection clipboard", { input: nextTask.prompt_content });
|
|
5200
|
-
console.log(
|
|
5299
|
+
console.log(chalk26.green("\u2705 Prompt copied to clipboard!"));
|
|
5201
5300
|
} catch (e) {
|
|
5202
|
-
console.log(
|
|
5301
|
+
console.log(chalk26.yellow("\u2139\uFE0F Copy prompt manually (xclip not available)"));
|
|
5203
5302
|
}
|
|
5204
5303
|
} else {
|
|
5205
|
-
console.log(
|
|
5304
|
+
console.log(chalk26.yellow("\u2139\uFE0F Copy prompt manually (Auto-copy not supported on this OS)"));
|
|
5206
5305
|
}
|
|
5207
5306
|
} catch (e) {
|
|
5208
5307
|
}
|
|
5209
5308
|
}
|
|
5210
5309
|
} else {
|
|
5211
|
-
console.log(
|
|
5310
|
+
console.log(chalk26.yellow("No prompt instructions available."));
|
|
5212
5311
|
if (nextTask.architectural_brief) {
|
|
5213
|
-
console.log(
|
|
5312
|
+
console.log(chalk26.bold("Brief:"));
|
|
5214
5313
|
console.log(nextTask.architectural_brief);
|
|
5215
5314
|
}
|
|
5216
5315
|
}
|
|
5217
5316
|
console.log("");
|
|
5218
5317
|
} catch (e) {
|
|
5219
|
-
spinner.fail(
|
|
5318
|
+
spinner.fail(chalk26.red(`Failed to fetch task: ${e.message}`));
|
|
5220
5319
|
}
|
|
5221
5320
|
});
|
|
5222
5321
|
return focus;
|
|
@@ -5229,25 +5328,25 @@ init_env();
|
|
|
5229
5328
|
init_esm_shims();
|
|
5230
5329
|
init_config();
|
|
5231
5330
|
import { Command as Command16 } from "commander";
|
|
5232
|
-
import
|
|
5331
|
+
import chalk27 from "chalk";
|
|
5233
5332
|
function createConfigCommand() {
|
|
5234
5333
|
const config2 = new Command16("config");
|
|
5235
5334
|
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) => {
|
|
5236
5335
|
if (!key) {
|
|
5237
|
-
console.log(
|
|
5238
|
-
console.log(
|
|
5336
|
+
console.log(chalk27.bold("Rigstate Configuration"));
|
|
5337
|
+
console.log(chalk27.dim("\u2500".repeat(40)));
|
|
5239
5338
|
try {
|
|
5240
5339
|
const apiKey = getApiKey();
|
|
5241
|
-
console.log(`${
|
|
5340
|
+
console.log(`${chalk27.cyan("api_key")}: ${apiKey.substring(0, 20)}...`);
|
|
5242
5341
|
} catch (e) {
|
|
5243
|
-
console.log(`${
|
|
5342
|
+
console.log(`${chalk27.cyan("api_key")}: ${chalk27.dim("(not set)")}`);
|
|
5244
5343
|
}
|
|
5245
5344
|
const projectId = getProjectId();
|
|
5246
|
-
console.log(`${
|
|
5345
|
+
console.log(`${chalk27.cyan("project_id")}: ${projectId || chalk27.dim("(not set)")}`);
|
|
5247
5346
|
const apiUrl = getApiUrl();
|
|
5248
|
-
console.log(`${
|
|
5347
|
+
console.log(`${chalk27.cyan("api_url")}: ${apiUrl}`);
|
|
5249
5348
|
console.log("");
|
|
5250
|
-
console.log(
|
|
5349
|
+
console.log(chalk27.dim('Use "rigstate config <key> <value>" to set a value.'));
|
|
5251
5350
|
return;
|
|
5252
5351
|
}
|
|
5253
5352
|
if (!value) {
|
|
@@ -5257,37 +5356,37 @@ function createConfigCommand() {
|
|
|
5257
5356
|
const apiKey = getApiKey();
|
|
5258
5357
|
console.log(apiKey);
|
|
5259
5358
|
} catch (e) {
|
|
5260
|
-
console.log(
|
|
5359
|
+
console.log(chalk27.dim("(not set)"));
|
|
5261
5360
|
}
|
|
5262
5361
|
break;
|
|
5263
5362
|
case "project_id":
|
|
5264
|
-
console.log(getProjectId() ||
|
|
5363
|
+
console.log(getProjectId() || chalk27.dim("(not set)"));
|
|
5265
5364
|
break;
|
|
5266
5365
|
case "api_url":
|
|
5267
5366
|
console.log(getApiUrl());
|
|
5268
5367
|
break;
|
|
5269
5368
|
default:
|
|
5270
|
-
console.log(
|
|
5271
|
-
console.log(
|
|
5369
|
+
console.log(chalk27.red(`Unknown config key: ${key}`));
|
|
5370
|
+
console.log(chalk27.dim("Valid keys: api_key, project_id, api_url"));
|
|
5272
5371
|
}
|
|
5273
5372
|
return;
|
|
5274
5373
|
}
|
|
5275
5374
|
switch (key) {
|
|
5276
5375
|
case "api_key":
|
|
5277
5376
|
setApiKey(value);
|
|
5278
|
-
console.log(
|
|
5377
|
+
console.log(chalk27.green(`\u2705 api_key updated`));
|
|
5279
5378
|
break;
|
|
5280
5379
|
case "project_id":
|
|
5281
5380
|
setProjectId(value);
|
|
5282
|
-
console.log(
|
|
5381
|
+
console.log(chalk27.green(`\u2705 project_id updated`));
|
|
5283
5382
|
break;
|
|
5284
5383
|
case "api_url":
|
|
5285
5384
|
setApiUrl(value);
|
|
5286
|
-
console.log(
|
|
5385
|
+
console.log(chalk27.green(`\u2705 api_url updated`));
|
|
5287
5386
|
break;
|
|
5288
5387
|
default:
|
|
5289
|
-
console.log(
|
|
5290
|
-
console.log(
|
|
5388
|
+
console.log(chalk27.red(`Unknown config key: ${key}`));
|
|
5389
|
+
console.log(chalk27.dim("Valid keys: api_key, project_id, api_url"));
|
|
5291
5390
|
}
|
|
5292
5391
|
});
|
|
5293
5392
|
return config2;
|
|
@@ -5297,7 +5396,7 @@ function createConfigCommand() {
|
|
|
5297
5396
|
init_esm_shims();
|
|
5298
5397
|
init_config();
|
|
5299
5398
|
import { Command as Command17 } from "commander";
|
|
5300
|
-
import
|
|
5399
|
+
import chalk28 from "chalk";
|
|
5301
5400
|
import { spawn } from "child_process";
|
|
5302
5401
|
import path27 from "path";
|
|
5303
5402
|
import fs24 from "fs";
|
|
@@ -5323,15 +5422,15 @@ function createMcpCommand() {
|
|
|
5323
5422
|
}
|
|
5324
5423
|
}
|
|
5325
5424
|
if (!serverPath) {
|
|
5326
|
-
console.error(
|
|
5327
|
-
console.error(
|
|
5328
|
-
console.error(
|
|
5425
|
+
console.error(chalk28.red("\u274C Error: Rigstate MCP Server binary not found."));
|
|
5426
|
+
console.error(chalk28.yellow("Please ensure that the mcp package is built:"));
|
|
5427
|
+
console.error(chalk28.white(" cd packages/mcp && npm run build"));
|
|
5329
5428
|
console.error("");
|
|
5330
|
-
console.error(
|
|
5331
|
-
console.error(
|
|
5429
|
+
console.error(chalk28.dim("Or run directly with:"));
|
|
5430
|
+
console.error(chalk28.white(" npx @rigstate/mcp"));
|
|
5332
5431
|
process.exit(1);
|
|
5333
5432
|
}
|
|
5334
|
-
console.log(
|
|
5433
|
+
console.log(chalk28.dim(`Starting MCP server from: ${serverPath}`));
|
|
5335
5434
|
const env = { ...process.env };
|
|
5336
5435
|
try {
|
|
5337
5436
|
const apiKey = getApiKey();
|
|
@@ -5350,7 +5449,7 @@ function createMcpCommand() {
|
|
|
5350
5449
|
stdio: ["inherit", "inherit", "inherit"]
|
|
5351
5450
|
});
|
|
5352
5451
|
worker.on("error", (err) => {
|
|
5353
|
-
console.error(
|
|
5452
|
+
console.error(chalk28.red(`\u274C Failed to start MCP server: ${err.message}`));
|
|
5354
5453
|
process.exit(1);
|
|
5355
5454
|
});
|
|
5356
5455
|
worker.on("exit", (code) => {
|
|
@@ -5365,7 +5464,7 @@ function createMcpCommand() {
|
|
|
5365
5464
|
// src/commands/nexus.ts
|
|
5366
5465
|
init_esm_shims();
|
|
5367
5466
|
import { Command as Command18 } from "commander";
|
|
5368
|
-
import
|
|
5467
|
+
import chalk30 from "chalk";
|
|
5369
5468
|
|
|
5370
5469
|
// src/nexus/dispatcher.ts
|
|
5371
5470
|
init_esm_shims();
|
|
@@ -5433,7 +5532,7 @@ var HiveScrubber = class {
|
|
|
5433
5532
|
};
|
|
5434
5533
|
|
|
5435
5534
|
// src/hive/gateway.ts
|
|
5436
|
-
import
|
|
5535
|
+
import chalk29 from "chalk";
|
|
5437
5536
|
var HiveGateway = class {
|
|
5438
5537
|
client;
|
|
5439
5538
|
enabled;
|
|
@@ -5443,7 +5542,7 @@ var HiveGateway = class {
|
|
|
5443
5542
|
constructor(baseUrl, token) {
|
|
5444
5543
|
this.enabled = !!token;
|
|
5445
5544
|
if (!this.enabled) {
|
|
5446
|
-
console.log(
|
|
5545
|
+
console.log(chalk29.dim("\u26A0\uFE0F Hive Gateway disabled (No Token provided). Running in localized mode."));
|
|
5447
5546
|
}
|
|
5448
5547
|
this.client = axios20.create({
|
|
5449
5548
|
baseURL: baseUrl,
|
|
@@ -5463,23 +5562,23 @@ var HiveGateway = class {
|
|
|
5463
5562
|
if (!this.enabled) return false;
|
|
5464
5563
|
const now = Date.now();
|
|
5465
5564
|
if (now - this.lastSignalTime < this.MIN_INTERVAL_MS) {
|
|
5466
|
-
console.warn(
|
|
5565
|
+
console.warn(chalk29.yellow("\u23F3 Hive Gateway Throttled. Signal dropped to preventing spam."));
|
|
5467
5566
|
return false;
|
|
5468
5567
|
}
|
|
5469
5568
|
const scrubResult = HiveScrubber.scrub(signal.ruleContent);
|
|
5470
5569
|
if (scrubResult.riskScore > 20) {
|
|
5471
|
-
console.error(
|
|
5570
|
+
console.error(chalk29.red(`\u{1F6D1} HIVE BLOCKED: Signal contains sensitive data (Risk: ${scrubResult.riskScore})`));
|
|
5472
5571
|
return false;
|
|
5473
5572
|
}
|
|
5474
5573
|
try {
|
|
5475
|
-
console.log(
|
|
5574
|
+
console.log(chalk29.blue(`\u{1F4E1} Uplinking to Hive... [${signal.vector}]`));
|
|
5476
5575
|
const payload = { ...signal, ruleContent: scrubResult.sanitizedContent };
|
|
5477
5576
|
await this.client.post("/signal", payload);
|
|
5478
5577
|
this.lastSignalTime = now;
|
|
5479
|
-
console.log(
|
|
5578
|
+
console.log(chalk29.green("\u2705 Signal Received by Hive Core. Knowledge Shared."));
|
|
5480
5579
|
return true;
|
|
5481
5580
|
} catch (error) {
|
|
5482
|
-
console.error(
|
|
5581
|
+
console.error(chalk29.red(`\u274C Hive Transmission Failed: ${error.message}`));
|
|
5483
5582
|
return false;
|
|
5484
5583
|
}
|
|
5485
5584
|
}
|
|
@@ -5581,10 +5680,10 @@ import inquirer4 from "inquirer";
|
|
|
5581
5680
|
function createNexusCommand() {
|
|
5582
5681
|
const command = new Command18("nexus");
|
|
5583
5682
|
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) => {
|
|
5584
|
-
console.log(
|
|
5683
|
+
console.log(chalk30.bold.magenta("\n\u{1F981} Welcome to The Nexus (Phase 8)\n"));
|
|
5585
5684
|
const dryRun = !options.force;
|
|
5586
5685
|
if (!dryRun) {
|
|
5587
|
-
console.log(
|
|
5686
|
+
console.log(chalk30.black.bgYellow(" WARNING ") + chalk30.yellow(" Dry-Run disabled! Eitri is authorized to write code."));
|
|
5588
5687
|
const { confirm } = await inquirer4.prompt([{
|
|
5589
5688
|
type: "confirm",
|
|
5590
5689
|
name: "confirm",
|
|
@@ -5605,26 +5704,26 @@ function createNexusCommand() {
|
|
|
5605
5704
|
};
|
|
5606
5705
|
const dispatcher = new NexusDispatcher(context);
|
|
5607
5706
|
dispatcher.on("order:created", (o) => {
|
|
5608
|
-
console.log(
|
|
5707
|
+
console.log(chalk30.blue(`\u{1F195} [${o.id.slice(0, 6)}] Order Created: `) + o.intent);
|
|
5609
5708
|
});
|
|
5610
5709
|
dispatcher.on("order:started", (o) => {
|
|
5611
|
-
console.log(
|
|
5710
|
+
console.log(chalk30.yellow(`\u23F3 [${o.id.slice(0, 6)}] Processing...`));
|
|
5612
5711
|
});
|
|
5613
5712
|
dispatcher.on("order:blocked", (o) => {
|
|
5614
|
-
console.log(
|
|
5615
|
-
console.log(
|
|
5616
|
-
console.log(
|
|
5713
|
+
console.log(chalk30.red(`\u{1F6D1} [${o.id.slice(0, 6)}] BLOCKED by Kill-Switch`));
|
|
5714
|
+
console.log(chalk30.dim(` Target: ${o.targetAgent} | Action: ${o.action}`));
|
|
5715
|
+
console.log(chalk30.dim(" Run with --force to execute automatically (NOT RECOMMENDED)."));
|
|
5617
5716
|
});
|
|
5618
|
-
dispatcher.on("agent:SINDRE", (o) => console.log(
|
|
5619
|
-
dispatcher.on("agent:EITRI", (o) => console.log(
|
|
5620
|
-
console.log(
|
|
5717
|
+
dispatcher.on("agent:SINDRE", (o) => console.log(chalk30.cyan(`\u{1F916} Sindre (Vault): I'm on it! (${o.action})`)));
|
|
5718
|
+
dispatcher.on("agent:EITRI", (o) => console.log(chalk30.green(`\u{1F477} Eitri (Smith): Ready to build! (${o.action})`)));
|
|
5719
|
+
console.log(chalk30.dim("\u{1F9E0} Frank is analyzing your intent..."));
|
|
5621
5720
|
await new Promise((r) => setTimeout(r, 800));
|
|
5622
5721
|
if (intent.toLowerCase().includes("db") || intent.toLowerCase().includes("database")) {
|
|
5623
5722
|
await dispatcher.dispatch("FRANK", "SINDRE", intent, "db.analyze", { raw: intent });
|
|
5624
5723
|
} else if (intent.toLowerCase().includes("create") || intent.toLowerCase().includes("code")) {
|
|
5625
5724
|
await dispatcher.dispatch("FRANK", "EITRI", intent, "fs.write", { path: "src/demo.ts", content: "// demo" });
|
|
5626
5725
|
} else {
|
|
5627
|
-
console.log(
|
|
5726
|
+
console.log(chalk30.gray("Frank didn't understand. Try 'create file' or 'check database'."));
|
|
5628
5727
|
}
|
|
5629
5728
|
});
|
|
5630
5729
|
return command;
|
|
@@ -5638,25 +5737,25 @@ init_esm_shims();
|
|
|
5638
5737
|
init_governance();
|
|
5639
5738
|
init_config();
|
|
5640
5739
|
import { Command as Command19 } from "commander";
|
|
5641
|
-
import
|
|
5740
|
+
import chalk31 from "chalk";
|
|
5642
5741
|
import axios21 from "axios";
|
|
5643
5742
|
function createOverrideCommand() {
|
|
5644
5743
|
const override = new Command19("override");
|
|
5645
5744
|
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) => {
|
|
5646
5745
|
const { reason } = options;
|
|
5647
|
-
console.log(
|
|
5746
|
+
console.log(chalk31.bold(`
|
|
5648
5747
|
\u{1F513} Initiating Governance Override Protocol...`));
|
|
5649
5748
|
const session = await getSessionState(process.cwd());
|
|
5650
5749
|
if (session.status !== "SOFT_LOCK") {
|
|
5651
|
-
console.log(
|
|
5750
|
+
console.log(chalk31.yellow(" Info: Session is not currently locked."));
|
|
5652
5751
|
return;
|
|
5653
5752
|
}
|
|
5654
|
-
console.log(
|
|
5655
|
-
console.log(
|
|
5753
|
+
console.log(chalk31.dim(` Active Violation: ${session.active_violation}`));
|
|
5754
|
+
console.log(chalk31.dim(` Reason Provided: "${reason}"`));
|
|
5656
5755
|
const success = await performOverride(violationId, reason, process.cwd());
|
|
5657
5756
|
if (success) {
|
|
5658
|
-
console.log(
|
|
5659
|
-
console.log(
|
|
5757
|
+
console.log(chalk31.green(` \u2705 Session UNLOCKED.`));
|
|
5758
|
+
console.log(chalk31.dim(` This event has been logged to the Mission Report.`));
|
|
5660
5759
|
try {
|
|
5661
5760
|
const projectId = getProjectId();
|
|
5662
5761
|
if (projectId) {
|
|
@@ -5673,13 +5772,13 @@ function createOverrideCommand() {
|
|
|
5673
5772
|
}, {
|
|
5674
5773
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
5675
5774
|
});
|
|
5676
|
-
console.log(
|
|
5775
|
+
console.log(chalk31.dim(` \u2601 Audit log synced to Cloud.`));
|
|
5677
5776
|
}
|
|
5678
5777
|
} catch (e) {
|
|
5679
|
-
console.log(
|
|
5778
|
+
console.log(chalk31.dim(` (Cloud audit sync failed: ${e.message})`));
|
|
5680
5779
|
}
|
|
5681
5780
|
} else {
|
|
5682
|
-
console.log(
|
|
5781
|
+
console.log(chalk31.red(` \u{1F6D1} Override Failed. Check project configuration.`));
|
|
5683
5782
|
}
|
|
5684
5783
|
});
|
|
5685
5784
|
return override;
|
|
@@ -5689,7 +5788,7 @@ function createOverrideCommand() {
|
|
|
5689
5788
|
init_esm_shims();
|
|
5690
5789
|
init_config();
|
|
5691
5790
|
import { Command as Command20 } from "commander";
|
|
5692
|
-
import
|
|
5791
|
+
import chalk32 from "chalk";
|
|
5693
5792
|
import ora13 from "ora";
|
|
5694
5793
|
import axios22 from "axios";
|
|
5695
5794
|
import inquirer5 from "inquirer";
|
|
@@ -5700,7 +5799,7 @@ function createIdeaCommand() {
|
|
|
5700
5799
|
const apiUrl = getApiUrl();
|
|
5701
5800
|
const projectId = getProjectId();
|
|
5702
5801
|
if (!projectId) {
|
|
5703
|
-
console.error(
|
|
5802
|
+
console.error(chalk32.red("Project context missing. Run rigstate link."));
|
|
5704
5803
|
process.exit(1);
|
|
5705
5804
|
}
|
|
5706
5805
|
let ideaTitle = title;
|
|
@@ -5736,14 +5835,14 @@ function createIdeaCommand() {
|
|
|
5736
5835
|
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
5737
5836
|
);
|
|
5738
5837
|
if (response.data.success) {
|
|
5739
|
-
spinner.succeed(
|
|
5740
|
-
console.log(
|
|
5838
|
+
spinner.succeed(chalk32.green("Idea Captured! \u{1F4A1}"));
|
|
5839
|
+
console.log(chalk32.dim(`ID: ${response.data.data?.id || "Saved"}`));
|
|
5741
5840
|
} else {
|
|
5742
5841
|
throw new Error(response.data.error);
|
|
5743
5842
|
}
|
|
5744
5843
|
} catch (e) {
|
|
5745
5844
|
const errorDetail = e.response?.data?.error || e.message;
|
|
5746
|
-
console.error(
|
|
5845
|
+
console.error(chalk32.red(`
|
|
5747
5846
|
Failed to capture idea: ${errorDetail}`));
|
|
5748
5847
|
}
|
|
5749
5848
|
});
|
|
@@ -5753,7 +5852,7 @@ Failed to capture idea: ${errorDetail}`));
|
|
|
5753
5852
|
init_esm_shims();
|
|
5754
5853
|
init_config();
|
|
5755
5854
|
import { Command as Command21 } from "commander";
|
|
5756
|
-
import
|
|
5855
|
+
import chalk33 from "chalk";
|
|
5757
5856
|
import ora14 from "ora";
|
|
5758
5857
|
import inquirer6 from "inquirer";
|
|
5759
5858
|
import fs25 from "fs/promises";
|
|
@@ -10329,7 +10428,7 @@ function createReleaseCommand() {
|
|
|
10329
10428
|
if (type === "major") newVersion = `${major + 1}.0.0`;
|
|
10330
10429
|
if (type === "minor") newVersion = `${major}.${minor + 1}.0`;
|
|
10331
10430
|
if (type === "patch") newVersion = `${major}.${minor}.${patch + 1}`;
|
|
10332
|
-
spinner.succeed(`Bumping ${pkg2.name} from ${
|
|
10431
|
+
spinner.succeed(`Bumping ${pkg2.name} from ${chalk33.dim(currentVersion)} to ${chalk33.green(newVersion)}`);
|
|
10333
10432
|
const { confirm } = await inquirer6.prompt([{
|
|
10334
10433
|
type: "confirm",
|
|
10335
10434
|
name: "confirm",
|
|
@@ -10359,7 +10458,7 @@ function createReleaseCommand() {
|
|
|
10359
10458
|
await git.addTag(`v${newVersion}`);
|
|
10360
10459
|
await git.push();
|
|
10361
10460
|
await git.pushTags();
|
|
10362
|
-
spinner.succeed(
|
|
10461
|
+
spinner.succeed(chalk33.bold.green(`\u{1F680} Release v${newVersion} shipped!`));
|
|
10363
10462
|
} catch (e) {
|
|
10364
10463
|
spinner.fail(e.message);
|
|
10365
10464
|
}
|
|
@@ -10377,7 +10476,7 @@ function getContext3() {
|
|
|
10377
10476
|
init_esm_shims();
|
|
10378
10477
|
init_config();
|
|
10379
10478
|
import { Command as Command22 } from "commander";
|
|
10380
|
-
import
|
|
10479
|
+
import chalk34 from "chalk";
|
|
10381
10480
|
import ora15 from "ora";
|
|
10382
10481
|
import axios23 from "axios";
|
|
10383
10482
|
function createRoadmapCommand() {
|
|
@@ -10388,7 +10487,7 @@ function createRoadmapCommand() {
|
|
|
10388
10487
|
const apiUrl = getApiUrl();
|
|
10389
10488
|
const projectId = getProjectId();
|
|
10390
10489
|
if (!projectId) {
|
|
10391
|
-
spinner.fail(
|
|
10490
|
+
spinner.fail(chalk34.red('Project context missing. Run "rigstate link".'));
|
|
10392
10491
|
return;
|
|
10393
10492
|
}
|
|
10394
10493
|
const response = await axios23.get(
|
|
@@ -10401,11 +10500,11 @@ function createRoadmapCommand() {
|
|
|
10401
10500
|
const tasks = response.data.data.roadmap || [];
|
|
10402
10501
|
spinner.stop();
|
|
10403
10502
|
if (tasks.length === 0) {
|
|
10404
|
-
console.log(
|
|
10503
|
+
console.log(chalk34.yellow("\nRoadmap is empty. Use the web UI to define your journey."));
|
|
10405
10504
|
return;
|
|
10406
10505
|
}
|
|
10407
|
-
console.log("\n" +
|
|
10408
|
-
console.log(
|
|
10506
|
+
console.log("\n" + chalk34.bold.underline("\u{1F6F0}\uFE0F TACTICAL OVERVIEW: PROJECT ROADMAP"));
|
|
10507
|
+
console.log(chalk34.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
10409
10508
|
const columns = {
|
|
10410
10509
|
"IN_PROGRESS": [],
|
|
10411
10510
|
"ACTIVE": [],
|
|
@@ -10417,14 +10516,14 @@ function createRoadmapCommand() {
|
|
|
10417
10516
|
columns[t.status].push(t);
|
|
10418
10517
|
}
|
|
10419
10518
|
});
|
|
10420
|
-
displayColumn("\u{1F525} IN PROGRESS", columns.IN_PROGRESS,
|
|
10421
|
-
displayColumn("\u25B6\uFE0F ACTIVE / NEXT", columns.ACTIVE,
|
|
10422
|
-
displayColumn("\u{1F512} LOCKED", columns.LOCKED,
|
|
10423
|
-
displayColumn("\u23F3 PENDING", columns.PENDING,
|
|
10424
|
-
console.log(
|
|
10425
|
-
console.log(
|
|
10519
|
+
displayColumn("\u{1F525} IN PROGRESS", columns.IN_PROGRESS, chalk34.yellow);
|
|
10520
|
+
displayColumn("\u25B6\uFE0F ACTIVE / NEXT", columns.ACTIVE, chalk34.green);
|
|
10521
|
+
displayColumn("\u{1F512} LOCKED", columns.LOCKED, chalk34.blue);
|
|
10522
|
+
displayColumn("\u23F3 PENDING", columns.PENDING, chalk34.gray);
|
|
10523
|
+
console.log(chalk34.dim("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
10524
|
+
console.log(chalk34.dim(`Total: ${tasks.length} tasks | Run "rigstate work" to start coding.`));
|
|
10426
10525
|
} catch (e) {
|
|
10427
|
-
spinner.fail(
|
|
10526
|
+
spinner.fail(chalk34.red(`
|
|
10428
10527
|
Failed to fetch roadmap: ${e.message}`));
|
|
10429
10528
|
}
|
|
10430
10529
|
});
|
|
@@ -10435,8 +10534,8 @@ function displayColumn(title, items, color) {
|
|
|
10435
10534
|
${color.bold(title)}`);
|
|
10436
10535
|
items.sort((a, b) => a.step_number - b.step_number).forEach((item) => {
|
|
10437
10536
|
const id = `T-${item.step_number}`.padEnd(8);
|
|
10438
|
-
const priority = item.priority === "MVP" ?
|
|
10439
|
-
console.log(` ${color("\u2022")} ${
|
|
10537
|
+
const priority = item.priority === "MVP" ? chalk34.magenta(" [MVP]") : "";
|
|
10538
|
+
console.log(` ${color("\u2022")} ${chalk34.bold(id)} ${item.title}${priority}`);
|
|
10440
10539
|
});
|
|
10441
10540
|
}
|
|
10442
10541
|
|
|
@@ -10444,7 +10543,7 @@ ${color.bold(title)}`);
|
|
|
10444
10543
|
init_esm_shims();
|
|
10445
10544
|
init_config();
|
|
10446
10545
|
import { Command as Command23 } from "commander";
|
|
10447
|
-
import
|
|
10546
|
+
import chalk35 from "chalk";
|
|
10448
10547
|
import ora16 from "ora";
|
|
10449
10548
|
import inquirer7 from "inquirer";
|
|
10450
10549
|
function createCouncilCommand() {
|
|
@@ -10455,7 +10554,7 @@ function createCouncilCommand() {
|
|
|
10455
10554
|
const apiUrl = getApiUrl();
|
|
10456
10555
|
const projectId = getProjectId();
|
|
10457
10556
|
if (!projectId) {
|
|
10458
|
-
console.error(
|
|
10557
|
+
console.error(chalk35.red('Project context missing. Run "rigstate link".'));
|
|
10459
10558
|
return;
|
|
10460
10559
|
}
|
|
10461
10560
|
let sessionTopic = topic;
|
|
@@ -10467,25 +10566,25 @@ function createCouncilCommand() {
|
|
|
10467
10566
|
}]);
|
|
10468
10567
|
sessionTopic = ans.topic;
|
|
10469
10568
|
}
|
|
10470
|
-
console.log(
|
|
10471
|
-
console.log(
|
|
10472
|
-
console.log(
|
|
10473
|
-
console.log(
|
|
10569
|
+
console.log(chalk35.bold.magenta("\n\u2696\uFE0F CONVENING THE COUNCIL OF SOVEREIGNTY\n"));
|
|
10570
|
+
console.log(chalk35.dim(`Topic: ${sessionTopic}`));
|
|
10571
|
+
console.log(chalk35.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
10572
|
+
console.log(chalk35.yellow("\n\u{1F9E0} Frank (Architect): Analyzing alignment with Project DNA..."));
|
|
10474
10573
|
await sleep(1500);
|
|
10475
|
-
console.log(
|
|
10476
|
-
console.log(
|
|
10574
|
+
console.log(chalk35.gray(' "This decision affects our backend scalability. I recommend caution."'));
|
|
10575
|
+
console.log(chalk35.blue("\n\u{1F6E1}\uFE0F Sigrid (Curator): Checking historical precedents..."));
|
|
10477
10576
|
await sleep(1500);
|
|
10478
|
-
console.log(
|
|
10479
|
-
console.log(
|
|
10577
|
+
console.log(chalk35.gray(` "Similar patterns in other projects led to technical debt. Let's review RLS."`));
|
|
10578
|
+
console.log(chalk35.green("\n\u{1F4D0} Einar (Analyst): Scanning dependency impact..."));
|
|
10480
10579
|
await sleep(1500);
|
|
10481
|
-
console.log(
|
|
10482
|
-
console.log(
|
|
10483
|
-
console.log(
|
|
10484
|
-
console.log(
|
|
10485
|
-
console.log(
|
|
10486
|
-
console.log(
|
|
10580
|
+
console.log(chalk35.gray(' "Implementation will require updating 3 core services."'));
|
|
10581
|
+
console.log(chalk35.bold.white("\n\u{1F4CB} [FINAL DECISION RECORD]"));
|
|
10582
|
+
console.log(chalk35.white(" Status: Approved with conditions"));
|
|
10583
|
+
console.log(chalk35.white(" Rationale: Value outweighs migration cost. Ensure SEC-SQL-01 compliance."));
|
|
10584
|
+
console.log(chalk35.dim("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
10585
|
+
console.log(chalk35.green("\u2705 Decision saved to Project Brain (ADR-102)"));
|
|
10487
10586
|
} catch (e) {
|
|
10488
|
-
console.error(
|
|
10587
|
+
console.error(chalk35.red(`
|
|
10489
10588
|
Council session aborted: ${e.message}`));
|
|
10490
10589
|
}
|
|
10491
10590
|
});
|
|
@@ -10529,19 +10628,19 @@ program.hook("preAction", async () => {
|
|
|
10529
10628
|
});
|
|
10530
10629
|
program.on("--help", () => {
|
|
10531
10630
|
console.log("");
|
|
10532
|
-
console.log(
|
|
10631
|
+
console.log(chalk36.bold("Examples:"));
|
|
10533
10632
|
console.log("");
|
|
10534
|
-
console.log(
|
|
10535
|
-
console.log(
|
|
10633
|
+
console.log(chalk36.cyan(" $ rigstate login sk_rigstate_your_api_key"));
|
|
10634
|
+
console.log(chalk36.dim(" Authenticate with your Rigstate API key"));
|
|
10536
10635
|
console.log("");
|
|
10537
|
-
console.log(
|
|
10538
|
-
console.log(
|
|
10636
|
+
console.log(chalk36.cyan(" $ rigstate scan"));
|
|
10637
|
+
console.log(chalk36.dim(" Scan the current directory"));
|
|
10539
10638
|
console.log("");
|
|
10540
|
-
console.log(
|
|
10541
|
-
console.log(
|
|
10639
|
+
console.log(chalk36.cyan(" $ rigstate scan ./src --project abc123"));
|
|
10640
|
+
console.log(chalk36.dim(" Scan a specific directory with project ID"));
|
|
10542
10641
|
console.log("");
|
|
10543
|
-
console.log(
|
|
10544
|
-
console.log(
|
|
10642
|
+
console.log(chalk36.cyan(" $ rigstate scan --json"));
|
|
10643
|
+
console.log(chalk36.dim(" Output results in JSON format (useful for IDE extensions)"));
|
|
10545
10644
|
console.log("");
|
|
10546
10645
|
});
|
|
10547
10646
|
program.parse(process.argv);
|