@rigstate/cli 0.7.32 → 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 +831 -724
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +870 -765
- 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-rules.ts +3 -4
- 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/src/utils/version.ts +6 -1
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();
|
|
@@ -245,6 +363,18 @@ var init_env = __esm({
|
|
|
245
363
|
}
|
|
246
364
|
});
|
|
247
365
|
|
|
366
|
+
// src/utils/version.ts
|
|
367
|
+
async function checkVersion() {
|
|
368
|
+
}
|
|
369
|
+
var CLI_VERSION;
|
|
370
|
+
var init_version = __esm({
|
|
371
|
+
"src/utils/version.ts"() {
|
|
372
|
+
"use strict";
|
|
373
|
+
init_esm_shims();
|
|
374
|
+
CLI_VERSION = "0.7.34";
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
248
378
|
// src/commands/sync-rules.ts
|
|
249
379
|
var sync_rules_exports = {};
|
|
250
380
|
__export(sync_rules_exports, {
|
|
@@ -252,11 +382,10 @@ __export(sync_rules_exports, {
|
|
|
252
382
|
syncProjectRules: () => syncProjectRules
|
|
253
383
|
});
|
|
254
384
|
import { Command as Command3 } from "commander";
|
|
255
|
-
import
|
|
385
|
+
import chalk4 from "chalk";
|
|
256
386
|
import ora2 from "ora";
|
|
257
387
|
import axios2 from "axios";
|
|
258
|
-
|
|
259
|
-
async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false) {
|
|
388
|
+
async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false, version = CLI_VERSION) {
|
|
260
389
|
const spinner = ora2("\u{1F6E1}\uFE0F Frank Protocol: Initializing retroactive sync...").start();
|
|
261
390
|
let success = true;
|
|
262
391
|
try {
|
|
@@ -271,7 +400,7 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false) {
|
|
|
271
400
|
const project = projectRes.data.data.projects[0];
|
|
272
401
|
spinner.text = `Syncing rules for ${project.name}...`;
|
|
273
402
|
if (dryRun) {
|
|
274
|
-
spinner.succeed(
|
|
403
|
+
spinner.succeed(chalk4.yellow(` [DRY-RUN] Would sync: ${project.name}`));
|
|
275
404
|
return true;
|
|
276
405
|
}
|
|
277
406
|
const syncResponse = await axios2.post(`${apiUrl}/api/v1/rules/sync`, {
|
|
@@ -281,9 +410,9 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false) {
|
|
|
281
410
|
});
|
|
282
411
|
if (syncResponse.data.success) {
|
|
283
412
|
if (syncResponse.data.data.github_synced) {
|
|
284
|
-
spinner.succeed(
|
|
413
|
+
spinner.succeed(chalk4.green(` \u2705 ${project.name} [${project.id}] \u2192 GitHub synced`));
|
|
285
414
|
} else {
|
|
286
|
-
spinner.info(
|
|
415
|
+
spinner.info(chalk4.blue(` \u2139\uFE0F ${project.name} [${project.id}] \u2192 Rules generated (no GitHub)`));
|
|
287
416
|
}
|
|
288
417
|
const files = syncResponse.data.data.files;
|
|
289
418
|
if (files && Array.isArray(files)) {
|
|
@@ -294,7 +423,7 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false) {
|
|
|
294
423
|
await fs26.mkdir(path29.dirname(filePath), { recursive: true });
|
|
295
424
|
await fs26.writeFile(filePath, file.content, "utf-8");
|
|
296
425
|
}
|
|
297
|
-
console.log(
|
|
426
|
+
console.log(chalk4.dim(` \u{1F4BE} Wrote ${files.length} rule files to local .cursor/rules/`));
|
|
298
427
|
try {
|
|
299
428
|
const masterPath = path29.join(process.cwd(), ".cursorrules");
|
|
300
429
|
let masterContent = "";
|
|
@@ -308,7 +437,7 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false) {
|
|
|
308
437
|
const ruleList = files.map((f) => f.path).filter((p) => p.endsWith(".mdc")).map((p) => `- ${p}`).join("\n");
|
|
309
438
|
const governanceBlock = `${START_MARKER}
|
|
310
439
|
# \u{1F6E1}\uFE0F Rigstate Governance (Do not edit this block manually)
|
|
311
|
-
# The following rules are enforced by the Rigstate Daemon (v${
|
|
440
|
+
# The following rules are enforced by the Rigstate Daemon (v${version}).
|
|
312
441
|
# Failure to adhere to these rules will be flagged during the 'work' cycle.
|
|
313
442
|
|
|
314
443
|
# YOU MUST ADHERE TO THESE PROACTIVE RULES:
|
|
@@ -329,20 +458,20 @@ ${END_MARKER}`;
|
|
|
329
458
|
${governanceBlock}` : governanceBlock;
|
|
330
459
|
}
|
|
331
460
|
await fs26.writeFile(masterPath, newContent, "utf-8");
|
|
332
|
-
console.log(
|
|
461
|
+
console.log(chalk4.dim(" \u{1F4DC} Updated master .cursorrules (Constitution enforced)"));
|
|
333
462
|
} catch (e) {
|
|
334
|
-
console.warn(
|
|
463
|
+
console.warn(chalk4.yellow(` \u26A0\uFE0F Could not update .cursorrules: ${e.message}`));
|
|
335
464
|
}
|
|
336
465
|
}
|
|
337
466
|
console.log("");
|
|
338
|
-
console.log(
|
|
339
|
-
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."));
|
|
340
469
|
} else {
|
|
341
|
-
spinner.warn(
|
|
470
|
+
spinner.warn(chalk4.yellow(` \u26A0\uFE0F ${project.name} \u2192 ${syncResponse.data.error || "Unknown error"}`));
|
|
342
471
|
success = false;
|
|
343
472
|
}
|
|
344
473
|
} catch (e) {
|
|
345
|
-
spinner.fail(
|
|
474
|
+
spinner.fail(chalk4.red(`Sync failed: ${e.message}`));
|
|
346
475
|
success = false;
|
|
347
476
|
}
|
|
348
477
|
return success;
|
|
@@ -354,25 +483,24 @@ function createSyncRulesCommand() {
|
|
|
354
483
|
try {
|
|
355
484
|
apiKey = getApiKey();
|
|
356
485
|
} catch (e) {
|
|
357
|
-
console.error(
|
|
486
|
+
console.error(chalk4.red('Not authenticated. Run "rigstate login" first.'));
|
|
358
487
|
return;
|
|
359
488
|
}
|
|
360
489
|
const apiUrl = getApiUrl();
|
|
361
490
|
if (options.project) {
|
|
362
491
|
await syncProjectRules(options.project, apiKey, apiUrl, options.dryRun);
|
|
363
492
|
} else {
|
|
364
|
-
console.log(
|
|
493
|
+
console.log(chalk4.yellow("Use --project <id> for now. (Mass sync logic awaiting migration)"));
|
|
365
494
|
}
|
|
366
495
|
});
|
|
367
496
|
return syncRules;
|
|
368
497
|
}
|
|
369
|
-
var require2;
|
|
370
498
|
var init_sync_rules = __esm({
|
|
371
499
|
"src/commands/sync-rules.ts"() {
|
|
372
500
|
"use strict";
|
|
373
501
|
init_esm_shims();
|
|
374
502
|
init_config();
|
|
375
|
-
|
|
503
|
+
init_version();
|
|
376
504
|
}
|
|
377
505
|
});
|
|
378
506
|
|
|
@@ -381,7 +509,7 @@ var suggest_exports = {};
|
|
|
381
509
|
__export(suggest_exports, {
|
|
382
510
|
suggestNextMove: () => suggestNextMove
|
|
383
511
|
});
|
|
384
|
-
import
|
|
512
|
+
import chalk5 from "chalk";
|
|
385
513
|
import axios3 from "axios";
|
|
386
514
|
async function suggestNextMove(projectId, apiKey, apiUrl) {
|
|
387
515
|
try {
|
|
@@ -401,18 +529,18 @@ async function suggestNextMove(projectId, apiKey, apiUrl) {
|
|
|
401
529
|
if (tasks.length === 0) return;
|
|
402
530
|
const nextTask = tasks[0];
|
|
403
531
|
console.log("");
|
|
404
|
-
console.log(
|
|
405
|
-
console.log(
|
|
406
|
-
console.log(`${
|
|
407
|
-
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)}`);
|
|
408
536
|
if (nextTask.role) {
|
|
409
|
-
console.log(`${
|
|
537
|
+
console.log(`${chalk5.bold("Required Role:")} ${chalk5.magenta(nextTask.role)}`);
|
|
410
538
|
}
|
|
411
539
|
console.log("");
|
|
412
|
-
console.log(
|
|
413
|
-
console.log(
|
|
414
|
-
console.log(
|
|
415
|
-
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"));
|
|
416
544
|
console.log("");
|
|
417
545
|
} catch (e) {
|
|
418
546
|
}
|
|
@@ -432,9 +560,9 @@ __export(skills_provisioner_exports, {
|
|
|
432
560
|
provisionSkills: () => provisionSkills
|
|
433
561
|
});
|
|
434
562
|
import axios6 from "axios";
|
|
435
|
-
import
|
|
436
|
-
import
|
|
437
|
-
import
|
|
563
|
+
import fs8 from "fs/promises";
|
|
564
|
+
import path9 from "path";
|
|
565
|
+
import chalk9 from "chalk";
|
|
438
566
|
async function provisionSkills(apiUrl, apiKey, projectId, rootDir) {
|
|
439
567
|
const skills = [];
|
|
440
568
|
try {
|
|
@@ -456,18 +584,18 @@ async function provisionSkills(apiUrl, apiKey, projectId, rootDir) {
|
|
|
456
584
|
}
|
|
457
585
|
} catch (e) {
|
|
458
586
|
const msg = e.response?.data?.error || e.message;
|
|
459
|
-
console.log(
|
|
587
|
+
console.log(chalk9.dim(` (Skills API not available: ${msg}, using core library)`));
|
|
460
588
|
}
|
|
461
589
|
if (skills.length === 0) {
|
|
462
590
|
const { getRigstateStandardSkills } = await import("@rigstate/rules-engine");
|
|
463
591
|
const coreSkills = getRigstateStandardSkills();
|
|
464
592
|
skills.push(...coreSkills);
|
|
465
593
|
}
|
|
466
|
-
const skillsDir =
|
|
467
|
-
await
|
|
594
|
+
const skillsDir = path9.join(rootDir, ".agent", "skills");
|
|
595
|
+
await fs8.mkdir(skillsDir, { recursive: true });
|
|
468
596
|
for (const skill of skills) {
|
|
469
|
-
const skillDir =
|
|
470
|
-
await
|
|
597
|
+
const skillDir = path9.join(skillsDir, skill.name);
|
|
598
|
+
await fs8.mkdir(skillDir, { recursive: true });
|
|
471
599
|
const skillContent = `---
|
|
472
600
|
name: ${skill.name}
|
|
473
601
|
description: ${skill.description}
|
|
@@ -480,10 +608,10 @@ ${skill.content}
|
|
|
480
608
|
|
|
481
609
|
---
|
|
482
610
|
*Provisioned by Rigstate CLI. Do not modify manually.*`;
|
|
483
|
-
const skillPath =
|
|
484
|
-
await
|
|
611
|
+
const skillPath = path9.join(skillDir, "SKILL.md");
|
|
612
|
+
await fs8.writeFile(skillPath, skillContent, "utf-8");
|
|
485
613
|
}
|
|
486
|
-
console.log(
|
|
614
|
+
console.log(chalk9.green(` \u2705 Provisioned ${skills.length} skill(s) to .agent/skills/`));
|
|
487
615
|
return skills;
|
|
488
616
|
}
|
|
489
617
|
function generateSkillsDiscoveryBlock(skills) {
|
|
@@ -498,16 +626,16 @@ ${skillBlocks}
|
|
|
498
626
|
</available_skills>`;
|
|
499
627
|
}
|
|
500
628
|
async function jitProvisionSkill(skillId, apiUrl, apiKey, projectId, rootDir) {
|
|
501
|
-
const rulesPath =
|
|
629
|
+
const rulesPath = path9.join(rootDir, ".cursorrules");
|
|
502
630
|
let rulesContent = "";
|
|
503
631
|
try {
|
|
504
|
-
rulesContent = await
|
|
632
|
+
rulesContent = await fs8.readFile(rulesPath, "utf-8");
|
|
505
633
|
} catch (e) {
|
|
506
634
|
return false;
|
|
507
635
|
}
|
|
508
636
|
const isProvisioned = rulesContent.includes(`<name>${skillId}</name>`) || rulesContent.includes(`.agent/skills/${skillId}`);
|
|
509
637
|
if (isProvisioned) return false;
|
|
510
|
-
console.log(
|
|
638
|
+
console.log(chalk9.yellow(` \u26A1 JIT PROVISIONING: Injecting ${skillId}...`));
|
|
511
639
|
try {
|
|
512
640
|
const skills = await provisionSkills(apiUrl, apiKey, projectId, rootDir);
|
|
513
641
|
const skillsBlock = generateSkillsDiscoveryBlock(skills);
|
|
@@ -522,10 +650,10 @@ async function jitProvisionSkill(skillId, apiUrl, apiKey, projectId, rootDir) {
|
|
|
522
650
|
rulesContent = rulesContent.slice(0, insertPoint + 3) + "\n\n" + skillsBlock + "\n" + rulesContent.slice(insertPoint + 3);
|
|
523
651
|
}
|
|
524
652
|
}
|
|
525
|
-
await
|
|
653
|
+
await fs8.writeFile(rulesPath, rulesContent, "utf-8");
|
|
526
654
|
return true;
|
|
527
655
|
} catch (e) {
|
|
528
|
-
console.log(
|
|
656
|
+
console.log(chalk9.red(` Failed to provision skill: ${e.message}`));
|
|
529
657
|
return false;
|
|
530
658
|
}
|
|
531
659
|
}
|
|
@@ -546,13 +674,13 @@ __export(governance_exports, {
|
|
|
546
674
|
performOverride: () => performOverride,
|
|
547
675
|
setSoftLock: () => setSoftLock
|
|
548
676
|
});
|
|
549
|
-
import
|
|
550
|
-
import
|
|
551
|
-
import
|
|
677
|
+
import fs9 from "fs/promises";
|
|
678
|
+
import path10 from "path";
|
|
679
|
+
import chalk10 from "chalk";
|
|
552
680
|
async function getGovernanceConfig(rootDir = process.cwd()) {
|
|
553
681
|
try {
|
|
554
|
-
const configPath =
|
|
555
|
-
const content = await
|
|
682
|
+
const configPath = path10.join(rootDir, "rigstate.config.json");
|
|
683
|
+
const content = await fs9.readFile(configPath, "utf-8");
|
|
556
684
|
const userConfig = JSON.parse(content);
|
|
557
685
|
return {
|
|
558
686
|
governance: {
|
|
@@ -566,37 +694,37 @@ async function getGovernanceConfig(rootDir = process.cwd()) {
|
|
|
566
694
|
}
|
|
567
695
|
async function getSessionState(rootDir = process.cwd()) {
|
|
568
696
|
try {
|
|
569
|
-
const sessionPath =
|
|
570
|
-
const content = await
|
|
697
|
+
const sessionPath = path10.join(rootDir, ".rigstate", "session.json");
|
|
698
|
+
const content = await fs9.readFile(sessionPath, "utf-8");
|
|
571
699
|
return JSON.parse(content);
|
|
572
700
|
} catch (e) {
|
|
573
701
|
return DEFAULT_SESSION;
|
|
574
702
|
}
|
|
575
703
|
}
|
|
576
704
|
async function setSoftLock(reason, violationId, rootDir = process.cwd()) {
|
|
577
|
-
const sessionPath =
|
|
705
|
+
const sessionPath = path10.join(rootDir, ".rigstate", "session.json");
|
|
578
706
|
const state = {
|
|
579
707
|
status: "SOFT_LOCK",
|
|
580
708
|
active_violation: violationId,
|
|
581
709
|
lock_reason: reason,
|
|
582
710
|
last_updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
583
711
|
};
|
|
584
|
-
await
|
|
585
|
-
await
|
|
712
|
+
await fs9.mkdir(path10.dirname(sessionPath), { recursive: true });
|
|
713
|
+
await fs9.writeFile(sessionPath, JSON.stringify(state, null, 2), "utf-8");
|
|
586
714
|
}
|
|
587
715
|
async function clearSoftLock(rootDir = process.cwd()) {
|
|
588
|
-
const sessionPath =
|
|
716
|
+
const sessionPath = path10.join(rootDir, ".rigstate", "session.json");
|
|
589
717
|
const state = {
|
|
590
718
|
...DEFAULT_SESSION,
|
|
591
719
|
last_updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
592
720
|
};
|
|
593
|
-
await
|
|
594
|
-
await
|
|
721
|
+
await fs9.mkdir(path10.dirname(sessionPath), { recursive: true });
|
|
722
|
+
await fs9.writeFile(sessionPath, JSON.stringify(state, null, 2), "utf-8");
|
|
595
723
|
}
|
|
596
724
|
async function performOverride(violationId, reason, rootDir = process.cwd()) {
|
|
597
725
|
const config2 = await getGovernanceConfig(rootDir);
|
|
598
726
|
if (!config2.governance.allow_overrides) {
|
|
599
|
-
console.log(
|
|
727
|
+
console.log(chalk10.red("\u274C Overrides are disabled for this project."));
|
|
600
728
|
return false;
|
|
601
729
|
}
|
|
602
730
|
await clearSoftLock(rootDir);
|
|
@@ -633,22 +761,22 @@ var watchdog_exports = {};
|
|
|
633
761
|
__export(watchdog_exports, {
|
|
634
762
|
runGuardianWatchdog: () => runGuardianWatchdog
|
|
635
763
|
});
|
|
636
|
-
import
|
|
637
|
-
import
|
|
638
|
-
import
|
|
764
|
+
import fs10 from "fs/promises";
|
|
765
|
+
import path11 from "path";
|
|
766
|
+
import chalk11 from "chalk";
|
|
639
767
|
import axios7 from "axios";
|
|
640
768
|
async function countLines(filePath) {
|
|
641
769
|
try {
|
|
642
|
-
const content = await
|
|
770
|
+
const content = await fs10.readFile(filePath, "utf-8");
|
|
643
771
|
return content.split("\n").length;
|
|
644
772
|
} catch (e) {
|
|
645
773
|
return 0;
|
|
646
774
|
}
|
|
647
775
|
}
|
|
648
776
|
async function getFiles(dir, extension) {
|
|
649
|
-
const entries = await
|
|
777
|
+
const entries = await fs10.readdir(dir, { withFileTypes: true });
|
|
650
778
|
const files = await Promise.all(entries.map(async (entry) => {
|
|
651
|
-
const res =
|
|
779
|
+
const res = path11.resolve(dir, entry.name);
|
|
652
780
|
if (entry.isDirectory()) {
|
|
653
781
|
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === ".next" || entry.name === "dist") return [];
|
|
654
782
|
return getFiles(res, extension);
|
|
@@ -676,8 +804,8 @@ async function fetchRulesFromApi(projectId) {
|
|
|
676
804
|
}
|
|
677
805
|
} catch (error) {
|
|
678
806
|
try {
|
|
679
|
-
const cachePath =
|
|
680
|
-
const content = await
|
|
807
|
+
const cachePath = path11.join(process.cwd(), CACHE_FILE);
|
|
808
|
+
const content = await fs10.readFile(cachePath, "utf-8");
|
|
681
809
|
const cached = JSON.parse(content);
|
|
682
810
|
if (cached.settings) {
|
|
683
811
|
return {
|
|
@@ -696,7 +824,7 @@ async function fetchRulesFromApi(projectId) {
|
|
|
696
824
|
};
|
|
697
825
|
}
|
|
698
826
|
async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
699
|
-
console.log(
|
|
827
|
+
console.log(chalk11.bold("\n\u{1F6E1}\uFE0F Active Guardian Watchdog Initiated..."));
|
|
700
828
|
let lmax = settings.lmax || DEFAULT_LMAX;
|
|
701
829
|
let lmaxWarning = settings.lmax_warning || DEFAULT_LMAX_WARNING;
|
|
702
830
|
let ruleSource = settings.lmax ? "Settings (Passed)" : "Default";
|
|
@@ -706,47 +834,47 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
706
834
|
lmaxWarning = apiRules.lmaxWarning;
|
|
707
835
|
ruleSource = apiRules.source;
|
|
708
836
|
}
|
|
709
|
-
console.log(
|
|
837
|
+
console.log(chalk11.dim(`Governance Rules: L_max=${lmax}, L_max_warning=${lmaxWarning}, Source: ${ruleSource}`));
|
|
710
838
|
const targetExtensions = [".ts", ".tsx"];
|
|
711
839
|
let scanTarget = rootPath;
|
|
712
|
-
const webSrc =
|
|
840
|
+
const webSrc = path11.join(rootPath, "apps", "web", "src");
|
|
713
841
|
try {
|
|
714
|
-
await
|
|
842
|
+
await fs10.access(webSrc);
|
|
715
843
|
scanTarget = webSrc;
|
|
716
844
|
} catch {
|
|
717
845
|
}
|
|
718
|
-
console.log(
|
|
846
|
+
console.log(chalk11.dim(`Scanning target: ${path11.relative(process.cwd(), scanTarget)}`));
|
|
719
847
|
const files = await getFiles(scanTarget, targetExtensions);
|
|
720
848
|
let violations = 0;
|
|
721
849
|
let warnings = 0;
|
|
722
850
|
const results = [];
|
|
723
851
|
for (const file of files) {
|
|
724
852
|
const lines = await countLines(file);
|
|
725
|
-
const relPath =
|
|
853
|
+
const relPath = path11.relative(rootPath, file);
|
|
726
854
|
if (lines > lmax) {
|
|
727
855
|
results.push({ file: relPath, lines, status: "VIOLATION" });
|
|
728
856
|
violations++;
|
|
729
|
-
console.log(
|
|
857
|
+
console.log(chalk11.red(`[VIOLATION] ${relPath}: ${lines} lines (Limit: ${lmax})`));
|
|
730
858
|
} else if (lines > lmaxWarning) {
|
|
731
859
|
results.push({ file: relPath, lines, status: "WARNING" });
|
|
732
860
|
warnings++;
|
|
733
|
-
console.log(
|
|
861
|
+
console.log(chalk11.yellow(`[WARNING] ${relPath}: ${lines} lines (Threshold: ${lmaxWarning})`));
|
|
734
862
|
}
|
|
735
863
|
}
|
|
736
864
|
if (violations === 0 && warnings === 0) {
|
|
737
|
-
console.log(
|
|
865
|
+
console.log(chalk11.green(`\u2714 All ${files.length} files are within governance limits.`));
|
|
738
866
|
} else {
|
|
739
|
-
console.log("\n" +
|
|
740
|
-
console.log(
|
|
741
|
-
console.log(
|
|
867
|
+
console.log("\n" + chalk11.bold("Summary:"));
|
|
868
|
+
console.log(chalk11.red(`Violations: ${violations}`));
|
|
869
|
+
console.log(chalk11.yellow(`Warnings: ${warnings}`));
|
|
742
870
|
const { getGovernanceConfig: getGovernanceConfig2, setSoftLock: setSoftLock2, InterventionLevel: InterventionLevel2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
743
871
|
const { governance } = await getGovernanceConfig2(rootPath);
|
|
744
|
-
console.log(
|
|
872
|
+
console.log(chalk11.dim(`Intervention Level: ${InterventionLevel2[governance.intervention_level] || "UNKNOWN"} (${governance.intervention_level})`));
|
|
745
873
|
if (violations > 0) {
|
|
746
|
-
console.log(
|
|
874
|
+
console.log(chalk11.red.bold("\nCRITICAL: Governance violations detected. Immediate refactoring required."));
|
|
747
875
|
if (governance.intervention_level >= InterventionLevel2.SENTINEL) {
|
|
748
|
-
console.log(
|
|
749
|
-
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.'));
|
|
750
878
|
await setSoftLock2("Sentinel Mode: Governance Violations Detected", "ARC-VIOLATION", rootPath);
|
|
751
879
|
}
|
|
752
880
|
}
|
|
@@ -769,9 +897,9 @@ async function runGuardianWatchdog(rootPath, settings = {}, projectId) {
|
|
|
769
897
|
}, {
|
|
770
898
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
771
899
|
});
|
|
772
|
-
console.log(
|
|
900
|
+
console.log(chalk11.dim("\u2714 Violations synced to Rigstate Cloud."));
|
|
773
901
|
} catch (e) {
|
|
774
|
-
console.log(
|
|
902
|
+
console.log(chalk11.dim("\u26A0 Cloud sync skipped: " + (e.message || "Unknown")));
|
|
775
903
|
}
|
|
776
904
|
}
|
|
777
905
|
}
|
|
@@ -1668,7 +1796,7 @@ var require_package = __commonJS({
|
|
|
1668
1796
|
"package.json"(exports, module) {
|
|
1669
1797
|
module.exports = {
|
|
1670
1798
|
name: "@rigstate/cli",
|
|
1671
|
-
version: "0.7.
|
|
1799
|
+
version: "0.7.34",
|
|
1672
1800
|
description: "Rigstate CLI - Code audit, sync and supervision tool",
|
|
1673
1801
|
type: "module",
|
|
1674
1802
|
main: "./dist/index.js",
|
|
@@ -1725,32 +1853,32 @@ var require_package = __commonJS({
|
|
|
1725
1853
|
// src/index.ts
|
|
1726
1854
|
init_esm_shims();
|
|
1727
1855
|
import { Command as Command24 } from "commander";
|
|
1728
|
-
import
|
|
1856
|
+
import chalk36 from "chalk";
|
|
1729
1857
|
|
|
1730
1858
|
// src/commands/login.ts
|
|
1731
1859
|
init_esm_shims();
|
|
1732
1860
|
init_config();
|
|
1733
1861
|
import { Command } from "commander";
|
|
1734
|
-
import
|
|
1862
|
+
import chalk2 from "chalk";
|
|
1735
1863
|
function createLoginCommand() {
|
|
1736
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) => {
|
|
1737
1865
|
try {
|
|
1738
1866
|
if (!apiKey || !apiKey.startsWith("sk_rigstate_")) {
|
|
1739
|
-
console.error(
|
|
1740
|
-
console.error(
|
|
1867
|
+
console.error(chalk2.red("\u274C Invalid API key format"));
|
|
1868
|
+
console.error(chalk2.dim('API keys must start with "sk_rigstate_"'));
|
|
1741
1869
|
process.exit(1);
|
|
1742
1870
|
}
|
|
1743
1871
|
setApiKey(apiKey);
|
|
1744
|
-
console.log(
|
|
1872
|
+
console.log(chalk2.green("\u2705 Successfully logged in!"));
|
|
1745
1873
|
console.log(
|
|
1746
|
-
|
|
1874
|
+
chalk2.dim(
|
|
1747
1875
|
`
|
|
1748
1876
|
Your API key has been securely stored. You can now use "rigstate scan" to audit your code.`
|
|
1749
1877
|
)
|
|
1750
1878
|
);
|
|
1751
|
-
console.log(
|
|
1752
|
-
console.log(
|
|
1753
|
-
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(`
|
|
1754
1882
|
{
|
|
1755
1883
|
"mcpServers": {
|
|
1756
1884
|
"rigstate": {
|
|
@@ -1767,7 +1895,7 @@ Your API key has been securely stored. You can now use "rigstate scan" to audit
|
|
|
1767
1895
|
}`));
|
|
1768
1896
|
} catch (error) {
|
|
1769
1897
|
console.error(
|
|
1770
|
-
|
|
1898
|
+
chalk2.red("\u274C Login failed:"),
|
|
1771
1899
|
error instanceof Error ? error.message : "Unknown error"
|
|
1772
1900
|
);
|
|
1773
1901
|
process.exit(1);
|
|
@@ -1779,24 +1907,24 @@ Your API key has been securely stored. You can now use "rigstate scan" to audit
|
|
|
1779
1907
|
init_esm_shims();
|
|
1780
1908
|
init_config();
|
|
1781
1909
|
import { Command as Command4 } from "commander";
|
|
1782
|
-
import
|
|
1783
|
-
import
|
|
1784
|
-
import
|
|
1910
|
+
import fs4 from "fs/promises";
|
|
1911
|
+
import path5 from "path";
|
|
1912
|
+
import chalk6 from "chalk";
|
|
1785
1913
|
import os from "os";
|
|
1786
1914
|
function createLinkCommand() {
|
|
1787
1915
|
return new Command4("link").description("Link current directory to a Rigstate project").argument("[projectId]", "Project ID to link").action(async (projectId) => {
|
|
1788
1916
|
try {
|
|
1789
|
-
const globalPath =
|
|
1790
|
-
const globalData = await
|
|
1917
|
+
const globalPath = path5.join(os.homedir(), ".rigstate", "config.json");
|
|
1918
|
+
const globalData = await fs4.readFile(globalPath, "utf-8").catch(() => null);
|
|
1791
1919
|
if (globalData) {
|
|
1792
1920
|
const config2 = JSON.parse(globalData);
|
|
1793
|
-
const
|
|
1794
|
-
if (config2.overrides && config2.overrides[
|
|
1795
|
-
const overrideId = config2.overrides[
|
|
1796
|
-
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}`));
|
|
1797
1925
|
if (!projectId) projectId = overrideId;
|
|
1798
1926
|
else if (projectId !== overrideId) {
|
|
1799
|
-
console.warn(
|
|
1927
|
+
console.warn(chalk6.red(`Ignoring provided ID ${projectId}. Using override.`));
|
|
1800
1928
|
projectId = overrideId;
|
|
1801
1929
|
}
|
|
1802
1930
|
}
|
|
@@ -1810,16 +1938,16 @@ function createLinkCommand() {
|
|
|
1810
1938
|
const apiKey = getApiKey();
|
|
1811
1939
|
const apiUrl = getApiUrl();
|
|
1812
1940
|
if (!apiKey) {
|
|
1813
|
-
console.error(
|
|
1941
|
+
console.error(chalk6.red('Not authenticated. Please run "rigstate login" or provide a Project ID.'));
|
|
1814
1942
|
process.exit(1);
|
|
1815
1943
|
}
|
|
1816
|
-
console.log(
|
|
1944
|
+
console.log(chalk6.dim("Fetching your projects..."));
|
|
1817
1945
|
const axios24 = (await import("axios")).default;
|
|
1818
1946
|
const response = await axios24.get(`${apiUrl}/api/v1/projects`, {
|
|
1819
1947
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1820
1948
|
});
|
|
1821
1949
|
if (!response.data.success || !response.data.data.projects?.length) {
|
|
1822
|
-
console.error(
|
|
1950
|
+
console.error(chalk6.yellow("No projects found. Create one at https://app.rigstate.com"));
|
|
1823
1951
|
process.exit(1);
|
|
1824
1952
|
}
|
|
1825
1953
|
const choices = response.data.data.projects.map((p) => ({
|
|
@@ -1834,54 +1962,49 @@ function createLinkCommand() {
|
|
|
1834
1962
|
}]);
|
|
1835
1963
|
projectId = answer.id;
|
|
1836
1964
|
} catch (e) {
|
|
1837
|
-
console.error(
|
|
1965
|
+
console.error(chalk6.red(`Failed to fetch projects: ${e.message}`));
|
|
1838
1966
|
console.error("Please provide project ID manually: rigstate link <id>");
|
|
1839
1967
|
process.exit(1);
|
|
1840
1968
|
}
|
|
1841
1969
|
}
|
|
1842
|
-
const
|
|
1843
|
-
const content = {
|
|
1844
|
-
project_id: projectId,
|
|
1845
|
-
linked_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1846
|
-
};
|
|
1847
|
-
const currentUrl = getApiUrl();
|
|
1848
|
-
if (currentUrl !== "https://app.rigstate.com") {
|
|
1849
|
-
content.api_url = currentUrl;
|
|
1850
|
-
}
|
|
1970
|
+
const cwd = process.cwd();
|
|
1851
1971
|
try {
|
|
1852
|
-
await
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
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)}`));
|
|
1856
1980
|
console.log("");
|
|
1857
|
-
console.log(
|
|
1981
|
+
console.log(chalk6.bold("\u{1F916} Rigstate Automation Detected"));
|
|
1858
1982
|
console.log("");
|
|
1859
|
-
const { getApiKey: _getApiKey, getApiUrl: _getApiUrl } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
1860
1983
|
const apiKey = getApiKey();
|
|
1861
1984
|
const apiUrl = getApiUrl();
|
|
1862
1985
|
if (apiKey) {
|
|
1863
|
-
console.log(
|
|
1986
|
+
console.log(chalk6.blue("\u{1F510} Checking Vault for secrets..."));
|
|
1864
1987
|
const { syncEnv: syncEnv2 } = await Promise.resolve().then(() => (init_env(), env_exports));
|
|
1865
1988
|
await syncEnv2(projectId, apiKey, apiUrl, true);
|
|
1866
|
-
console.log(
|
|
1989
|
+
console.log(chalk6.blue("\u{1F9E0} Syncing neural instructions..."));
|
|
1867
1990
|
const { syncProjectRules: syncProjectRules2 } = await Promise.resolve().then(() => (init_sync_rules(), sync_rules_exports));
|
|
1868
1991
|
await syncProjectRules2(projectId, apiKey, apiUrl);
|
|
1869
|
-
console.log(
|
|
1992
|
+
console.log(chalk6.blue("\u{1F6E1}\uFE0F Injecting Guardian hooks & Safety nets..."));
|
|
1870
1993
|
await installHooks(process.cwd());
|
|
1871
1994
|
await hardenGitIgnore(process.cwd());
|
|
1872
1995
|
console.log("");
|
|
1873
|
-
console.log(
|
|
1996
|
+
console.log(chalk6.bold.green("\u{1F680} Link Complete! Your environment is ready."));
|
|
1874
1997
|
const { suggestNextMove: suggestNextMove2 } = await Promise.resolve().then(() => (init_suggest(), suggest_exports));
|
|
1875
1998
|
await suggestNextMove2(projectId, apiKey, apiUrl);
|
|
1876
1999
|
} else {
|
|
1877
2000
|
console.log("");
|
|
1878
|
-
console.log(
|
|
2001
|
+
console.log(chalk6.bold.green("\u{1F680} Link Complete!"));
|
|
1879
2002
|
}
|
|
1880
2003
|
} catch (error) {
|
|
1881
2004
|
if (error.message?.includes("Not authenticated")) {
|
|
1882
|
-
console.warn(
|
|
2005
|
+
console.warn(chalk6.yellow('\u26A0\uFE0F Not authenticated. Run "rigstate login" to enable automation features.'));
|
|
1883
2006
|
} else {
|
|
1884
|
-
console.error(
|
|
2007
|
+
console.error(chalk6.red(`Failed to link project: ${error.message}`));
|
|
1885
2008
|
}
|
|
1886
2009
|
}
|
|
1887
2010
|
});
|
|
@@ -1910,15 +2033,15 @@ async function hardenGitIgnore(cwd) {
|
|
|
1910
2033
|
}
|
|
1911
2034
|
const missing = REQUIRED_IGNORES.filter((line) => !content.includes(line) && !line.startsWith("#"));
|
|
1912
2035
|
if (missing.length > 0) {
|
|
1913
|
-
console.log(
|
|
2036
|
+
console.log(chalk6.dim(" Configuring .gitignore for Rigstate safety..."));
|
|
1914
2037
|
const toAppend = "\n\n" + REQUIRED_IGNORES.join("\n") + "\n";
|
|
1915
2038
|
await fs26.writeFile(ignorePath, content + toAppend, "utf-8");
|
|
1916
|
-
console.log(
|
|
2039
|
+
console.log(chalk6.green(" \u2714 .gitignore updated (Artifacts protected)"));
|
|
1917
2040
|
} else {
|
|
1918
|
-
console.log(
|
|
2041
|
+
console.log(chalk6.green(" \u2714 .gitignore already hardened"));
|
|
1919
2042
|
}
|
|
1920
2043
|
} catch (e) {
|
|
1921
|
-
console.warn(
|
|
2044
|
+
console.warn(chalk6.yellow(` Could not update .gitignore: ${e.message}`));
|
|
1922
2045
|
}
|
|
1923
2046
|
}
|
|
1924
2047
|
async function installHooks(cwd) {
|
|
@@ -1927,7 +2050,7 @@ async function installHooks(cwd) {
|
|
|
1927
2050
|
try {
|
|
1928
2051
|
await fs26.access(path29.join(cwd, ".git"));
|
|
1929
2052
|
} catch {
|
|
1930
|
-
console.log(
|
|
2053
|
+
console.log(chalk6.dim(" (Not a git repository, skipping hooks)"));
|
|
1931
2054
|
return;
|
|
1932
2055
|
}
|
|
1933
2056
|
const hooksDir = path29.join(cwd, ".husky");
|
|
@@ -1938,7 +2061,7 @@ async function installHooks(cwd) {
|
|
|
1938
2061
|
await fs26.access(preCommitPath);
|
|
1939
2062
|
const content = await fs26.readFile(preCommitPath, "utf-8");
|
|
1940
2063
|
if (content.includes("rigstate")) {
|
|
1941
|
-
console.log(
|
|
2064
|
+
console.log(chalk6.green(" \u2714 Git hooks already active"));
|
|
1942
2065
|
} else {
|
|
1943
2066
|
shouldInstall = true;
|
|
1944
2067
|
}
|
|
@@ -1967,10 +2090,10 @@ exit $?
|
|
|
1967
2090
|
} else {
|
|
1968
2091
|
await fs26.writeFile(preCommitPath, PRE_COMMIT_SCRIPT2, { mode: 493 });
|
|
1969
2092
|
}
|
|
1970
|
-
console.log(
|
|
2093
|
+
console.log(chalk6.green(" \u2714 Applied Guardian protection (git-hooks)"));
|
|
1971
2094
|
}
|
|
1972
2095
|
} catch (e) {
|
|
1973
|
-
console.log(
|
|
2096
|
+
console.log(chalk6.dim(" (Skipped hooks: " + e.message + ")"));
|
|
1974
2097
|
}
|
|
1975
2098
|
}
|
|
1976
2099
|
async function fileExists(path29) {
|
|
@@ -1987,21 +2110,21 @@ async function fileExists(path29) {
|
|
|
1987
2110
|
init_esm_shims();
|
|
1988
2111
|
init_config();
|
|
1989
2112
|
import { Command as Command5 } from "commander";
|
|
1990
|
-
import
|
|
2113
|
+
import chalk7 from "chalk";
|
|
1991
2114
|
import ora3 from "ora";
|
|
1992
2115
|
import axios4 from "axios";
|
|
1993
2116
|
import { glob } from "glob";
|
|
1994
|
-
import
|
|
1995
|
-
import
|
|
2117
|
+
import fs6 from "fs/promises";
|
|
2118
|
+
import path7 from "path";
|
|
1996
2119
|
|
|
1997
2120
|
// src/utils/files.ts
|
|
1998
2121
|
init_esm_shims();
|
|
1999
|
-
import
|
|
2000
|
-
import
|
|
2122
|
+
import fs5 from "fs/promises";
|
|
2123
|
+
import path6 from "path";
|
|
2001
2124
|
async function readGitignore(dir) {
|
|
2002
|
-
const gitignorePath =
|
|
2125
|
+
const gitignorePath = path6.join(dir, ".gitignore");
|
|
2003
2126
|
try {
|
|
2004
|
-
const content = await
|
|
2127
|
+
const content = await fs5.readFile(gitignorePath, "utf-8");
|
|
2005
2128
|
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
2006
2129
|
} catch (error) {
|
|
2007
2130
|
return [];
|
|
@@ -2063,7 +2186,7 @@ function isCodeFile(filePath) {
|
|
|
2063
2186
|
".vue",
|
|
2064
2187
|
".svelte"
|
|
2065
2188
|
];
|
|
2066
|
-
const ext =
|
|
2189
|
+
const ext = path6.extname(filePath).toLowerCase();
|
|
2067
2190
|
return codeExtensions.includes(ext);
|
|
2068
2191
|
}
|
|
2069
2192
|
|
|
@@ -2077,26 +2200,26 @@ function createScanCommand() {
|
|
|
2077
2200
|
const projectId = options.project || getProjectId();
|
|
2078
2201
|
if (!projectId) {
|
|
2079
2202
|
console.warn(
|
|
2080
|
-
|
|
2203
|
+
chalk7.yellow(
|
|
2081
2204
|
"\u26A0\uFE0F No project ID specified. Use --project <id> or set a default."
|
|
2082
2205
|
)
|
|
2083
2206
|
);
|
|
2084
2207
|
}
|
|
2085
|
-
const scanPath =
|
|
2086
|
-
spinner.start(`Scanning ${
|
|
2208
|
+
const scanPath = path7.resolve(process.cwd(), targetPath);
|
|
2209
|
+
spinner.start(`Scanning ${chalk7.cyan(scanPath)}...`);
|
|
2087
2210
|
const gitignorePatterns = await readGitignore(scanPath);
|
|
2088
|
-
const pattern =
|
|
2211
|
+
const pattern = path7.join(scanPath, "**/*");
|
|
2089
2212
|
const allFiles = await glob(pattern, {
|
|
2090
2213
|
nodir: true,
|
|
2091
2214
|
dot: false,
|
|
2092
2215
|
ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**", "**/build/**"]
|
|
2093
2216
|
});
|
|
2094
2217
|
const codeFiles = allFiles.filter((file) => {
|
|
2095
|
-
const relativePath =
|
|
2218
|
+
const relativePath = path7.relative(scanPath, file);
|
|
2096
2219
|
return isCodeFile(file) && !shouldIgnore(relativePath, gitignorePatterns);
|
|
2097
2220
|
});
|
|
2098
2221
|
if (codeFiles.length === 0) {
|
|
2099
|
-
spinner.warn(
|
|
2222
|
+
spinner.warn(chalk7.yellow("No code files found to scan."));
|
|
2100
2223
|
return;
|
|
2101
2224
|
}
|
|
2102
2225
|
spinner.text = `Found ${codeFiles.length} files. Scanning...`;
|
|
@@ -2105,10 +2228,10 @@ function createScanCommand() {
|
|
|
2105
2228
|
const severityCounts = {};
|
|
2106
2229
|
for (let i = 0; i < codeFiles.length; i++) {
|
|
2107
2230
|
const filePath = codeFiles[i];
|
|
2108
|
-
const relativePath =
|
|
2231
|
+
const relativePath = path7.relative(scanPath, filePath);
|
|
2109
2232
|
spinner.text = `Scanning ${i + 1}/${codeFiles.length}: ${relativePath}`;
|
|
2110
2233
|
try {
|
|
2111
|
-
const content = await
|
|
2234
|
+
const content = await fs6.readFile(filePath, "utf-8");
|
|
2112
2235
|
const response = await axios4.post(
|
|
2113
2236
|
`${apiUrl}/api/v1/audit`,
|
|
2114
2237
|
{
|
|
@@ -2144,15 +2267,15 @@ function createScanCommand() {
|
|
|
2144
2267
|
}
|
|
2145
2268
|
} catch (fileError) {
|
|
2146
2269
|
if (axios4.isAxiosError(fileError)) {
|
|
2147
|
-
console.warn(
|
|
2270
|
+
console.warn(chalk7.yellow(`
|
|
2148
2271
|
\u26A0\uFE0F Skipping ${relativePath}: ${fileError.message}`));
|
|
2149
2272
|
} else {
|
|
2150
|
-
console.warn(
|
|
2273
|
+
console.warn(chalk7.yellow(`
|
|
2151
2274
|
\u26A0\uFE0F Error reading ${relativePath}`));
|
|
2152
2275
|
}
|
|
2153
2276
|
}
|
|
2154
2277
|
}
|
|
2155
|
-
spinner.succeed(
|
|
2278
|
+
spinner.succeed(chalk7.green("\u2705 Scan completed!"));
|
|
2156
2279
|
const aggregatedResponse = {
|
|
2157
2280
|
results,
|
|
2158
2281
|
summary: {
|
|
@@ -2167,21 +2290,21 @@ function createScanCommand() {
|
|
|
2167
2290
|
printPrettyResults(aggregatedResponse);
|
|
2168
2291
|
}
|
|
2169
2292
|
} catch (error) {
|
|
2170
|
-
spinner.fail(
|
|
2293
|
+
spinner.fail(chalk7.red("\u274C Scan failed"));
|
|
2171
2294
|
if (axios4.isAxiosError(error)) {
|
|
2172
2295
|
if (error.response) {
|
|
2173
|
-
console.error(
|
|
2296
|
+
console.error(chalk7.red("API Error:"), error.response.data);
|
|
2174
2297
|
} else if (error.request) {
|
|
2175
2298
|
console.error(
|
|
2176
|
-
|
|
2299
|
+
chalk7.red("Network Error:"),
|
|
2177
2300
|
"Could not reach the API. Is the server running?"
|
|
2178
2301
|
);
|
|
2179
2302
|
} else {
|
|
2180
|
-
console.error(
|
|
2303
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2181
2304
|
}
|
|
2182
2305
|
} else {
|
|
2183
2306
|
console.error(
|
|
2184
|
-
|
|
2307
|
+
chalk7.red("Error:"),
|
|
2185
2308
|
error instanceof Error ? error.message : "Unknown error"
|
|
2186
2309
|
);
|
|
2187
2310
|
}
|
|
@@ -2191,10 +2314,10 @@ function createScanCommand() {
|
|
|
2191
2314
|
}
|
|
2192
2315
|
function printPrettyResults(data) {
|
|
2193
2316
|
const { results, summary } = data;
|
|
2194
|
-
console.log("\n" +
|
|
2195
|
-
console.log(
|
|
2196
|
-
console.log(`Total Files Scanned: ${
|
|
2197
|
-
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)}`);
|
|
2198
2321
|
if (summary.by_severity) {
|
|
2199
2322
|
console.log("\nIssues by Severity:");
|
|
2200
2323
|
Object.entries(summary.by_severity).forEach(([severity, count]) => {
|
|
@@ -2203,39 +2326,39 @@ function printPrettyResults(data) {
|
|
|
2203
2326
|
});
|
|
2204
2327
|
}
|
|
2205
2328
|
if (results && results.length > 0) {
|
|
2206
|
-
console.log("\n" +
|
|
2207
|
-
console.log(
|
|
2329
|
+
console.log("\n" + chalk7.bold("\u{1F50D} Detailed Results"));
|
|
2330
|
+
console.log(chalk7.dim("\u2500".repeat(60)));
|
|
2208
2331
|
results.forEach((result) => {
|
|
2209
2332
|
if (result.issues && result.issues.length > 0) {
|
|
2210
2333
|
console.log(`
|
|
2211
|
-
${
|
|
2334
|
+
${chalk7.bold(result.file_path)}`);
|
|
2212
2335
|
result.issues.forEach((issue) => {
|
|
2213
2336
|
const severityColor = getSeverityColor(issue.severity);
|
|
2214
|
-
const lineInfo = issue.line ?
|
|
2337
|
+
const lineInfo = issue.line ? chalk7.dim(`:${issue.line}`) : "";
|
|
2215
2338
|
console.log(
|
|
2216
2339
|
` ${severityColor(`[${issue.severity.toUpperCase()}]`)} ${issue.type}${lineInfo}`
|
|
2217
2340
|
);
|
|
2218
|
-
console.log(` ${
|
|
2341
|
+
console.log(` ${chalk7.dim(issue.message)}`);
|
|
2219
2342
|
});
|
|
2220
2343
|
}
|
|
2221
2344
|
});
|
|
2222
2345
|
}
|
|
2223
|
-
console.log("\n" +
|
|
2346
|
+
console.log("\n" + chalk7.dim("\u2500".repeat(60)));
|
|
2224
2347
|
}
|
|
2225
2348
|
function getSeverityColor(severity) {
|
|
2226
2349
|
switch (severity.toLowerCase()) {
|
|
2227
2350
|
case "critical":
|
|
2228
|
-
return
|
|
2351
|
+
return chalk7.red.bold;
|
|
2229
2352
|
case "high":
|
|
2230
|
-
return
|
|
2353
|
+
return chalk7.red;
|
|
2231
2354
|
case "medium":
|
|
2232
|
-
return
|
|
2355
|
+
return chalk7.yellow;
|
|
2233
2356
|
case "low":
|
|
2234
|
-
return
|
|
2357
|
+
return chalk7.blue;
|
|
2235
2358
|
case "info":
|
|
2236
|
-
return
|
|
2359
|
+
return chalk7.gray;
|
|
2237
2360
|
default:
|
|
2238
|
-
return
|
|
2361
|
+
return chalk7.white;
|
|
2239
2362
|
}
|
|
2240
2363
|
}
|
|
2241
2364
|
|
|
@@ -2243,12 +2366,12 @@ function getSeverityColor(severity) {
|
|
|
2243
2366
|
init_esm_shims();
|
|
2244
2367
|
init_config();
|
|
2245
2368
|
import { Command as Command6 } from "commander";
|
|
2246
|
-
import
|
|
2369
|
+
import chalk8 from "chalk";
|
|
2247
2370
|
import ora4 from "ora";
|
|
2248
2371
|
import axios5 from "axios";
|
|
2249
2372
|
import { glob as glob2 } from "glob";
|
|
2250
|
-
import
|
|
2251
|
-
import
|
|
2373
|
+
import fs7 from "fs/promises";
|
|
2374
|
+
import path8 from "path";
|
|
2252
2375
|
import inquirer from "inquirer";
|
|
2253
2376
|
import * as Diff from "diff";
|
|
2254
2377
|
function createFixCommand() {
|
|
@@ -2259,31 +2382,31 @@ function createFixCommand() {
|
|
|
2259
2382
|
const apiUrl = getApiUrl();
|
|
2260
2383
|
const projectId = options.project || getProjectId();
|
|
2261
2384
|
if (!projectId) {
|
|
2262
|
-
console.log(
|
|
2385
|
+
console.log(chalk8.yellow("\u26A0\uFE0F Project ID is required for fixing. Using default or pass --project <id>"));
|
|
2263
2386
|
}
|
|
2264
|
-
const scanPath =
|
|
2387
|
+
const scanPath = path8.resolve(process.cwd(), targetPath);
|
|
2265
2388
|
const gitignorePatterns = await readGitignore(scanPath);
|
|
2266
|
-
const pattern =
|
|
2389
|
+
const pattern = path8.join(scanPath, "**/*");
|
|
2267
2390
|
const allFiles = await glob2(pattern, { nodir: true, dot: false, ignore: ["**/node_modules/**", "**/.git/**"] });
|
|
2268
2391
|
const codeFiles = allFiles.filter((file) => {
|
|
2269
|
-
const relativePath =
|
|
2392
|
+
const relativePath = path8.relative(scanPath, file);
|
|
2270
2393
|
return isCodeFile(file) && !shouldIgnore(relativePath, gitignorePatterns);
|
|
2271
2394
|
});
|
|
2272
2395
|
if (codeFiles.length === 0) {
|
|
2273
|
-
console.log(
|
|
2396
|
+
console.log(chalk8.yellow("No code files found."));
|
|
2274
2397
|
return;
|
|
2275
2398
|
}
|
|
2276
|
-
console.log(
|
|
2399
|
+
console.log(chalk8.bold(`
|
|
2277
2400
|
\u{1F9E0} Rigstate Fix Mode`));
|
|
2278
|
-
console.log(
|
|
2401
|
+
console.log(chalk8.dim(`Scanning ${codeFiles.length} files with Project Context...
|
|
2279
2402
|
`));
|
|
2280
2403
|
let fixedCount = 0;
|
|
2281
2404
|
for (let i = 0; i < codeFiles.length; i++) {
|
|
2282
2405
|
const filePath = codeFiles[i];
|
|
2283
|
-
const relativePath =
|
|
2406
|
+
const relativePath = path8.relative(scanPath, filePath);
|
|
2284
2407
|
spinner.start(`Analyzing ${relativePath}...`);
|
|
2285
2408
|
try {
|
|
2286
|
-
const content = await
|
|
2409
|
+
const content = await fs7.readFile(filePath, "utf-8");
|
|
2287
2410
|
const response = await axios5.post(
|
|
2288
2411
|
`${apiUrl}/api/v1/audit`,
|
|
2289
2412
|
{ content, file_path: relativePath, project_id: projectId },
|
|
@@ -2294,22 +2417,22 @@ function createFixCommand() {
|
|
|
2294
2417
|
if (fixableIssues.length > 0) {
|
|
2295
2418
|
spinner.stop();
|
|
2296
2419
|
console.log(`
|
|
2297
|
-
${
|
|
2420
|
+
${chalk8.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
2298
2421
|
for (const issue of fixableIssues) {
|
|
2299
|
-
console.log(
|
|
2422
|
+
console.log(chalk8.red(`
|
|
2300
2423
|
[${issue.type}] ${issue.title}`));
|
|
2301
|
-
console.log(
|
|
2424
|
+
console.log(chalk8.dim(issue.suggestion || issue.message));
|
|
2302
2425
|
const diff = Diff.createTwoFilesPatch(relativePath, relativePath, content, issue.fixed_content, "Current", "Fixed");
|
|
2303
2426
|
console.log("\n" + diff.split("\n").slice(0, 15).join("\n") + (diff.split("\n").length > 15 ? "\n..." : ""));
|
|
2304
2427
|
const { apply } = await inquirer.prompt([{
|
|
2305
2428
|
type: "confirm",
|
|
2306
2429
|
name: "apply",
|
|
2307
|
-
message: `Apply this fix to ${
|
|
2430
|
+
message: `Apply this fix to ${chalk8.cyan(relativePath)}?`,
|
|
2308
2431
|
default: true
|
|
2309
2432
|
}]);
|
|
2310
2433
|
if (apply) {
|
|
2311
|
-
await
|
|
2312
|
-
console.log(
|
|
2434
|
+
await fs7.writeFile(filePath, issue.fixed_content);
|
|
2435
|
+
console.log(chalk8.green(`\u2705 Fixed applied!`));
|
|
2313
2436
|
fixedCount++;
|
|
2314
2437
|
if (issue.related_step_id) {
|
|
2315
2438
|
const { completeStep } = await inquirer.prompt([{
|
|
@@ -2325,15 +2448,15 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
2325
2448
|
{ step_id: issue.related_step_id, status: "COMPLETED", project_id: projectId },
|
|
2326
2449
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
2327
2450
|
);
|
|
2328
|
-
console.log(
|
|
2451
|
+
console.log(chalk8.green(`\u{1F680} Roadmap updated! Mission Control is in sync.`));
|
|
2329
2452
|
} catch (err) {
|
|
2330
|
-
console.error(
|
|
2453
|
+
console.error(chalk8.yellow(`Failed to update roadmap: ${err.message}`));
|
|
2331
2454
|
}
|
|
2332
2455
|
}
|
|
2333
2456
|
}
|
|
2334
2457
|
break;
|
|
2335
2458
|
} else {
|
|
2336
|
-
console.log(
|
|
2459
|
+
console.log(chalk8.dim("Skipped."));
|
|
2337
2460
|
}
|
|
2338
2461
|
}
|
|
2339
2462
|
} else {
|
|
@@ -2343,11 +2466,11 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
2343
2466
|
}
|
|
2344
2467
|
}
|
|
2345
2468
|
spinner.stop();
|
|
2346
|
-
console.log(
|
|
2469
|
+
console.log(chalk8.bold.green(`
|
|
2347
2470
|
|
|
2348
2471
|
\u{1F680} Fix session complete!`));
|
|
2349
2472
|
console.log(`Frank fixed ${fixedCount} detected issues.`);
|
|
2350
|
-
console.log(
|
|
2473
|
+
console.log(chalk8.dim(`Run 'rigstate scan' to verify remaining issues.`));
|
|
2351
2474
|
} catch (error) {
|
|
2352
2475
|
spinner.fail("Fix session failed");
|
|
2353
2476
|
console.error(error.message);
|
|
@@ -2359,11 +2482,11 @@ ${chalk7.bold(relativePath)}: Found ${fixableIssues.length} fixable issues.`);
|
|
|
2359
2482
|
init_esm_shims();
|
|
2360
2483
|
init_config();
|
|
2361
2484
|
import { Command as Command7 } from "commander";
|
|
2362
|
-
import
|
|
2485
|
+
import chalk12 from "chalk";
|
|
2363
2486
|
import ora5 from "ora";
|
|
2364
2487
|
import axios8 from "axios";
|
|
2365
|
-
import
|
|
2366
|
-
import
|
|
2488
|
+
import fs11 from "fs/promises";
|
|
2489
|
+
import path12 from "path";
|
|
2367
2490
|
function createSyncCommand() {
|
|
2368
2491
|
const sync = new Command7("sync");
|
|
2369
2492
|
sync.description("Synchronize local state with Rigstate Cloud").option("-p, --project <id>", "Specify Project ID (saves to config automatically)").action(async (options) => {
|
|
@@ -2378,13 +2501,9 @@ function createSyncCommand() {
|
|
|
2378
2501
|
}
|
|
2379
2502
|
let projectId = options.project;
|
|
2380
2503
|
if (!projectId) {
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
const manifest = JSON.parse(manifestContent);
|
|
2385
|
-
if (manifest.project_id) projectId = manifest.project_id;
|
|
2386
|
-
} catch (e) {
|
|
2387
|
-
}
|
|
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;
|
|
2388
2507
|
}
|
|
2389
2508
|
if (!projectId) projectId = getProjectId();
|
|
2390
2509
|
if (options.project) {
|
|
@@ -2404,31 +2523,30 @@ function createSyncCommand() {
|
|
|
2404
2523
|
}
|
|
2405
2524
|
const { roadmap, project } = response.data.data;
|
|
2406
2525
|
const timestamp = response.data.timestamp;
|
|
2407
|
-
const targetPath =
|
|
2526
|
+
const targetPath = path12.join(process.cwd(), "roadmap.json");
|
|
2408
2527
|
const fileContent = JSON.stringify({
|
|
2409
2528
|
project,
|
|
2410
2529
|
last_synced: timestamp,
|
|
2411
2530
|
roadmap
|
|
2412
2531
|
}, null, 2);
|
|
2413
|
-
await
|
|
2532
|
+
await fs11.writeFile(targetPath, fileContent, "utf-8");
|
|
2414
2533
|
try {
|
|
2415
|
-
const
|
|
2416
|
-
|
|
2534
|
+
const { saveManifest: saveManifest2 } = await Promise.resolve().then(() => (init_manifest(), manifest_exports));
|
|
2535
|
+
await saveManifest2({
|
|
2417
2536
|
project_id: projectId,
|
|
2418
|
-
|
|
2419
|
-
|
|
2537
|
+
linked_at: timestamp,
|
|
2538
|
+
// Using timestamp as linked_at for consistency
|
|
2420
2539
|
api_url: apiUrl
|
|
2421
|
-
};
|
|
2422
|
-
await fs9.writeFile(manifestPath, JSON.stringify(manifestContent, null, 2), "utf-8");
|
|
2540
|
+
});
|
|
2423
2541
|
} catch (e) {
|
|
2424
2542
|
}
|
|
2425
|
-
console.log(
|
|
2543
|
+
console.log(chalk12.bold("\n\u{1F9E0} Agent Skills Provisioning..."));
|
|
2426
2544
|
try {
|
|
2427
2545
|
const { provisionSkills: provisionSkills2, generateSkillsDiscoveryBlock: generateSkillsDiscoveryBlock2 } = await Promise.resolve().then(() => (init_skills_provisioner(), skills_provisioner_exports));
|
|
2428
2546
|
const skills = await provisionSkills2(apiUrl, apiKey, projectId, process.cwd());
|
|
2429
|
-
const cursorRulesPath =
|
|
2547
|
+
const cursorRulesPath = path12.join(process.cwd(), ".cursorrules");
|
|
2430
2548
|
try {
|
|
2431
|
-
let rulesContent = await
|
|
2549
|
+
let rulesContent = await fs11.readFile(cursorRulesPath, "utf-8");
|
|
2432
2550
|
const skillsBlock = generateSkillsDiscoveryBlock2(skills);
|
|
2433
2551
|
if (rulesContent.includes("<available_skills>")) {
|
|
2434
2552
|
rulesContent = rulesContent.replace(
|
|
@@ -2441,17 +2559,17 @@ function createSyncCommand() {
|
|
|
2441
2559
|
rulesContent = rulesContent.slice(0, insertPoint + 3) + "\n\n" + skillsBlock + "\n" + rulesContent.slice(insertPoint + 3);
|
|
2442
2560
|
}
|
|
2443
2561
|
}
|
|
2444
|
-
await
|
|
2445
|
-
console.log(
|
|
2562
|
+
await fs11.writeFile(cursorRulesPath, rulesContent, "utf-8");
|
|
2563
|
+
console.log(chalk12.dim(` Updated .cursorrules with skills discovery block`));
|
|
2446
2564
|
} catch (e) {
|
|
2447
2565
|
}
|
|
2448
2566
|
} catch (e) {
|
|
2449
|
-
console.log(
|
|
2567
|
+
console.log(chalk12.yellow(` \u26A0 Skills provisioning skipped: ${e.message}`));
|
|
2450
2568
|
}
|
|
2451
2569
|
try {
|
|
2452
|
-
const logPath =
|
|
2570
|
+
const logPath = path12.join(process.cwd(), ".rigstate", "logs", "last_execution.json");
|
|
2453
2571
|
try {
|
|
2454
|
-
const logContent = await
|
|
2572
|
+
const logContent = await fs11.readFile(logPath, "utf-8");
|
|
2455
2573
|
const logData = JSON.parse(logContent);
|
|
2456
2574
|
if (logData.task_summary) {
|
|
2457
2575
|
await axios8.post(`${apiUrl}/api/v1/execution-logs`, {
|
|
@@ -2461,8 +2579,8 @@ function createSyncCommand() {
|
|
|
2461
2579
|
}, {
|
|
2462
2580
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2463
2581
|
});
|
|
2464
|
-
await
|
|
2465
|
-
console.log(
|
|
2582
|
+
await fs11.unlink(logPath);
|
|
2583
|
+
console.log(chalk12.dim(`\u2714 Mission Report uploaded.`));
|
|
2466
2584
|
}
|
|
2467
2585
|
} catch (e) {
|
|
2468
2586
|
if (e.code !== "ENOENT") {
|
|
@@ -2470,12 +2588,12 @@ function createSyncCommand() {
|
|
|
2470
2588
|
}
|
|
2471
2589
|
} catch (e) {
|
|
2472
2590
|
}
|
|
2473
|
-
spinner.succeed(
|
|
2474
|
-
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`));
|
|
2475
2593
|
const { runGuardianWatchdog: runGuardianWatchdog2 } = await Promise.resolve().then(() => (init_watchdog(), watchdog_exports));
|
|
2476
2594
|
const settings = response.data.data.settings || {};
|
|
2477
2595
|
await runGuardianWatchdog2(process.cwd(), settings, projectId);
|
|
2478
|
-
console.log(
|
|
2596
|
+
console.log(chalk12.bold("\n\u{1F4E1} Agent Bridge Heartbeat..."));
|
|
2479
2597
|
try {
|
|
2480
2598
|
const bridgeResponse = await axios8.get(`${apiUrl}/api/v1/agent/bridge`, {
|
|
2481
2599
|
params: { project_id: projectId },
|
|
@@ -2486,10 +2604,10 @@ function createSyncCommand() {
|
|
|
2486
2604
|
const pending = tasks.filter((t) => t.status === "PENDING");
|
|
2487
2605
|
const approved = tasks.filter((t) => t.status === "APPROVED");
|
|
2488
2606
|
if (pending.length > 0 || approved.length > 0) {
|
|
2489
|
-
console.log(
|
|
2490
|
-
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.'));
|
|
2491
2609
|
} else {
|
|
2492
|
-
console.log(
|
|
2610
|
+
console.log(chalk12.green("\u2714 Heartbeat healthy. No pending bridge tasks."));
|
|
2493
2611
|
}
|
|
2494
2612
|
const pings = pending.filter((t) => t.proposal?.startsWith("ping"));
|
|
2495
2613
|
for (const ping of pings) {
|
|
@@ -2500,25 +2618,25 @@ function createSyncCommand() {
|
|
|
2500
2618
|
}, {
|
|
2501
2619
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2502
2620
|
});
|
|
2503
|
-
console.log(
|
|
2621
|
+
console.log(chalk12.cyan(`\u{1F3D3} Pong! Acknowledged heartbeat signal [${ping.id}]`));
|
|
2504
2622
|
}
|
|
2505
2623
|
}
|
|
2506
2624
|
} catch (e) {
|
|
2507
|
-
console.log(
|
|
2625
|
+
console.log(chalk12.yellow(`\u26A0 Could not verify Bridge status: ${e.message}`));
|
|
2508
2626
|
}
|
|
2509
2627
|
if (options.project) {
|
|
2510
|
-
console.log(
|
|
2628
|
+
console.log(chalk12.blue(`Project context saved. Future commands will use this project.`));
|
|
2511
2629
|
}
|
|
2512
2630
|
try {
|
|
2513
|
-
const migrationDir =
|
|
2514
|
-
const files = await
|
|
2631
|
+
const migrationDir = path12.join(process.cwd(), "supabase", "migrations");
|
|
2632
|
+
const files = await fs11.readdir(migrationDir);
|
|
2515
2633
|
const sqlFiles = files.filter((f) => f.endsWith(".sql")).sort();
|
|
2516
2634
|
if (sqlFiles.length > 0) {
|
|
2517
2635
|
const latestMigration = sqlFiles[sqlFiles.length - 1];
|
|
2518
|
-
console.log(
|
|
2636
|
+
console.log(chalk12.dim(`
|
|
2519
2637
|
\u{1F6E1} Migration Guard:`));
|
|
2520
|
-
console.log(
|
|
2521
|
-
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.`));
|
|
2522
2640
|
}
|
|
2523
2641
|
} catch (e) {
|
|
2524
2642
|
}
|
|
@@ -2530,15 +2648,15 @@ function createSyncCommand() {
|
|
|
2530
2648
|
);
|
|
2531
2649
|
if (vaultResponse.data.success) {
|
|
2532
2650
|
const vaultContent = vaultResponse.data.data.content || "";
|
|
2533
|
-
const localEnvPath =
|
|
2651
|
+
const localEnvPath = path12.join(process.cwd(), ".env.local");
|
|
2534
2652
|
let localContent = "";
|
|
2535
2653
|
try {
|
|
2536
|
-
localContent = await
|
|
2654
|
+
localContent = await fs11.readFile(localEnvPath, "utf-8");
|
|
2537
2655
|
} catch (e) {
|
|
2538
2656
|
}
|
|
2539
2657
|
if (vaultContent.trim() !== localContent.trim()) {
|
|
2540
|
-
console.log(
|
|
2541
|
-
console.log(
|
|
2658
|
+
console.log(chalk12.bold("\n\u{1F510} Sovereign Foundation (Vault):"));
|
|
2659
|
+
console.log(chalk12.yellow(" Status: Drift Detected / Update Available"));
|
|
2542
2660
|
const { syncVault } = await import("inquirer").then((m) => m.default.prompt([{
|
|
2543
2661
|
type: "confirm",
|
|
2544
2662
|
name: "syncVault",
|
|
@@ -2546,25 +2664,25 @@ function createSyncCommand() {
|
|
|
2546
2664
|
default: false
|
|
2547
2665
|
}]));
|
|
2548
2666
|
if (syncVault) {
|
|
2549
|
-
await
|
|
2550
|
-
console.log(
|
|
2667
|
+
await fs11.writeFile(localEnvPath, vaultContent, "utf-8");
|
|
2668
|
+
console.log(chalk12.green(" \u2705 .env.local synchronized with Vault."));
|
|
2551
2669
|
} else {
|
|
2552
|
-
console.log(
|
|
2670
|
+
console.log(chalk12.dim(" Skipped vault sync."));
|
|
2553
2671
|
}
|
|
2554
2672
|
} else {
|
|
2555
|
-
console.log(
|
|
2673
|
+
console.log(chalk12.dim("\n\u{1F510} Sovereign Foundation: Synced."));
|
|
2556
2674
|
}
|
|
2557
2675
|
}
|
|
2558
2676
|
} catch (e) {
|
|
2559
2677
|
}
|
|
2560
|
-
console.log(
|
|
2678
|
+
console.log(chalk12.dim("\n\u{1F6E1}\uFE0F System Integrity Check..."));
|
|
2561
2679
|
await checkSystemIntegrity(apiUrl, apiKey, projectId);
|
|
2562
2680
|
} catch (error) {
|
|
2563
2681
|
if (axios8.isAxiosError(error)) {
|
|
2564
2682
|
const message = error.response?.data?.error || error.message;
|
|
2565
|
-
spinner.fail(
|
|
2683
|
+
spinner.fail(chalk12.red(`Sync failed: ${message}`));
|
|
2566
2684
|
} else {
|
|
2567
|
-
spinner.fail(
|
|
2685
|
+
spinner.fail(chalk12.red("Sync failed: " + (error.message || "Unknown error")));
|
|
2568
2686
|
}
|
|
2569
2687
|
}
|
|
2570
2688
|
});
|
|
@@ -2580,65 +2698,50 @@ async function checkSystemIntegrity(apiUrl, apiKey, projectId) {
|
|
|
2580
2698
|
const { migrations, rls, guardian_violations } = response.data.data;
|
|
2581
2699
|
if (migrations) {
|
|
2582
2700
|
if (migrations.in_sync) {
|
|
2583
|
-
console.log(
|
|
2701
|
+
console.log(chalk12.green(` \u2705 Migrations synced (${migrations.count} versions)`));
|
|
2584
2702
|
} else {
|
|
2585
|
-
console.log(
|
|
2703
|
+
console.log(chalk12.red(` \u{1F6D1} CRITICAL: DB Schema out of sync! ${migrations.missing?.length || 0} migrations not applied.`));
|
|
2586
2704
|
if (migrations.missing?.length > 0) {
|
|
2587
|
-
console.log(
|
|
2705
|
+
console.log(chalk12.dim(` Missing: ${migrations.missing.slice(0, 3).join(", ")}${migrations.missing.length > 3 ? "..." : ""}`));
|
|
2588
2706
|
}
|
|
2589
|
-
console.log(
|
|
2707
|
+
console.log(chalk12.yellow(` Run 'supabase db push' or apply migrations immediately.`));
|
|
2590
2708
|
}
|
|
2591
2709
|
}
|
|
2592
2710
|
if (rls) {
|
|
2593
2711
|
if (rls.all_secured) {
|
|
2594
|
-
console.log(
|
|
2712
|
+
console.log(chalk12.green(` \u2705 RLS Audit Passed (${rls.table_count} tables secured)`));
|
|
2595
2713
|
} else {
|
|
2596
|
-
console.log(
|
|
2714
|
+
console.log(chalk12.red(` \u{1F6D1} CRITICAL: Security Vulnerability! ${rls.unsecured?.length || 0} tables have RLS disabled.`));
|
|
2597
2715
|
rls.unsecured?.forEach((table) => {
|
|
2598
|
-
console.log(
|
|
2716
|
+
console.log(chalk12.red(` - ${table}`));
|
|
2599
2717
|
});
|
|
2600
|
-
console.log(
|
|
2718
|
+
console.log(chalk12.yellow(' Enable RLS immediately: ALTER TABLE "table" ENABLE ROW LEVEL SECURITY;'));
|
|
2601
2719
|
}
|
|
2602
2720
|
}
|
|
2603
2721
|
if (guardian_violations) {
|
|
2604
2722
|
if (guardian_violations.count === 0) {
|
|
2605
|
-
console.log(
|
|
2723
|
+
console.log(chalk12.green(" \u2705 Guardian: No active violations"));
|
|
2606
2724
|
} else {
|
|
2607
|
-
console.log(
|
|
2608
|
-
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.'));
|
|
2609
2727
|
}
|
|
2610
2728
|
}
|
|
2611
2729
|
}
|
|
2612
2730
|
} catch (e) {
|
|
2613
|
-
console.log(
|
|
2731
|
+
console.log(chalk12.dim(" (System integrity check skipped - API endpoint not available)"));
|
|
2614
2732
|
}
|
|
2615
2733
|
}
|
|
2616
2734
|
|
|
2617
2735
|
// src/commands/init.ts
|
|
2618
2736
|
init_esm_shims();
|
|
2737
|
+
init_manifest();
|
|
2738
|
+
init_config();
|
|
2619
2739
|
import { Command as Command8 } from "commander";
|
|
2620
|
-
import
|
|
2621
|
-
import
|
|
2622
|
-
import
|
|
2740
|
+
import chalk13 from "chalk";
|
|
2741
|
+
import fs12 from "fs/promises";
|
|
2742
|
+
import path13 from "path";
|
|
2623
2743
|
import ora6 from "ora";
|
|
2624
2744
|
import { execSync } from "child_process";
|
|
2625
|
-
|
|
2626
|
-
// src/utils/manifest.ts
|
|
2627
|
-
init_esm_shims();
|
|
2628
|
-
import fs10 from "fs/promises";
|
|
2629
|
-
import path11 from "path";
|
|
2630
|
-
async function loadManifest() {
|
|
2631
|
-
try {
|
|
2632
|
-
const manifestPath = path11.join(process.cwd(), ".rigstate");
|
|
2633
|
-
const content = await fs10.readFile(manifestPath, "utf-8");
|
|
2634
|
-
return JSON.parse(content);
|
|
2635
|
-
} catch {
|
|
2636
|
-
return null;
|
|
2637
|
-
}
|
|
2638
|
-
}
|
|
2639
|
-
|
|
2640
|
-
// src/commands/init.ts
|
|
2641
|
-
init_config();
|
|
2642
2745
|
import axios9 from "axios";
|
|
2643
2746
|
function createInitCommand() {
|
|
2644
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) => {
|
|
@@ -2647,7 +2750,7 @@ function createInitCommand() {
|
|
|
2647
2750
|
try {
|
|
2648
2751
|
apiKey = getApiKey();
|
|
2649
2752
|
} catch (e) {
|
|
2650
|
-
spinner.fail(
|
|
2753
|
+
spinner.fail(chalk13.red('Not authenticated. Run "rigstate login" first.'));
|
|
2651
2754
|
return;
|
|
2652
2755
|
}
|
|
2653
2756
|
const apiUrl = getApiUrl();
|
|
@@ -2744,7 +2847,7 @@ function createInitCommand() {
|
|
|
2744
2847
|
selectedOrgId = orgId;
|
|
2745
2848
|
}
|
|
2746
2849
|
if (!selectedOrgId) {
|
|
2747
|
-
console.log(
|
|
2850
|
+
console.log(chalk13.yellow("No organization available. Please create the project via the Rigstate dashboard."));
|
|
2748
2851
|
return;
|
|
2749
2852
|
}
|
|
2750
2853
|
spinner.start("Creating new project...");
|
|
@@ -2756,13 +2859,13 @@ function createInitCommand() {
|
|
|
2756
2859
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
2757
2860
|
});
|
|
2758
2861
|
if (!createResponse.data.success) {
|
|
2759
|
-
spinner.fail(
|
|
2862
|
+
spinner.fail(chalk13.red("Failed to create project: " + createResponse.data.error));
|
|
2760
2863
|
return;
|
|
2761
2864
|
}
|
|
2762
2865
|
projectId = createResponse.data.data.project.id;
|
|
2763
|
-
spinner.succeed(
|
|
2866
|
+
spinner.succeed(chalk13.green(`Created new project: ${newName}`));
|
|
2764
2867
|
} catch (e) {
|
|
2765
|
-
spinner.fail(
|
|
2868
|
+
spinner.fail(chalk13.red("Project creation API not available. Please create via dashboard."));
|
|
2766
2869
|
return;
|
|
2767
2870
|
}
|
|
2768
2871
|
} else {
|
|
@@ -2772,28 +2875,27 @@ function createInitCommand() {
|
|
|
2772
2875
|
spinner.start(`Linking to project ID: ${projectId}...`);
|
|
2773
2876
|
}
|
|
2774
2877
|
setProjectId(projectId);
|
|
2775
|
-
const
|
|
2776
|
-
|
|
2878
|
+
const { saveManifest: saveManifest2 } = await Promise.resolve().then(() => (init_manifest(), manifest_exports));
|
|
2879
|
+
await saveManifest2({
|
|
2777
2880
|
project_id: projectId,
|
|
2778
|
-
|
|
2881
|
+
linked_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2779
2882
|
api_url: apiUrl
|
|
2780
|
-
};
|
|
2781
|
-
await fs11.writeFile(manifestPath, JSON.stringify(manifestContent, null, 2), "utf-8");
|
|
2883
|
+
});
|
|
2782
2884
|
try {
|
|
2783
|
-
await
|
|
2885
|
+
await fs12.access(".git");
|
|
2784
2886
|
} catch {
|
|
2785
2887
|
spinner.text = "Initializing git repository...";
|
|
2786
2888
|
execSync("git init", { stdio: "ignore" });
|
|
2787
2889
|
}
|
|
2788
|
-
spinner.succeed(
|
|
2890
|
+
spinner.succeed(chalk13.green(`\u2705 Linked to project: ${projectId}`));
|
|
2789
2891
|
await generateRules(apiUrl, apiKey, projectId, options.force, spinner);
|
|
2790
2892
|
console.log("");
|
|
2791
|
-
console.log(
|
|
2792
|
-
console.log(
|
|
2793
|
-
console.log(
|
|
2794
|
-
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"));
|
|
2795
2897
|
} catch (e) {
|
|
2796
|
-
spinner.fail(
|
|
2898
|
+
spinner.fail(chalk13.red("Initialization failed: " + e.message));
|
|
2797
2899
|
}
|
|
2798
2900
|
});
|
|
2799
2901
|
}
|
|
@@ -2808,67 +2910,68 @@ async function generateRules(apiUrl, apiKey, projectId, force, spinner) {
|
|
|
2808
2910
|
if (response.data.success || response.data.files) {
|
|
2809
2911
|
const files = response.data.files || [];
|
|
2810
2912
|
if (files.length === 0 && response.data.rules) {
|
|
2811
|
-
const rulesPath =
|
|
2812
|
-
await
|
|
2813
|
-
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)"));
|
|
2814
2916
|
return;
|
|
2815
2917
|
}
|
|
2816
2918
|
for (const file of files) {
|
|
2817
|
-
const targetPath =
|
|
2818
|
-
const targetDir =
|
|
2819
|
-
await
|
|
2919
|
+
const targetPath = path13.join(process.cwd(), file.path);
|
|
2920
|
+
const targetDir = path13.dirname(targetPath);
|
|
2921
|
+
await fs12.mkdir(targetDir, { recursive: true });
|
|
2820
2922
|
try {
|
|
2821
|
-
await
|
|
2923
|
+
await fs12.access(targetPath);
|
|
2822
2924
|
if (!force && !file.path.startsWith(".cursor/rules/")) {
|
|
2823
|
-
console.log(
|
|
2925
|
+
console.log(chalk13.dim(` ${file.path} already exists. Skipping.`));
|
|
2824
2926
|
continue;
|
|
2825
2927
|
}
|
|
2826
2928
|
} catch {
|
|
2827
2929
|
}
|
|
2828
|
-
await
|
|
2930
|
+
await fs12.writeFile(targetPath, file.content, "utf-8");
|
|
2829
2931
|
}
|
|
2830
2932
|
if (files.length > 0) {
|
|
2831
|
-
const legacyPath =
|
|
2933
|
+
const legacyPath = path13.join(process.cwd(), ".cursorrules");
|
|
2832
2934
|
try {
|
|
2833
|
-
const stats = await
|
|
2935
|
+
const stats = await fs12.stat(legacyPath);
|
|
2834
2936
|
if (stats.isFile()) {
|
|
2835
|
-
await
|
|
2836
|
-
console.log(
|
|
2937
|
+
await fs12.rename(legacyPath, `${legacyPath}.bak`);
|
|
2938
|
+
console.log(chalk13.dim(" Moved legacy .cursorrules to .cursorrules.bak"));
|
|
2837
2939
|
}
|
|
2838
2940
|
} catch (e) {
|
|
2839
2941
|
}
|
|
2840
2942
|
}
|
|
2841
|
-
spinner.succeed(
|
|
2943
|
+
spinner.succeed(chalk13.green(`\u2714 Generated ${files.length} rule files (v${response.data.version || "3.0"})`));
|
|
2842
2944
|
} else {
|
|
2843
|
-
spinner.info(
|
|
2945
|
+
spinner.info(chalk13.dim(" Rules generation skipped (API response invalid)"));
|
|
2844
2946
|
}
|
|
2845
2947
|
} catch (e) {
|
|
2846
|
-
spinner.info(
|
|
2948
|
+
spinner.info(chalk13.dim(` Rules generation failed: ${e.message}`));
|
|
2847
2949
|
}
|
|
2848
2950
|
}
|
|
2849
2951
|
|
|
2850
2952
|
// src/commands/check.ts
|
|
2851
2953
|
init_esm_shims();
|
|
2852
2954
|
init_config();
|
|
2955
|
+
init_manifest();
|
|
2853
2956
|
import { Command as Command9 } from "commander";
|
|
2854
|
-
import
|
|
2957
|
+
import chalk15 from "chalk";
|
|
2855
2958
|
import ora7 from "ora";
|
|
2856
2959
|
import axios10 from "axios";
|
|
2857
2960
|
import { glob as glob3 } from "glob";
|
|
2858
|
-
import
|
|
2859
|
-
import
|
|
2961
|
+
import fs14 from "fs/promises";
|
|
2962
|
+
import path15 from "path";
|
|
2860
2963
|
import { execSync as execSync2 } from "child_process";
|
|
2861
2964
|
|
|
2862
2965
|
// src/utils/rule-engine.ts
|
|
2863
2966
|
init_esm_shims();
|
|
2864
|
-
import
|
|
2865
|
-
import
|
|
2866
|
-
import
|
|
2967
|
+
import fs13 from "fs/promises";
|
|
2968
|
+
import path14 from "path";
|
|
2969
|
+
import chalk14 from "chalk";
|
|
2867
2970
|
async function checkFile(filePath, rules, rootPath) {
|
|
2868
2971
|
const violations = [];
|
|
2869
|
-
const relativePath =
|
|
2972
|
+
const relativePath = path14.relative(rootPath, filePath);
|
|
2870
2973
|
try {
|
|
2871
|
-
const content = await
|
|
2974
|
+
const content = await fs13.readFile(filePath, "utf-8");
|
|
2872
2975
|
const lines = content.split("\n");
|
|
2873
2976
|
for (const rule of rules) {
|
|
2874
2977
|
const ruleViolations = await evaluateRule(rule, content, lines, relativePath);
|
|
@@ -2959,7 +3062,7 @@ async function evaluateRule(rule, content, lines, filePath) {
|
|
|
2959
3062
|
case "NAMING_CONVENTION": {
|
|
2960
3063
|
const value = rule.value;
|
|
2961
3064
|
const pattern = new RegExp(value.pattern);
|
|
2962
|
-
const fileName =
|
|
3065
|
+
const fileName = path14.basename(filePath);
|
|
2963
3066
|
if (filePath.includes(value.context) && !pattern.test(fileName)) {
|
|
2964
3067
|
violations.push({
|
|
2965
3068
|
file: filePath,
|
|
@@ -3018,12 +3121,12 @@ function checkFunctionLines(content, lines, filePath, rule, limit) {
|
|
|
3018
3121
|
}
|
|
3019
3122
|
function formatViolations(violations) {
|
|
3020
3123
|
for (const v of violations) {
|
|
3021
|
-
const severityColor = v.severity === "critical" ?
|
|
3022
|
-
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}`) : "";
|
|
3023
3126
|
console.log(` ${severityColor(`[${v.severity.toUpperCase()}]`)} ${v.file}${lineInfo}`);
|
|
3024
3127
|
console.log(` ${v.message}`);
|
|
3025
3128
|
if (v.details) {
|
|
3026
|
-
console.log(` ${
|
|
3129
|
+
console.log(` ${chalk14.dim(v.details)}`);
|
|
3027
3130
|
}
|
|
3028
3131
|
}
|
|
3029
3132
|
}
|
|
@@ -3068,15 +3171,15 @@ function createCheckCommand() {
|
|
|
3068
3171
|
projectId = getProjectId();
|
|
3069
3172
|
}
|
|
3070
3173
|
if (!projectId) {
|
|
3071
|
-
console.log(
|
|
3072
|
-
console.log(
|
|
3174
|
+
console.log(chalk15.red("\u274C No project context found."));
|
|
3175
|
+
console.log(chalk15.dim(' Run "rigstate link" or pass --project <id>'));
|
|
3073
3176
|
process.exit(2);
|
|
3074
3177
|
}
|
|
3075
3178
|
let apiKey;
|
|
3076
3179
|
try {
|
|
3077
3180
|
apiKey = getApiKey();
|
|
3078
3181
|
} catch {
|
|
3079
|
-
console.log(
|
|
3182
|
+
console.log(chalk15.red('\u274C Not authenticated. Run "rigstate login" first.'));
|
|
3080
3183
|
process.exit(2);
|
|
3081
3184
|
}
|
|
3082
3185
|
spinner.start("Fetching Guardian rules...");
|
|
@@ -3104,17 +3207,17 @@ function createCheckCommand() {
|
|
|
3104
3207
|
} catch (apiError) {
|
|
3105
3208
|
const cached = await loadCachedRules(projectId);
|
|
3106
3209
|
if (cached && !isStale(cached.timestamp, CACHE_MAX_AGE_MS)) {
|
|
3107
|
-
spinner.warn(
|
|
3210
|
+
spinner.warn(chalk15.yellow("Using cached rules (API unavailable)"));
|
|
3108
3211
|
rules = cached.rules;
|
|
3109
3212
|
settings = cached.settings;
|
|
3110
3213
|
} else {
|
|
3111
|
-
spinner.fail(
|
|
3112
|
-
console.log(
|
|
3214
|
+
spinner.fail(chalk15.red("Failed to fetch rules and no valid cache"));
|
|
3215
|
+
console.log(chalk15.dim(` Error: ${apiError.message}`));
|
|
3113
3216
|
process.exit(2);
|
|
3114
3217
|
}
|
|
3115
3218
|
}
|
|
3116
3219
|
spinner.succeed(`Loaded ${rules.length} Guardian rules`);
|
|
3117
|
-
const scanPath =
|
|
3220
|
+
const scanPath = path15.resolve(process.cwd(), targetPath);
|
|
3118
3221
|
let filesToCheck;
|
|
3119
3222
|
if (options.staged) {
|
|
3120
3223
|
spinner.start("Getting staged files...");
|
|
@@ -3123,14 +3226,14 @@ function createCheckCommand() {
|
|
|
3123
3226
|
encoding: "utf-8",
|
|
3124
3227
|
cwd: process.cwd()
|
|
3125
3228
|
});
|
|
3126
|
-
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));
|
|
3127
3230
|
} catch {
|
|
3128
3231
|
spinner.fail("Not a git repository or no staged files");
|
|
3129
3232
|
process.exit(2);
|
|
3130
3233
|
}
|
|
3131
3234
|
} else {
|
|
3132
|
-
spinner.start(`Scanning ${
|
|
3133
|
-
const pattern =
|
|
3235
|
+
spinner.start(`Scanning ${chalk15.cyan(targetPath)}...`);
|
|
3236
|
+
const pattern = path15.join(scanPath, "**/*");
|
|
3134
3237
|
const allFiles = await glob3(pattern, {
|
|
3135
3238
|
nodir: true,
|
|
3136
3239
|
dot: false,
|
|
@@ -3146,7 +3249,7 @@ function createCheckCommand() {
|
|
|
3146
3249
|
filesToCheck = allFiles.filter((f) => isCodeFile2(f));
|
|
3147
3250
|
}
|
|
3148
3251
|
if (filesToCheck.length === 0) {
|
|
3149
|
-
spinner.warn(
|
|
3252
|
+
spinner.warn(chalk15.yellow("No code files found to check."));
|
|
3150
3253
|
outputResults([], !!options.json);
|
|
3151
3254
|
process.exit(0);
|
|
3152
3255
|
}
|
|
@@ -3155,7 +3258,7 @@ function createCheckCommand() {
|
|
|
3155
3258
|
const results = [];
|
|
3156
3259
|
for (let i = 0; i < filesToCheck.length; i++) {
|
|
3157
3260
|
const file = filesToCheck[i];
|
|
3158
|
-
spinner.text = `Checking ${i + 1}/${filesToCheck.length}: ${
|
|
3261
|
+
spinner.text = `Checking ${i + 1}/${filesToCheck.length}: ${path15.basename(file)}`;
|
|
3159
3262
|
const result = await checkFile(file, rules, process.cwd());
|
|
3160
3263
|
results.push(result);
|
|
3161
3264
|
}
|
|
@@ -3165,47 +3268,47 @@ function createCheckCommand() {
|
|
|
3165
3268
|
outputResults(results, true);
|
|
3166
3269
|
} else {
|
|
3167
3270
|
outputResults(results, false);
|
|
3168
|
-
console.log("\n" +
|
|
3169
|
-
console.log(
|
|
3170
|
-
console.log(`Files checked: ${
|
|
3171
|
-
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)}`);
|
|
3172
3275
|
if (summary.totalViolations > 0) {
|
|
3173
|
-
console.log(` ${
|
|
3174
|
-
console.log(` ${
|
|
3175
|
-
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}`);
|
|
3176
3279
|
}
|
|
3177
|
-
console.log(
|
|
3280
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
3178
3281
|
}
|
|
3179
3282
|
if (options.strict !== void 0) {
|
|
3180
3283
|
const strictLevel = typeof options.strict === "string" ? options.strict : "all";
|
|
3181
3284
|
if (strictLevel === "critical" && summary.criticalCount > 0) {
|
|
3182
|
-
console.log(
|
|
3285
|
+
console.log(chalk15.red("\n\u274C Check failed: Critical violations found"));
|
|
3183
3286
|
process.exit(1);
|
|
3184
3287
|
} else if (strictLevel === "all" && summary.totalViolations > 0) {
|
|
3185
|
-
console.log(
|
|
3288
|
+
console.log(chalk15.red("\n\u274C Check failed: Violations found"));
|
|
3186
3289
|
process.exit(1);
|
|
3187
3290
|
}
|
|
3188
3291
|
}
|
|
3189
3292
|
if (summary.totalViolations === 0) {
|
|
3190
|
-
console.log(
|
|
3293
|
+
console.log(chalk15.green("\n\u2705 All checks passed!"));
|
|
3191
3294
|
}
|
|
3192
3295
|
process.exit(0);
|
|
3193
3296
|
} catch (error) {
|
|
3194
|
-
spinner.fail(
|
|
3195
|
-
console.error(
|
|
3297
|
+
spinner.fail(chalk15.red("Check failed"));
|
|
3298
|
+
console.error(chalk15.red("Error:"), error.message);
|
|
3196
3299
|
process.exit(2);
|
|
3197
3300
|
}
|
|
3198
3301
|
});
|
|
3199
3302
|
}
|
|
3200
3303
|
function isCodeFile2(filePath) {
|
|
3201
3304
|
const codeExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
3202
|
-
const ext =
|
|
3305
|
+
const ext = path15.extname(filePath).toLowerCase();
|
|
3203
3306
|
return codeExtensions.includes(ext);
|
|
3204
3307
|
}
|
|
3205
3308
|
async function loadCachedRules(projectId) {
|
|
3206
3309
|
try {
|
|
3207
|
-
const cachePath =
|
|
3208
|
-
const content = await
|
|
3310
|
+
const cachePath = path15.join(process.cwd(), CACHE_FILE2);
|
|
3311
|
+
const content = await fs14.readFile(cachePath, "utf-8");
|
|
3209
3312
|
const cached = JSON.parse(content);
|
|
3210
3313
|
if (cached.projectId !== projectId) {
|
|
3211
3314
|
return null;
|
|
@@ -3217,16 +3320,16 @@ async function loadCachedRules(projectId) {
|
|
|
3217
3320
|
}
|
|
3218
3321
|
async function saveCachedRules(projectId, rules, settings) {
|
|
3219
3322
|
try {
|
|
3220
|
-
const cacheDir =
|
|
3221
|
-
await
|
|
3323
|
+
const cacheDir = path15.join(process.cwd(), ".rigstate");
|
|
3324
|
+
await fs14.mkdir(cacheDir, { recursive: true });
|
|
3222
3325
|
const cached = {
|
|
3223
3326
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3224
3327
|
projectId,
|
|
3225
3328
|
rules,
|
|
3226
3329
|
settings
|
|
3227
3330
|
};
|
|
3228
|
-
await
|
|
3229
|
-
|
|
3331
|
+
await fs14.writeFile(
|
|
3332
|
+
path15.join(cacheDir, "rules-cache.json"),
|
|
3230
3333
|
JSON.stringify(cached, null, 2)
|
|
3231
3334
|
);
|
|
3232
3335
|
} catch {
|
|
@@ -3248,8 +3351,8 @@ function outputResults(results, json) {
|
|
|
3248
3351
|
if (!hasViolations) {
|
|
3249
3352
|
return;
|
|
3250
3353
|
}
|
|
3251
|
-
console.log("\n" +
|
|
3252
|
-
console.log(
|
|
3354
|
+
console.log("\n" + chalk15.bold("\u{1F50D} Violations Found"));
|
|
3355
|
+
console.log(chalk15.dim("\u2500".repeat(50)));
|
|
3253
3356
|
for (const result of results) {
|
|
3254
3357
|
if (result.violations.length > 0) {
|
|
3255
3358
|
formatViolations(result.violations);
|
|
@@ -3260,9 +3363,9 @@ function outputResults(results, json) {
|
|
|
3260
3363
|
// src/commands/hooks.ts
|
|
3261
3364
|
init_esm_shims();
|
|
3262
3365
|
import { Command as Command10 } from "commander";
|
|
3263
|
-
import
|
|
3264
|
-
import
|
|
3265
|
-
import
|
|
3366
|
+
import chalk16 from "chalk";
|
|
3367
|
+
import fs15 from "fs/promises";
|
|
3368
|
+
import path16 from "path";
|
|
3266
3369
|
var PRE_COMMIT_SCRIPT = `#!/bin/sh
|
|
3267
3370
|
# Rigstate Guardian Pre-commit Hook
|
|
3268
3371
|
# Installed by: rigstate hooks install
|
|
@@ -3291,23 +3394,23 @@ function createHooksCommand() {
|
|
|
3291
3394
|
const hooks = new Command10("hooks").description("Manage git hooks for Guardian integration");
|
|
3292
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) => {
|
|
3293
3396
|
try {
|
|
3294
|
-
const gitDir =
|
|
3397
|
+
const gitDir = path16.join(process.cwd(), ".git");
|
|
3295
3398
|
try {
|
|
3296
|
-
await
|
|
3399
|
+
await fs15.access(gitDir);
|
|
3297
3400
|
} catch {
|
|
3298
|
-
console.log(
|
|
3299
|
-
console.log(
|
|
3401
|
+
console.log(chalk16.red("\u274C Not a git repository."));
|
|
3402
|
+
console.log(chalk16.dim(' Initialize with "git init" first.'));
|
|
3300
3403
|
process.exit(1);
|
|
3301
3404
|
}
|
|
3302
|
-
const hooksDir =
|
|
3303
|
-
await
|
|
3304
|
-
const preCommitPath =
|
|
3405
|
+
const hooksDir = path16.join(gitDir, "hooks");
|
|
3406
|
+
await fs15.mkdir(hooksDir, { recursive: true });
|
|
3407
|
+
const preCommitPath = path16.join(hooksDir, "pre-commit");
|
|
3305
3408
|
let existingContent = "";
|
|
3306
3409
|
try {
|
|
3307
|
-
existingContent = await
|
|
3410
|
+
existingContent = await fs15.readFile(preCommitPath, "utf-8");
|
|
3308
3411
|
if (existingContent.includes("rigstate")) {
|
|
3309
|
-
console.log(
|
|
3310
|
-
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.'));
|
|
3311
3414
|
return;
|
|
3312
3415
|
}
|
|
3313
3416
|
} catch {
|
|
@@ -3318,34 +3421,34 @@ function createHooksCommand() {
|
|
|
3318
3421
|
}
|
|
3319
3422
|
if (existingContent && !existingContent.includes("rigstate")) {
|
|
3320
3423
|
const combinedScript = existingContent + "\n\n" + script.replace("#!/bin/sh\n", "");
|
|
3321
|
-
await
|
|
3322
|
-
console.log(
|
|
3424
|
+
await fs15.writeFile(preCommitPath, combinedScript, { mode: 493 });
|
|
3425
|
+
console.log(chalk16.green("\u2705 Rigstate hook appended to existing pre-commit."));
|
|
3323
3426
|
} else {
|
|
3324
|
-
await
|
|
3325
|
-
console.log(
|
|
3427
|
+
await fs15.writeFile(preCommitPath, script, { mode: 493 });
|
|
3428
|
+
console.log(chalk16.green("\u2705 Pre-commit hook installed!"));
|
|
3326
3429
|
}
|
|
3327
|
-
console.log(
|
|
3328
|
-
console.log(
|
|
3430
|
+
console.log(chalk16.dim(` Path: ${preCommitPath}`));
|
|
3431
|
+
console.log(chalk16.dim(` Strict level: ${options.strict}`));
|
|
3329
3432
|
console.log("");
|
|
3330
|
-
console.log(
|
|
3331
|
-
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.'));
|
|
3332
3435
|
} catch (error) {
|
|
3333
|
-
console.error(
|
|
3436
|
+
console.error(chalk16.red("Failed to install hook:"), error.message);
|
|
3334
3437
|
process.exit(1);
|
|
3335
3438
|
}
|
|
3336
3439
|
});
|
|
3337
3440
|
hooks.command("uninstall").description("Remove Rigstate pre-commit hook").action(async () => {
|
|
3338
3441
|
try {
|
|
3339
|
-
const preCommitPath =
|
|
3442
|
+
const preCommitPath = path16.join(process.cwd(), ".git", "hooks", "pre-commit");
|
|
3340
3443
|
try {
|
|
3341
|
-
const content = await
|
|
3444
|
+
const content = await fs15.readFile(preCommitPath, "utf-8");
|
|
3342
3445
|
if (!content.includes("rigstate")) {
|
|
3343
|
-
console.log(
|
|
3446
|
+
console.log(chalk16.yellow("\u26A0 No Rigstate hook found in pre-commit."));
|
|
3344
3447
|
return;
|
|
3345
3448
|
}
|
|
3346
3449
|
if (content.includes("# Rigstate Guardian Pre-commit Hook") && content.trim().split("\n").filter((l) => l && !l.startsWith("#")).length <= 4) {
|
|
3347
|
-
await
|
|
3348
|
-
console.log(
|
|
3450
|
+
await fs15.unlink(preCommitPath);
|
|
3451
|
+
console.log(chalk16.green("\u2705 Pre-commit hook removed."));
|
|
3349
3452
|
} else {
|
|
3350
3453
|
const lines = content.split("\n");
|
|
3351
3454
|
const filteredLines = [];
|
|
@@ -3363,14 +3466,14 @@ function createHooksCommand() {
|
|
|
3363
3466
|
filteredLines.push(line);
|
|
3364
3467
|
}
|
|
3365
3468
|
}
|
|
3366
|
-
await
|
|
3367
|
-
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."));
|
|
3368
3471
|
}
|
|
3369
3472
|
} catch {
|
|
3370
|
-
console.log(
|
|
3473
|
+
console.log(chalk16.yellow("\u26A0 No pre-commit hook found."));
|
|
3371
3474
|
}
|
|
3372
3475
|
} catch (error) {
|
|
3373
|
-
console.error(
|
|
3476
|
+
console.error(chalk16.red("Failed to uninstall hook:"), error.message);
|
|
3374
3477
|
process.exit(1);
|
|
3375
3478
|
}
|
|
3376
3479
|
});
|
|
@@ -3380,40 +3483,40 @@ function createHooksCommand() {
|
|
|
3380
3483
|
// src/commands/daemon.ts
|
|
3381
3484
|
init_esm_shims();
|
|
3382
3485
|
import { Command as Command11 } from "commander";
|
|
3383
|
-
import
|
|
3486
|
+
import chalk22 from "chalk";
|
|
3384
3487
|
import ora8 from "ora";
|
|
3385
|
-
import
|
|
3386
|
-
import
|
|
3488
|
+
import fs21 from "fs/promises";
|
|
3489
|
+
import path24 from "path";
|
|
3387
3490
|
|
|
3388
3491
|
// src/daemon/factory.ts
|
|
3389
3492
|
init_esm_shims();
|
|
3390
3493
|
|
|
3391
3494
|
// src/daemon/core.ts
|
|
3392
3495
|
init_esm_shims();
|
|
3393
|
-
import
|
|
3394
|
-
import * as
|
|
3395
|
-
import
|
|
3496
|
+
import chalk20 from "chalk";
|
|
3497
|
+
import * as fs19 from "fs/promises";
|
|
3498
|
+
import path22 from "path";
|
|
3396
3499
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
3397
3500
|
|
|
3398
3501
|
// src/daemon/file-watcher.ts
|
|
3399
3502
|
init_esm_shims();
|
|
3400
3503
|
import * as chokidar from "chokidar";
|
|
3401
|
-
import
|
|
3504
|
+
import path17 from "path";
|
|
3402
3505
|
import { EventEmitter } from "events";
|
|
3403
3506
|
var CODE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
3404
3507
|
function isCodeFile3(filePath) {
|
|
3405
|
-
const ext =
|
|
3508
|
+
const ext = path17.extname(filePath).toLowerCase();
|
|
3406
3509
|
return CODE_EXTENSIONS.includes(ext);
|
|
3407
3510
|
}
|
|
3408
3511
|
function createFileWatcher(watchPath) {
|
|
3409
3512
|
const emitter = new EventEmitter();
|
|
3410
3513
|
let watcher = null;
|
|
3411
3514
|
emitter.start = () => {
|
|
3412
|
-
const absolutePath =
|
|
3515
|
+
const absolutePath = path17.resolve(process.cwd(), watchPath);
|
|
3413
3516
|
watcher = chokidar.watch(absolutePath, {
|
|
3414
3517
|
ignored: (pathStr) => {
|
|
3415
|
-
const relativePath =
|
|
3416
|
-
const segments = relativePath.split(
|
|
3518
|
+
const relativePath = path17.relative(process.cwd(), pathStr);
|
|
3519
|
+
const segments = relativePath.split(path17.sep);
|
|
3417
3520
|
const ignoreDirs = [
|
|
3418
3521
|
"node_modules",
|
|
3419
3522
|
".git",
|
|
@@ -3445,7 +3548,7 @@ function createFileWatcher(watchPath) {
|
|
|
3445
3548
|
if (segments.some((segment) => ignoreDirs.includes(segment))) {
|
|
3446
3549
|
return true;
|
|
3447
3550
|
}
|
|
3448
|
-
const isFile = !!
|
|
3551
|
+
const isFile = !!path17.extname(pathStr);
|
|
3449
3552
|
if (isFile && !isCodeFile3(pathStr)) {
|
|
3450
3553
|
return true;
|
|
3451
3554
|
}
|
|
@@ -3468,17 +3571,17 @@ function createFileWatcher(watchPath) {
|
|
|
3468
3571
|
});
|
|
3469
3572
|
watcher.on("change", (filePath) => {
|
|
3470
3573
|
if (isCodeFile3(filePath)) {
|
|
3471
|
-
emitter.emit("change",
|
|
3574
|
+
emitter.emit("change", path17.relative(process.cwd(), filePath));
|
|
3472
3575
|
}
|
|
3473
3576
|
});
|
|
3474
3577
|
watcher.on("add", (filePath) => {
|
|
3475
3578
|
if (isCodeFile3(filePath)) {
|
|
3476
|
-
emitter.emit("add",
|
|
3579
|
+
emitter.emit("add", path17.relative(process.cwd(), filePath));
|
|
3477
3580
|
}
|
|
3478
3581
|
});
|
|
3479
3582
|
watcher.on("unlink", (filePath) => {
|
|
3480
3583
|
if (isCodeFile3(filePath)) {
|
|
3481
|
-
emitter.emit("unlink",
|
|
3584
|
+
emitter.emit("unlink", path17.relative(process.cwd(), filePath));
|
|
3482
3585
|
}
|
|
3483
3586
|
});
|
|
3484
3587
|
watcher.on("error", (error) => {
|
|
@@ -3501,7 +3604,7 @@ function createFileWatcher(watchPath) {
|
|
|
3501
3604
|
init_esm_shims();
|
|
3502
3605
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
3503
3606
|
import { dirname } from "path";
|
|
3504
|
-
import
|
|
3607
|
+
import path18 from "path";
|
|
3505
3608
|
import axios11 from "axios";
|
|
3506
3609
|
var GLOBAL_HEURISTICS = [
|
|
3507
3610
|
{
|
|
@@ -3533,7 +3636,7 @@ var HeuristicEngine = class {
|
|
|
3533
3636
|
rules = [];
|
|
3534
3637
|
cachePath;
|
|
3535
3638
|
constructor() {
|
|
3536
|
-
this.cachePath =
|
|
3639
|
+
this.cachePath = path18.join(process.cwd(), ".rigstate", "cache", "heuristics.json");
|
|
3537
3640
|
this.loadRules();
|
|
3538
3641
|
}
|
|
3539
3642
|
async loadRules() {
|
|
@@ -3648,9 +3751,9 @@ function createHeuristicEngine() {
|
|
|
3648
3751
|
|
|
3649
3752
|
// src/daemon/intervention-protocol.ts
|
|
3650
3753
|
init_esm_shims();
|
|
3651
|
-
import
|
|
3652
|
-
import * as
|
|
3653
|
-
import * as
|
|
3754
|
+
import chalk17 from "chalk";
|
|
3755
|
+
import * as fs16 from "fs";
|
|
3756
|
+
import * as path19 from "path";
|
|
3654
3757
|
var InterventionProtocol = class {
|
|
3655
3758
|
activeViolators = /* @__PURE__ */ new Set();
|
|
3656
3759
|
/**
|
|
@@ -3673,18 +3776,18 @@ var InterventionProtocol = class {
|
|
|
3673
3776
|
}
|
|
3674
3777
|
syncLockFile() {
|
|
3675
3778
|
try {
|
|
3676
|
-
const lockDir =
|
|
3677
|
-
if (!
|
|
3678
|
-
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");
|
|
3679
3782
|
if (this.activeViolators.size > 0) {
|
|
3680
3783
|
const content = `HARD_LOCK_ACTIVE
|
|
3681
3784
|
Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
3682
3785
|
|
|
3683
3786
|
Blocking Files:
|
|
3684
3787
|
${Array.from(this.activeViolators).join("\n")}`;
|
|
3685
|
-
|
|
3788
|
+
fs16.writeFileSync(lockPath, content, "utf-8");
|
|
3686
3789
|
} else {
|
|
3687
|
-
if (
|
|
3790
|
+
if (fs16.existsSync(lockPath)) fs16.unlinkSync(lockPath);
|
|
3688
3791
|
}
|
|
3689
3792
|
} catch (e) {
|
|
3690
3793
|
console.error("Failed to sync guardian lock file:", e);
|
|
@@ -3738,11 +3841,11 @@ ${Array.from(this.activeViolators).join("\n")}`;
|
|
|
3738
3841
|
enforce(decision) {
|
|
3739
3842
|
if (decision.mode === "OPEN") return;
|
|
3740
3843
|
const icon = decision.mode === "HARD_LOCK" ? "\u{1F6AB}" : "\u26A0\uFE0F";
|
|
3741
|
-
const color = decision.mode === "HARD_LOCK" ?
|
|
3844
|
+
const color = decision.mode === "HARD_LOCK" ? chalk17.bgRed.white.bold : chalk17.yellow.bold;
|
|
3742
3845
|
console.log("\n" + color(` ${icon} [${decision.mode}] INTERVENTION `));
|
|
3743
|
-
console.log(
|
|
3846
|
+
console.log(chalk17.redBright(` ${decision.message}`));
|
|
3744
3847
|
if (decision.blockCommit) {
|
|
3745
|
-
console.log(
|
|
3848
|
+
console.log(chalk17.dim(" \u{1F512} Commit functionality is logically suspended until fixed."));
|
|
3746
3849
|
}
|
|
3747
3850
|
}
|
|
3748
3851
|
};
|
|
@@ -3753,9 +3856,9 @@ function createInterventionProtocol() {
|
|
|
3753
3856
|
// src/daemon/guardian-monitor.ts
|
|
3754
3857
|
init_esm_shims();
|
|
3755
3858
|
import axios12 from "axios";
|
|
3756
|
-
import
|
|
3757
|
-
import
|
|
3758
|
-
import
|
|
3859
|
+
import chalk18 from "chalk";
|
|
3860
|
+
import fs17 from "fs/promises";
|
|
3861
|
+
import path20 from "path";
|
|
3759
3862
|
var CACHE_FILE3 = ".rigstate/rules-cache.json";
|
|
3760
3863
|
var CACHE_TTL_MS2 = 5 * 60 * 1e3;
|
|
3761
3864
|
function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
@@ -3780,7 +3883,7 @@ function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
|
3780
3883
|
} catch (error) {
|
|
3781
3884
|
if (apiUrl.includes("localhost") || apiUrl.includes("127.0.0.1")) {
|
|
3782
3885
|
const cloudUrl = "https://app.rigstate.com";
|
|
3783
|
-
console.log(
|
|
3886
|
+
console.log(chalk18.blue(` \u2601\uFE0F Local API not found. Attempting Cloud Fallback (${cloudUrl})...`));
|
|
3784
3887
|
try {
|
|
3785
3888
|
const cloudResponse = await axios12.get(`${cloudUrl}/api/v1/guardian/rules`, {
|
|
3786
3889
|
params: { project_id: projectId },
|
|
@@ -3789,22 +3892,22 @@ function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
|
3789
3892
|
});
|
|
3790
3893
|
if (cloudResponse.data.success && cloudResponse.data.data.rules) {
|
|
3791
3894
|
rules = cloudResponse.data.data.rules;
|
|
3792
|
-
console.log(
|
|
3895
|
+
console.log(chalk18.green(` \u2705 Successfully loaded rules from Rigstate Cloud!`));
|
|
3793
3896
|
lastFetch = Date.now();
|
|
3794
3897
|
await saveCachedRules2(projectId, rules);
|
|
3795
3898
|
return;
|
|
3796
3899
|
}
|
|
3797
3900
|
} catch (cloudError) {
|
|
3798
|
-
console.error(
|
|
3901
|
+
console.error(chalk18.red(` \u274C Cloud Fallback failed: ${cloudError.message}`));
|
|
3799
3902
|
}
|
|
3800
3903
|
}
|
|
3801
|
-
console.error(
|
|
3904
|
+
console.error(chalk18.red(` \u26A0\uFE0F Failed to fetch rules from API: ${error.message}`));
|
|
3802
3905
|
if (error.response) {
|
|
3803
|
-
console.error(
|
|
3906
|
+
console.error(chalk18.red(` Status: ${error.response.status} - ${JSON.stringify(error.response.data)}`));
|
|
3804
3907
|
}
|
|
3805
3908
|
const cached = await loadCachedRules2(projectId);
|
|
3806
3909
|
if (cached) {
|
|
3807
|
-
console.log(
|
|
3910
|
+
console.log(chalk18.yellow(" \u2139\uFE0F Using cached rules as fallback"));
|
|
3808
3911
|
rules = cached.rules;
|
|
3809
3912
|
lastFetch = Date.now();
|
|
3810
3913
|
return;
|
|
@@ -3821,7 +3924,7 @@ function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
|
3821
3924
|
passed: true
|
|
3822
3925
|
};
|
|
3823
3926
|
}
|
|
3824
|
-
const absolutePath =
|
|
3927
|
+
const absolutePath = path20.resolve(process.cwd(), filePath);
|
|
3825
3928
|
return checkFile(absolutePath, rules, process.cwd());
|
|
3826
3929
|
};
|
|
3827
3930
|
const getRuleCount = () => rules.length;
|
|
@@ -3835,8 +3938,8 @@ function createGuardianMonitor(projectId, apiUrl, apiKey) {
|
|
|
3835
3938
|
}
|
|
3836
3939
|
async function loadCachedRules2(projectId) {
|
|
3837
3940
|
try {
|
|
3838
|
-
const cachePath =
|
|
3839
|
-
const content = await
|
|
3941
|
+
const cachePath = path20.join(process.cwd(), CACHE_FILE3);
|
|
3942
|
+
const content = await fs17.readFile(cachePath, "utf-8");
|
|
3840
3943
|
const cached = JSON.parse(content);
|
|
3841
3944
|
if (cached.projectId !== projectId) {
|
|
3842
3945
|
return null;
|
|
@@ -3848,16 +3951,16 @@ async function loadCachedRules2(projectId) {
|
|
|
3848
3951
|
}
|
|
3849
3952
|
async function saveCachedRules2(projectId, rules) {
|
|
3850
3953
|
try {
|
|
3851
|
-
const cacheDir =
|
|
3852
|
-
await
|
|
3954
|
+
const cacheDir = path20.join(process.cwd(), ".rigstate");
|
|
3955
|
+
await fs17.mkdir(cacheDir, { recursive: true });
|
|
3853
3956
|
const cached = {
|
|
3854
3957
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3855
3958
|
projectId,
|
|
3856
3959
|
rules,
|
|
3857
3960
|
settings: { lmax: 400, lmax_warning: 350 }
|
|
3858
3961
|
};
|
|
3859
|
-
await
|
|
3860
|
-
|
|
3962
|
+
await fs17.writeFile(
|
|
3963
|
+
path20.join(cacheDir, "rules-cache.json"),
|
|
3861
3964
|
JSON.stringify(cached, null, 2)
|
|
3862
3965
|
);
|
|
3863
3966
|
} catch {
|
|
@@ -3957,37 +4060,37 @@ init_sync_rules();
|
|
|
3957
4060
|
|
|
3958
4061
|
// src/utils/logger.ts
|
|
3959
4062
|
init_esm_shims();
|
|
3960
|
-
import
|
|
4063
|
+
import chalk19 from "chalk";
|
|
3961
4064
|
var Logger = class {
|
|
3962
4065
|
static formatMessage(level, message, context) {
|
|
3963
4066
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3964
4067
|
let prefix = "";
|
|
3965
4068
|
switch (level) {
|
|
3966
4069
|
case "INFO" /* INFO */:
|
|
3967
|
-
prefix =
|
|
4070
|
+
prefix = chalk19.blue(`[${"INFO" /* INFO */}]`);
|
|
3968
4071
|
break;
|
|
3969
4072
|
case "WARN" /* WARN */:
|
|
3970
|
-
prefix =
|
|
4073
|
+
prefix = chalk19.yellow(`[${"WARN" /* WARN */}]`);
|
|
3971
4074
|
break;
|
|
3972
4075
|
case "ERROR" /* ERROR */:
|
|
3973
|
-
prefix =
|
|
4076
|
+
prefix = chalk19.red(`[${"ERROR" /* ERROR */}]`);
|
|
3974
4077
|
break;
|
|
3975
4078
|
case "DEBUG" /* DEBUG */:
|
|
3976
|
-
prefix =
|
|
4079
|
+
prefix = chalk19.gray(`[${"DEBUG" /* DEBUG */}]`);
|
|
3977
4080
|
break;
|
|
3978
4081
|
}
|
|
3979
|
-
let output = `${
|
|
4082
|
+
let output = `${chalk19.gray(timestamp)} ${prefix} ${message}`;
|
|
3980
4083
|
if (context) {
|
|
3981
4084
|
if (context instanceof Error) {
|
|
3982
4085
|
output += `
|
|
3983
|
-
${
|
|
4086
|
+
${chalk19.red(context.stack || context.message)}`;
|
|
3984
4087
|
} else if (typeof context === "object") {
|
|
3985
4088
|
try {
|
|
3986
4089
|
output += `
|
|
3987
|
-
${
|
|
4090
|
+
${chalk19.gray(JSON.stringify(context, null, 2))}`;
|
|
3988
4091
|
} catch (e) {
|
|
3989
4092
|
output += `
|
|
3990
|
-
${
|
|
4093
|
+
${chalk19.gray("[Circular or invalid object]")}`;
|
|
3991
4094
|
}
|
|
3992
4095
|
} else {
|
|
3993
4096
|
output += ` ${String(context)}`;
|
|
@@ -4015,8 +4118,8 @@ ${chalk18.gray("[Circular or invalid object]")}`;
|
|
|
4015
4118
|
init_esm_shims();
|
|
4016
4119
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
4017
4120
|
import chokidar2 from "chokidar";
|
|
4018
|
-
import
|
|
4019
|
-
import
|
|
4121
|
+
import path21 from "path";
|
|
4122
|
+
import fs18 from "fs/promises";
|
|
4020
4123
|
import crypto from "crypto";
|
|
4021
4124
|
import axios15 from "axios";
|
|
4022
4125
|
var KnowledgeHarvester = class extends EventEmitter3 {
|
|
@@ -4034,8 +4137,8 @@ var KnowledgeHarvester = class extends EventEmitter3 {
|
|
|
4034
4137
|
}
|
|
4035
4138
|
async start() {
|
|
4036
4139
|
await this.loadHashes();
|
|
4037
|
-
const rulesPath =
|
|
4038
|
-
const watchPattern =
|
|
4140
|
+
const rulesPath = path21.join(this.config.watchPath, ".cursor", "rules");
|
|
4141
|
+
const watchPattern = path21.join(rulesPath, "**", "*.mdc");
|
|
4039
4142
|
Logger.debug(`\u{1F33E} Harvester watching: ${watchPattern}`);
|
|
4040
4143
|
this.watcher = chokidar2.watch(watchPattern, {
|
|
4041
4144
|
persistent: true,
|
|
@@ -4056,7 +4159,7 @@ var KnowledgeHarvester = class extends EventEmitter3 {
|
|
|
4056
4159
|
}
|
|
4057
4160
|
}
|
|
4058
4161
|
async handleFileEvent(filePath, event) {
|
|
4059
|
-
const fileName =
|
|
4162
|
+
const fileName = path21.basename(filePath);
|
|
4060
4163
|
if (this.IGNORED_PREFIXES.some((prefix) => fileName.startsWith(prefix))) {
|
|
4061
4164
|
return;
|
|
4062
4165
|
}
|
|
@@ -4072,27 +4175,27 @@ var KnowledgeHarvester = class extends EventEmitter3 {
|
|
|
4072
4175
|
if (this.processingQueue.has(filePath)) return;
|
|
4073
4176
|
this.processingQueue.add(filePath);
|
|
4074
4177
|
try {
|
|
4075
|
-
const content = await
|
|
4178
|
+
const content = await fs18.readFile(filePath, "utf-8");
|
|
4076
4179
|
const currentHash = this.computeHash(content);
|
|
4077
4180
|
if (this.ruleHashes.get(filePath) === currentHash) {
|
|
4078
|
-
Logger.debug(`Skipping ${
|
|
4181
|
+
Logger.debug(`Skipping ${path21.basename(filePath)} (unchanged hash)`);
|
|
4079
4182
|
return;
|
|
4080
4183
|
}
|
|
4081
4184
|
if (content.length < 20) {
|
|
4082
|
-
Logger.debug(`Skipping ${
|
|
4185
|
+
Logger.debug(`Skipping ${path21.basename(filePath)} (too short)`);
|
|
4083
4186
|
return;
|
|
4084
4187
|
}
|
|
4085
4188
|
await this.submitSignal(filePath, content);
|
|
4086
4189
|
this.ruleHashes.set(filePath, currentHash);
|
|
4087
4190
|
} catch (error) {
|
|
4088
|
-
Logger.warn(`Harvester failed to process ${
|
|
4191
|
+
Logger.warn(`Harvester failed to process ${path21.basename(filePath)}: ${error.message}`);
|
|
4089
4192
|
} finally {
|
|
4090
4193
|
this.processingQueue.delete(filePath);
|
|
4091
4194
|
}
|
|
4092
4195
|
}
|
|
4093
4196
|
async submitSignal(filePath, content) {
|
|
4094
|
-
const title =
|
|
4095
|
-
const relativePath =
|
|
4197
|
+
const title = path21.basename(filePath, ".mdc");
|
|
4198
|
+
const relativePath = path21.relative(process.cwd(), filePath);
|
|
4096
4199
|
Logger.info(`\u{1F33E} Harvesting new knowledge: ${title}`);
|
|
4097
4200
|
try {
|
|
4098
4201
|
const descriptionMatch = content.match(/description:\s*(.*)/);
|
|
@@ -4126,14 +4229,14 @@ var KnowledgeHarvester = class extends EventEmitter3 {
|
|
|
4126
4229
|
}
|
|
4127
4230
|
}
|
|
4128
4231
|
async loadHashes() {
|
|
4129
|
-
const rulesPath =
|
|
4232
|
+
const rulesPath = path21.join(this.config.watchPath, ".cursor", "rules");
|
|
4130
4233
|
try {
|
|
4131
|
-
await
|
|
4132
|
-
const files = await
|
|
4234
|
+
await fs18.mkdir(rulesPath, { recursive: true });
|
|
4235
|
+
const files = await fs18.readdir(rulesPath);
|
|
4133
4236
|
for (const file of files) {
|
|
4134
4237
|
if (file.endsWith(".mdc")) {
|
|
4135
|
-
const fullPath =
|
|
4136
|
-
const content = await
|
|
4238
|
+
const fullPath = path21.join(rulesPath, file);
|
|
4239
|
+
const content = await fs18.readFile(fullPath, "utf-8");
|
|
4137
4240
|
this.ruleHashes.set(fullPath, this.computeHash(content));
|
|
4138
4241
|
}
|
|
4139
4242
|
}
|
|
@@ -4170,7 +4273,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4170
4273
|
}
|
|
4171
4274
|
async start() {
|
|
4172
4275
|
if (this.state.isRunning) {
|
|
4173
|
-
console.log(
|
|
4276
|
+
console.log(chalk20.yellow("Daemon is already running."));
|
|
4174
4277
|
return;
|
|
4175
4278
|
}
|
|
4176
4279
|
this.printWelcome();
|
|
@@ -4202,8 +4305,8 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4202
4305
|
try {
|
|
4203
4306
|
await this.setupBridge();
|
|
4204
4307
|
} catch (e) {
|
|
4205
|
-
console.error(
|
|
4206
|
-
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)"));
|
|
4207
4310
|
}
|
|
4208
4311
|
}
|
|
4209
4312
|
this.printActive();
|
|
@@ -4219,16 +4322,16 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4219
4322
|
}
|
|
4220
4323
|
}
|
|
4221
4324
|
printWelcome() {
|
|
4222
|
-
console.log(
|
|
4223
|
-
console.log(
|
|
4224
|
-
console.log(
|
|
4225
|
-
console.log(
|
|
4226
|
-
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)));
|
|
4227
4330
|
}
|
|
4228
4331
|
printActive() {
|
|
4229
|
-
console.log(
|
|
4230
|
-
console.log(
|
|
4231
|
-
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"));
|
|
4232
4335
|
}
|
|
4233
4336
|
async syncHeuristics() {
|
|
4234
4337
|
if (!this.heuristicEngine) return;
|
|
@@ -4251,7 +4354,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4251
4354
|
}
|
|
4252
4355
|
async getLineCount(filePath) {
|
|
4253
4356
|
try {
|
|
4254
|
-
const content = await
|
|
4357
|
+
const content = await fs19.readFile(filePath, "utf-8");
|
|
4255
4358
|
return content.split("\n").length;
|
|
4256
4359
|
} catch (e) {
|
|
4257
4360
|
return 0;
|
|
@@ -4288,7 +4391,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4288
4391
|
}
|
|
4289
4392
|
}
|
|
4290
4393
|
async updateViolationReport(violations) {
|
|
4291
|
-
const reportPath =
|
|
4394
|
+
const reportPath = path22.join(process.cwd(), ".rigstate", "ACTIVE_VIOLATIONS.md");
|
|
4292
4395
|
const allViolations = Array.from(this.violationsMap.entries());
|
|
4293
4396
|
const totalCount = allViolations.reduce((acc, [, v]) => acc + v.length, 0);
|
|
4294
4397
|
let content = `# \u{1F6E1}\uFE0F Guardian Status: ${totalCount > 0 ? "\u26A0\uFE0F ATTENTION" : "\u2705 PASS"}
|
|
@@ -4304,7 +4407,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4304
4407
|
} else {
|
|
4305
4408
|
content += "### \u{1F6A8} Active Violations\n\n";
|
|
4306
4409
|
for (const [file, fileViolations] of allViolations) {
|
|
4307
|
-
const relPath =
|
|
4410
|
+
const relPath = path22.relative(process.cwd(), file);
|
|
4308
4411
|
content += `#### \u{1F4C4} ${relPath}
|
|
4309
4412
|
`;
|
|
4310
4413
|
for (const v of fileViolations) {
|
|
@@ -4316,7 +4419,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4316
4419
|
content += "\n---\n*Rigstate Daemon is watching. Fix violations to clear this report.*";
|
|
4317
4420
|
}
|
|
4318
4421
|
try {
|
|
4319
|
-
await
|
|
4422
|
+
await fs19.writeFile(reportPath, content, "utf-8");
|
|
4320
4423
|
} catch (e) {
|
|
4321
4424
|
}
|
|
4322
4425
|
}
|
|
@@ -4336,27 +4439,27 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4336
4439
|
}
|
|
4337
4440
|
}
|
|
4338
4441
|
async setupBridge() {
|
|
4339
|
-
console.log(
|
|
4442
|
+
console.log(chalk20.dim("\u{1F309} Connecting to Agent Bridge..."));
|
|
4340
4443
|
this.bridgeListener = createBridgeListener(this.config.projectId, this.config.apiUrl, this.config.apiKey);
|
|
4341
4444
|
this.bridgeListener.on("task", (task) => {
|
|
4342
4445
|
this.state.lastActivity = (/* @__PURE__ */ new Date()).toISOString();
|
|
4343
4446
|
this.state.tasksProcessed++;
|
|
4344
|
-
console.log(
|
|
4447
|
+
console.log(chalk20.cyan(`
|
|
4345
4448
|
\u{1F4E5} New task received: ${task.id}`));
|
|
4346
4449
|
this.emit("task", task);
|
|
4347
4450
|
});
|
|
4348
4451
|
await this.bridgeListener.connect();
|
|
4349
|
-
console.log(
|
|
4452
|
+
console.log(chalk20.green(" \u2713 Agent Bridge connected"));
|
|
4350
4453
|
}
|
|
4351
4454
|
async stop() {
|
|
4352
4455
|
if (!this.state.isRunning) return;
|
|
4353
|
-
console.log(
|
|
4456
|
+
console.log(chalk20.dim("\n\u{1F6D1} Stopping Guardian Daemon..."));
|
|
4354
4457
|
if (this.fileWatcher) await this.fileWatcher.stop();
|
|
4355
4458
|
if (this.bridgeListener) await this.bridgeListener.disconnect();
|
|
4356
4459
|
if (this.harvester) await this.harvester.stop();
|
|
4357
4460
|
if (this.syncInterval) clearInterval(this.syncInterval);
|
|
4358
4461
|
this.state.isRunning = false;
|
|
4359
|
-
console.log(
|
|
4462
|
+
console.log(chalk20.green("\u2713 Daemon stopped."));
|
|
4360
4463
|
this.emit("stopped", this.state);
|
|
4361
4464
|
}
|
|
4362
4465
|
getState() {
|
|
@@ -4366,6 +4469,7 @@ var GuardianDaemon = class extends EventEmitter4 {
|
|
|
4366
4469
|
|
|
4367
4470
|
// src/daemon/factory.ts
|
|
4368
4471
|
init_config();
|
|
4472
|
+
init_manifest();
|
|
4369
4473
|
async function createDaemon(options) {
|
|
4370
4474
|
const apiUrl = getApiUrl();
|
|
4371
4475
|
let projectId = options.project;
|
|
@@ -4395,9 +4499,9 @@ async function createDaemon(options) {
|
|
|
4395
4499
|
|
|
4396
4500
|
// src/utils/service-manager.ts
|
|
4397
4501
|
init_esm_shims();
|
|
4398
|
-
import
|
|
4399
|
-
import
|
|
4400
|
-
import
|
|
4502
|
+
import chalk21 from "chalk";
|
|
4503
|
+
import fs20 from "fs/promises";
|
|
4504
|
+
import path23 from "path";
|
|
4401
4505
|
import { execSync as execSync3 } from "child_process";
|
|
4402
4506
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4403
4507
|
async function execShellCommand(cmd) {
|
|
@@ -4409,22 +4513,22 @@ async function execShellCommand(cmd) {
|
|
|
4409
4513
|
}
|
|
4410
4514
|
}
|
|
4411
4515
|
async function enableDaemon() {
|
|
4412
|
-
console.log(
|
|
4516
|
+
console.log(chalk21.bold("\n\u2699\uFE0F Enabling Rigstate Background Service (macOS)\n"));
|
|
4413
4517
|
if (process.platform !== "darwin") {
|
|
4414
|
-
console.error(
|
|
4415
|
-
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!"));
|
|
4416
4520
|
return;
|
|
4417
4521
|
}
|
|
4418
4522
|
const homeDir = process.env.HOME || "";
|
|
4419
4523
|
if (!homeDir) {
|
|
4420
|
-
console.error(
|
|
4524
|
+
console.error(chalk21.red("\u274C Could not determine HOME directory."));
|
|
4421
4525
|
return;
|
|
4422
4526
|
}
|
|
4423
|
-
const agentsDir =
|
|
4424
|
-
const logDir =
|
|
4425
|
-
const plistPath =
|
|
4426
|
-
await
|
|
4427
|
-
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 });
|
|
4428
4532
|
const scriptPath = fileURLToPath2(import.meta.url);
|
|
4429
4533
|
const nodePath = process.execPath;
|
|
4430
4534
|
const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -4443,9 +4547,9 @@ async function enableDaemon() {
|
|
|
4443
4547
|
<key>WorkingDirectory</key>
|
|
4444
4548
|
<string>${process.cwd()}</string>
|
|
4445
4549
|
<key>StandardOutPath</key>
|
|
4446
|
-
<string>${
|
|
4550
|
+
<string>${path23.join(logDir, "daemon.out.log")}</string>
|
|
4447
4551
|
<key>StandardErrorPath</key>
|
|
4448
|
-
<string>${
|
|
4552
|
+
<string>${path23.join(logDir, "daemon.err.log")}</string>
|
|
4449
4553
|
<key>RunAtLoad</key>
|
|
4450
4554
|
<true/>
|
|
4451
4555
|
<key>KeepAlive</key>
|
|
@@ -4458,33 +4562,33 @@ async function enableDaemon() {
|
|
|
4458
4562
|
</dict>
|
|
4459
4563
|
</plist>`;
|
|
4460
4564
|
try {
|
|
4461
|
-
await
|
|
4462
|
-
console.log(
|
|
4565
|
+
await fs20.writeFile(plistPath, plistContent);
|
|
4566
|
+
console.log(chalk21.dim(`Created plist at: ${plistPath}`));
|
|
4463
4567
|
try {
|
|
4464
4568
|
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
4465
4569
|
} catch (e) {
|
|
4466
4570
|
}
|
|
4467
4571
|
await execShellCommand(`launchctl load ${plistPath}`);
|
|
4468
|
-
console.log(
|
|
4469
|
-
console.log(
|
|
4470
|
-
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."));
|
|
4471
4575
|
} catch (error) {
|
|
4472
|
-
console.error(
|
|
4576
|
+
console.error(chalk21.red("\u274C Failed to enable daemon:"), error.message);
|
|
4473
4577
|
}
|
|
4474
4578
|
}
|
|
4475
4579
|
async function disableDaemon() {
|
|
4476
|
-
console.log(
|
|
4580
|
+
console.log(chalk21.bold("\n\u2699\uFE0F Disabling Rigstate Background Service\n"));
|
|
4477
4581
|
const homeDir = process.env.HOME || "";
|
|
4478
|
-
const plistPath =
|
|
4582
|
+
const plistPath = path23.join(homeDir, "Library/LaunchAgents/com.rigstate.daemon.plist");
|
|
4479
4583
|
try {
|
|
4480
4584
|
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
4481
|
-
await
|
|
4482
|
-
console.log(
|
|
4585
|
+
await fs20.unlink(plistPath);
|
|
4586
|
+
console.log(chalk21.green("\u2705 Successfully disabled background daemon."));
|
|
4483
4587
|
} catch (error) {
|
|
4484
4588
|
if (error.code === "ENOENT") {
|
|
4485
|
-
console.log(
|
|
4589
|
+
console.log(chalk21.green("\u2705 Daemon was not enabled."));
|
|
4486
4590
|
} else {
|
|
4487
|
-
console.error(
|
|
4591
|
+
console.error(chalk21.red("\u274C Failed to disable daemon:"), error.message);
|
|
4488
4592
|
}
|
|
4489
4593
|
}
|
|
4490
4594
|
}
|
|
@@ -4509,17 +4613,17 @@ function createDaemonCommand() {
|
|
|
4509
4613
|
}
|
|
4510
4614
|
const spinner = ora8();
|
|
4511
4615
|
try {
|
|
4512
|
-
const pidPath =
|
|
4616
|
+
const pidPath = path24.join(process.cwd(), PID_FILE);
|
|
4513
4617
|
try {
|
|
4514
|
-
const content = await
|
|
4618
|
+
const content = await fs21.readFile(pidPath, "utf-8");
|
|
4515
4619
|
const pid = parseInt(content.trim(), 10);
|
|
4516
4620
|
try {
|
|
4517
4621
|
process.kill(pid, 0);
|
|
4518
|
-
console.log(
|
|
4519
|
-
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.
|
|
4520
4624
|
`));
|
|
4521
4625
|
} catch {
|
|
4522
|
-
await
|
|
4626
|
+
await fs21.unlink(pidPath).catch(() => {
|
|
4523
4627
|
});
|
|
4524
4628
|
}
|
|
4525
4629
|
} catch {
|
|
@@ -4534,7 +4638,7 @@ function createDaemonCommand() {
|
|
|
4534
4638
|
spinner.stop();
|
|
4535
4639
|
await writePidFile();
|
|
4536
4640
|
process.on("SIGINT", async () => {
|
|
4537
|
-
console.log(
|
|
4641
|
+
console.log(chalk22.dim("\n\nShutting down..."));
|
|
4538
4642
|
await daemonInstance.stop();
|
|
4539
4643
|
await cleanupPidFile();
|
|
4540
4644
|
process.exit(0);
|
|
@@ -4554,8 +4658,8 @@ function createDaemonCommand() {
|
|
|
4554
4658
|
await new Promise(() => {
|
|
4555
4659
|
});
|
|
4556
4660
|
} catch (error) {
|
|
4557
|
-
spinner.fail(
|
|
4558
|
-
console.error(
|
|
4661
|
+
spinner.fail(chalk22.red("Failed to start daemon"));
|
|
4662
|
+
console.error(chalk22.red("Error:"), error.message);
|
|
4559
4663
|
process.exit(1);
|
|
4560
4664
|
}
|
|
4561
4665
|
});
|
|
@@ -4563,14 +4667,14 @@ function createDaemonCommand() {
|
|
|
4563
4667
|
}
|
|
4564
4668
|
async function isRunning() {
|
|
4565
4669
|
try {
|
|
4566
|
-
const pidPath =
|
|
4567
|
-
const content = await
|
|
4670
|
+
const pidPath = path24.join(process.cwd(), PID_FILE);
|
|
4671
|
+
const content = await fs21.readFile(pidPath, "utf-8");
|
|
4568
4672
|
const pid = parseInt(content.trim(), 10);
|
|
4569
4673
|
try {
|
|
4570
4674
|
process.kill(pid, 0);
|
|
4571
4675
|
return true;
|
|
4572
4676
|
} catch {
|
|
4573
|
-
await
|
|
4677
|
+
await fs21.unlink(pidPath);
|
|
4574
4678
|
return false;
|
|
4575
4679
|
}
|
|
4576
4680
|
} catch {
|
|
@@ -4579,57 +4683,57 @@ async function isRunning() {
|
|
|
4579
4683
|
}
|
|
4580
4684
|
async function writePidFile() {
|
|
4581
4685
|
try {
|
|
4582
|
-
const dir =
|
|
4583
|
-
await
|
|
4584
|
-
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());
|
|
4585
4689
|
} catch {
|
|
4586
4690
|
}
|
|
4587
4691
|
}
|
|
4588
4692
|
async function cleanupPidFile() {
|
|
4589
4693
|
try {
|
|
4590
|
-
await
|
|
4591
|
-
await
|
|
4694
|
+
await fs21.unlink(path24.join(process.cwd(), PID_FILE));
|
|
4695
|
+
await fs21.unlink(path24.join(process.cwd(), STATE_FILE));
|
|
4592
4696
|
} catch {
|
|
4593
4697
|
}
|
|
4594
4698
|
}
|
|
4595
4699
|
async function writeStateFile(state) {
|
|
4596
4700
|
try {
|
|
4597
|
-
const dir =
|
|
4598
|
-
await
|
|
4599
|
-
await
|
|
4600
|
-
|
|
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"),
|
|
4601
4705
|
JSON.stringify(state, null, 2)
|
|
4602
4706
|
);
|
|
4603
4707
|
} catch {
|
|
4604
4708
|
}
|
|
4605
4709
|
}
|
|
4606
4710
|
async function showStatus() {
|
|
4607
|
-
console.log(
|
|
4711
|
+
console.log(chalk22.bold("\n\u{1F6E1}\uFE0F Guardian Daemon Status\n"));
|
|
4608
4712
|
const running = await isRunning();
|
|
4609
4713
|
if (!running) {
|
|
4610
|
-
console.log(
|
|
4611
|
-
console.log(
|
|
4714
|
+
console.log(chalk22.yellow("Status: Not running"));
|
|
4715
|
+
console.log(chalk22.dim('Use "rigstate daemon" to start.\n'));
|
|
4612
4716
|
return;
|
|
4613
4717
|
}
|
|
4614
|
-
console.log(
|
|
4718
|
+
console.log(chalk22.green("Status: Running"));
|
|
4615
4719
|
try {
|
|
4616
|
-
const statePath =
|
|
4617
|
-
const content = await
|
|
4720
|
+
const statePath = path24.join(process.cwd(), STATE_FILE);
|
|
4721
|
+
const content = await fs21.readFile(statePath, "utf-8");
|
|
4618
4722
|
const state = JSON.parse(content);
|
|
4619
|
-
console.log(
|
|
4723
|
+
console.log(chalk22.dim("\u2500".repeat(40)));
|
|
4620
4724
|
console.log(`Started at: ${state.startedAt || "Unknown"}`);
|
|
4621
4725
|
console.log(`Files checked: ${state.filesChecked || 0}`);
|
|
4622
4726
|
console.log(`Violations: ${state.violationsFound || 0}`);
|
|
4623
4727
|
console.log(`Tasks processed: ${state.tasksProcessed || 0}`);
|
|
4624
4728
|
console.log(`Last activity: ${state.lastActivity || "None"}`);
|
|
4625
|
-
console.log(
|
|
4729
|
+
console.log(chalk22.dim("\u2500".repeat(40)));
|
|
4626
4730
|
} catch {
|
|
4627
|
-
console.log(
|
|
4731
|
+
console.log(chalk22.dim("(State file not found)"));
|
|
4628
4732
|
}
|
|
4629
4733
|
try {
|
|
4630
|
-
const pidPath =
|
|
4631
|
-
const pid = await
|
|
4632
|
-
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()}`));
|
|
4633
4737
|
} catch {
|
|
4634
4738
|
}
|
|
4635
4739
|
console.log("");
|
|
@@ -4640,7 +4744,7 @@ init_esm_shims();
|
|
|
4640
4744
|
init_config();
|
|
4641
4745
|
init_suggest();
|
|
4642
4746
|
import { Command as Command13 } from "commander";
|
|
4643
|
-
import
|
|
4747
|
+
import chalk24 from "chalk";
|
|
4644
4748
|
import ora10 from "ora";
|
|
4645
4749
|
import axios17 from "axios";
|
|
4646
4750
|
import inquirer3 from "inquirer";
|
|
@@ -4649,11 +4753,11 @@ import inquirer3 from "inquirer";
|
|
|
4649
4753
|
init_esm_shims();
|
|
4650
4754
|
init_config();
|
|
4651
4755
|
import { Command as Command12 } from "commander";
|
|
4652
|
-
import
|
|
4756
|
+
import chalk23 from "chalk";
|
|
4653
4757
|
import ora9 from "ora";
|
|
4654
4758
|
import axios16 from "axios";
|
|
4655
|
-
import
|
|
4656
|
-
import
|
|
4759
|
+
import fs22 from "fs/promises";
|
|
4760
|
+
import path25 from "path";
|
|
4657
4761
|
import inquirer2 from "inquirer";
|
|
4658
4762
|
function createPlanCommand() {
|
|
4659
4763
|
const plan = new Command12("plan");
|
|
@@ -4711,7 +4815,7 @@ async function executePlan(taskId) {
|
|
|
4711
4815
|
taskDescription = task.description;
|
|
4712
4816
|
}
|
|
4713
4817
|
spinner.start("Generating Context for Frank...");
|
|
4714
|
-
const contextPath =
|
|
4818
|
+
const contextPath = path25.join(process.cwd(), ".rigstate", "CURRENT_CONTEXT.md");
|
|
4715
4819
|
const contextContent = `
|
|
4716
4820
|
# \u{1F3AF} Active Mission: ${taskTitle}
|
|
4717
4821
|
**ID:** ${taskId}
|
|
@@ -4726,10 +4830,10 @@ ${taskDescription}
|
|
|
4726
4830
|
|
|
4727
4831
|
*Generated by Rigstate CLI at ${(/* @__PURE__ */ new Date()).toLocaleString()}*
|
|
4728
4832
|
`;
|
|
4729
|
-
await
|
|
4730
|
-
await
|
|
4731
|
-
const planPath =
|
|
4732
|
-
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);
|
|
4733
4837
|
if (!planExists) {
|
|
4734
4838
|
const planTemplate = `
|
|
4735
4839
|
# \u{1F4CB} Implementation Plan: ${taskTitle}
|
|
@@ -4748,23 +4852,38 @@ ${taskDescription}
|
|
|
4748
4852
|
## 4. \u{1F680} Execution
|
|
4749
4853
|
[Frank: Log your progress here]
|
|
4750
4854
|
`;
|
|
4751
|
-
await
|
|
4752
|
-
spinner.succeed(
|
|
4855
|
+
await fs22.writeFile(planPath, planTemplate.trim());
|
|
4856
|
+
spinner.succeed(chalk23.green("Created new IMPLEMENTATION_PLAN.md"));
|
|
4753
4857
|
} else {
|
|
4754
|
-
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)."));
|
|
4755
4874
|
}
|
|
4756
4875
|
console.log("");
|
|
4757
|
-
console.log(
|
|
4758
|
-
console.log(
|
|
4759
|
-
console.log(`1. Context loaded into: ${
|
|
4760
|
-
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")}`);
|
|
4761
4880
|
console.log("");
|
|
4762
|
-
console.log(
|
|
4763
|
-
console.log(
|
|
4764
|
-
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."));
|
|
4765
4884
|
console.log("");
|
|
4766
4885
|
} catch (e) {
|
|
4767
|
-
spinner.fail(
|
|
4886
|
+
spinner.fail(chalk23.red(`Planning failed: ${e.message}`));
|
|
4768
4887
|
}
|
|
4769
4888
|
}
|
|
4770
4889
|
function getContext() {
|
|
@@ -4809,7 +4928,7 @@ async function listInteractive() {
|
|
|
4809
4928
|
});
|
|
4810
4929
|
spinner.stop();
|
|
4811
4930
|
if (actionableTasks.length === 0) {
|
|
4812
|
-
console.log(
|
|
4931
|
+
console.log(chalk24.yellow("Roadmap clear. No actionable tasks found."));
|
|
4813
4932
|
return;
|
|
4814
4933
|
}
|
|
4815
4934
|
const choices = actionableTasks.map((t) => {
|
|
@@ -4818,7 +4937,7 @@ async function listInteractive() {
|
|
|
4818
4937
|
if (t.status === "IN_PROGRESS") icon = "\u{1F525}";
|
|
4819
4938
|
if (t.status === "ACTIVE") icon = "\u25B6\uFE0F";
|
|
4820
4939
|
return {
|
|
4821
|
-
name: `${icon} ${
|
|
4940
|
+
name: `${icon} ${chalk24.bold(id)}: ${t.title} [${t.status}]`,
|
|
4822
4941
|
value: t.id
|
|
4823
4942
|
};
|
|
4824
4943
|
});
|
|
@@ -4865,25 +4984,25 @@ async function setTaskStatus(taskId, status) {
|
|
|
4865
4984
|
{ step_id: realId, status, project_id: projectId },
|
|
4866
4985
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
4867
4986
|
);
|
|
4868
|
-
spinner.succeed(
|
|
4987
|
+
spinner.succeed(chalk24.green(`Task updated to ${status}.`));
|
|
4869
4988
|
if (status === "IN_PROGRESS") {
|
|
4870
|
-
console.log(
|
|
4989
|
+
console.log(chalk24.blue(`
|
|
4871
4990
|
\u{1F4A1} Tip: Provide 'Frank' with context by mentioning @.cursorrules in your chat.`));
|
|
4872
4991
|
}
|
|
4873
4992
|
} catch (e) {
|
|
4874
|
-
spinner.fail(
|
|
4993
|
+
spinner.fail(chalk24.red(`Failed: ${e.message}`));
|
|
4875
4994
|
}
|
|
4876
4995
|
}
|
|
4877
4996
|
async function finishTask(taskId) {
|
|
4878
4997
|
console.log("");
|
|
4879
|
-
console.log(
|
|
4880
|
-
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"));
|
|
4881
5000
|
const auditSpinner = ora10(" Analyzing architectural integrity...").start();
|
|
4882
5001
|
await new Promise((r) => setTimeout(r, 1500));
|
|
4883
5002
|
auditSpinner.succeed("Architecture: VALIDATED (SEC-ARCH-01 Pass)");
|
|
4884
5003
|
await setTaskStatus(taskId, "COMPLETED");
|
|
4885
5004
|
console.log("");
|
|
4886
|
-
console.log(
|
|
5005
|
+
console.log(chalk24.bold.green("\u{1F389} TASK COMPLETE! Momentum Preserved."));
|
|
4887
5006
|
const { projectId, apiKey, apiUrl } = getContext2();
|
|
4888
5007
|
await suggestNextMove(projectId, apiKey, apiUrl);
|
|
4889
5008
|
}
|
|
@@ -4901,39 +5020,35 @@ function getContext2() {
|
|
|
4901
5020
|
init_esm_shims();
|
|
4902
5021
|
init_config();
|
|
4903
5022
|
import { Command as Command14 } from "commander";
|
|
4904
|
-
import
|
|
5023
|
+
import chalk25 from "chalk";
|
|
4905
5024
|
import ora11 from "ora";
|
|
4906
5025
|
import chokidar3 from "chokidar";
|
|
4907
|
-
import
|
|
4908
|
-
import
|
|
5026
|
+
import fs23 from "fs/promises";
|
|
5027
|
+
import path26 from "path";
|
|
4909
5028
|
import { execSync as execSync4 } from "child_process";
|
|
4910
5029
|
import axios18 from "axios";
|
|
4911
5030
|
function createWatchCommand() {
|
|
4912
5031
|
const watch2 = new Command14("watch");
|
|
4913
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) => {
|
|
4914
|
-
console.log(
|
|
4915
|
-
console.log(
|
|
5033
|
+
console.log(chalk25.bold.blue("\u{1F52D} Rigstate Watch Mode"));
|
|
5034
|
+
console.log(chalk25.dim("Monitoring for task completion..."));
|
|
4916
5035
|
console.log("");
|
|
4917
5036
|
let apiKey;
|
|
4918
5037
|
let projectId;
|
|
4919
5038
|
try {
|
|
4920
5039
|
apiKey = getApiKey();
|
|
4921
5040
|
} catch (e) {
|
|
4922
|
-
console.log(
|
|
5041
|
+
console.log(chalk25.red('Not authenticated. Run "rigstate login" first.'));
|
|
4923
5042
|
return;
|
|
4924
5043
|
}
|
|
4925
5044
|
projectId = getProjectId();
|
|
4926
5045
|
if (!projectId) {
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
const manifest = JSON.parse(content);
|
|
4931
|
-
projectId = manifest.project_id;
|
|
4932
|
-
} catch (e) {
|
|
4933
|
-
}
|
|
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;
|
|
4934
5049
|
}
|
|
4935
5050
|
if (!projectId) {
|
|
4936
|
-
console.log(
|
|
5051
|
+
console.log(chalk25.red('No project context. Run "rigstate link" or "rigstate sync --project <id>" first.'));
|
|
4937
5052
|
return;
|
|
4938
5053
|
}
|
|
4939
5054
|
const apiUrl = getApiUrl();
|
|
@@ -4943,8 +5058,8 @@ function createWatchCommand() {
|
|
|
4943
5058
|
runTests: options.runTests || false,
|
|
4944
5059
|
testCommand: options.testCommand || "npm test"
|
|
4945
5060
|
};
|
|
4946
|
-
console.log(
|
|
4947
|
-
console.log(
|
|
5061
|
+
console.log(chalk25.dim(`Auto-commit: ${config2.autoCommit ? "ON" : "OFF"}`));
|
|
5062
|
+
console.log(chalk25.dim(`Auto-push: ${config2.autoPush ? "ON" : "OFF"}`));
|
|
4948
5063
|
console.log("");
|
|
4949
5064
|
const fetchActiveTask = async () => {
|
|
4950
5065
|
try {
|
|
@@ -4972,17 +5087,17 @@ function createWatchCommand() {
|
|
|
4972
5087
|
};
|
|
4973
5088
|
const checkCriteria = async (criteria) => {
|
|
4974
5089
|
try {
|
|
4975
|
-
const fullPath =
|
|
5090
|
+
const fullPath = path26.resolve(process.cwd(), criteria.path);
|
|
4976
5091
|
switch (criteria.type) {
|
|
4977
5092
|
case "file_exists":
|
|
4978
|
-
await
|
|
5093
|
+
await fs23.access(fullPath);
|
|
4979
5094
|
return true;
|
|
4980
5095
|
case "file_content":
|
|
4981
|
-
const content = await
|
|
5096
|
+
const content = await fs23.readFile(fullPath, "utf-8");
|
|
4982
5097
|
return content.length > 0;
|
|
4983
5098
|
case "content_match":
|
|
4984
5099
|
if (!criteria.match) return false;
|
|
4985
|
-
const fileContent = await
|
|
5100
|
+
const fileContent = await fs23.readFile(fullPath, "utf-8");
|
|
4986
5101
|
return fileContent.includes(criteria.match);
|
|
4987
5102
|
default:
|
|
4988
5103
|
return false;
|
|
@@ -5011,7 +5126,7 @@ function createWatchCommand() {
|
|
|
5011
5126
|
}, {
|
|
5012
5127
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
5013
5128
|
});
|
|
5014
|
-
spinner.succeed(
|
|
5129
|
+
spinner.succeed(chalk25.green(`\u2705 Task #${task.step_number} completed: ${task.title}`));
|
|
5015
5130
|
if (config2.autoCommit) {
|
|
5016
5131
|
spinner.start("Committing changes...");
|
|
5017
5132
|
try {
|
|
@@ -5033,7 +5148,7 @@ function createWatchCommand() {
|
|
|
5033
5148
|
}
|
|
5034
5149
|
}
|
|
5035
5150
|
console.log("");
|
|
5036
|
-
console.log(
|
|
5151
|
+
console.log(chalk25.blue("Watching for next task..."));
|
|
5037
5152
|
} catch (e) {
|
|
5038
5153
|
spinner.fail(`Failed to complete task: ${e.message}`);
|
|
5039
5154
|
}
|
|
@@ -5046,7 +5161,7 @@ function createWatchCommand() {
|
|
|
5046
5161
|
const task = await fetchActiveTask();
|
|
5047
5162
|
if (!task) {
|
|
5048
5163
|
if (currentTask) {
|
|
5049
|
-
console.log(
|
|
5164
|
+
console.log(chalk25.green("\u{1F389} All tasks completed! Watching for new tasks..."));
|
|
5050
5165
|
currentTask = null;
|
|
5051
5166
|
}
|
|
5052
5167
|
isProcessing = false;
|
|
@@ -5055,10 +5170,10 @@ function createWatchCommand() {
|
|
|
5055
5170
|
if (!currentTask || currentTask.id !== task.id) {
|
|
5056
5171
|
currentTask = task;
|
|
5057
5172
|
console.log("");
|
|
5058
|
-
console.log(
|
|
5059
|
-
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}`));
|
|
5060
5175
|
if (task.verification_criteria) {
|
|
5061
|
-
console.log(
|
|
5176
|
+
console.log(chalk25.dim("Verification: Auto-checking criteria..."));
|
|
5062
5177
|
}
|
|
5063
5178
|
}
|
|
5064
5179
|
if (task.verification_criteria && Array.isArray(task.verification_criteria)) {
|
|
@@ -5071,7 +5186,7 @@ function createWatchCommand() {
|
|
|
5071
5186
|
}
|
|
5072
5187
|
}
|
|
5073
5188
|
if (allPassed) {
|
|
5074
|
-
console.log(
|
|
5189
|
+
console.log(chalk25.green("\u2713 All verification criteria passed!"));
|
|
5075
5190
|
await completeTask(task.id, task);
|
|
5076
5191
|
currentTask = null;
|
|
5077
5192
|
}
|
|
@@ -5096,11 +5211,11 @@ function createWatchCommand() {
|
|
|
5096
5211
|
setTimeout(() => processActiveTask(), 500);
|
|
5097
5212
|
}
|
|
5098
5213
|
});
|
|
5099
|
-
console.log(
|
|
5214
|
+
console.log(chalk25.dim("Watching for file changes... (Ctrl+C to exit)"));
|
|
5100
5215
|
setInterval(() => processActiveTask(), 3e4);
|
|
5101
5216
|
process.on("SIGINT", () => {
|
|
5102
5217
|
console.log("");
|
|
5103
|
-
console.log(
|
|
5218
|
+
console.log(chalk25.dim("Watch mode stopped."));
|
|
5104
5219
|
watcher.close();
|
|
5105
5220
|
process.exit(0);
|
|
5106
5221
|
});
|
|
@@ -5112,12 +5227,10 @@ function createWatchCommand() {
|
|
|
5112
5227
|
init_esm_shims();
|
|
5113
5228
|
init_config();
|
|
5114
5229
|
import { Command as Command15 } from "commander";
|
|
5115
|
-
import
|
|
5230
|
+
import chalk26 from "chalk";
|
|
5116
5231
|
import ora12 from "ora";
|
|
5117
5232
|
import axios19 from "axios";
|
|
5118
5233
|
import { execSync as execSync5 } from "child_process";
|
|
5119
|
-
import fs23 from "fs/promises";
|
|
5120
|
-
import path26 from "path";
|
|
5121
5234
|
function createFocusCommand() {
|
|
5122
5235
|
const focus = new Command15("focus");
|
|
5123
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) => {
|
|
@@ -5127,21 +5240,17 @@ function createFocusCommand() {
|
|
|
5127
5240
|
try {
|
|
5128
5241
|
apiKey = getApiKey();
|
|
5129
5242
|
} catch (e) {
|
|
5130
|
-
spinner.fail(
|
|
5243
|
+
spinner.fail(chalk26.red('Not authenticated. Run "rigstate login" first.'));
|
|
5131
5244
|
return;
|
|
5132
5245
|
}
|
|
5133
5246
|
projectId = getProjectId();
|
|
5134
5247
|
if (!projectId) {
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
const manifest = JSON.parse(content);
|
|
5139
|
-
projectId = manifest.project_id;
|
|
5140
|
-
} catch (e) {
|
|
5141
|
-
}
|
|
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;
|
|
5142
5251
|
}
|
|
5143
5252
|
if (!projectId) {
|
|
5144
|
-
spinner.fail(
|
|
5253
|
+
spinner.fail(chalk26.red('No project context. Run "rigstate link" first.'));
|
|
5145
5254
|
return;
|
|
5146
5255
|
}
|
|
5147
5256
|
const apiUrl = getApiUrl();
|
|
@@ -5172,41 +5281,41 @@ function createFocusCommand() {
|
|
|
5172
5281
|
const nextTask = activeTasks[0];
|
|
5173
5282
|
spinner.stop();
|
|
5174
5283
|
console.log("");
|
|
5175
|
-
console.log(
|
|
5176
|
-
const statusColor = nextTask.status === "IN_PROGRESS" ?
|
|
5177
|
-
console.log(
|
|
5178
|
-
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)));
|
|
5179
5288
|
if (nextTask.prompt_content) {
|
|
5180
|
-
console.log(
|
|
5181
|
-
console.log(
|
|
5289
|
+
console.log(chalk26.white(nextTask.prompt_content));
|
|
5290
|
+
console.log(chalk26.dim("\u2500".repeat(60)));
|
|
5182
5291
|
if (options.copy !== false) {
|
|
5183
5292
|
try {
|
|
5184
5293
|
if (process.platform === "darwin") {
|
|
5185
5294
|
execSync5("pbcopy", { input: nextTask.prompt_content });
|
|
5186
|
-
console.log(
|
|
5295
|
+
console.log(chalk26.green("\u2705 Prompt copied to clipboard! Ready to paste (Cmd+V)."));
|
|
5187
5296
|
} else if (process.platform === "linux") {
|
|
5188
5297
|
try {
|
|
5189
5298
|
execSync5("xclip -selection clipboard", { input: nextTask.prompt_content });
|
|
5190
|
-
console.log(
|
|
5299
|
+
console.log(chalk26.green("\u2705 Prompt copied to clipboard!"));
|
|
5191
5300
|
} catch (e) {
|
|
5192
|
-
console.log(
|
|
5301
|
+
console.log(chalk26.yellow("\u2139\uFE0F Copy prompt manually (xclip not available)"));
|
|
5193
5302
|
}
|
|
5194
5303
|
} else {
|
|
5195
|
-
console.log(
|
|
5304
|
+
console.log(chalk26.yellow("\u2139\uFE0F Copy prompt manually (Auto-copy not supported on this OS)"));
|
|
5196
5305
|
}
|
|
5197
5306
|
} catch (e) {
|
|
5198
5307
|
}
|
|
5199
5308
|
}
|
|
5200
5309
|
} else {
|
|
5201
|
-
console.log(
|
|
5310
|
+
console.log(chalk26.yellow("No prompt instructions available."));
|
|
5202
5311
|
if (nextTask.architectural_brief) {
|
|
5203
|
-
console.log(
|
|
5312
|
+
console.log(chalk26.bold("Brief:"));
|
|
5204
5313
|
console.log(nextTask.architectural_brief);
|
|
5205
5314
|
}
|
|
5206
5315
|
}
|
|
5207
5316
|
console.log("");
|
|
5208
5317
|
} catch (e) {
|
|
5209
|
-
spinner.fail(
|
|
5318
|
+
spinner.fail(chalk26.red(`Failed to fetch task: ${e.message}`));
|
|
5210
5319
|
}
|
|
5211
5320
|
});
|
|
5212
5321
|
return focus;
|
|
@@ -5219,25 +5328,25 @@ init_env();
|
|
|
5219
5328
|
init_esm_shims();
|
|
5220
5329
|
init_config();
|
|
5221
5330
|
import { Command as Command16 } from "commander";
|
|
5222
|
-
import
|
|
5331
|
+
import chalk27 from "chalk";
|
|
5223
5332
|
function createConfigCommand() {
|
|
5224
5333
|
const config2 = new Command16("config");
|
|
5225
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) => {
|
|
5226
5335
|
if (!key) {
|
|
5227
|
-
console.log(
|
|
5228
|
-
console.log(
|
|
5336
|
+
console.log(chalk27.bold("Rigstate Configuration"));
|
|
5337
|
+
console.log(chalk27.dim("\u2500".repeat(40)));
|
|
5229
5338
|
try {
|
|
5230
5339
|
const apiKey = getApiKey();
|
|
5231
|
-
console.log(`${
|
|
5340
|
+
console.log(`${chalk27.cyan("api_key")}: ${apiKey.substring(0, 20)}...`);
|
|
5232
5341
|
} catch (e) {
|
|
5233
|
-
console.log(`${
|
|
5342
|
+
console.log(`${chalk27.cyan("api_key")}: ${chalk27.dim("(not set)")}`);
|
|
5234
5343
|
}
|
|
5235
5344
|
const projectId = getProjectId();
|
|
5236
|
-
console.log(`${
|
|
5345
|
+
console.log(`${chalk27.cyan("project_id")}: ${projectId || chalk27.dim("(not set)")}`);
|
|
5237
5346
|
const apiUrl = getApiUrl();
|
|
5238
|
-
console.log(`${
|
|
5347
|
+
console.log(`${chalk27.cyan("api_url")}: ${apiUrl}`);
|
|
5239
5348
|
console.log("");
|
|
5240
|
-
console.log(
|
|
5349
|
+
console.log(chalk27.dim('Use "rigstate config <key> <value>" to set a value.'));
|
|
5241
5350
|
return;
|
|
5242
5351
|
}
|
|
5243
5352
|
if (!value) {
|
|
@@ -5247,37 +5356,37 @@ function createConfigCommand() {
|
|
|
5247
5356
|
const apiKey = getApiKey();
|
|
5248
5357
|
console.log(apiKey);
|
|
5249
5358
|
} catch (e) {
|
|
5250
|
-
console.log(
|
|
5359
|
+
console.log(chalk27.dim("(not set)"));
|
|
5251
5360
|
}
|
|
5252
5361
|
break;
|
|
5253
5362
|
case "project_id":
|
|
5254
|
-
console.log(getProjectId() ||
|
|
5363
|
+
console.log(getProjectId() || chalk27.dim("(not set)"));
|
|
5255
5364
|
break;
|
|
5256
5365
|
case "api_url":
|
|
5257
5366
|
console.log(getApiUrl());
|
|
5258
5367
|
break;
|
|
5259
5368
|
default:
|
|
5260
|
-
console.log(
|
|
5261
|
-
console.log(
|
|
5369
|
+
console.log(chalk27.red(`Unknown config key: ${key}`));
|
|
5370
|
+
console.log(chalk27.dim("Valid keys: api_key, project_id, api_url"));
|
|
5262
5371
|
}
|
|
5263
5372
|
return;
|
|
5264
5373
|
}
|
|
5265
5374
|
switch (key) {
|
|
5266
5375
|
case "api_key":
|
|
5267
5376
|
setApiKey(value);
|
|
5268
|
-
console.log(
|
|
5377
|
+
console.log(chalk27.green(`\u2705 api_key updated`));
|
|
5269
5378
|
break;
|
|
5270
5379
|
case "project_id":
|
|
5271
5380
|
setProjectId(value);
|
|
5272
|
-
console.log(
|
|
5381
|
+
console.log(chalk27.green(`\u2705 project_id updated`));
|
|
5273
5382
|
break;
|
|
5274
5383
|
case "api_url":
|
|
5275
5384
|
setApiUrl(value);
|
|
5276
|
-
console.log(
|
|
5385
|
+
console.log(chalk27.green(`\u2705 api_url updated`));
|
|
5277
5386
|
break;
|
|
5278
5387
|
default:
|
|
5279
|
-
console.log(
|
|
5280
|
-
console.log(
|
|
5388
|
+
console.log(chalk27.red(`Unknown config key: ${key}`));
|
|
5389
|
+
console.log(chalk27.dim("Valid keys: api_key, project_id, api_url"));
|
|
5281
5390
|
}
|
|
5282
5391
|
});
|
|
5283
5392
|
return config2;
|
|
@@ -5287,7 +5396,7 @@ function createConfigCommand() {
|
|
|
5287
5396
|
init_esm_shims();
|
|
5288
5397
|
init_config();
|
|
5289
5398
|
import { Command as Command17 } from "commander";
|
|
5290
|
-
import
|
|
5399
|
+
import chalk28 from "chalk";
|
|
5291
5400
|
import { spawn } from "child_process";
|
|
5292
5401
|
import path27 from "path";
|
|
5293
5402
|
import fs24 from "fs";
|
|
@@ -5313,15 +5422,15 @@ function createMcpCommand() {
|
|
|
5313
5422
|
}
|
|
5314
5423
|
}
|
|
5315
5424
|
if (!serverPath) {
|
|
5316
|
-
console.error(
|
|
5317
|
-
console.error(
|
|
5318
|
-
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"));
|
|
5319
5428
|
console.error("");
|
|
5320
|
-
console.error(
|
|
5321
|
-
console.error(
|
|
5429
|
+
console.error(chalk28.dim("Or run directly with:"));
|
|
5430
|
+
console.error(chalk28.white(" npx @rigstate/mcp"));
|
|
5322
5431
|
process.exit(1);
|
|
5323
5432
|
}
|
|
5324
|
-
console.log(
|
|
5433
|
+
console.log(chalk28.dim(`Starting MCP server from: ${serverPath}`));
|
|
5325
5434
|
const env = { ...process.env };
|
|
5326
5435
|
try {
|
|
5327
5436
|
const apiKey = getApiKey();
|
|
@@ -5340,7 +5449,7 @@ function createMcpCommand() {
|
|
|
5340
5449
|
stdio: ["inherit", "inherit", "inherit"]
|
|
5341
5450
|
});
|
|
5342
5451
|
worker.on("error", (err) => {
|
|
5343
|
-
console.error(
|
|
5452
|
+
console.error(chalk28.red(`\u274C Failed to start MCP server: ${err.message}`));
|
|
5344
5453
|
process.exit(1);
|
|
5345
5454
|
});
|
|
5346
5455
|
worker.on("exit", (code) => {
|
|
@@ -5355,7 +5464,7 @@ function createMcpCommand() {
|
|
|
5355
5464
|
// src/commands/nexus.ts
|
|
5356
5465
|
init_esm_shims();
|
|
5357
5466
|
import { Command as Command18 } from "commander";
|
|
5358
|
-
import
|
|
5467
|
+
import chalk30 from "chalk";
|
|
5359
5468
|
|
|
5360
5469
|
// src/nexus/dispatcher.ts
|
|
5361
5470
|
init_esm_shims();
|
|
@@ -5423,7 +5532,7 @@ var HiveScrubber = class {
|
|
|
5423
5532
|
};
|
|
5424
5533
|
|
|
5425
5534
|
// src/hive/gateway.ts
|
|
5426
|
-
import
|
|
5535
|
+
import chalk29 from "chalk";
|
|
5427
5536
|
var HiveGateway = class {
|
|
5428
5537
|
client;
|
|
5429
5538
|
enabled;
|
|
@@ -5433,7 +5542,7 @@ var HiveGateway = class {
|
|
|
5433
5542
|
constructor(baseUrl, token) {
|
|
5434
5543
|
this.enabled = !!token;
|
|
5435
5544
|
if (!this.enabled) {
|
|
5436
|
-
console.log(
|
|
5545
|
+
console.log(chalk29.dim("\u26A0\uFE0F Hive Gateway disabled (No Token provided). Running in localized mode."));
|
|
5437
5546
|
}
|
|
5438
5547
|
this.client = axios20.create({
|
|
5439
5548
|
baseURL: baseUrl,
|
|
@@ -5453,23 +5562,23 @@ var HiveGateway = class {
|
|
|
5453
5562
|
if (!this.enabled) return false;
|
|
5454
5563
|
const now = Date.now();
|
|
5455
5564
|
if (now - this.lastSignalTime < this.MIN_INTERVAL_MS) {
|
|
5456
|
-
console.warn(
|
|
5565
|
+
console.warn(chalk29.yellow("\u23F3 Hive Gateway Throttled. Signal dropped to preventing spam."));
|
|
5457
5566
|
return false;
|
|
5458
5567
|
}
|
|
5459
5568
|
const scrubResult = HiveScrubber.scrub(signal.ruleContent);
|
|
5460
5569
|
if (scrubResult.riskScore > 20) {
|
|
5461
|
-
console.error(
|
|
5570
|
+
console.error(chalk29.red(`\u{1F6D1} HIVE BLOCKED: Signal contains sensitive data (Risk: ${scrubResult.riskScore})`));
|
|
5462
5571
|
return false;
|
|
5463
5572
|
}
|
|
5464
5573
|
try {
|
|
5465
|
-
console.log(
|
|
5574
|
+
console.log(chalk29.blue(`\u{1F4E1} Uplinking to Hive... [${signal.vector}]`));
|
|
5466
5575
|
const payload = { ...signal, ruleContent: scrubResult.sanitizedContent };
|
|
5467
5576
|
await this.client.post("/signal", payload);
|
|
5468
5577
|
this.lastSignalTime = now;
|
|
5469
|
-
console.log(
|
|
5578
|
+
console.log(chalk29.green("\u2705 Signal Received by Hive Core. Knowledge Shared."));
|
|
5470
5579
|
return true;
|
|
5471
5580
|
} catch (error) {
|
|
5472
|
-
console.error(
|
|
5581
|
+
console.error(chalk29.red(`\u274C Hive Transmission Failed: ${error.message}`));
|
|
5473
5582
|
return false;
|
|
5474
5583
|
}
|
|
5475
5584
|
}
|
|
@@ -5571,10 +5680,10 @@ import inquirer4 from "inquirer";
|
|
|
5571
5680
|
function createNexusCommand() {
|
|
5572
5681
|
const command = new Command18("nexus");
|
|
5573
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) => {
|
|
5574
|
-
console.log(
|
|
5683
|
+
console.log(chalk30.bold.magenta("\n\u{1F981} Welcome to The Nexus (Phase 8)\n"));
|
|
5575
5684
|
const dryRun = !options.force;
|
|
5576
5685
|
if (!dryRun) {
|
|
5577
|
-
console.log(
|
|
5686
|
+
console.log(chalk30.black.bgYellow(" WARNING ") + chalk30.yellow(" Dry-Run disabled! Eitri is authorized to write code."));
|
|
5578
5687
|
const { confirm } = await inquirer4.prompt([{
|
|
5579
5688
|
type: "confirm",
|
|
5580
5689
|
name: "confirm",
|
|
@@ -5595,26 +5704,26 @@ function createNexusCommand() {
|
|
|
5595
5704
|
};
|
|
5596
5705
|
const dispatcher = new NexusDispatcher(context);
|
|
5597
5706
|
dispatcher.on("order:created", (o) => {
|
|
5598
|
-
console.log(
|
|
5707
|
+
console.log(chalk30.blue(`\u{1F195} [${o.id.slice(0, 6)}] Order Created: `) + o.intent);
|
|
5599
5708
|
});
|
|
5600
5709
|
dispatcher.on("order:started", (o) => {
|
|
5601
|
-
console.log(
|
|
5710
|
+
console.log(chalk30.yellow(`\u23F3 [${o.id.slice(0, 6)}] Processing...`));
|
|
5602
5711
|
});
|
|
5603
5712
|
dispatcher.on("order:blocked", (o) => {
|
|
5604
|
-
console.log(
|
|
5605
|
-
console.log(
|
|
5606
|
-
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)."));
|
|
5607
5716
|
});
|
|
5608
|
-
dispatcher.on("agent:SINDRE", (o) => console.log(
|
|
5609
|
-
dispatcher.on("agent:EITRI", (o) => console.log(
|
|
5610
|
-
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..."));
|
|
5611
5720
|
await new Promise((r) => setTimeout(r, 800));
|
|
5612
5721
|
if (intent.toLowerCase().includes("db") || intent.toLowerCase().includes("database")) {
|
|
5613
5722
|
await dispatcher.dispatch("FRANK", "SINDRE", intent, "db.analyze", { raw: intent });
|
|
5614
5723
|
} else if (intent.toLowerCase().includes("create") || intent.toLowerCase().includes("code")) {
|
|
5615
5724
|
await dispatcher.dispatch("FRANK", "EITRI", intent, "fs.write", { path: "src/demo.ts", content: "// demo" });
|
|
5616
5725
|
} else {
|
|
5617
|
-
console.log(
|
|
5726
|
+
console.log(chalk30.gray("Frank didn't understand. Try 'create file' or 'check database'."));
|
|
5618
5727
|
}
|
|
5619
5728
|
});
|
|
5620
5729
|
return command;
|
|
@@ -5628,25 +5737,25 @@ init_esm_shims();
|
|
|
5628
5737
|
init_governance();
|
|
5629
5738
|
init_config();
|
|
5630
5739
|
import { Command as Command19 } from "commander";
|
|
5631
|
-
import
|
|
5740
|
+
import chalk31 from "chalk";
|
|
5632
5741
|
import axios21 from "axios";
|
|
5633
5742
|
function createOverrideCommand() {
|
|
5634
5743
|
const override = new Command19("override");
|
|
5635
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) => {
|
|
5636
5745
|
const { reason } = options;
|
|
5637
|
-
console.log(
|
|
5746
|
+
console.log(chalk31.bold(`
|
|
5638
5747
|
\u{1F513} Initiating Governance Override Protocol...`));
|
|
5639
5748
|
const session = await getSessionState(process.cwd());
|
|
5640
5749
|
if (session.status !== "SOFT_LOCK") {
|
|
5641
|
-
console.log(
|
|
5750
|
+
console.log(chalk31.yellow(" Info: Session is not currently locked."));
|
|
5642
5751
|
return;
|
|
5643
5752
|
}
|
|
5644
|
-
console.log(
|
|
5645
|
-
console.log(
|
|
5753
|
+
console.log(chalk31.dim(` Active Violation: ${session.active_violation}`));
|
|
5754
|
+
console.log(chalk31.dim(` Reason Provided: "${reason}"`));
|
|
5646
5755
|
const success = await performOverride(violationId, reason, process.cwd());
|
|
5647
5756
|
if (success) {
|
|
5648
|
-
console.log(
|
|
5649
|
-
console.log(
|
|
5757
|
+
console.log(chalk31.green(` \u2705 Session UNLOCKED.`));
|
|
5758
|
+
console.log(chalk31.dim(` This event has been logged to the Mission Report.`));
|
|
5650
5759
|
try {
|
|
5651
5760
|
const projectId = getProjectId();
|
|
5652
5761
|
if (projectId) {
|
|
@@ -5663,13 +5772,13 @@ function createOverrideCommand() {
|
|
|
5663
5772
|
}, {
|
|
5664
5773
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
5665
5774
|
});
|
|
5666
|
-
console.log(
|
|
5775
|
+
console.log(chalk31.dim(` \u2601 Audit log synced to Cloud.`));
|
|
5667
5776
|
}
|
|
5668
5777
|
} catch (e) {
|
|
5669
|
-
console.log(
|
|
5778
|
+
console.log(chalk31.dim(` (Cloud audit sync failed: ${e.message})`));
|
|
5670
5779
|
}
|
|
5671
5780
|
} else {
|
|
5672
|
-
console.log(
|
|
5781
|
+
console.log(chalk31.red(` \u{1F6D1} Override Failed. Check project configuration.`));
|
|
5673
5782
|
}
|
|
5674
5783
|
});
|
|
5675
5784
|
return override;
|
|
@@ -5679,7 +5788,7 @@ function createOverrideCommand() {
|
|
|
5679
5788
|
init_esm_shims();
|
|
5680
5789
|
init_config();
|
|
5681
5790
|
import { Command as Command20 } from "commander";
|
|
5682
|
-
import
|
|
5791
|
+
import chalk32 from "chalk";
|
|
5683
5792
|
import ora13 from "ora";
|
|
5684
5793
|
import axios22 from "axios";
|
|
5685
5794
|
import inquirer5 from "inquirer";
|
|
@@ -5690,7 +5799,7 @@ function createIdeaCommand() {
|
|
|
5690
5799
|
const apiUrl = getApiUrl();
|
|
5691
5800
|
const projectId = getProjectId();
|
|
5692
5801
|
if (!projectId) {
|
|
5693
|
-
console.error(
|
|
5802
|
+
console.error(chalk32.red("Project context missing. Run rigstate link."));
|
|
5694
5803
|
process.exit(1);
|
|
5695
5804
|
}
|
|
5696
5805
|
let ideaTitle = title;
|
|
@@ -5726,14 +5835,14 @@ function createIdeaCommand() {
|
|
|
5726
5835
|
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
5727
5836
|
);
|
|
5728
5837
|
if (response.data.success) {
|
|
5729
|
-
spinner.succeed(
|
|
5730
|
-
console.log(
|
|
5838
|
+
spinner.succeed(chalk32.green("Idea Captured! \u{1F4A1}"));
|
|
5839
|
+
console.log(chalk32.dim(`ID: ${response.data.data?.id || "Saved"}`));
|
|
5731
5840
|
} else {
|
|
5732
5841
|
throw new Error(response.data.error);
|
|
5733
5842
|
}
|
|
5734
5843
|
} catch (e) {
|
|
5735
5844
|
const errorDetail = e.response?.data?.error || e.message;
|
|
5736
|
-
console.error(
|
|
5845
|
+
console.error(chalk32.red(`
|
|
5737
5846
|
Failed to capture idea: ${errorDetail}`));
|
|
5738
5847
|
}
|
|
5739
5848
|
});
|
|
@@ -5743,7 +5852,7 @@ Failed to capture idea: ${errorDetail}`));
|
|
|
5743
5852
|
init_esm_shims();
|
|
5744
5853
|
init_config();
|
|
5745
5854
|
import { Command as Command21 } from "commander";
|
|
5746
|
-
import
|
|
5855
|
+
import chalk33 from "chalk";
|
|
5747
5856
|
import ora14 from "ora";
|
|
5748
5857
|
import inquirer6 from "inquirer";
|
|
5749
5858
|
import fs25 from "fs/promises";
|
|
@@ -8617,7 +8726,7 @@ function versionParser(stdOut) {
|
|
|
8617
8726
|
}
|
|
8618
8727
|
var NOT_INSTALLED;
|
|
8619
8728
|
var parsers7;
|
|
8620
|
-
var
|
|
8729
|
+
var init_version2 = __esm2({
|
|
8621
8730
|
"src/lib/tasks/version.ts"() {
|
|
8622
8731
|
"use strict";
|
|
8623
8732
|
init_utils();
|
|
@@ -8665,7 +8774,7 @@ var init_simple_git_api = __esm2({
|
|
|
8665
8774
|
init_show();
|
|
8666
8775
|
init_status();
|
|
8667
8776
|
init_task();
|
|
8668
|
-
|
|
8777
|
+
init_version2();
|
|
8669
8778
|
init_utils();
|
|
8670
8779
|
SimpleGitApi = class {
|
|
8671
8780
|
constructor(_executor) {
|
|
@@ -10319,7 +10428,7 @@ function createReleaseCommand() {
|
|
|
10319
10428
|
if (type === "major") newVersion = `${major + 1}.0.0`;
|
|
10320
10429
|
if (type === "minor") newVersion = `${major}.${minor + 1}.0`;
|
|
10321
10430
|
if (type === "patch") newVersion = `${major}.${minor}.${patch + 1}`;
|
|
10322
|
-
spinner.succeed(`Bumping ${pkg2.name} from ${
|
|
10431
|
+
spinner.succeed(`Bumping ${pkg2.name} from ${chalk33.dim(currentVersion)} to ${chalk33.green(newVersion)}`);
|
|
10323
10432
|
const { confirm } = await inquirer6.prompt([{
|
|
10324
10433
|
type: "confirm",
|
|
10325
10434
|
name: "confirm",
|
|
@@ -10349,7 +10458,7 @@ function createReleaseCommand() {
|
|
|
10349
10458
|
await git.addTag(`v${newVersion}`);
|
|
10350
10459
|
await git.push();
|
|
10351
10460
|
await git.pushTags();
|
|
10352
|
-
spinner.succeed(
|
|
10461
|
+
spinner.succeed(chalk33.bold.green(`\u{1F680} Release v${newVersion} shipped!`));
|
|
10353
10462
|
} catch (e) {
|
|
10354
10463
|
spinner.fail(e.message);
|
|
10355
10464
|
}
|
|
@@ -10367,7 +10476,7 @@ function getContext3() {
|
|
|
10367
10476
|
init_esm_shims();
|
|
10368
10477
|
init_config();
|
|
10369
10478
|
import { Command as Command22 } from "commander";
|
|
10370
|
-
import
|
|
10479
|
+
import chalk34 from "chalk";
|
|
10371
10480
|
import ora15 from "ora";
|
|
10372
10481
|
import axios23 from "axios";
|
|
10373
10482
|
function createRoadmapCommand() {
|
|
@@ -10378,7 +10487,7 @@ function createRoadmapCommand() {
|
|
|
10378
10487
|
const apiUrl = getApiUrl();
|
|
10379
10488
|
const projectId = getProjectId();
|
|
10380
10489
|
if (!projectId) {
|
|
10381
|
-
spinner.fail(
|
|
10490
|
+
spinner.fail(chalk34.red('Project context missing. Run "rigstate link".'));
|
|
10382
10491
|
return;
|
|
10383
10492
|
}
|
|
10384
10493
|
const response = await axios23.get(
|
|
@@ -10391,11 +10500,11 @@ function createRoadmapCommand() {
|
|
|
10391
10500
|
const tasks = response.data.data.roadmap || [];
|
|
10392
10501
|
spinner.stop();
|
|
10393
10502
|
if (tasks.length === 0) {
|
|
10394
|
-
console.log(
|
|
10503
|
+
console.log(chalk34.yellow("\nRoadmap is empty. Use the web UI to define your journey."));
|
|
10395
10504
|
return;
|
|
10396
10505
|
}
|
|
10397
|
-
console.log("\n" +
|
|
10398
|
-
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"));
|
|
10399
10508
|
const columns = {
|
|
10400
10509
|
"IN_PROGRESS": [],
|
|
10401
10510
|
"ACTIVE": [],
|
|
@@ -10407,14 +10516,14 @@ function createRoadmapCommand() {
|
|
|
10407
10516
|
columns[t.status].push(t);
|
|
10408
10517
|
}
|
|
10409
10518
|
});
|
|
10410
|
-
displayColumn("\u{1F525} IN PROGRESS", columns.IN_PROGRESS,
|
|
10411
|
-
displayColumn("\u25B6\uFE0F ACTIVE / NEXT", columns.ACTIVE,
|
|
10412
|
-
displayColumn("\u{1F512} LOCKED", columns.LOCKED,
|
|
10413
|
-
displayColumn("\u23F3 PENDING", columns.PENDING,
|
|
10414
|
-
console.log(
|
|
10415
|
-
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.`));
|
|
10416
10525
|
} catch (e) {
|
|
10417
|
-
spinner.fail(
|
|
10526
|
+
spinner.fail(chalk34.red(`
|
|
10418
10527
|
Failed to fetch roadmap: ${e.message}`));
|
|
10419
10528
|
}
|
|
10420
10529
|
});
|
|
@@ -10425,8 +10534,8 @@ function displayColumn(title, items, color) {
|
|
|
10425
10534
|
${color.bold(title)}`);
|
|
10426
10535
|
items.sort((a, b) => a.step_number - b.step_number).forEach((item) => {
|
|
10427
10536
|
const id = `T-${item.step_number}`.padEnd(8);
|
|
10428
|
-
const priority = item.priority === "MVP" ?
|
|
10429
|
-
console.log(` ${color("\u2022")} ${
|
|
10537
|
+
const priority = item.priority === "MVP" ? chalk34.magenta(" [MVP]") : "";
|
|
10538
|
+
console.log(` ${color("\u2022")} ${chalk34.bold(id)} ${item.title}${priority}`);
|
|
10430
10539
|
});
|
|
10431
10540
|
}
|
|
10432
10541
|
|
|
@@ -10434,7 +10543,7 @@ ${color.bold(title)}`);
|
|
|
10434
10543
|
init_esm_shims();
|
|
10435
10544
|
init_config();
|
|
10436
10545
|
import { Command as Command23 } from "commander";
|
|
10437
|
-
import
|
|
10546
|
+
import chalk35 from "chalk";
|
|
10438
10547
|
import ora16 from "ora";
|
|
10439
10548
|
import inquirer7 from "inquirer";
|
|
10440
10549
|
function createCouncilCommand() {
|
|
@@ -10445,7 +10554,7 @@ function createCouncilCommand() {
|
|
|
10445
10554
|
const apiUrl = getApiUrl();
|
|
10446
10555
|
const projectId = getProjectId();
|
|
10447
10556
|
if (!projectId) {
|
|
10448
|
-
console.error(
|
|
10557
|
+
console.error(chalk35.red('Project context missing. Run "rigstate link".'));
|
|
10449
10558
|
return;
|
|
10450
10559
|
}
|
|
10451
10560
|
let sessionTopic = topic;
|
|
@@ -10457,25 +10566,25 @@ function createCouncilCommand() {
|
|
|
10457
10566
|
}]);
|
|
10458
10567
|
sessionTopic = ans.topic;
|
|
10459
10568
|
}
|
|
10460
|
-
console.log(
|
|
10461
|
-
console.log(
|
|
10462
|
-
console.log(
|
|
10463
|
-
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..."));
|
|
10464
10573
|
await sleep(1500);
|
|
10465
|
-
console.log(
|
|
10466
|
-
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..."));
|
|
10467
10576
|
await sleep(1500);
|
|
10468
|
-
console.log(
|
|
10469
|
-
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..."));
|
|
10470
10579
|
await sleep(1500);
|
|
10471
|
-
console.log(
|
|
10472
|
-
console.log(
|
|
10473
|
-
console.log(
|
|
10474
|
-
console.log(
|
|
10475
|
-
console.log(
|
|
10476
|
-
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)"));
|
|
10477
10586
|
} catch (e) {
|
|
10478
|
-
console.error(
|
|
10587
|
+
console.error(chalk35.red(`
|
|
10479
10588
|
Council session aborted: ${e.message}`));
|
|
10480
10589
|
}
|
|
10481
10590
|
});
|
|
@@ -10484,12 +10593,8 @@ function sleep(ms) {
|
|
|
10484
10593
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
10485
10594
|
}
|
|
10486
10595
|
|
|
10487
|
-
// src/utils/version.ts
|
|
10488
|
-
init_esm_shims();
|
|
10489
|
-
async function checkVersion() {
|
|
10490
|
-
}
|
|
10491
|
-
|
|
10492
10596
|
// src/index.ts
|
|
10597
|
+
init_version();
|
|
10493
10598
|
import dotenv from "dotenv";
|
|
10494
10599
|
var pkg = require_package();
|
|
10495
10600
|
dotenv.config();
|
|
@@ -10523,19 +10628,19 @@ program.hook("preAction", async () => {
|
|
|
10523
10628
|
});
|
|
10524
10629
|
program.on("--help", () => {
|
|
10525
10630
|
console.log("");
|
|
10526
|
-
console.log(
|
|
10631
|
+
console.log(chalk36.bold("Examples:"));
|
|
10527
10632
|
console.log("");
|
|
10528
|
-
console.log(
|
|
10529
|
-
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"));
|
|
10530
10635
|
console.log("");
|
|
10531
|
-
console.log(
|
|
10532
|
-
console.log(
|
|
10636
|
+
console.log(chalk36.cyan(" $ rigstate scan"));
|
|
10637
|
+
console.log(chalk36.dim(" Scan the current directory"));
|
|
10533
10638
|
console.log("");
|
|
10534
|
-
console.log(
|
|
10535
|
-
console.log(
|
|
10639
|
+
console.log(chalk36.cyan(" $ rigstate scan ./src --project abc123"));
|
|
10640
|
+
console.log(chalk36.dim(" Scan a specific directory with project ID"));
|
|
10536
10641
|
console.log("");
|
|
10537
|
-
console.log(
|
|
10538
|
-
console.log(
|
|
10642
|
+
console.log(chalk36.cyan(" $ rigstate scan --json"));
|
|
10643
|
+
console.log(chalk36.dim(" Output results in JSON format (useful for IDE extensions)"));
|
|
10539
10644
|
console.log("");
|
|
10540
10645
|
});
|
|
10541
10646
|
program.parse(process.argv);
|