@rigstate/cli 0.7.30 → 0.7.32
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 +362 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +366 -168
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/sync-rules.ts +54 -0
- package/src/daemon/core.ts +38 -1
- package/src/daemon/harvester.ts +199 -0
package/dist/index.js
CHANGED
|
@@ -255,6 +255,7 @@ import { Command as Command3 } from "commander";
|
|
|
255
255
|
import chalk3 from "chalk";
|
|
256
256
|
import ora2 from "ora";
|
|
257
257
|
import axios2 from "axios";
|
|
258
|
+
import { createRequire } from "module";
|
|
258
259
|
async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false) {
|
|
259
260
|
const spinner = ora2("\u{1F6E1}\uFE0F Frank Protocol: Initializing retroactive sync...").start();
|
|
260
261
|
let success = true;
|
|
@@ -286,14 +287,52 @@ async function syncProjectRules(projectId, apiKey, apiUrl, dryRun = false) {
|
|
|
286
287
|
}
|
|
287
288
|
const files = syncResponse.data.data.files;
|
|
288
289
|
if (files && Array.isArray(files)) {
|
|
289
|
-
const
|
|
290
|
-
const
|
|
290
|
+
const fs26 = await import("fs/promises");
|
|
291
|
+
const path29 = await import("path");
|
|
291
292
|
for (const file of files) {
|
|
292
|
-
const filePath =
|
|
293
|
-
await
|
|
294
|
-
await
|
|
293
|
+
const filePath = path29.join(process.cwd(), file.path);
|
|
294
|
+
await fs26.mkdir(path29.dirname(filePath), { recursive: true });
|
|
295
|
+
await fs26.writeFile(filePath, file.content, "utf-8");
|
|
295
296
|
}
|
|
296
297
|
console.log(chalk3.dim(` \u{1F4BE} Wrote ${files.length} rule files to local .cursor/rules/`));
|
|
298
|
+
try {
|
|
299
|
+
const masterPath = path29.join(process.cwd(), ".cursorrules");
|
|
300
|
+
let masterContent = "";
|
|
301
|
+
try {
|
|
302
|
+
masterContent = await fs26.readFile(masterPath, "utf-8");
|
|
303
|
+
} catch {
|
|
304
|
+
masterContent = "";
|
|
305
|
+
}
|
|
306
|
+
const START_MARKER = "<!-- RIGSTATE_GOVERNANCE_START -->";
|
|
307
|
+
const END_MARKER = "<!-- RIGSTATE_GOVERNANCE_END -->";
|
|
308
|
+
const ruleList = files.map((f) => f.path).filter((p) => p.endsWith(".mdc")).map((p) => `- ${p}`).join("\n");
|
|
309
|
+
const governanceBlock = `${START_MARKER}
|
|
310
|
+
# \u{1F6E1}\uFE0F Rigstate Governance (Do not edit this block manually)
|
|
311
|
+
# The following rules are enforced by the Rigstate Daemon (v${require2("../../package.json").version}).
|
|
312
|
+
# Failure to adhere to these rules will be flagged during the 'work' cycle.
|
|
313
|
+
|
|
314
|
+
# YOU MUST ADHERE TO THESE PROACTIVE RULES:
|
|
315
|
+
${ruleList}
|
|
316
|
+
|
|
317
|
+
# INSTRUCTIONS FOR AI AGENT:
|
|
318
|
+
# 1. You MUST read the relevant .mdc files in .cursor/rules/ before generating code.
|
|
319
|
+
# 2. If a rule in .cursor/rules/ conflicts with your training, OBEY THE RULE.
|
|
320
|
+
# 3. Consult .rigstate/ACTIVE_VIOLATIONS.md for current architectural health.
|
|
321
|
+
${END_MARKER}`;
|
|
322
|
+
let newContent = masterContent;
|
|
323
|
+
if (masterContent.includes(START_MARKER)) {
|
|
324
|
+
const regex = new RegExp(`${START_MARKER}[\\s\\S]*?${END_MARKER}`, "g");
|
|
325
|
+
newContent = masterContent.replace(regex, governanceBlock);
|
|
326
|
+
} else {
|
|
327
|
+
newContent = masterContent ? `${masterContent}
|
|
328
|
+
|
|
329
|
+
${governanceBlock}` : governanceBlock;
|
|
330
|
+
}
|
|
331
|
+
await fs26.writeFile(masterPath, newContent, "utf-8");
|
|
332
|
+
console.log(chalk3.dim(" \u{1F4DC} Updated master .cursorrules (Constitution enforced)"));
|
|
333
|
+
} catch (e) {
|
|
334
|
+
console.warn(chalk3.yellow(` \u26A0\uFE0F Could not update .cursorrules: ${e.message}`));
|
|
335
|
+
}
|
|
297
336
|
}
|
|
298
337
|
console.log("");
|
|
299
338
|
console.log(chalk3.cyan("\u{1F6E1}\uFE0F Frank Protocol v1.0 has been injected into the rules engine."));
|
|
@@ -327,11 +366,13 @@ function createSyncRulesCommand() {
|
|
|
327
366
|
});
|
|
328
367
|
return syncRules;
|
|
329
368
|
}
|
|
369
|
+
var require2;
|
|
330
370
|
var init_sync_rules = __esm({
|
|
331
371
|
"src/commands/sync-rules.ts"() {
|
|
332
372
|
"use strict";
|
|
333
373
|
init_esm_shims();
|
|
334
374
|
init_config();
|
|
375
|
+
require2 = createRequire(import.meta.url);
|
|
335
376
|
}
|
|
336
377
|
});
|
|
337
378
|
|
|
@@ -1533,10 +1574,10 @@ var require_src2 = __commonJS({
|
|
|
1533
1574
|
var fs_1 = __require("fs");
|
|
1534
1575
|
var debug_1 = __importDefault(require_src());
|
|
1535
1576
|
var log = debug_1.default("@kwsites/file-exists");
|
|
1536
|
-
function check(
|
|
1537
|
-
log(`checking %s`,
|
|
1577
|
+
function check(path29, isFile, isDirectory) {
|
|
1578
|
+
log(`checking %s`, path29);
|
|
1538
1579
|
try {
|
|
1539
|
-
const stat = fs_1.statSync(
|
|
1580
|
+
const stat = fs_1.statSync(path29);
|
|
1540
1581
|
if (stat.isFile() && isFile) {
|
|
1541
1582
|
log(`[OK] path represents a file`);
|
|
1542
1583
|
return true;
|
|
@@ -1556,8 +1597,8 @@ var require_src2 = __commonJS({
|
|
|
1556
1597
|
throw e;
|
|
1557
1598
|
}
|
|
1558
1599
|
}
|
|
1559
|
-
function exists2(
|
|
1560
|
-
return check(
|
|
1600
|
+
function exists2(path29, type = exports.READABLE) {
|
|
1601
|
+
return check(path29, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
1561
1602
|
}
|
|
1562
1603
|
exports.exists = exists2;
|
|
1563
1604
|
exports.FILE = 1;
|
|
@@ -1627,7 +1668,7 @@ var require_package = __commonJS({
|
|
|
1627
1668
|
"package.json"(exports, module) {
|
|
1628
1669
|
module.exports = {
|
|
1629
1670
|
name: "@rigstate/cli",
|
|
1630
|
-
version: "0.7.
|
|
1671
|
+
version: "0.7.32",
|
|
1631
1672
|
description: "Rigstate CLI - Code audit, sync and supervision tool",
|
|
1632
1673
|
type: "module",
|
|
1633
1674
|
main: "./dist/index.js",
|
|
@@ -1773,8 +1814,8 @@ function createLinkCommand() {
|
|
|
1773
1814
|
process.exit(1);
|
|
1774
1815
|
}
|
|
1775
1816
|
console.log(chalk5.dim("Fetching your projects..."));
|
|
1776
|
-
const
|
|
1777
|
-
const response = await
|
|
1817
|
+
const axios24 = (await import("axios")).default;
|
|
1818
|
+
const response = await axios24.get(`${apiUrl}/api/v1/projects`, {
|
|
1778
1819
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1779
1820
|
});
|
|
1780
1821
|
if (!response.data.success || !response.data.data.projects?.length) {
|
|
@@ -1846,9 +1887,9 @@ function createLinkCommand() {
|
|
|
1846
1887
|
});
|
|
1847
1888
|
}
|
|
1848
1889
|
async function hardenGitIgnore(cwd) {
|
|
1849
|
-
const
|
|
1850
|
-
const
|
|
1851
|
-
const ignorePath =
|
|
1890
|
+
const fs26 = await import("fs/promises");
|
|
1891
|
+
const path29 = await import("path");
|
|
1892
|
+
const ignorePath = path29.join(cwd, ".gitignore");
|
|
1852
1893
|
const REQUIRED_IGNORES = [
|
|
1853
1894
|
"# Rigstate - Runtime Artifacts (Do not commit)",
|
|
1854
1895
|
".rigstate/ACTIVE_VIOLATIONS.md",
|
|
@@ -1863,7 +1904,7 @@ async function hardenGitIgnore(cwd) {
|
|
|
1863
1904
|
try {
|
|
1864
1905
|
let content = "";
|
|
1865
1906
|
try {
|
|
1866
|
-
content = await
|
|
1907
|
+
content = await fs26.readFile(ignorePath, "utf-8");
|
|
1867
1908
|
} catch {
|
|
1868
1909
|
content = "";
|
|
1869
1910
|
}
|
|
@@ -1871,7 +1912,7 @@ async function hardenGitIgnore(cwd) {
|
|
|
1871
1912
|
if (missing.length > 0) {
|
|
1872
1913
|
console.log(chalk5.dim(" Configuring .gitignore for Rigstate safety..."));
|
|
1873
1914
|
const toAppend = "\n\n" + REQUIRED_IGNORES.join("\n") + "\n";
|
|
1874
|
-
await
|
|
1915
|
+
await fs26.writeFile(ignorePath, content + toAppend, "utf-8");
|
|
1875
1916
|
console.log(chalk5.green(" \u2714 .gitignore updated (Artifacts protected)"));
|
|
1876
1917
|
} else {
|
|
1877
1918
|
console.log(chalk5.green(" \u2714 .gitignore already hardened"));
|
|
@@ -1881,21 +1922,21 @@ async function hardenGitIgnore(cwd) {
|
|
|
1881
1922
|
}
|
|
1882
1923
|
}
|
|
1883
1924
|
async function installHooks(cwd) {
|
|
1884
|
-
const
|
|
1885
|
-
const
|
|
1925
|
+
const fs26 = await import("fs/promises");
|
|
1926
|
+
const path29 = await import("path");
|
|
1886
1927
|
try {
|
|
1887
|
-
await
|
|
1928
|
+
await fs26.access(path29.join(cwd, ".git"));
|
|
1888
1929
|
} catch {
|
|
1889
1930
|
console.log(chalk5.dim(" (Not a git repository, skipping hooks)"));
|
|
1890
1931
|
return;
|
|
1891
1932
|
}
|
|
1892
|
-
const hooksDir =
|
|
1933
|
+
const hooksDir = path29.join(cwd, ".husky");
|
|
1893
1934
|
try {
|
|
1894
|
-
const preCommitPath =
|
|
1935
|
+
const preCommitPath = path29.join(cwd, ".git/hooks/pre-commit");
|
|
1895
1936
|
let shouldInstall = false;
|
|
1896
1937
|
try {
|
|
1897
|
-
await
|
|
1898
|
-
const content = await
|
|
1938
|
+
await fs26.access(preCommitPath);
|
|
1939
|
+
const content = await fs26.readFile(preCommitPath, "utf-8");
|
|
1899
1940
|
if (content.includes("rigstate")) {
|
|
1900
1941
|
console.log(chalk5.green(" \u2714 Git hooks already active"));
|
|
1901
1942
|
} else {
|
|
@@ -1919,12 +1960,12 @@ echo "\u{1F6E1}\uFE0F Running Guardian checks..."
|
|
|
1919
1960
|
rigstate check --staged --strict=critical
|
|
1920
1961
|
exit $?
|
|
1921
1962
|
`;
|
|
1922
|
-
await
|
|
1963
|
+
await fs26.mkdir(path29.dirname(preCommitPath), { recursive: true });
|
|
1923
1964
|
if (await fileExists(preCommitPath)) {
|
|
1924
|
-
const existing = await
|
|
1925
|
-
await
|
|
1965
|
+
const existing = await fs26.readFile(preCommitPath, "utf-8");
|
|
1966
|
+
await fs26.writeFile(preCommitPath, existing + "\n\n" + PRE_COMMIT_SCRIPT2.replace("#!/bin/sh\n", ""), { mode: 493 });
|
|
1926
1967
|
} else {
|
|
1927
|
-
await
|
|
1968
|
+
await fs26.writeFile(preCommitPath, PRE_COMMIT_SCRIPT2, { mode: 493 });
|
|
1928
1969
|
}
|
|
1929
1970
|
console.log(chalk5.green(" \u2714 Applied Guardian protection (git-hooks)"));
|
|
1930
1971
|
}
|
|
@@ -1932,10 +1973,10 @@ exit $?
|
|
|
1932
1973
|
console.log(chalk5.dim(" (Skipped hooks: " + e.message + ")"));
|
|
1933
1974
|
}
|
|
1934
1975
|
}
|
|
1935
|
-
async function fileExists(
|
|
1936
|
-
const
|
|
1976
|
+
async function fileExists(path29) {
|
|
1977
|
+
const fs26 = await import("fs/promises");
|
|
1937
1978
|
try {
|
|
1938
|
-
await
|
|
1979
|
+
await fs26.access(path29);
|
|
1939
1980
|
return true;
|
|
1940
1981
|
} catch {
|
|
1941
1982
|
return false;
|
|
@@ -3341,8 +3382,8 @@ init_esm_shims();
|
|
|
3341
3382
|
import { Command as Command11 } from "commander";
|
|
3342
3383
|
import chalk21 from "chalk";
|
|
3343
3384
|
import ora8 from "ora";
|
|
3344
|
-
import
|
|
3345
|
-
import
|
|
3385
|
+
import fs20 from "fs/promises";
|
|
3386
|
+
import path23 from "path";
|
|
3346
3387
|
|
|
3347
3388
|
// src/daemon/factory.ts
|
|
3348
3389
|
init_esm_shims();
|
|
@@ -3350,9 +3391,9 @@ init_esm_shims();
|
|
|
3350
3391
|
// src/daemon/core.ts
|
|
3351
3392
|
init_esm_shims();
|
|
3352
3393
|
import chalk19 from "chalk";
|
|
3353
|
-
import * as
|
|
3354
|
-
import
|
|
3355
|
-
import { EventEmitter as
|
|
3394
|
+
import * as fs18 from "fs/promises";
|
|
3395
|
+
import path21 from "path";
|
|
3396
|
+
import { EventEmitter as EventEmitter4 } from "events";
|
|
3356
3397
|
|
|
3357
3398
|
// src/daemon/file-watcher.ts
|
|
3358
3399
|
init_esm_shims();
|
|
@@ -3970,8 +4011,142 @@ ${chalk18.gray("[Circular or invalid object]")}`;
|
|
|
3970
4011
|
}
|
|
3971
4012
|
};
|
|
3972
4013
|
|
|
4014
|
+
// src/daemon/harvester.ts
|
|
4015
|
+
init_esm_shims();
|
|
4016
|
+
import { EventEmitter as EventEmitter3 } from "events";
|
|
4017
|
+
import chokidar2 from "chokidar";
|
|
4018
|
+
import path20 from "path";
|
|
4019
|
+
import fs17 from "fs/promises";
|
|
4020
|
+
import crypto from "crypto";
|
|
4021
|
+
import axios15 from "axios";
|
|
4022
|
+
var KnowledgeHarvester = class extends EventEmitter3 {
|
|
4023
|
+
watcher = null;
|
|
4024
|
+
config;
|
|
4025
|
+
ruleHashes = /* @__PURE__ */ new Map();
|
|
4026
|
+
isReady = false;
|
|
4027
|
+
processingQueue = /* @__PURE__ */ new Set();
|
|
4028
|
+
debounceTimers = /* @__PURE__ */ new Map();
|
|
4029
|
+
// Ignore list to prevent feedback loops with system rules
|
|
4030
|
+
IGNORED_PREFIXES = ["rigstate-identity", "rigstate-guardian"];
|
|
4031
|
+
constructor(config2) {
|
|
4032
|
+
super();
|
|
4033
|
+
this.config = config2;
|
|
4034
|
+
}
|
|
4035
|
+
async start() {
|
|
4036
|
+
await this.loadHashes();
|
|
4037
|
+
const rulesPath = path20.join(this.config.watchPath, ".cursor", "rules");
|
|
4038
|
+
const watchPattern = path20.join(rulesPath, "**", "*.mdc");
|
|
4039
|
+
Logger.debug(`\u{1F33E} Harvester watching: ${watchPattern}`);
|
|
4040
|
+
this.watcher = chokidar2.watch(watchPattern, {
|
|
4041
|
+
persistent: true,
|
|
4042
|
+
ignoreInitial: true,
|
|
4043
|
+
// Don't harvest what's already there on boot
|
|
4044
|
+
awaitWriteFinish: {
|
|
4045
|
+
stabilityThreshold: 2e3,
|
|
4046
|
+
pollInterval: 100
|
|
4047
|
+
}
|
|
4048
|
+
});
|
|
4049
|
+
this.watcher.on("add", (path29) => this.handleFileEvent(path29, "add")).on("change", (path29) => this.handleFileEvent(path29, "change"));
|
|
4050
|
+
this.isReady = true;
|
|
4051
|
+
}
|
|
4052
|
+
async stop() {
|
|
4053
|
+
if (this.watcher) {
|
|
4054
|
+
await this.watcher.close();
|
|
4055
|
+
this.watcher = null;
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
4058
|
+
async handleFileEvent(filePath, event) {
|
|
4059
|
+
const fileName = path20.basename(filePath);
|
|
4060
|
+
if (this.IGNORED_PREFIXES.some((prefix) => fileName.startsWith(prefix))) {
|
|
4061
|
+
return;
|
|
4062
|
+
}
|
|
4063
|
+
if (this.debounceTimers.has(filePath)) {
|
|
4064
|
+
clearTimeout(this.debounceTimers.get(filePath));
|
|
4065
|
+
}
|
|
4066
|
+
this.debounceTimers.set(filePath, setTimeout(async () => {
|
|
4067
|
+
this.processFile(filePath);
|
|
4068
|
+
this.debounceTimers.delete(filePath);
|
|
4069
|
+
}, 5e3));
|
|
4070
|
+
}
|
|
4071
|
+
async processFile(filePath) {
|
|
4072
|
+
if (this.processingQueue.has(filePath)) return;
|
|
4073
|
+
this.processingQueue.add(filePath);
|
|
4074
|
+
try {
|
|
4075
|
+
const content = await fs17.readFile(filePath, "utf-8");
|
|
4076
|
+
const currentHash = this.computeHash(content);
|
|
4077
|
+
if (this.ruleHashes.get(filePath) === currentHash) {
|
|
4078
|
+
Logger.debug(`Skipping ${path20.basename(filePath)} (unchanged hash)`);
|
|
4079
|
+
return;
|
|
4080
|
+
}
|
|
4081
|
+
if (content.length < 20) {
|
|
4082
|
+
Logger.debug(`Skipping ${path20.basename(filePath)} (too short)`);
|
|
4083
|
+
return;
|
|
4084
|
+
}
|
|
4085
|
+
await this.submitSignal(filePath, content);
|
|
4086
|
+
this.ruleHashes.set(filePath, currentHash);
|
|
4087
|
+
} catch (error) {
|
|
4088
|
+
Logger.warn(`Harvester failed to process ${path20.basename(filePath)}: ${error.message}`);
|
|
4089
|
+
} finally {
|
|
4090
|
+
this.processingQueue.delete(filePath);
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
async submitSignal(filePath, content) {
|
|
4094
|
+
const title = path20.basename(filePath, ".mdc");
|
|
4095
|
+
const relativePath = path20.relative(process.cwd(), filePath);
|
|
4096
|
+
Logger.info(`\u{1F33E} Harvesting new knowledge: ${title}`);
|
|
4097
|
+
try {
|
|
4098
|
+
const descriptionMatch = content.match(/description:\s*(.*)/);
|
|
4099
|
+
const description = descriptionMatch ? descriptionMatch[1].trim() : "Auto-harvested from IDE interaction";
|
|
4100
|
+
const payload = {
|
|
4101
|
+
project_id: this.config.projectId,
|
|
4102
|
+
title,
|
|
4103
|
+
category: "ARCHITECTURE",
|
|
4104
|
+
// Default
|
|
4105
|
+
severity: "MEDIUM",
|
|
4106
|
+
instruction: content,
|
|
4107
|
+
reasoning: `Harvested from local file: ${relativePath}`,
|
|
4108
|
+
source_type: "IDE_HARVESTER"
|
|
4109
|
+
};
|
|
4110
|
+
const response = await axios15.post(`${this.config.apiUrl}/api/v1/curator/signals`, payload, {
|
|
4111
|
+
headers: { Authorization: `Bearer ${this.config.apiKey}` }
|
|
4112
|
+
});
|
|
4113
|
+
if (response.data.success) {
|
|
4114
|
+
Logger.info(`\u2705 Signal submitted for review: ${title}`);
|
|
4115
|
+
} else {
|
|
4116
|
+
throw new Error(response.data.error || "Unknown API error");
|
|
4117
|
+
}
|
|
4118
|
+
} catch (error) {
|
|
4119
|
+
if (error.response?.status === 404) {
|
|
4120
|
+
Logger.debug("Curator API not reachable (404). Signal stored locally (mock).");
|
|
4121
|
+
} else {
|
|
4122
|
+
Logger.error(`Failed to submit signal: ${error.message}`);
|
|
4123
|
+
this.ruleHashes.delete(filePath);
|
|
4124
|
+
throw error;
|
|
4125
|
+
}
|
|
4126
|
+
}
|
|
4127
|
+
}
|
|
4128
|
+
async loadHashes() {
|
|
4129
|
+
const rulesPath = path20.join(this.config.watchPath, ".cursor", "rules");
|
|
4130
|
+
try {
|
|
4131
|
+
await fs17.mkdir(rulesPath, { recursive: true });
|
|
4132
|
+
const files = await fs17.readdir(rulesPath);
|
|
4133
|
+
for (const file of files) {
|
|
4134
|
+
if (file.endsWith(".mdc")) {
|
|
4135
|
+
const fullPath = path20.join(rulesPath, file);
|
|
4136
|
+
const content = await fs17.readFile(fullPath, "utf-8");
|
|
4137
|
+
this.ruleHashes.set(fullPath, this.computeHash(content));
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
4140
|
+
} catch (e) {
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
computeHash(content) {
|
|
4144
|
+
return crypto.createHash("sha256").update(content).digest("hex");
|
|
4145
|
+
}
|
|
4146
|
+
};
|
|
4147
|
+
|
|
3973
4148
|
// src/daemon/core.ts
|
|
3974
|
-
var GuardianDaemon = class extends
|
|
4149
|
+
var GuardianDaemon = class extends EventEmitter4 {
|
|
3975
4150
|
config;
|
|
3976
4151
|
state;
|
|
3977
4152
|
fileWatcher = null;
|
|
@@ -3979,6 +4154,8 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
3979
4154
|
heuristicEngine = null;
|
|
3980
4155
|
interventionProtocol = null;
|
|
3981
4156
|
bridgeListener = null;
|
|
4157
|
+
harvester = null;
|
|
4158
|
+
syncInterval = null;
|
|
3982
4159
|
constructor(config2) {
|
|
3983
4160
|
super();
|
|
3984
4161
|
this.config = config2;
|
|
@@ -4002,13 +4179,24 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
4002
4179
|
this.heuristicEngine = createHeuristicEngine();
|
|
4003
4180
|
this.interventionProtocol = createInterventionProtocol();
|
|
4004
4181
|
this.guardianMonitor = createGuardianMonitor(this.config.projectId, this.config.apiUrl, this.config.apiKey);
|
|
4182
|
+
this.harvester = new KnowledgeHarvester({
|
|
4183
|
+
projectId: this.config.projectId,
|
|
4184
|
+
apiUrl: this.config.apiUrl,
|
|
4185
|
+
apiKey: this.config.apiKey,
|
|
4186
|
+
watchPath: process.cwd()
|
|
4187
|
+
});
|
|
4005
4188
|
await this.guardianMonitor.loadRules();
|
|
4006
4189
|
Logger.info(`Loaded ${this.guardianMonitor.getRuleCount()} rules`);
|
|
4007
4190
|
Logger.info("Syncing Brain to IDE (.cursor/rules)...");
|
|
4008
|
-
await
|
|
4191
|
+
await this.runRuleSync();
|
|
4009
4192
|
await this.syncHeuristics();
|
|
4010
4193
|
if (this.config.checkOnChange) {
|
|
4011
4194
|
this.setupFileWatcher();
|
|
4195
|
+
await this.harvester.start();
|
|
4196
|
+
Logger.info("Starting Auto-Sync Poller (5m interval)...");
|
|
4197
|
+
this.syncInterval = setInterval(() => {
|
|
4198
|
+
this.runRuleSync().catch((e) => Logger.error(`Auto-Sync failed: ${e.message}`));
|
|
4199
|
+
}, 5 * 60 * 1e3);
|
|
4012
4200
|
}
|
|
4013
4201
|
if (this.config.bridgeEnabled) {
|
|
4014
4202
|
try {
|
|
@@ -4022,6 +4210,14 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
4022
4210
|
await this.updateViolationReport([]);
|
|
4023
4211
|
this.emit("started", this.state);
|
|
4024
4212
|
}
|
|
4213
|
+
async runRuleSync() {
|
|
4214
|
+
try {
|
|
4215
|
+
await syncProjectRules(this.config.projectId, this.config.apiKey, this.config.apiUrl);
|
|
4216
|
+
Logger.debug("Auto-Sync completed successfully");
|
|
4217
|
+
} catch (error) {
|
|
4218
|
+
Logger.warn(`Rule sync hiccup: ${error.message}`);
|
|
4219
|
+
}
|
|
4220
|
+
}
|
|
4025
4221
|
printWelcome() {
|
|
4026
4222
|
console.log(chalk19.bold.blue("\n\u{1F6E1}\uFE0F Guardian Daemon Starting..."));
|
|
4027
4223
|
console.log(chalk19.dim(`Project: ${this.config.projectId}`));
|
|
@@ -4042,7 +4238,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
4042
4238
|
setupFileWatcher() {
|
|
4043
4239
|
Logger.info("Starting file watcher...");
|
|
4044
4240
|
this.fileWatcher = createFileWatcher(this.config.watchPath);
|
|
4045
|
-
this.fileWatcher.on("change", (
|
|
4241
|
+
this.fileWatcher.on("change", (path29) => this.handleFileChange(path29));
|
|
4046
4242
|
this.fileWatcher.start();
|
|
4047
4243
|
Logger.info("File watcher active");
|
|
4048
4244
|
}
|
|
@@ -4055,7 +4251,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
4055
4251
|
}
|
|
4056
4252
|
async getLineCount(filePath) {
|
|
4057
4253
|
try {
|
|
4058
|
-
const content = await
|
|
4254
|
+
const content = await fs18.readFile(filePath, "utf-8");
|
|
4059
4255
|
return content.split("\n").length;
|
|
4060
4256
|
} catch (e) {
|
|
4061
4257
|
return 0;
|
|
@@ -4092,7 +4288,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
4092
4288
|
}
|
|
4093
4289
|
}
|
|
4094
4290
|
async updateViolationReport(violations) {
|
|
4095
|
-
const reportPath =
|
|
4291
|
+
const reportPath = path21.join(process.cwd(), ".rigstate", "ACTIVE_VIOLATIONS.md");
|
|
4096
4292
|
const allViolations = Array.from(this.violationsMap.entries());
|
|
4097
4293
|
const totalCount = allViolations.reduce((acc, [, v]) => acc + v.length, 0);
|
|
4098
4294
|
let content = `# \u{1F6E1}\uFE0F Guardian Status: ${totalCount > 0 ? "\u26A0\uFE0F ATTENTION" : "\u2705 PASS"}
|
|
@@ -4108,7 +4304,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
4108
4304
|
} else {
|
|
4109
4305
|
content += "### \u{1F6A8} Active Violations\n\n";
|
|
4110
4306
|
for (const [file, fileViolations] of allViolations) {
|
|
4111
|
-
const relPath =
|
|
4307
|
+
const relPath = path21.relative(process.cwd(), file);
|
|
4112
4308
|
content += `#### \u{1F4C4} ${relPath}
|
|
4113
4309
|
`;
|
|
4114
4310
|
for (const v of fileViolations) {
|
|
@@ -4120,7 +4316,7 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
4120
4316
|
content += "\n---\n*Rigstate Daemon is watching. Fix violations to clear this report.*";
|
|
4121
4317
|
}
|
|
4122
4318
|
try {
|
|
4123
|
-
await
|
|
4319
|
+
await fs18.writeFile(reportPath, content, "utf-8");
|
|
4124
4320
|
} catch (e) {
|
|
4125
4321
|
}
|
|
4126
4322
|
}
|
|
@@ -4157,6 +4353,8 @@ var GuardianDaemon = class extends EventEmitter3 {
|
|
|
4157
4353
|
console.log(chalk19.dim("\n\u{1F6D1} Stopping Guardian Daemon..."));
|
|
4158
4354
|
if (this.fileWatcher) await this.fileWatcher.stop();
|
|
4159
4355
|
if (this.bridgeListener) await this.bridgeListener.disconnect();
|
|
4356
|
+
if (this.harvester) await this.harvester.stop();
|
|
4357
|
+
if (this.syncInterval) clearInterval(this.syncInterval);
|
|
4160
4358
|
this.state.isRunning = false;
|
|
4161
4359
|
console.log(chalk19.green("\u2713 Daemon stopped."));
|
|
4162
4360
|
this.emit("stopped", this.state);
|
|
@@ -4198,8 +4396,8 @@ async function createDaemon(options) {
|
|
|
4198
4396
|
// src/utils/service-manager.ts
|
|
4199
4397
|
init_esm_shims();
|
|
4200
4398
|
import chalk20 from "chalk";
|
|
4201
|
-
import
|
|
4202
|
-
import
|
|
4399
|
+
import fs19 from "fs/promises";
|
|
4400
|
+
import path22 from "path";
|
|
4203
4401
|
import { execSync as execSync3 } from "child_process";
|
|
4204
4402
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4205
4403
|
async function execShellCommand(cmd) {
|
|
@@ -4222,11 +4420,11 @@ async function enableDaemon() {
|
|
|
4222
4420
|
console.error(chalk20.red("\u274C Could not determine HOME directory."));
|
|
4223
4421
|
return;
|
|
4224
4422
|
}
|
|
4225
|
-
const agentsDir =
|
|
4226
|
-
const logDir =
|
|
4227
|
-
const plistPath =
|
|
4228
|
-
await
|
|
4229
|
-
await
|
|
4423
|
+
const agentsDir = path22.join(homeDir, "Library/LaunchAgents");
|
|
4424
|
+
const logDir = path22.join(homeDir, ".rigstate/logs");
|
|
4425
|
+
const plistPath = path22.join(agentsDir, "com.rigstate.daemon.plist");
|
|
4426
|
+
await fs19.mkdir(agentsDir, { recursive: true });
|
|
4427
|
+
await fs19.mkdir(logDir, { recursive: true });
|
|
4230
4428
|
const scriptPath = fileURLToPath2(import.meta.url);
|
|
4231
4429
|
const nodePath = process.execPath;
|
|
4232
4430
|
const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -4245,9 +4443,9 @@ async function enableDaemon() {
|
|
|
4245
4443
|
<key>WorkingDirectory</key>
|
|
4246
4444
|
<string>${process.cwd()}</string>
|
|
4247
4445
|
<key>StandardOutPath</key>
|
|
4248
|
-
<string>${
|
|
4446
|
+
<string>${path22.join(logDir, "daemon.out.log")}</string>
|
|
4249
4447
|
<key>StandardErrorPath</key>
|
|
4250
|
-
<string>${
|
|
4448
|
+
<string>${path22.join(logDir, "daemon.err.log")}</string>
|
|
4251
4449
|
<key>RunAtLoad</key>
|
|
4252
4450
|
<true/>
|
|
4253
4451
|
<key>KeepAlive</key>
|
|
@@ -4260,7 +4458,7 @@ async function enableDaemon() {
|
|
|
4260
4458
|
</dict>
|
|
4261
4459
|
</plist>`;
|
|
4262
4460
|
try {
|
|
4263
|
-
await
|
|
4461
|
+
await fs19.writeFile(plistPath, plistContent);
|
|
4264
4462
|
console.log(chalk20.dim(`Created plist at: ${plistPath}`));
|
|
4265
4463
|
try {
|
|
4266
4464
|
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
@@ -4277,10 +4475,10 @@ async function enableDaemon() {
|
|
|
4277
4475
|
async function disableDaemon() {
|
|
4278
4476
|
console.log(chalk20.bold("\n\u2699\uFE0F Disabling Rigstate Background Service\n"));
|
|
4279
4477
|
const homeDir = process.env.HOME || "";
|
|
4280
|
-
const plistPath =
|
|
4478
|
+
const plistPath = path22.join(homeDir, "Library/LaunchAgents/com.rigstate.daemon.plist");
|
|
4281
4479
|
try {
|
|
4282
4480
|
await execShellCommand(`launchctl unload ${plistPath}`);
|
|
4283
|
-
await
|
|
4481
|
+
await fs19.unlink(plistPath);
|
|
4284
4482
|
console.log(chalk20.green("\u2705 Successfully disabled background daemon."));
|
|
4285
4483
|
} catch (error) {
|
|
4286
4484
|
if (error.code === "ENOENT") {
|
|
@@ -4311,9 +4509,9 @@ function createDaemonCommand() {
|
|
|
4311
4509
|
}
|
|
4312
4510
|
const spinner = ora8();
|
|
4313
4511
|
try {
|
|
4314
|
-
const pidPath =
|
|
4512
|
+
const pidPath = path23.join(process.cwd(), PID_FILE);
|
|
4315
4513
|
try {
|
|
4316
|
-
const content = await
|
|
4514
|
+
const content = await fs20.readFile(pidPath, "utf-8");
|
|
4317
4515
|
const pid = parseInt(content.trim(), 10);
|
|
4318
4516
|
try {
|
|
4319
4517
|
process.kill(pid, 0);
|
|
@@ -4321,7 +4519,7 @@ function createDaemonCommand() {
|
|
|
4321
4519
|
console.log(chalk21.dim(` Run "rigstate daemon status" for details or Ctrl+C to stop.
|
|
4322
4520
|
`));
|
|
4323
4521
|
} catch {
|
|
4324
|
-
await
|
|
4522
|
+
await fs20.unlink(pidPath).catch(() => {
|
|
4325
4523
|
});
|
|
4326
4524
|
}
|
|
4327
4525
|
} catch {
|
|
@@ -4365,14 +4563,14 @@ function createDaemonCommand() {
|
|
|
4365
4563
|
}
|
|
4366
4564
|
async function isRunning() {
|
|
4367
4565
|
try {
|
|
4368
|
-
const pidPath =
|
|
4369
|
-
const content = await
|
|
4566
|
+
const pidPath = path23.join(process.cwd(), PID_FILE);
|
|
4567
|
+
const content = await fs20.readFile(pidPath, "utf-8");
|
|
4370
4568
|
const pid = parseInt(content.trim(), 10);
|
|
4371
4569
|
try {
|
|
4372
4570
|
process.kill(pid, 0);
|
|
4373
4571
|
return true;
|
|
4374
4572
|
} catch {
|
|
4375
|
-
await
|
|
4573
|
+
await fs20.unlink(pidPath);
|
|
4376
4574
|
return false;
|
|
4377
4575
|
}
|
|
4378
4576
|
} catch {
|
|
@@ -4381,25 +4579,25 @@ async function isRunning() {
|
|
|
4381
4579
|
}
|
|
4382
4580
|
async function writePidFile() {
|
|
4383
4581
|
try {
|
|
4384
|
-
const dir =
|
|
4385
|
-
await
|
|
4386
|
-
await
|
|
4582
|
+
const dir = path23.join(process.cwd(), ".rigstate");
|
|
4583
|
+
await fs20.mkdir(dir, { recursive: true });
|
|
4584
|
+
await fs20.writeFile(path23.join(dir, "daemon.pid"), process.pid.toString());
|
|
4387
4585
|
} catch {
|
|
4388
4586
|
}
|
|
4389
4587
|
}
|
|
4390
4588
|
async function cleanupPidFile() {
|
|
4391
4589
|
try {
|
|
4392
|
-
await
|
|
4393
|
-
await
|
|
4590
|
+
await fs20.unlink(path23.join(process.cwd(), PID_FILE));
|
|
4591
|
+
await fs20.unlink(path23.join(process.cwd(), STATE_FILE));
|
|
4394
4592
|
} catch {
|
|
4395
4593
|
}
|
|
4396
4594
|
}
|
|
4397
4595
|
async function writeStateFile(state) {
|
|
4398
4596
|
try {
|
|
4399
|
-
const dir =
|
|
4400
|
-
await
|
|
4401
|
-
await
|
|
4402
|
-
|
|
4597
|
+
const dir = path23.join(process.cwd(), ".rigstate");
|
|
4598
|
+
await fs20.mkdir(dir, { recursive: true });
|
|
4599
|
+
await fs20.writeFile(
|
|
4600
|
+
path23.join(dir, "daemon.state.json"),
|
|
4403
4601
|
JSON.stringify(state, null, 2)
|
|
4404
4602
|
);
|
|
4405
4603
|
} catch {
|
|
@@ -4415,8 +4613,8 @@ async function showStatus() {
|
|
|
4415
4613
|
}
|
|
4416
4614
|
console.log(chalk21.green("Status: Running"));
|
|
4417
4615
|
try {
|
|
4418
|
-
const statePath =
|
|
4419
|
-
const content = await
|
|
4616
|
+
const statePath = path23.join(process.cwd(), STATE_FILE);
|
|
4617
|
+
const content = await fs20.readFile(statePath, "utf-8");
|
|
4420
4618
|
const state = JSON.parse(content);
|
|
4421
4619
|
console.log(chalk21.dim("\u2500".repeat(40)));
|
|
4422
4620
|
console.log(`Started at: ${state.startedAt || "Unknown"}`);
|
|
@@ -4429,8 +4627,8 @@ async function showStatus() {
|
|
|
4429
4627
|
console.log(chalk21.dim("(State file not found)"));
|
|
4430
4628
|
}
|
|
4431
4629
|
try {
|
|
4432
|
-
const pidPath =
|
|
4433
|
-
const pid = await
|
|
4630
|
+
const pidPath = path23.join(process.cwd(), PID_FILE);
|
|
4631
|
+
const pid = await fs20.readFile(pidPath, "utf-8");
|
|
4434
4632
|
console.log(chalk21.dim(`PID: ${pid.trim()}`));
|
|
4435
4633
|
} catch {
|
|
4436
4634
|
}
|
|
@@ -4444,7 +4642,7 @@ init_suggest();
|
|
|
4444
4642
|
import { Command as Command13 } from "commander";
|
|
4445
4643
|
import chalk23 from "chalk";
|
|
4446
4644
|
import ora10 from "ora";
|
|
4447
|
-
import
|
|
4645
|
+
import axios17 from "axios";
|
|
4448
4646
|
import inquirer3 from "inquirer";
|
|
4449
4647
|
|
|
4450
4648
|
// src/commands/plan.ts
|
|
@@ -4453,9 +4651,9 @@ init_config();
|
|
|
4453
4651
|
import { Command as Command12 } from "commander";
|
|
4454
4652
|
import chalk22 from "chalk";
|
|
4455
4653
|
import ora9 from "ora";
|
|
4456
|
-
import
|
|
4457
|
-
import
|
|
4458
|
-
import
|
|
4654
|
+
import axios16 from "axios";
|
|
4655
|
+
import fs21 from "fs/promises";
|
|
4656
|
+
import path24 from "path";
|
|
4459
4657
|
import inquirer2 from "inquirer";
|
|
4460
4658
|
function createPlanCommand() {
|
|
4461
4659
|
const plan = new Command12("plan");
|
|
@@ -4473,7 +4671,7 @@ async function executePlan(taskId) {
|
|
|
4473
4671
|
let taskDescription = "";
|
|
4474
4672
|
if (!taskId) {
|
|
4475
4673
|
spinner.text = "Fetching actionable tasks...";
|
|
4476
|
-
const response = await
|
|
4674
|
+
const response = await axios16.get(
|
|
4477
4675
|
`${apiUrl}/api/v1/roadmap?project_id=${projectId}`,
|
|
4478
4676
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
4479
4677
|
);
|
|
@@ -4500,7 +4698,7 @@ async function executePlan(taskId) {
|
|
|
4500
4698
|
taskId = `T-${answer.task.step_number}`;
|
|
4501
4699
|
} else {
|
|
4502
4700
|
spinner.text = `Fetching details for ${taskId}...`;
|
|
4503
|
-
const response = await
|
|
4701
|
+
const response = await axios16.get(
|
|
4504
4702
|
`${apiUrl}/api/v1/roadmap?project_id=${projectId}`,
|
|
4505
4703
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
4506
4704
|
);
|
|
@@ -4513,7 +4711,7 @@ async function executePlan(taskId) {
|
|
|
4513
4711
|
taskDescription = task.description;
|
|
4514
4712
|
}
|
|
4515
4713
|
spinner.start("Generating Context for Frank...");
|
|
4516
|
-
const contextPath =
|
|
4714
|
+
const contextPath = path24.join(process.cwd(), ".rigstate", "CURRENT_CONTEXT.md");
|
|
4517
4715
|
const contextContent = `
|
|
4518
4716
|
# \u{1F3AF} Active Mission: ${taskTitle}
|
|
4519
4717
|
**ID:** ${taskId}
|
|
@@ -4528,10 +4726,10 @@ ${taskDescription}
|
|
|
4528
4726
|
|
|
4529
4727
|
*Generated by Rigstate CLI at ${(/* @__PURE__ */ new Date()).toLocaleString()}*
|
|
4530
4728
|
`;
|
|
4531
|
-
await
|
|
4532
|
-
await
|
|
4533
|
-
const planPath =
|
|
4534
|
-
const planExists = await
|
|
4729
|
+
await fs21.mkdir(path24.dirname(contextPath), { recursive: true });
|
|
4730
|
+
await fs21.writeFile(contextPath, contextContent.trim());
|
|
4731
|
+
const planPath = path24.join(process.cwd(), "IMPLEMENTATION_PLAN.md");
|
|
4732
|
+
const planExists = await fs21.stat(planPath).then(() => true).catch(() => false);
|
|
4535
4733
|
if (!planExists) {
|
|
4536
4734
|
const planTemplate = `
|
|
4537
4735
|
# \u{1F4CB} Implementation Plan: ${taskTitle}
|
|
@@ -4550,7 +4748,7 @@ ${taskDescription}
|
|
|
4550
4748
|
## 4. \u{1F680} Execution
|
|
4551
4749
|
[Frank: Log your progress here]
|
|
4552
4750
|
`;
|
|
4553
|
-
await
|
|
4751
|
+
await fs21.writeFile(planPath, planTemplate.trim());
|
|
4554
4752
|
spinner.succeed(chalk22.green("Created new IMPLEMENTATION_PLAN.md"));
|
|
4555
4753
|
} else {
|
|
4556
4754
|
spinner.info(chalk22.yellow("IMPLEMENTATION_PLAN.md already exists. Preserving it."));
|
|
@@ -4597,7 +4795,7 @@ async function listInteractive() {
|
|
|
4597
4795
|
const spinner = ora10("Fetching roadmap...").start();
|
|
4598
4796
|
try {
|
|
4599
4797
|
const { projectId, apiKey, apiUrl } = getContext2();
|
|
4600
|
-
const response = await
|
|
4798
|
+
const response = await axios17.get(
|
|
4601
4799
|
`${apiUrl}/api/v1/roadmap?project_id=${projectId}`,
|
|
4602
4800
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
4603
4801
|
);
|
|
@@ -4657,12 +4855,12 @@ async function setTaskStatus(taskId, status) {
|
|
|
4657
4855
|
let realId = taskId;
|
|
4658
4856
|
if (taskId.startsWith("T-") || taskId.length < 10) {
|
|
4659
4857
|
spinner.text = "Resolving Task ID...";
|
|
4660
|
-
const lookup = await
|
|
4858
|
+
const lookup = await axios17.get(`${apiUrl}/api/v1/roadmap?project_id=${projectId}`, { headers: { Authorization: `Bearer ${apiKey}` } });
|
|
4661
4859
|
const task = lookup.data.data.roadmap.find((t) => `T-${t.step_number}` === taskId || t.step_number.toString() === taskId);
|
|
4662
4860
|
if (!task) throw new Error(`Task ${taskId} not found.`);
|
|
4663
4861
|
realId = task.id;
|
|
4664
4862
|
}
|
|
4665
|
-
await
|
|
4863
|
+
await axios17.post(
|
|
4666
4864
|
`${apiUrl}/api/v1/roadmap/update-status`,
|
|
4667
4865
|
{ step_id: realId, status, project_id: projectId },
|
|
4668
4866
|
{ headers: { "Authorization": `Bearer ${apiKey}` } }
|
|
@@ -4705,11 +4903,11 @@ init_config();
|
|
|
4705
4903
|
import { Command as Command14 } from "commander";
|
|
4706
4904
|
import chalk24 from "chalk";
|
|
4707
4905
|
import ora11 from "ora";
|
|
4708
|
-
import
|
|
4709
|
-
import
|
|
4710
|
-
import
|
|
4906
|
+
import chokidar3 from "chokidar";
|
|
4907
|
+
import fs22 from "fs/promises";
|
|
4908
|
+
import path25 from "path";
|
|
4711
4909
|
import { execSync as execSync4 } from "child_process";
|
|
4712
|
-
import
|
|
4910
|
+
import axios18 from "axios";
|
|
4713
4911
|
function createWatchCommand() {
|
|
4714
4912
|
const watch2 = new Command14("watch");
|
|
4715
4913
|
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) => {
|
|
@@ -4727,8 +4925,8 @@ function createWatchCommand() {
|
|
|
4727
4925
|
projectId = getProjectId();
|
|
4728
4926
|
if (!projectId) {
|
|
4729
4927
|
try {
|
|
4730
|
-
const manifestPath =
|
|
4731
|
-
const content = await
|
|
4928
|
+
const manifestPath = path25.join(process.cwd(), ".rigstate");
|
|
4929
|
+
const content = await fs22.readFile(manifestPath, "utf-8");
|
|
4732
4930
|
const manifest = JSON.parse(content);
|
|
4733
4931
|
projectId = manifest.project_id;
|
|
4734
4932
|
} catch (e) {
|
|
@@ -4750,7 +4948,7 @@ function createWatchCommand() {
|
|
|
4750
4948
|
console.log("");
|
|
4751
4949
|
const fetchActiveTask = async () => {
|
|
4752
4950
|
try {
|
|
4753
|
-
const response = await
|
|
4951
|
+
const response = await axios18.get(`${apiUrl}/api/v1/roadmap`, {
|
|
4754
4952
|
params: { project_id: projectId },
|
|
4755
4953
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4756
4954
|
});
|
|
@@ -4774,17 +4972,17 @@ function createWatchCommand() {
|
|
|
4774
4972
|
};
|
|
4775
4973
|
const checkCriteria = async (criteria) => {
|
|
4776
4974
|
try {
|
|
4777
|
-
const fullPath =
|
|
4975
|
+
const fullPath = path25.resolve(process.cwd(), criteria.path);
|
|
4778
4976
|
switch (criteria.type) {
|
|
4779
4977
|
case "file_exists":
|
|
4780
|
-
await
|
|
4978
|
+
await fs22.access(fullPath);
|
|
4781
4979
|
return true;
|
|
4782
4980
|
case "file_content":
|
|
4783
|
-
const content = await
|
|
4981
|
+
const content = await fs22.readFile(fullPath, "utf-8");
|
|
4784
4982
|
return content.length > 0;
|
|
4785
4983
|
case "content_match":
|
|
4786
4984
|
if (!criteria.match) return false;
|
|
4787
|
-
const fileContent = await
|
|
4985
|
+
const fileContent = await fs22.readFile(fullPath, "utf-8");
|
|
4788
4986
|
return fileContent.includes(criteria.match);
|
|
4789
4987
|
default:
|
|
4790
4988
|
return false;
|
|
@@ -4806,7 +5004,7 @@ function createWatchCommand() {
|
|
|
4806
5004
|
return;
|
|
4807
5005
|
}
|
|
4808
5006
|
}
|
|
4809
|
-
await
|
|
5007
|
+
await axios18.post(`${apiUrl}/api/v1/roadmap/update-status`, {
|
|
4810
5008
|
project_id: projectId,
|
|
4811
5009
|
chunk_id: taskId,
|
|
4812
5010
|
status: "COMPLETED"
|
|
@@ -4881,7 +5079,7 @@ function createWatchCommand() {
|
|
|
4881
5079
|
isProcessing = false;
|
|
4882
5080
|
};
|
|
4883
5081
|
await processActiveTask();
|
|
4884
|
-
const watcher =
|
|
5082
|
+
const watcher = chokidar3.watch(".", {
|
|
4885
5083
|
ignored: [
|
|
4886
5084
|
/(^|[\/\\])\../,
|
|
4887
5085
|
// dotfiles
|
|
@@ -4916,10 +5114,10 @@ init_config();
|
|
|
4916
5114
|
import { Command as Command15 } from "commander";
|
|
4917
5115
|
import chalk25 from "chalk";
|
|
4918
5116
|
import ora12 from "ora";
|
|
4919
|
-
import
|
|
5117
|
+
import axios19 from "axios";
|
|
4920
5118
|
import { execSync as execSync5 } from "child_process";
|
|
4921
|
-
import
|
|
4922
|
-
import
|
|
5119
|
+
import fs23 from "fs/promises";
|
|
5120
|
+
import path26 from "path";
|
|
4923
5121
|
function createFocusCommand() {
|
|
4924
5122
|
const focus = new Command15("focus");
|
|
4925
5123
|
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) => {
|
|
@@ -4935,8 +5133,8 @@ function createFocusCommand() {
|
|
|
4935
5133
|
projectId = getProjectId();
|
|
4936
5134
|
if (!projectId) {
|
|
4937
5135
|
try {
|
|
4938
|
-
const manifestPath =
|
|
4939
|
-
const content = await
|
|
5136
|
+
const manifestPath = path26.join(process.cwd(), ".rigstate");
|
|
5137
|
+
const content = await fs23.readFile(manifestPath, "utf-8");
|
|
4940
5138
|
const manifest = JSON.parse(content);
|
|
4941
5139
|
projectId = manifest.project_id;
|
|
4942
5140
|
} catch (e) {
|
|
@@ -4948,7 +5146,7 @@ function createFocusCommand() {
|
|
|
4948
5146
|
}
|
|
4949
5147
|
const apiUrl = getApiUrl();
|
|
4950
5148
|
try {
|
|
4951
|
-
const response = await
|
|
5149
|
+
const response = await axios19.get(`${apiUrl}/api/v1/roadmap`, {
|
|
4952
5150
|
params: { project_id: projectId },
|
|
4953
5151
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4954
5152
|
});
|
|
@@ -5091,25 +5289,25 @@ init_config();
|
|
|
5091
5289
|
import { Command as Command17 } from "commander";
|
|
5092
5290
|
import chalk27 from "chalk";
|
|
5093
5291
|
import { spawn } from "child_process";
|
|
5094
|
-
import
|
|
5095
|
-
import
|
|
5292
|
+
import path27 from "path";
|
|
5293
|
+
import fs24 from "fs";
|
|
5096
5294
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
5097
5295
|
var __filename2 = fileURLToPath3(import.meta.url);
|
|
5098
|
-
var __dirname2 =
|
|
5296
|
+
var __dirname2 = path27.dirname(__filename2);
|
|
5099
5297
|
function createMcpCommand() {
|
|
5100
5298
|
const mcp = new Command17("mcp");
|
|
5101
5299
|
mcp.description("Run the Rigstate MCP server for AI editors").action(async () => {
|
|
5102
5300
|
const possiblePaths = [
|
|
5103
5301
|
// From packages/cli -> packages/mcp (sibling package)
|
|
5104
|
-
|
|
5302
|
+
path27.resolve(__dirname2, "../../mcp/dist/index.js"),
|
|
5105
5303
|
// If installed globally or via npm
|
|
5106
|
-
|
|
5304
|
+
path27.resolve(__dirname2, "../../../mcp/dist/index.js"),
|
|
5107
5305
|
// Development path from packages/cli/dist
|
|
5108
|
-
|
|
5306
|
+
path27.resolve(__dirname2, "../../../packages/mcp/dist/index.js")
|
|
5109
5307
|
];
|
|
5110
5308
|
let serverPath = "";
|
|
5111
5309
|
for (const p of possiblePaths) {
|
|
5112
|
-
if (
|
|
5310
|
+
if (fs24.existsSync(p)) {
|
|
5113
5311
|
serverPath = p;
|
|
5114
5312
|
break;
|
|
5115
5313
|
}
|
|
@@ -5161,12 +5359,12 @@ import chalk29 from "chalk";
|
|
|
5161
5359
|
|
|
5162
5360
|
// src/nexus/dispatcher.ts
|
|
5163
5361
|
init_esm_shims();
|
|
5164
|
-
import
|
|
5362
|
+
import EventEmitter5 from "events";
|
|
5165
5363
|
import { v4 as uuidv4 } from "uuid";
|
|
5166
5364
|
|
|
5167
5365
|
// src/hive/gateway.ts
|
|
5168
5366
|
init_esm_shims();
|
|
5169
|
-
import
|
|
5367
|
+
import axios20 from "axios";
|
|
5170
5368
|
|
|
5171
5369
|
// src/hive/scrubber.ts
|
|
5172
5370
|
init_esm_shims();
|
|
@@ -5237,7 +5435,7 @@ var HiveGateway = class {
|
|
|
5237
5435
|
if (!this.enabled) {
|
|
5238
5436
|
console.log(chalk28.dim("\u26A0\uFE0F Hive Gateway disabled (No Token provided). Running in localized mode."));
|
|
5239
5437
|
}
|
|
5240
|
-
this.client =
|
|
5438
|
+
this.client = axios20.create({
|
|
5241
5439
|
baseURL: baseUrl,
|
|
5242
5440
|
headers: {
|
|
5243
5441
|
"Authorization": `Bearer ${token}`,
|
|
@@ -5278,7 +5476,7 @@ var HiveGateway = class {
|
|
|
5278
5476
|
};
|
|
5279
5477
|
|
|
5280
5478
|
// src/nexus/dispatcher.ts
|
|
5281
|
-
var NexusDispatcher = class extends
|
|
5479
|
+
var NexusDispatcher = class extends EventEmitter5 {
|
|
5282
5480
|
context;
|
|
5283
5481
|
orderQueue = [];
|
|
5284
5482
|
orderHistory = [];
|
|
@@ -5431,7 +5629,7 @@ init_governance();
|
|
|
5431
5629
|
init_config();
|
|
5432
5630
|
import { Command as Command19 } from "commander";
|
|
5433
5631
|
import chalk30 from "chalk";
|
|
5434
|
-
import
|
|
5632
|
+
import axios21 from "axios";
|
|
5435
5633
|
function createOverrideCommand() {
|
|
5436
5634
|
const override = new Command19("override");
|
|
5437
5635
|
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) => {
|
|
@@ -5454,7 +5652,7 @@ function createOverrideCommand() {
|
|
|
5454
5652
|
if (projectId) {
|
|
5455
5653
|
const apiUrl = getApiUrl();
|
|
5456
5654
|
const apiKey = getApiKey();
|
|
5457
|
-
await
|
|
5655
|
+
await axios21.post(`${apiUrl}/api/v1/execution-logs`, {
|
|
5458
5656
|
project_id: projectId,
|
|
5459
5657
|
task_id: "OVERRIDE-" + Date.now(),
|
|
5460
5658
|
task_title: `Governance Override: ${violationId}`,
|
|
@@ -5483,7 +5681,7 @@ init_config();
|
|
|
5483
5681
|
import { Command as Command20 } from "commander";
|
|
5484
5682
|
import chalk31 from "chalk";
|
|
5485
5683
|
import ora13 from "ora";
|
|
5486
|
-
import
|
|
5684
|
+
import axios22 from "axios";
|
|
5487
5685
|
import inquirer5 from "inquirer";
|
|
5488
5686
|
function createIdeaCommand() {
|
|
5489
5687
|
return new Command20("idea").description("Capture a new idea or feature request").argument("[title]", "Quick title of the idea").option("-d, --desc <text>", "Detailed description").option("-t, --tag <tags>", "Comma separated tags (e.g. ui,auth)").action(async (title, options) => {
|
|
@@ -5517,7 +5715,7 @@ function createIdeaCommand() {
|
|
|
5517
5715
|
if (tags.length === 0) {
|
|
5518
5716
|
}
|
|
5519
5717
|
const spinner = ora13("Securing idea in the Lab...").start();
|
|
5520
|
-
const response = await
|
|
5718
|
+
const response = await axios22.post(
|
|
5521
5719
|
`${apiUrl}/api/v1/ideas`,
|
|
5522
5720
|
{
|
|
5523
5721
|
project_id: projectId,
|
|
@@ -5548,8 +5746,8 @@ import { Command as Command21 } from "commander";
|
|
|
5548
5746
|
import chalk32 from "chalk";
|
|
5549
5747
|
import ora14 from "ora";
|
|
5550
5748
|
import inquirer6 from "inquirer";
|
|
5551
|
-
import
|
|
5552
|
-
import
|
|
5749
|
+
import fs25 from "fs/promises";
|
|
5750
|
+
import path28 from "path";
|
|
5553
5751
|
|
|
5554
5752
|
// ../../node_modules/simple-git/dist/esm/index.js
|
|
5555
5753
|
init_esm_shims();
|
|
@@ -5560,7 +5758,7 @@ var import_promise_deferred2 = __toESM(require_dist2(), 1);
|
|
|
5560
5758
|
import { Buffer as Buffer2 } from "buffer";
|
|
5561
5759
|
import { spawn as spawn2 } from "child_process";
|
|
5562
5760
|
import { normalize } from "path";
|
|
5563
|
-
import { EventEmitter as
|
|
5761
|
+
import { EventEmitter as EventEmitter6 } from "events";
|
|
5564
5762
|
var __defProp2 = Object.defineProperty;
|
|
5565
5763
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
5566
5764
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
@@ -5589,8 +5787,8 @@ function pathspec(...paths) {
|
|
|
5589
5787
|
cache.set(key, paths);
|
|
5590
5788
|
return key;
|
|
5591
5789
|
}
|
|
5592
|
-
function isPathSpec(
|
|
5593
|
-
return
|
|
5790
|
+
function isPathSpec(path29) {
|
|
5791
|
+
return path29 instanceof String && cache.has(path29);
|
|
5594
5792
|
}
|
|
5595
5793
|
function toPaths(pathSpec) {
|
|
5596
5794
|
return cache.get(pathSpec) || [];
|
|
@@ -5679,8 +5877,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
5679
5877
|
function forEachLineWithContent(input, callback) {
|
|
5680
5878
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
5681
5879
|
}
|
|
5682
|
-
function folderExists(
|
|
5683
|
-
return (0, import_file_exists.exists)(
|
|
5880
|
+
function folderExists(path29) {
|
|
5881
|
+
return (0, import_file_exists.exists)(path29, import_file_exists.FOLDER);
|
|
5684
5882
|
}
|
|
5685
5883
|
function append(target, item) {
|
|
5686
5884
|
if (Array.isArray(target)) {
|
|
@@ -6084,8 +6282,8 @@ function checkIsRepoRootTask() {
|
|
|
6084
6282
|
commands,
|
|
6085
6283
|
format: "utf-8",
|
|
6086
6284
|
onError,
|
|
6087
|
-
parser(
|
|
6088
|
-
return /^\.(git)?$/.test(
|
|
6285
|
+
parser(path29) {
|
|
6286
|
+
return /^\.(git)?$/.test(path29.trim());
|
|
6089
6287
|
}
|
|
6090
6288
|
};
|
|
6091
6289
|
}
|
|
@@ -6519,11 +6717,11 @@ function parseGrep(grep) {
|
|
|
6519
6717
|
const paths = /* @__PURE__ */ new Set();
|
|
6520
6718
|
const results = {};
|
|
6521
6719
|
forEachLineWithContent(grep, (input) => {
|
|
6522
|
-
const [
|
|
6523
|
-
paths.add(
|
|
6524
|
-
(results[
|
|
6720
|
+
const [path29, line, preview] = input.split(NULL);
|
|
6721
|
+
paths.add(path29);
|
|
6722
|
+
(results[path29] = results[path29] || []).push({
|
|
6525
6723
|
line: asNumber(line),
|
|
6526
|
-
path:
|
|
6724
|
+
path: path29,
|
|
6527
6725
|
preview
|
|
6528
6726
|
});
|
|
6529
6727
|
});
|
|
@@ -7288,14 +7486,14 @@ var init_hash_object = __esm2({
|
|
|
7288
7486
|
init_task();
|
|
7289
7487
|
}
|
|
7290
7488
|
});
|
|
7291
|
-
function parseInit(bare,
|
|
7489
|
+
function parseInit(bare, path29, text) {
|
|
7292
7490
|
const response = String(text).trim();
|
|
7293
7491
|
let result;
|
|
7294
7492
|
if (result = initResponseRegex.exec(response)) {
|
|
7295
|
-
return new InitSummary(bare,
|
|
7493
|
+
return new InitSummary(bare, path29, false, result[1]);
|
|
7296
7494
|
}
|
|
7297
7495
|
if (result = reInitResponseRegex.exec(response)) {
|
|
7298
|
-
return new InitSummary(bare,
|
|
7496
|
+
return new InitSummary(bare, path29, true, result[1]);
|
|
7299
7497
|
}
|
|
7300
7498
|
let gitDir = "";
|
|
7301
7499
|
const tokens = response.split(" ");
|
|
@@ -7306,7 +7504,7 @@ function parseInit(bare, path28, text) {
|
|
|
7306
7504
|
break;
|
|
7307
7505
|
}
|
|
7308
7506
|
}
|
|
7309
|
-
return new InitSummary(bare,
|
|
7507
|
+
return new InitSummary(bare, path29, /^re/i.test(response), gitDir);
|
|
7310
7508
|
}
|
|
7311
7509
|
var InitSummary;
|
|
7312
7510
|
var initResponseRegex;
|
|
@@ -7315,9 +7513,9 @@ var init_InitSummary = __esm2({
|
|
|
7315
7513
|
"src/lib/responses/InitSummary.ts"() {
|
|
7316
7514
|
"use strict";
|
|
7317
7515
|
InitSummary = class {
|
|
7318
|
-
constructor(bare,
|
|
7516
|
+
constructor(bare, path29, existing, gitDir) {
|
|
7319
7517
|
this.bare = bare;
|
|
7320
|
-
this.path =
|
|
7518
|
+
this.path = path29;
|
|
7321
7519
|
this.existing = existing;
|
|
7322
7520
|
this.gitDir = gitDir;
|
|
7323
7521
|
}
|
|
@@ -7329,7 +7527,7 @@ var init_InitSummary = __esm2({
|
|
|
7329
7527
|
function hasBareCommand(command) {
|
|
7330
7528
|
return command.includes(bareCommand);
|
|
7331
7529
|
}
|
|
7332
|
-
function initTask(bare = false,
|
|
7530
|
+
function initTask(bare = false, path29, customArgs) {
|
|
7333
7531
|
const commands = ["init", ...customArgs];
|
|
7334
7532
|
if (bare && !hasBareCommand(commands)) {
|
|
7335
7533
|
commands.splice(1, 0, bareCommand);
|
|
@@ -7338,7 +7536,7 @@ function initTask(bare = false, path28, customArgs) {
|
|
|
7338
7536
|
commands,
|
|
7339
7537
|
format: "utf-8",
|
|
7340
7538
|
parser(text) {
|
|
7341
|
-
return parseInit(commands.includes("--bare"),
|
|
7539
|
+
return parseInit(commands.includes("--bare"), path29, text);
|
|
7342
7540
|
}
|
|
7343
7541
|
};
|
|
7344
7542
|
}
|
|
@@ -8154,12 +8352,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
8154
8352
|
"use strict";
|
|
8155
8353
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
8156
8354
|
FileStatusSummary = class {
|
|
8157
|
-
constructor(
|
|
8158
|
-
this.path =
|
|
8355
|
+
constructor(path29, index, working_dir) {
|
|
8356
|
+
this.path = path29;
|
|
8159
8357
|
this.index = index;
|
|
8160
8358
|
this.working_dir = working_dir;
|
|
8161
8359
|
if (index === "R" || working_dir === "R") {
|
|
8162
|
-
const detail = fromPathRegex.exec(
|
|
8360
|
+
const detail = fromPathRegex.exec(path29) || [null, path29, path29];
|
|
8163
8361
|
this.from = detail[2] || "";
|
|
8164
8362
|
this.path = detail[1] || "";
|
|
8165
8363
|
}
|
|
@@ -8190,14 +8388,14 @@ function splitLine(result, lineStr) {
|
|
|
8190
8388
|
default:
|
|
8191
8389
|
return;
|
|
8192
8390
|
}
|
|
8193
|
-
function data(index, workingDir,
|
|
8391
|
+
function data(index, workingDir, path29) {
|
|
8194
8392
|
const raw = `${index}${workingDir}`;
|
|
8195
8393
|
const handler = parsers6.get(raw);
|
|
8196
8394
|
if (handler) {
|
|
8197
|
-
handler(result,
|
|
8395
|
+
handler(result, path29);
|
|
8198
8396
|
}
|
|
8199
8397
|
if (raw !== "##" && raw !== "!!") {
|
|
8200
|
-
result.files.push(new FileStatusSummary(
|
|
8398
|
+
result.files.push(new FileStatusSummary(path29, index, workingDir));
|
|
8201
8399
|
}
|
|
8202
8400
|
}
|
|
8203
8401
|
}
|
|
@@ -8510,9 +8708,9 @@ var init_simple_git_api = __esm2({
|
|
|
8510
8708
|
next
|
|
8511
8709
|
);
|
|
8512
8710
|
}
|
|
8513
|
-
hashObject(
|
|
8711
|
+
hashObject(path29, write) {
|
|
8514
8712
|
return this._runTask(
|
|
8515
|
-
hashObjectTask(
|
|
8713
|
+
hashObjectTask(path29, write === true),
|
|
8516
8714
|
trailingFunctionArgument(arguments)
|
|
8517
8715
|
);
|
|
8518
8716
|
}
|
|
@@ -8865,8 +9063,8 @@ var init_branch = __esm2({
|
|
|
8865
9063
|
}
|
|
8866
9064
|
});
|
|
8867
9065
|
function toPath(input) {
|
|
8868
|
-
const
|
|
8869
|
-
return
|
|
9066
|
+
const path29 = input.trim().replace(/^["']|["']$/g, "");
|
|
9067
|
+
return path29 && normalize(path29);
|
|
8870
9068
|
}
|
|
8871
9069
|
var parseCheckIgnore;
|
|
8872
9070
|
var init_CheckIgnore = __esm2({
|
|
@@ -9180,8 +9378,8 @@ __export2(sub_module_exports, {
|
|
|
9180
9378
|
subModuleTask: () => subModuleTask,
|
|
9181
9379
|
updateSubModuleTask: () => updateSubModuleTask
|
|
9182
9380
|
});
|
|
9183
|
-
function addSubModuleTask(repo,
|
|
9184
|
-
return subModuleTask(["add", repo,
|
|
9381
|
+
function addSubModuleTask(repo, path29) {
|
|
9382
|
+
return subModuleTask(["add", repo, path29]);
|
|
9185
9383
|
}
|
|
9186
9384
|
function initSubModuleTask(customArgs) {
|
|
9187
9385
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -9511,8 +9709,8 @@ var require_git = __commonJS2({
|
|
|
9511
9709
|
}
|
|
9512
9710
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
9513
9711
|
};
|
|
9514
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
9515
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
9712
|
+
Git2.prototype.submoduleAdd = function(repo, path29, then) {
|
|
9713
|
+
return this._runTask(addSubModuleTask2(repo, path29), trailingFunctionArgument2(arguments));
|
|
9516
9714
|
};
|
|
9517
9715
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
9518
9716
|
return this._runTask(
|
|
@@ -9926,7 +10124,7 @@ init_utils();
|
|
|
9926
10124
|
var PluginStore = class {
|
|
9927
10125
|
constructor() {
|
|
9928
10126
|
this.plugins = /* @__PURE__ */ new Set();
|
|
9929
|
-
this.events = new
|
|
10127
|
+
this.events = new EventEmitter6();
|
|
9930
10128
|
}
|
|
9931
10129
|
on(type, listener) {
|
|
9932
10130
|
this.events.on(type, listener);
|
|
@@ -10112,8 +10310,8 @@ function createReleaseCommand() {
|
|
|
10112
10310
|
return;
|
|
10113
10311
|
}
|
|
10114
10312
|
spinner.text = "Scanning completed tasks...";
|
|
10115
|
-
const pkgPath =
|
|
10116
|
-
const pkgContent = await
|
|
10313
|
+
const pkgPath = path28.resolve(process.cwd(), "package.json");
|
|
10314
|
+
const pkgContent = await fs25.readFile(pkgPath, "utf-8");
|
|
10117
10315
|
const pkg2 = JSON.parse(pkgContent);
|
|
10118
10316
|
const currentVersion = pkg2.version;
|
|
10119
10317
|
const [major, minor, patch] = currentVersion.split(".").map(Number);
|
|
@@ -10133,17 +10331,17 @@ function createReleaseCommand() {
|
|
|
10133
10331
|
return;
|
|
10134
10332
|
}
|
|
10135
10333
|
pkg2.version = newVersion;
|
|
10136
|
-
await
|
|
10137
|
-
const changelogPath =
|
|
10334
|
+
await fs25.writeFile(pkgPath, JSON.stringify(pkg2, null, 4));
|
|
10335
|
+
const changelogPath = path28.resolve(process.cwd(), "CHANGELOG.md");
|
|
10138
10336
|
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
10139
10337
|
const entry = `
|
|
10140
10338
|
## [${newVersion}] - ${date}
|
|
10141
10339
|
- Automated release via Rigstate.
|
|
10142
10340
|
`;
|
|
10143
10341
|
try {
|
|
10144
|
-
await
|
|
10342
|
+
await fs25.appendFile(changelogPath, entry);
|
|
10145
10343
|
} catch {
|
|
10146
|
-
await
|
|
10344
|
+
await fs25.writeFile(changelogPath, "# Changelog\n" + entry);
|
|
10147
10345
|
}
|
|
10148
10346
|
spinner.start("Tagging and pushing...");
|
|
10149
10347
|
await git.add(["package.json", "CHANGELOG.md"]);
|
|
@@ -10171,7 +10369,7 @@ init_config();
|
|
|
10171
10369
|
import { Command as Command22 } from "commander";
|
|
10172
10370
|
import chalk33 from "chalk";
|
|
10173
10371
|
import ora15 from "ora";
|
|
10174
|
-
import
|
|
10372
|
+
import axios23 from "axios";
|
|
10175
10373
|
function createRoadmapCommand() {
|
|
10176
10374
|
return new Command22("roadmap").alias("tactical").description("View project roadmap and task status (Tactical View)").action(async () => {
|
|
10177
10375
|
const spinner = ora15("Fetching tactical overview...").start();
|
|
@@ -10183,7 +10381,7 @@ function createRoadmapCommand() {
|
|
|
10183
10381
|
spinner.fail(chalk33.red('Project context missing. Run "rigstate link".'));
|
|
10184
10382
|
return;
|
|
10185
10383
|
}
|
|
10186
|
-
const response = await
|
|
10384
|
+
const response = await axios23.get(
|
|
10187
10385
|
`${apiUrl}/api/v1/roadmap?project_id=${projectId}`,
|
|
10188
10386
|
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
10189
10387
|
);
|