gossipcat 0.4.31 → 0.5.2
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/README.md +28 -0
- package/dist-dashboard/assets/Geist-Variable-jflMhO5d.woff2 +0 -0
- package/dist-dashboard/assets/dashboard-overview.png +0 -0
- package/dist-dashboard/assets/dashboard-skills.png +0 -0
- package/dist-dashboard/assets/dashboard-team.png +0 -0
- package/dist-dashboard/assets/index-BggwL1Da.css +1 -0
- package/dist-dashboard/assets/index-BxhrNkau.js +78 -0
- package/dist-dashboard/index.html +16 -8
- package/dist-mcp/mcp-server.js +778 -403
- package/package.json +1 -1
- package/dist-dashboard/assets/index-CC9eddQj.css +0 -1
- package/dist-dashboard/assets/index-CLlV_738.js +0 -71
package/dist-mcp/mcp-server.js
CHANGED
|
@@ -734,8 +734,8 @@ var init_agent_registry = __esm({
|
|
|
734
734
|
setPerformanceReader(reader) {
|
|
735
735
|
this.perfReader = reader;
|
|
736
736
|
}
|
|
737
|
-
setSuggesterCache(
|
|
738
|
-
this.suggesterCache =
|
|
737
|
+
setSuggesterCache(cache3) {
|
|
738
|
+
this.suggesterCache = cache3;
|
|
739
739
|
}
|
|
740
740
|
getDispatchWeight(agentId) {
|
|
741
741
|
if (this.perfReader?.isCircuitOpen(agentId)) return 0.3;
|
|
@@ -11407,11 +11407,11 @@ var init_performance_reader = __esm({
|
|
|
11407
11407
|
* Returns false on any IO/parse error — recovery defaults to "no relief"
|
|
11408
11408
|
* when we can't prove a skill is bound.
|
|
11409
11409
|
*/
|
|
11410
|
-
hasSkillForCategory(agentId, category,
|
|
11410
|
+
hasSkillForCategory(agentId, category, cache3) {
|
|
11411
11411
|
if (!agentId || !category) return false;
|
|
11412
11412
|
const normalizedTarget = normalizeSkillName(category);
|
|
11413
11413
|
const cacheKey = agentId + "\0" + normalizedTarget;
|
|
11414
|
-
const cached4 =
|
|
11414
|
+
const cached4 = cache3.get(cacheKey);
|
|
11415
11415
|
if (cached4 !== void 0) return cached4;
|
|
11416
11416
|
const indexMap = this.getSkillIndexEnabledMap();
|
|
11417
11417
|
const agentIndex = indexMap?.[agentId];
|
|
@@ -11443,7 +11443,7 @@ var init_performance_reader = __esm({
|
|
|
11443
11443
|
}
|
|
11444
11444
|
} catch {
|
|
11445
11445
|
}
|
|
11446
|
-
|
|
11446
|
+
cache3.set(cacheKey, result);
|
|
11447
11447
|
return result;
|
|
11448
11448
|
}
|
|
11449
11449
|
/**
|
|
@@ -12776,9 +12776,9 @@ function deriveAggregateKey(signal, projectRoot, boundAtCache) {
|
|
|
12776
12776
|
timestampMs: ts2
|
|
12777
12777
|
};
|
|
12778
12778
|
}
|
|
12779
|
-
function resolveBoundAtMs(agentId, category, projectRoot,
|
|
12779
|
+
function resolveBoundAtMs(agentId, category, projectRoot, cache3, fallbackMs) {
|
|
12780
12780
|
const key = agentId + "\0" + category;
|
|
12781
|
-
const cached4 =
|
|
12781
|
+
const cached4 = cache3.get(key);
|
|
12782
12782
|
if (cached4 !== void 0) {
|
|
12783
12783
|
return cached4 === boundAtMissSentinel ? fallbackMs : cached4;
|
|
12784
12784
|
}
|
|
@@ -12787,13 +12787,13 @@ function resolveBoundAtMs(agentId, category, projectRoot, cache2, fallbackMs) {
|
|
|
12787
12787
|
if (typeof boundAt === "string" && boundAt.length > 0) {
|
|
12788
12788
|
const ms = new Date(boundAt).getTime();
|
|
12789
12789
|
if (isFinite(ms) && ms > 0) {
|
|
12790
|
-
|
|
12790
|
+
cache3.set(key, ms);
|
|
12791
12791
|
return ms;
|
|
12792
12792
|
}
|
|
12793
12793
|
}
|
|
12794
12794
|
} catch {
|
|
12795
12795
|
}
|
|
12796
|
-
|
|
12796
|
+
cache3.set(key, boundAtMissSentinel);
|
|
12797
12797
|
return fallbackMs;
|
|
12798
12798
|
}
|
|
12799
12799
|
var import_fs14, import_path15, loggedCounterErrors, MAX_TELEMETRY_BYTES, VALID_CONSENSUS_SIGNALS, VALID_IMPL_SIGNALS, VALID_META_SIGNALS, VALID_PIPELINE_SIGNALS, SYSTEM_SENTINEL_AGENT_ID, rowsWrittenSinceCheck, DRIFT_SAMPLE_INTERVAL, INTERNAL, boundAtMissSentinel, PerformanceWriter;
|
|
@@ -17366,9 +17366,9 @@ function getRuntimeFlag(key, defaultValue, registry2 = RUNTIME_FLAG_REGISTRY) {
|
|
|
17366
17366
|
if (envVal !== void 0 && envVal !== "") {
|
|
17367
17367
|
return envVal;
|
|
17368
17368
|
}
|
|
17369
|
-
const
|
|
17370
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
17371
|
-
return
|
|
17369
|
+
const cache3 = ensureLoaded(registry2);
|
|
17370
|
+
if (Object.prototype.hasOwnProperty.call(cache3, key)) {
|
|
17371
|
+
return cache3[key];
|
|
17372
17372
|
}
|
|
17373
17373
|
if (defaultValue !== void 0) {
|
|
17374
17374
|
return defaultValue;
|
|
@@ -17568,10 +17568,10 @@ async function unsetRuntimeFlag(key, source, reason, registry2 = RUNTIME_FLAG_RE
|
|
|
17568
17568
|
}
|
|
17569
17569
|
}
|
|
17570
17570
|
function listRuntimeFlags(registry2 = RUNTIME_FLAG_REGISTRY) {
|
|
17571
|
-
const
|
|
17571
|
+
const cache3 = ensureLoaded(registry2);
|
|
17572
17572
|
return Object.entries(registry2).map(([key, spec]) => {
|
|
17573
17573
|
const envVal = process.env[key];
|
|
17574
|
-
const fileVal = Object.prototype.hasOwnProperty.call(
|
|
17574
|
+
const fileVal = Object.prototype.hasOwnProperty.call(cache3, key) ? cache3[key] : void 0;
|
|
17575
17575
|
let value;
|
|
17576
17576
|
let from;
|
|
17577
17577
|
if (envVal !== void 0 && envVal !== "") {
|
|
@@ -23823,8 +23823,8 @@ message: Your question?
|
|
|
23823
23823
|
}
|
|
23824
23824
|
/** Start all worker agents (connect to relay) */
|
|
23825
23825
|
async start() {
|
|
23826
|
-
const { existsSync:
|
|
23827
|
-
const { join:
|
|
23826
|
+
const { existsSync: existsSync70, readFileSync: readFileSync64 } = await import("fs");
|
|
23827
|
+
const { join: join83 } = await import("path");
|
|
23828
23828
|
for (const config2 of this.registry.getAll()) {
|
|
23829
23829
|
if (config2.native) continue;
|
|
23830
23830
|
if (this.workers.has(config2.id)) continue;
|
|
@@ -23833,8 +23833,8 @@ message: Your question?
|
|
|
23833
23833
|
apiKey = await this.keyProviderFn(config2.provider) ?? void 0;
|
|
23834
23834
|
}
|
|
23835
23835
|
const llm = createProvider(config2.provider, config2.model, apiKey);
|
|
23836
|
-
const instructionsPath =
|
|
23837
|
-
const instructions =
|
|
23836
|
+
const instructionsPath = join83(this.projectRoot, ".gossip", "agents", config2.id, "instructions.md");
|
|
23837
|
+
const instructions = existsSync70(instructionsPath) ? readFileSync64(instructionsPath, "utf-8") : void 0;
|
|
23838
23838
|
const enableWebSearch = config2.preset === "researcher" || config2.skills.includes("research");
|
|
23839
23839
|
const worker = new WorkerAgent(config2.id, llm, this.relayUrl, ALL_TOOLS, instructions, enableWebSearch, this.relayApiKey);
|
|
23840
23840
|
await worker.start();
|
|
@@ -24031,8 +24031,8 @@ message: Your question?
|
|
|
24031
24031
|
this.registry.register(config2);
|
|
24032
24032
|
}
|
|
24033
24033
|
async syncWorkers(keyProvider) {
|
|
24034
|
-
const { existsSync:
|
|
24035
|
-
const { join:
|
|
24034
|
+
const { existsSync: existsSync70, readFileSync: readFileSync64 } = await import("fs");
|
|
24035
|
+
const { join: join83 } = await import("path");
|
|
24036
24036
|
let added = 0;
|
|
24037
24037
|
for (const ac of this.registry.getAll()) {
|
|
24038
24038
|
if (ac.native) continue;
|
|
@@ -24049,8 +24049,8 @@ message: Your question?
|
|
|
24049
24049
|
this.workers.delete(ac.id);
|
|
24050
24050
|
}
|
|
24051
24051
|
const llm = createProvider(ac.provider, ac.model, key ?? void 0, void 0, ac.base_url);
|
|
24052
|
-
const instructionsPath =
|
|
24053
|
-
const instructions =
|
|
24052
|
+
const instructionsPath = join83(this.projectRoot, ".gossip", "agents", ac.id, "instructions.md");
|
|
24053
|
+
const instructions = existsSync70(instructionsPath) ? readFileSync64(instructionsPath, "utf-8") : void 0;
|
|
24054
24054
|
const enableWebSearch = ac.preset === "researcher" || ac.skills.includes("research");
|
|
24055
24055
|
const worker = new WorkerAgent(ac.id, llm, this.relayUrl, ALL_TOOLS, instructions, enableWebSearch, this.relayApiKey);
|
|
24056
24056
|
await worker.start();
|
|
@@ -30051,11 +30051,18 @@ async function overviewHandler(projectRoot, ctx2) {
|
|
|
30051
30051
|
const now = Date.now();
|
|
30052
30052
|
const hourMs = 60 * 60 * 1e3;
|
|
30053
30053
|
const graphPath = (0, import_path53.join)(projectRoot, ".gossip", "task-graph.jsonl");
|
|
30054
|
-
|
|
30054
|
+
const archivePath = graphPath + ".1";
|
|
30055
|
+
if ((0, import_fs49.existsSync)(graphPath) || (0, import_fs49.existsSync)(archivePath)) {
|
|
30055
30056
|
try {
|
|
30056
30057
|
const created = /* @__PURE__ */ new Map();
|
|
30057
30058
|
const finished = /* @__PURE__ */ new Set();
|
|
30058
|
-
const lines =
|
|
30059
|
+
const lines = [];
|
|
30060
|
+
if ((0, import_fs49.existsSync)(archivePath)) {
|
|
30061
|
+
lines.push(...(0, import_fs49.readFileSync)(archivePath, "utf-8").split("\n").filter(Boolean));
|
|
30062
|
+
}
|
|
30063
|
+
if ((0, import_fs49.existsSync)(graphPath)) {
|
|
30064
|
+
lines.push(...(0, import_fs49.readFileSync)(graphPath, "utf-8").split("\n").filter(Boolean));
|
|
30065
|
+
}
|
|
30059
30066
|
for (const line of lines) {
|
|
30060
30067
|
try {
|
|
30061
30068
|
const ev = JSON.parse(line);
|
|
@@ -30332,11 +30339,17 @@ function readForcedDevelops(projectRoot, agentId, category) {
|
|
|
30332
30339
|
}
|
|
30333
30340
|
function readTaskGraphByAgent(projectRoot) {
|
|
30334
30341
|
const taskGraphPath = (0, import_path55.join)(projectRoot, ".gossip", "task-graph.jsonl");
|
|
30342
|
+
const archivePath = taskGraphPath + ".1";
|
|
30335
30343
|
const result = /* @__PURE__ */ new Map();
|
|
30336
|
-
if (!(0, import_fs51.existsSync)(taskGraphPath)) return result;
|
|
30337
|
-
let lines;
|
|
30344
|
+
if (!(0, import_fs51.existsSync)(taskGraphPath) && !(0, import_fs51.existsSync)(archivePath)) return result;
|
|
30345
|
+
let lines = [];
|
|
30338
30346
|
try {
|
|
30339
|
-
|
|
30347
|
+
if ((0, import_fs51.existsSync)(archivePath)) {
|
|
30348
|
+
lines.push(...(0, import_fs51.readFileSync)(archivePath, "utf-8").split("\n").filter(Boolean));
|
|
30349
|
+
}
|
|
30350
|
+
if ((0, import_fs51.existsSync)(taskGraphPath)) {
|
|
30351
|
+
lines.push(...(0, import_fs51.readFileSync)(taskGraphPath, "utf-8").split("\n").filter(Boolean));
|
|
30352
|
+
}
|
|
30340
30353
|
} catch {
|
|
30341
30354
|
return result;
|
|
30342
30355
|
}
|
|
@@ -30531,12 +30544,206 @@ var init_api_agents = __esm({
|
|
|
30531
30544
|
function isCorrupt(projectRoot, index) {
|
|
30532
30545
|
return (0, import_fs52.existsSync)((0, import_path56.join)(projectRoot, ".gossip", "skill-index.json")) && !index.exists();
|
|
30533
30546
|
}
|
|
30547
|
+
function readSkillFrontmatter2(projectRoot, agentId, skillName) {
|
|
30548
|
+
try {
|
|
30549
|
+
const path7 = (0, import_path56.join)(projectRoot, ".gossip", "agents", agentId, "skills", `${skillName}.md`);
|
|
30550
|
+
if (!(0, import_fs52.existsSync)(path7)) return null;
|
|
30551
|
+
const raw = (0, import_fs52.readFileSync)(path7, "utf-8");
|
|
30552
|
+
if (!raw.startsWith("---")) return null;
|
|
30553
|
+
const end = raw.indexOf("\n---", 3);
|
|
30554
|
+
if (end === -1) return null;
|
|
30555
|
+
const block = raw.slice(3, end);
|
|
30556
|
+
const out = {};
|
|
30557
|
+
for (const line of block.split("\n")) {
|
|
30558
|
+
const m = line.match(/^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*(.+?)\s*$/);
|
|
30559
|
+
if (!m) continue;
|
|
30560
|
+
const key = m[1];
|
|
30561
|
+
let value = m[2];
|
|
30562
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
30563
|
+
value = value.slice(1, -1);
|
|
30564
|
+
}
|
|
30565
|
+
if (key === "status") out.status = value;
|
|
30566
|
+
else if (key === "bound_at") out.bound_at = value;
|
|
30567
|
+
else if (key === "passed_baseline_rate") {
|
|
30568
|
+
const n = Number(value);
|
|
30569
|
+
if (Number.isFinite(n)) out.passed_baseline_rate = n;
|
|
30570
|
+
}
|
|
30571
|
+
}
|
|
30572
|
+
return out;
|
|
30573
|
+
} catch {
|
|
30574
|
+
return null;
|
|
30575
|
+
}
|
|
30576
|
+
}
|
|
30577
|
+
function buildSignalIndex(projectRoot) {
|
|
30578
|
+
const idx = { byAgentSkill: /* @__PURE__ */ new Map() };
|
|
30579
|
+
const perfPath = (0, import_path56.join)(projectRoot, ".gossip", "agent-performance.jsonl");
|
|
30580
|
+
if (!(0, import_fs52.existsSync)(perfPath)) return idx;
|
|
30581
|
+
let raw;
|
|
30582
|
+
try {
|
|
30583
|
+
raw = readJsonlWithRotated(perfPath);
|
|
30584
|
+
} catch {
|
|
30585
|
+
return idx;
|
|
30586
|
+
}
|
|
30587
|
+
if (!raw) return idx;
|
|
30588
|
+
const retracted = /* @__PURE__ */ new Set();
|
|
30589
|
+
const retractedConsensusIds = /* @__PURE__ */ new Set();
|
|
30590
|
+
const rows = [];
|
|
30591
|
+
for (const line of raw.split("\n")) {
|
|
30592
|
+
if (!line.trim()) continue;
|
|
30593
|
+
try {
|
|
30594
|
+
rows.push(JSON.parse(line));
|
|
30595
|
+
} catch {
|
|
30596
|
+
}
|
|
30597
|
+
}
|
|
30598
|
+
for (const r of rows) {
|
|
30599
|
+
if (r.signal === "consensus_round_retracted") {
|
|
30600
|
+
const cid = r.consensus_id;
|
|
30601
|
+
if (typeof cid === "string" && cid.length > 0) retractedConsensusIds.add(cid);
|
|
30602
|
+
continue;
|
|
30603
|
+
}
|
|
30604
|
+
if (r.signal === "signal_retracted") {
|
|
30605
|
+
const agentId = r.agentId;
|
|
30606
|
+
const taskKey = r.taskId ?? r.timestamp;
|
|
30607
|
+
const retractedSignal = r.retractedSignal;
|
|
30608
|
+
if (!agentId || !taskKey) continue;
|
|
30609
|
+
if (typeof retractedSignal === "string") {
|
|
30610
|
+
retracted.add(`${agentId}:${taskKey}:${retractedSignal}`);
|
|
30611
|
+
} else {
|
|
30612
|
+
retracted.add(`${agentId}:${taskKey}:*`);
|
|
30613
|
+
}
|
|
30614
|
+
}
|
|
30615
|
+
}
|
|
30616
|
+
for (const r of rows) {
|
|
30617
|
+
if (r.type !== "consensus") continue;
|
|
30618
|
+
const signal = r.signal;
|
|
30619
|
+
if (!signal) continue;
|
|
30620
|
+
if (!CORRECT_SIGNALS.has(signal) && !HALLUC_SIGNALS.has(signal)) continue;
|
|
30621
|
+
const agentId = r.agentId;
|
|
30622
|
+
const category = r.category;
|
|
30623
|
+
const tsStr = r.timestamp;
|
|
30624
|
+
if (!agentId || !category || !tsStr) continue;
|
|
30625
|
+
const ts2 = new Date(tsStr).getTime();
|
|
30626
|
+
if (!Number.isFinite(ts2) || ts2 === 0) continue;
|
|
30627
|
+
const taskKey = r.taskId ?? tsStr;
|
|
30628
|
+
if (retracted.has(`${agentId}:${taskKey}:${signal}`)) continue;
|
|
30629
|
+
if (retracted.has(`${agentId}:${taskKey}:*`)) continue;
|
|
30630
|
+
const findingId = r.findingId;
|
|
30631
|
+
if (typeof findingId === "string") {
|
|
30632
|
+
let drop = false;
|
|
30633
|
+
for (const cid of retractedConsensusIds) {
|
|
30634
|
+
if (findingId.startsWith(cid + ":")) {
|
|
30635
|
+
drop = true;
|
|
30636
|
+
break;
|
|
30637
|
+
}
|
|
30638
|
+
}
|
|
30639
|
+
if (drop) continue;
|
|
30640
|
+
}
|
|
30641
|
+
const skillKey = normalizeSkillName(category);
|
|
30642
|
+
if (!skillKey) continue;
|
|
30643
|
+
let perAgent = idx.byAgentSkill.get(agentId);
|
|
30644
|
+
if (!perAgent) {
|
|
30645
|
+
perAgent = /* @__PURE__ */ new Map();
|
|
30646
|
+
idx.byAgentSkill.set(agentId, perAgent);
|
|
30647
|
+
}
|
|
30648
|
+
let arr = perAgent.get(skillKey);
|
|
30649
|
+
if (!arr) {
|
|
30650
|
+
arr = [];
|
|
30651
|
+
perAgent.set(skillKey, arr);
|
|
30652
|
+
}
|
|
30653
|
+
arr.push({ ts: ts2, signal });
|
|
30654
|
+
}
|
|
30655
|
+
for (const perAgent of idx.byAgentSkill.values()) {
|
|
30656
|
+
for (const arr of perAgent.values()) arr.sort((a, b) => a.ts - b.ts);
|
|
30657
|
+
}
|
|
30658
|
+
return idx;
|
|
30659
|
+
}
|
|
30660
|
+
function deriveEffectiveness(projectRoot, index, signalIdx, nowMs) {
|
|
30661
|
+
const out = [];
|
|
30662
|
+
for (const agentId of index.getAgentIds()) {
|
|
30663
|
+
for (const slot of index.getAgentSlots(agentId)) {
|
|
30664
|
+
if (!slot.enabled) continue;
|
|
30665
|
+
const fm = readSkillFrontmatter2(projectRoot, agentId, slot.skill);
|
|
30666
|
+
const boundAtIso = fm?.bound_at ?? slot.boundAt;
|
|
30667
|
+
const boundAtMs = new Date(boundAtIso).getTime();
|
|
30668
|
+
if (!Number.isFinite(boundAtMs) || boundAtMs <= 0) continue;
|
|
30669
|
+
const windowStartMs = Math.max(boundAtMs, nowMs - WINDOW_MS2);
|
|
30670
|
+
const totalSpan = Math.max(nowMs - windowStartMs, NUM_BUCKETS);
|
|
30671
|
+
const bucketMs = totalSpan / NUM_BUCKETS;
|
|
30672
|
+
const events = signalIdx.byAgentSkill.get(agentId)?.get(normalizeSkillName(slot.skill)) ?? [];
|
|
30673
|
+
const buckets = Array.from(
|
|
30674
|
+
{ length: NUM_BUCKETS },
|
|
30675
|
+
() => ({ c: 0, h: 0 })
|
|
30676
|
+
);
|
|
30677
|
+
let n = 0;
|
|
30678
|
+
for (const ev of events) {
|
|
30679
|
+
if (ev.ts < windowStartMs) continue;
|
|
30680
|
+
const rel = ev.ts - windowStartMs;
|
|
30681
|
+
let i = Math.floor(rel / bucketMs);
|
|
30682
|
+
if (i < 0) i = 0;
|
|
30683
|
+
if (i >= NUM_BUCKETS) i = NUM_BUCKETS - 1;
|
|
30684
|
+
if (CORRECT_SIGNALS.has(ev.signal)) buckets[i].c++;
|
|
30685
|
+
else if (HALLUC_SIGNALS.has(ev.signal)) buckets[i].h++;
|
|
30686
|
+
n++;
|
|
30687
|
+
}
|
|
30688
|
+
const curve = buckets.map((b, i) => {
|
|
30689
|
+
const total = b.c + b.h;
|
|
30690
|
+
const t = windowStartMs + (i + 1) * bucketMs;
|
|
30691
|
+
return { t, value: total > 0 ? b.c / total : null };
|
|
30692
|
+
});
|
|
30693
|
+
const threshold = fm?.passed_baseline_rate ?? DEFAULT_THRESHOLD;
|
|
30694
|
+
const status = fm?.status ?? null;
|
|
30695
|
+
out.push({
|
|
30696
|
+
agentId,
|
|
30697
|
+
skill: slot.skill,
|
|
30698
|
+
status,
|
|
30699
|
+
curve,
|
|
30700
|
+
threshold,
|
|
30701
|
+
n,
|
|
30702
|
+
boundAt: boundAtIso
|
|
30703
|
+
});
|
|
30704
|
+
}
|
|
30705
|
+
}
|
|
30706
|
+
return out;
|
|
30707
|
+
}
|
|
30708
|
+
function jsonlMtime(projectRoot) {
|
|
30709
|
+
try {
|
|
30710
|
+
return (0, import_fs52.statSync)((0, import_path56.join)(projectRoot, ".gossip", "agent-performance.jsonl")).mtimeMs;
|
|
30711
|
+
} catch {
|
|
30712
|
+
return 0;
|
|
30713
|
+
}
|
|
30714
|
+
}
|
|
30715
|
+
function cacheHit(projectRoot, nowMs) {
|
|
30716
|
+
const entry = cache2.get(projectRoot);
|
|
30717
|
+
if (!entry) return null;
|
|
30718
|
+
if (nowMs - entry.builtAtMs > CACHE_TTL_MS) return null;
|
|
30719
|
+
if (entry.jsonlMtimeMs !== jsonlMtime(projectRoot)) return null;
|
|
30720
|
+
return entry.payload;
|
|
30721
|
+
}
|
|
30534
30722
|
async function skillsGetHandler(projectRoot) {
|
|
30723
|
+
const nowMs = Date.now();
|
|
30724
|
+
const cached4 = cacheHit(projectRoot, nowMs);
|
|
30725
|
+
if (cached4) return cached4;
|
|
30535
30726
|
try {
|
|
30536
30727
|
const index = new SkillIndex(projectRoot);
|
|
30537
|
-
|
|
30728
|
+
let effectiveness = [];
|
|
30729
|
+
try {
|
|
30730
|
+
const signalIdx = buildSignalIndex(projectRoot);
|
|
30731
|
+
effectiveness = deriveEffectiveness(projectRoot, index, signalIdx, nowMs);
|
|
30732
|
+
} catch {
|
|
30733
|
+
}
|
|
30734
|
+
const payload = {
|
|
30735
|
+
index: index.getIndex(),
|
|
30736
|
+
suggestions: [],
|
|
30737
|
+
effectiveness
|
|
30738
|
+
};
|
|
30739
|
+
cache2.set(projectRoot, {
|
|
30740
|
+
payload,
|
|
30741
|
+
builtAtMs: nowMs,
|
|
30742
|
+
jsonlMtimeMs: jsonlMtime(projectRoot)
|
|
30743
|
+
});
|
|
30744
|
+
return payload;
|
|
30538
30745
|
} catch {
|
|
30539
|
-
return { index: {}, suggestions: [] };
|
|
30746
|
+
return { index: {}, suggestions: [], effectiveness: [] };
|
|
30540
30747
|
}
|
|
30541
30748
|
}
|
|
30542
30749
|
async function skillsBindHandler(projectRoot, body) {
|
|
@@ -30553,19 +30760,33 @@ async function skillsBindHandler(projectRoot, body) {
|
|
|
30553
30760
|
const changed = index.disable(body.agent_id, body.skill);
|
|
30554
30761
|
if (!changed) return { success: false, error: "Skill not bound to agent" };
|
|
30555
30762
|
}
|
|
30763
|
+
cache2.delete(projectRoot);
|
|
30556
30764
|
return { success: true };
|
|
30557
30765
|
} catch (err) {
|
|
30558
30766
|
return { success: false, error: err instanceof Error ? err.message : "Unknown error" };
|
|
30559
30767
|
}
|
|
30560
30768
|
}
|
|
30561
|
-
var import_fs52, import_path56, AGENT_ID_RE2;
|
|
30769
|
+
var import_fs52, import_path56, AGENT_ID_RE2, NUM_BUCKETS, WINDOW_MS2, DEFAULT_THRESHOLD, CACHE_TTL_MS, CORRECT_SIGNALS, HALLUC_SIGNALS, cache2;
|
|
30562
30770
|
var init_api_skills = __esm({
|
|
30563
30771
|
"packages/relay/src/dashboard/api-skills.ts"() {
|
|
30564
30772
|
"use strict";
|
|
30565
30773
|
init_skill_index();
|
|
30774
|
+
init_src4();
|
|
30566
30775
|
import_fs52 = require("fs");
|
|
30567
30776
|
import_path56 = require("path");
|
|
30568
30777
|
AGENT_ID_RE2 = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
30778
|
+
NUM_BUCKETS = 10;
|
|
30779
|
+
WINDOW_MS2 = 7 * 24 * 60 * 60 * 1e3;
|
|
30780
|
+
DEFAULT_THRESHOLD = 0.7;
|
|
30781
|
+
CACHE_TTL_MS = 6e4;
|
|
30782
|
+
CORRECT_SIGNALS = /* @__PURE__ */ new Set([
|
|
30783
|
+
"agreement",
|
|
30784
|
+
"category_confirmed",
|
|
30785
|
+
"consensus_verified",
|
|
30786
|
+
"unique_confirmed"
|
|
30787
|
+
]);
|
|
30788
|
+
HALLUC_SIGNALS = /* @__PURE__ */ new Set(["disagreement", "hallucination_caught"]);
|
|
30789
|
+
cache2 = /* @__PURE__ */ new Map();
|
|
30569
30790
|
}
|
|
30570
30791
|
});
|
|
30571
30792
|
|
|
@@ -30849,6 +31070,123 @@ var init_api_consensus = __esm({
|
|
|
30849
31070
|
}
|
|
30850
31071
|
});
|
|
30851
31072
|
|
|
31073
|
+
// packages/relay/src/dashboard/api-consensus-flow.ts
|
|
31074
|
+
function isValidConsensusId(id) {
|
|
31075
|
+
return SAFE_CONSENSUS_ID.test(id);
|
|
31076
|
+
}
|
|
31077
|
+
function familyOf(agentId) {
|
|
31078
|
+
if (agentId.startsWith("sonnet-")) return "sonnet";
|
|
31079
|
+
if (agentId.startsWith("gemini-")) return "gemini";
|
|
31080
|
+
if (agentId.startsWith("opus-")) return "opus";
|
|
31081
|
+
if (agentId.startsWith("haiku-")) return "haiku";
|
|
31082
|
+
return "other";
|
|
31083
|
+
}
|
|
31084
|
+
function tally(report, bucket) {
|
|
31085
|
+
const arr = report?.[bucket];
|
|
31086
|
+
return Array.isArray(arr) ? arr : [];
|
|
31087
|
+
}
|
|
31088
|
+
function consensusFlowHandler(projectRoot, query) {
|
|
31089
|
+
const consensusId = query?.get("consensusId")?.trim() ?? "";
|
|
31090
|
+
if (!consensusId) {
|
|
31091
|
+
return { error: "consensusId query parameter is required" };
|
|
31092
|
+
}
|
|
31093
|
+
if (!isValidConsensusId(consensusId)) {
|
|
31094
|
+
return { error: `invalid consensusId shape (expected xxxxxxxx-xxxxxxxx hex)` };
|
|
31095
|
+
}
|
|
31096
|
+
const reportPath = (0, import_path61.join)(projectRoot, ".gossip", "consensus-reports", `${consensusId}.json`);
|
|
31097
|
+
if (!(0, import_fs56.existsSync)(reportPath)) {
|
|
31098
|
+
return { error: `consensus ${consensusId} not found` };
|
|
31099
|
+
}
|
|
31100
|
+
let report;
|
|
31101
|
+
try {
|
|
31102
|
+
report = JSON.parse((0, import_fs56.readFileSync)(reportPath, "utf-8"));
|
|
31103
|
+
} catch (e) {
|
|
31104
|
+
return { error: `failed to parse consensus report: ${e?.message ?? "unknown error"}` };
|
|
31105
|
+
}
|
|
31106
|
+
const buckets = {
|
|
31107
|
+
confirmed: tally(report, "confirmed"),
|
|
31108
|
+
disputed: tally(report, "disputed"),
|
|
31109
|
+
unverified: tally(report, "unverified"),
|
|
31110
|
+
unique: tally(report, "unique")
|
|
31111
|
+
};
|
|
31112
|
+
const newFindings = Array.isArray(report?.newFindings) ? report.newFindings : [];
|
|
31113
|
+
const totalFindings = buckets.confirmed.length + buckets.disputed.length + buckets.unverified.length + buckets.unique.length + newFindings.length;
|
|
31114
|
+
const familyAgents = /* @__PURE__ */ new Map();
|
|
31115
|
+
for (const verdict of ["confirmed", "disputed", "unverified", "unique"]) {
|
|
31116
|
+
for (const f of buckets[verdict]) {
|
|
31117
|
+
const agent = f.originalAgentId;
|
|
31118
|
+
if (!agent) continue;
|
|
31119
|
+
const fam = familyOf(agent);
|
|
31120
|
+
if (!familyAgents.has(fam)) familyAgents.set(fam, /* @__PURE__ */ new Set());
|
|
31121
|
+
familyAgents.get(fam).add(agent);
|
|
31122
|
+
}
|
|
31123
|
+
}
|
|
31124
|
+
const modelFamilyToFindings = Array.from(familyAgents.entries()).map(([family, ids]) => ({
|
|
31125
|
+
family,
|
|
31126
|
+
agentIds: Array.from(ids).sort(),
|
|
31127
|
+
agentCount: ids.size
|
|
31128
|
+
})).sort((a, b) => a.family.localeCompare(b.family));
|
|
31129
|
+
const edgeCounts = /* @__PURE__ */ new Map();
|
|
31130
|
+
for (const verdict of ["confirmed", "disputed", "unverified", "unique"]) {
|
|
31131
|
+
for (const f of buckets[verdict]) {
|
|
31132
|
+
const agent = f.originalAgentId;
|
|
31133
|
+
if (!agent) continue;
|
|
31134
|
+
const fam = familyOf(agent);
|
|
31135
|
+
const key = `${fam}::${verdict}`;
|
|
31136
|
+
edgeCounts.set(key, (edgeCounts.get(key) ?? 0) + 1);
|
|
31137
|
+
}
|
|
31138
|
+
}
|
|
31139
|
+
const familyToOutcome = [];
|
|
31140
|
+
for (const [key, count] of edgeCounts) {
|
|
31141
|
+
const [fam, verdict] = key.split("::");
|
|
31142
|
+
const agentCount = familyAgents.get(fam)?.size ?? 0;
|
|
31143
|
+
familyToOutcome.push({
|
|
31144
|
+
from: { family: fam, agentCount },
|
|
31145
|
+
to: { verdict, count },
|
|
31146
|
+
weight: totalFindings > 0 ? count / totalFindings : 0
|
|
31147
|
+
});
|
|
31148
|
+
}
|
|
31149
|
+
familyToOutcome.sort((a, b) => {
|
|
31150
|
+
if (a.from.family !== b.from.family) return a.from.family.localeCompare(b.from.family);
|
|
31151
|
+
return a.to.verdict.localeCompare(b.to.verdict);
|
|
31152
|
+
});
|
|
31153
|
+
const out = {
|
|
31154
|
+
consensusId,
|
|
31155
|
+
timestamp: typeof report?.timestamp === "string" ? report.timestamp : "",
|
|
31156
|
+
agentCount: typeof report?.agentCount === "number" ? report.agentCount : 0,
|
|
31157
|
+
modelFamilyToFindings,
|
|
31158
|
+
familyToOutcome,
|
|
31159
|
+
summary: {
|
|
31160
|
+
totalFindings,
|
|
31161
|
+
confirmed: buckets.confirmed.length,
|
|
31162
|
+
disputed: buckets.disputed.length,
|
|
31163
|
+
unverified: buckets.unverified.length,
|
|
31164
|
+
unique: buckets.unique.length,
|
|
31165
|
+
newFindings: newFindings.length
|
|
31166
|
+
}
|
|
31167
|
+
};
|
|
31168
|
+
if (report?.crossReviewAssignments && typeof report.crossReviewAssignments === "object") {
|
|
31169
|
+
out.crossReviewAssignments = report.crossReviewAssignments;
|
|
31170
|
+
}
|
|
31171
|
+
if (Array.isArray(report?.crossReviewCoverage)) {
|
|
31172
|
+
out.crossReviewCoverage = report.crossReviewCoverage;
|
|
31173
|
+
}
|
|
31174
|
+
if (report?.partialReview === true) out.partialReview = true;
|
|
31175
|
+
if (report?.coverageDegraded && typeof report.coverageDegraded === "object") {
|
|
31176
|
+
out.coverageDegraded = report.coverageDegraded;
|
|
31177
|
+
}
|
|
31178
|
+
return out;
|
|
31179
|
+
}
|
|
31180
|
+
var import_fs56, import_path61, SAFE_CONSENSUS_ID;
|
|
31181
|
+
var init_api_consensus_flow = __esm({
|
|
31182
|
+
"packages/relay/src/dashboard/api-consensus-flow.ts"() {
|
|
31183
|
+
"use strict";
|
|
31184
|
+
import_fs56 = require("fs");
|
|
31185
|
+
import_path61 = require("path");
|
|
31186
|
+
SAFE_CONSENSUS_ID = /^[0-9a-f]{8}-[0-9a-f]{8}$/;
|
|
31187
|
+
}
|
|
31188
|
+
});
|
|
31189
|
+
|
|
30852
31190
|
// packages/relay/src/dashboard/api-signals.ts
|
|
30853
31191
|
function inferSource(entry) {
|
|
30854
31192
|
const raw = typeof entry.source === "string" ? entry.source.toLowerCase() : "";
|
|
@@ -30874,7 +31212,7 @@ async function signalsHandler(projectRoot, query) {
|
|
|
30874
31212
|
const cursor = query?.get("cursor") ?? null;
|
|
30875
31213
|
const limit = Math.min(Math.max(parseInt(query?.get("limit") ?? "", 10) || DEFAULT_LIMIT, 1), MAX_LIMIT);
|
|
30876
31214
|
const offset = Math.max(parseInt(query?.get("offset") ?? "", 10) || 0, 0);
|
|
30877
|
-
const perfPath = (0,
|
|
31215
|
+
const perfPath = (0, import_path62.join)(projectRoot, ".gossip", "agent-performance.jsonl");
|
|
30878
31216
|
const all = [];
|
|
30879
31217
|
const roundRetractions = [];
|
|
30880
31218
|
const signalFilterSet = signalFilters.length ? new Set(signalFilters) : null;
|
|
@@ -30936,11 +31274,11 @@ async function signalsHandler(projectRoot, query) {
|
|
|
30936
31274
|
if (nextCursor) response.nextCursor = nextCursor;
|
|
30937
31275
|
return response;
|
|
30938
31276
|
}
|
|
30939
|
-
var
|
|
31277
|
+
var import_path62, MAX_LIMIT, DEFAULT_LIMIT, META_SIGNALS;
|
|
30940
31278
|
var init_api_signals = __esm({
|
|
30941
31279
|
"packages/relay/src/dashboard/api-signals.ts"() {
|
|
30942
31280
|
"use strict";
|
|
30943
|
-
|
|
31281
|
+
import_path62 = require("path");
|
|
30944
31282
|
init_src4();
|
|
30945
31283
|
MAX_LIMIT = 500;
|
|
30946
31284
|
DEFAULT_LIMIT = 50;
|
|
@@ -30953,7 +31291,7 @@ function extractCitations(findingText, projectRoot) {
|
|
|
30953
31291
|
const out = [];
|
|
30954
31292
|
let realRoot;
|
|
30955
31293
|
try {
|
|
30956
|
-
realRoot = (0,
|
|
31294
|
+
realRoot = (0, import_fs57.realpathSync)((0, import_path63.resolve)(projectRoot));
|
|
30957
31295
|
} catch {
|
|
30958
31296
|
return out;
|
|
30959
31297
|
}
|
|
@@ -30964,23 +31302,23 @@ function extractCitations(findingText, projectRoot) {
|
|
|
30964
31302
|
const line = parseInt(m[2], 10);
|
|
30965
31303
|
if (!Number.isFinite(line) || line < 1) continue;
|
|
30966
31304
|
if (filePath.includes("\0")) continue;
|
|
30967
|
-
const abs = (0,
|
|
30968
|
-
const preRel = (0,
|
|
31305
|
+
const abs = (0, import_path63.resolve)(realRoot, filePath);
|
|
31306
|
+
const preRel = (0, import_path63.relative)(realRoot, abs);
|
|
30969
31307
|
if (preRel === "" || preRel.startsWith("..")) continue;
|
|
30970
|
-
if (!(0,
|
|
31308
|
+
if (!(0, import_fs57.existsSync)(abs)) {
|
|
30971
31309
|
out.push({ file: filePath, line, snippet: "// file not found" });
|
|
30972
31310
|
continue;
|
|
30973
31311
|
}
|
|
30974
31312
|
let realAbs;
|
|
30975
31313
|
try {
|
|
30976
|
-
realAbs = (0,
|
|
31314
|
+
realAbs = (0, import_fs57.realpathSync)(abs);
|
|
30977
31315
|
} catch {
|
|
30978
31316
|
continue;
|
|
30979
31317
|
}
|
|
30980
|
-
const rel = (0,
|
|
31318
|
+
const rel = (0, import_path63.relative)(realRoot, realAbs);
|
|
30981
31319
|
if (rel === "" || rel.startsWith("..")) continue;
|
|
30982
31320
|
try {
|
|
30983
|
-
const lines = (0,
|
|
31321
|
+
const lines = (0, import_fs57.readFileSync)(realAbs, "utf-8").split("\n");
|
|
30984
31322
|
const start = Math.max(0, line - 1 - SNIPPET_CONTEXT);
|
|
30985
31323
|
const end = Math.min(lines.length, line + SNIPPET_CONTEXT);
|
|
30986
31324
|
out.push({ file: filePath, line, snippet: lines.slice(start, end).join("\n") });
|
|
@@ -30993,9 +31331,9 @@ function extractCitations(findingText, projectRoot) {
|
|
|
30993
31331
|
async function findingHandler(projectRoot, consensusId, findingId) {
|
|
30994
31332
|
if (!SAFE_ID.test(consensusId)) throw new Error(`consensus ${consensusId} not found`);
|
|
30995
31333
|
if (!SAFE_ID.test(findingId)) throw new Error(`finding ${findingId} not found in ${consensusId}`);
|
|
30996
|
-
const reportPath = (0,
|
|
30997
|
-
if (!(0,
|
|
30998
|
-
const report = JSON.parse((0,
|
|
31334
|
+
const reportPath = (0, import_path63.join)(projectRoot, ".gossip", "consensus-reports", `${consensusId}.json`);
|
|
31335
|
+
if (!(0, import_fs57.existsSync)(reportPath)) throw new Error(`consensus ${consensusId} not found`);
|
|
31336
|
+
const report = JSON.parse((0, import_fs57.readFileSync)(reportPath, "utf-8"));
|
|
30999
31337
|
const buckets = [
|
|
31000
31338
|
["confirmed", "confirmed"],
|
|
31001
31339
|
["disputed", "disputed"],
|
|
@@ -31016,7 +31354,7 @@ async function findingHandler(projectRoot, consensusId, findingId) {
|
|
|
31016
31354
|
}
|
|
31017
31355
|
if (!found) throw new Error(`finding ${findingId} not found in ${consensusId}`);
|
|
31018
31356
|
const signals = [];
|
|
31019
|
-
const perfPath = (0,
|
|
31357
|
+
const perfPath = (0, import_path63.join)(projectRoot, ".gossip", "agent-performance.jsonl");
|
|
31020
31358
|
try {
|
|
31021
31359
|
const raw = readJsonlWithRotated(perfPath);
|
|
31022
31360
|
if (raw) {
|
|
@@ -31058,13 +31396,13 @@ async function findingHandler(projectRoot, consensusId, findingId) {
|
|
|
31058
31396
|
citations
|
|
31059
31397
|
};
|
|
31060
31398
|
}
|
|
31061
|
-
var
|
|
31399
|
+
var import_fs57, import_path63, SAFE_ID, SNIPPET_CONTEXT, CITE_PATTERN;
|
|
31062
31400
|
var init_api_finding = __esm({
|
|
31063
31401
|
"packages/relay/src/dashboard/api-finding.ts"() {
|
|
31064
31402
|
"use strict";
|
|
31065
|
-
|
|
31403
|
+
import_fs57 = require("fs");
|
|
31066
31404
|
init_src4();
|
|
31067
|
-
|
|
31405
|
+
import_path63 = require("path");
|
|
31068
31406
|
SAFE_ID = /^[\w:.\-]+$/;
|
|
31069
31407
|
SNIPPET_CONTEXT = 2;
|
|
31070
31408
|
CITE_PATTERN = /<cite tag="file">([^<:]+):(\d+)<\/cite>/g;
|
|
@@ -31077,13 +31415,13 @@ async function openFindingsHandler(projectRoot) {
|
|
|
31077
31415
|
let open = 0;
|
|
31078
31416
|
let resolved = 0;
|
|
31079
31417
|
let staleAnchor = 0;
|
|
31080
|
-
const findingsPath = (0,
|
|
31081
|
-
if (!(0,
|
|
31418
|
+
const findingsPath = (0, import_path64.join)(projectRoot, ".gossip", "implementation-findings.jsonl");
|
|
31419
|
+
if (!(0, import_fs58.existsSync)(findingsPath)) {
|
|
31082
31420
|
return { rows, totals: { open: 0, resolved: 0, staleAnchor: 0 } };
|
|
31083
31421
|
}
|
|
31084
31422
|
let raw;
|
|
31085
31423
|
try {
|
|
31086
|
-
raw = (0,
|
|
31424
|
+
raw = (0, import_fs58.readFileSync)(findingsPath, "utf-8");
|
|
31087
31425
|
} catch {
|
|
31088
31426
|
return { rows, totals: { open: 0, resolved: 0, staleAnchor: 0 } };
|
|
31089
31427
|
}
|
|
@@ -31121,40 +31459,40 @@ async function openFindingsHandler(projectRoot) {
|
|
|
31121
31459
|
}
|
|
31122
31460
|
return { rows, totals: { open, resolved, staleAnchor } };
|
|
31123
31461
|
}
|
|
31124
|
-
var
|
|
31462
|
+
var import_fs58, import_path64;
|
|
31125
31463
|
var init_api_open_findings = __esm({
|
|
31126
31464
|
"packages/relay/src/dashboard/api-open-findings.ts"() {
|
|
31127
31465
|
"use strict";
|
|
31128
|
-
|
|
31129
|
-
|
|
31466
|
+
import_fs58 = require("fs");
|
|
31467
|
+
import_path64 = require("path");
|
|
31130
31468
|
}
|
|
31131
31469
|
});
|
|
31132
31470
|
|
|
31133
31471
|
// packages/relay/src/dashboard/api-learnings.ts
|
|
31134
31472
|
async function learningsHandler(projectRoot) {
|
|
31135
|
-
const agentsDir = (0,
|
|
31136
|
-
if (!(0,
|
|
31473
|
+
const agentsDir = (0, import_path65.join)(projectRoot, ".gossip", "agents");
|
|
31474
|
+
if (!(0, import_fs59.existsSync)(agentsDir)) return { learnings: [] };
|
|
31137
31475
|
const all = [];
|
|
31138
31476
|
let agentIds;
|
|
31139
31477
|
try {
|
|
31140
|
-
agentIds = (0,
|
|
31478
|
+
agentIds = (0, import_fs59.readdirSync)(agentsDir).filter((f) => !f.startsWith("."));
|
|
31141
31479
|
} catch {
|
|
31142
31480
|
return { learnings: [] };
|
|
31143
31481
|
}
|
|
31144
31482
|
for (const agentId of agentIds) {
|
|
31145
|
-
const knowledgeDir = (0,
|
|
31146
|
-
if (!(0,
|
|
31483
|
+
const knowledgeDir = (0, import_path65.join)(agentsDir, agentId, "memory", "knowledge");
|
|
31484
|
+
if (!(0, import_fs59.existsSync)(knowledgeDir)) continue;
|
|
31147
31485
|
let files;
|
|
31148
31486
|
try {
|
|
31149
|
-
files = (0,
|
|
31487
|
+
files = (0, import_fs59.readdirSync)(knowledgeDir).filter((f) => f.endsWith(".md"));
|
|
31150
31488
|
} catch {
|
|
31151
31489
|
continue;
|
|
31152
31490
|
}
|
|
31153
31491
|
for (const filename of files) {
|
|
31154
|
-
const filepath = (0,
|
|
31492
|
+
const filepath = (0, import_path65.join)(knowledgeDir, filename);
|
|
31155
31493
|
try {
|
|
31156
|
-
const stat4 = (0,
|
|
31157
|
-
const raw = (0,
|
|
31494
|
+
const stat4 = (0, import_fs59.statSync)(filepath);
|
|
31495
|
+
const raw = (0, import_fs59.readFileSync)(filepath, "utf-8");
|
|
31158
31496
|
const fm = parseFrontmatter3(raw);
|
|
31159
31497
|
all.push({
|
|
31160
31498
|
agentId,
|
|
@@ -31181,28 +31519,41 @@ function parseFrontmatter3(raw) {
|
|
|
31181
31519
|
}
|
|
31182
31520
|
return fm;
|
|
31183
31521
|
}
|
|
31184
|
-
var
|
|
31522
|
+
var import_fs59, import_path65, MAX_LEARNINGS;
|
|
31185
31523
|
var init_api_learnings = __esm({
|
|
31186
31524
|
"packages/relay/src/dashboard/api-learnings.ts"() {
|
|
31187
31525
|
"use strict";
|
|
31188
|
-
|
|
31189
|
-
|
|
31526
|
+
import_fs59 = require("fs");
|
|
31527
|
+
import_path65 = require("path");
|
|
31190
31528
|
MAX_LEARNINGS = 10;
|
|
31191
31529
|
}
|
|
31192
31530
|
});
|
|
31193
31531
|
|
|
31194
31532
|
// packages/relay/src/dashboard/api-tasks.ts
|
|
31533
|
+
function readTaskGraphLines(graphPath) {
|
|
31534
|
+
const out = [];
|
|
31535
|
+
const archive = graphPath + ".1";
|
|
31536
|
+
if ((0, import_fs60.existsSync)(archive)) {
|
|
31537
|
+
out.push(...(0, import_fs60.readFileSync)(archive, "utf-8").split("\n").filter(Boolean));
|
|
31538
|
+
}
|
|
31539
|
+
if ((0, import_fs60.existsSync)(graphPath)) {
|
|
31540
|
+
out.push(...(0, import_fs60.readFileSync)(graphPath, "utf-8").split("\n").filter(Boolean));
|
|
31541
|
+
}
|
|
31542
|
+
return out;
|
|
31543
|
+
}
|
|
31195
31544
|
async function tasksHandler(projectRoot, query) {
|
|
31196
31545
|
const rawLimit = parseInt(query?.get("limit") ?? "50", 10);
|
|
31197
31546
|
const rawOffset = parseInt(query?.get("offset") ?? "0", 10);
|
|
31198
31547
|
const limit = isNaN(rawLimit) || rawLimit < 1 ? 50 : Math.min(rawLimit, 2e3);
|
|
31199
31548
|
const offset = isNaN(rawOffset) || rawOffset < 0 ? 0 : rawOffset;
|
|
31200
|
-
const graphPath = (0,
|
|
31201
|
-
if (!(0,
|
|
31549
|
+
const graphPath = (0, import_path66.join)(projectRoot, ".gossip", "task-graph.jsonl");
|
|
31550
|
+
if (!(0, import_fs60.existsSync)(graphPath) && !(0, import_fs60.existsSync)(graphPath + ".1")) {
|
|
31551
|
+
return { items: [], total: 0, offset, limit };
|
|
31552
|
+
}
|
|
31202
31553
|
const created = /* @__PURE__ */ new Map();
|
|
31203
31554
|
const completed = /* @__PURE__ */ new Map();
|
|
31204
31555
|
try {
|
|
31205
|
-
const lines = (
|
|
31556
|
+
const lines = readTaskGraphLines(graphPath);
|
|
31206
31557
|
for (const line of lines) {
|
|
31207
31558
|
try {
|
|
31208
31559
|
const entry = JSON.parse(line);
|
|
@@ -31258,24 +31609,24 @@ async function tasksHandler(projectRoot, query) {
|
|
|
31258
31609
|
tasks.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
31259
31610
|
return { items: tasks.slice(offset, offset + limit), total: tasks.length, offset, limit };
|
|
31260
31611
|
}
|
|
31261
|
-
var
|
|
31612
|
+
var import_fs60, import_path66;
|
|
31262
31613
|
var init_api_tasks = __esm({
|
|
31263
31614
|
"packages/relay/src/dashboard/api-tasks.ts"() {
|
|
31264
31615
|
"use strict";
|
|
31265
|
-
|
|
31266
|
-
|
|
31616
|
+
import_fs60 = require("fs");
|
|
31617
|
+
import_path66 = require("path");
|
|
31267
31618
|
init_utility_agents();
|
|
31268
31619
|
}
|
|
31269
31620
|
});
|
|
31270
31621
|
|
|
31271
31622
|
// packages/relay/src/dashboard/api-active-tasks.ts
|
|
31272
31623
|
async function activeTasksHandler(projectRoot) {
|
|
31273
|
-
const taskGraphPath = (0,
|
|
31274
|
-
if (!(0,
|
|
31624
|
+
const taskGraphPath = (0, import_path67.join)(projectRoot, ".gossip", "task-graph.jsonl");
|
|
31625
|
+
if (!(0, import_fs61.existsSync)(taskGraphPath)) return { tasks: [] };
|
|
31275
31626
|
const created = /* @__PURE__ */ new Map();
|
|
31276
31627
|
const finished = /* @__PURE__ */ new Set();
|
|
31277
31628
|
try {
|
|
31278
|
-
const lines = (0,
|
|
31629
|
+
const lines = (0, import_fs61.readFileSync)(taskGraphPath, "utf-8").trim().split("\n").filter(Boolean);
|
|
31279
31630
|
for (const line of lines) {
|
|
31280
31631
|
try {
|
|
31281
31632
|
const ev = JSON.parse(line);
|
|
@@ -31303,12 +31654,12 @@ async function activeTasksHandler(projectRoot) {
|
|
|
31303
31654
|
active.sort((a, b) => b.startedAt.localeCompare(a.startedAt));
|
|
31304
31655
|
return { tasks: active.slice(0, 10) };
|
|
31305
31656
|
}
|
|
31306
|
-
var
|
|
31657
|
+
var import_fs61, import_path67;
|
|
31307
31658
|
var init_api_active_tasks = __esm({
|
|
31308
31659
|
"packages/relay/src/dashboard/api-active-tasks.ts"() {
|
|
31309
31660
|
"use strict";
|
|
31310
|
-
|
|
31311
|
-
|
|
31661
|
+
import_fs61 = require("fs");
|
|
31662
|
+
import_path67 = require("path");
|
|
31312
31663
|
init_utility_agents();
|
|
31313
31664
|
}
|
|
31314
31665
|
});
|
|
@@ -31322,25 +31673,25 @@ function categorize(text) {
|
|
|
31322
31673
|
return "other";
|
|
31323
31674
|
}
|
|
31324
31675
|
function logsHandler(projectRoot, query) {
|
|
31325
|
-
const logPath = (0,
|
|
31326
|
-
if (!(0,
|
|
31676
|
+
const logPath = (0, import_path68.join)(projectRoot, ".gossip", "mcp.log");
|
|
31677
|
+
if (!(0, import_fs62.existsSync)(logPath)) {
|
|
31327
31678
|
return { entries: [], totalLines: 0, fileSize: 0 };
|
|
31328
31679
|
}
|
|
31329
31680
|
const filter = query?.get("filter") || void 0;
|
|
31330
31681
|
const tail = parseInt(query?.get("tail") || "200", 10);
|
|
31331
31682
|
const clampedTail = Math.min(Math.max(tail, 10), 2e3);
|
|
31332
|
-
const fileSize = (0,
|
|
31683
|
+
const fileSize = (0, import_fs62.statSync)(logPath).size;
|
|
31333
31684
|
const MAX_READ = 512 * 1024;
|
|
31334
31685
|
const readFrom = Math.max(0, fileSize - MAX_READ);
|
|
31335
31686
|
const readLen = fileSize - readFrom;
|
|
31336
|
-
const fd = (0,
|
|
31687
|
+
const fd = (0, import_fs62.openSync)(logPath, "r");
|
|
31337
31688
|
let buf = Buffer.alloc(0);
|
|
31338
31689
|
try {
|
|
31339
31690
|
buf = Buffer.allocUnsafe(readLen);
|
|
31340
|
-
const bytesRead = (0,
|
|
31691
|
+
const bytesRead = (0, import_fs62.readSync)(fd, buf, 0, readLen, readFrom);
|
|
31341
31692
|
buf = buf.subarray(0, bytesRead);
|
|
31342
31693
|
} finally {
|
|
31343
|
-
(0,
|
|
31694
|
+
(0, import_fs62.closeSync)(fd);
|
|
31344
31695
|
}
|
|
31345
31696
|
let raw = buf.toString("utf-8");
|
|
31346
31697
|
let lineOffset = 0;
|
|
@@ -31348,13 +31699,13 @@ function logsHandler(projectRoot, query) {
|
|
|
31348
31699
|
const nl = raw.indexOf("\n");
|
|
31349
31700
|
raw = nl >= 0 ? raw.slice(nl + 1) : raw;
|
|
31350
31701
|
const SCAN_CHUNK = 64 * 1024;
|
|
31351
|
-
const scanFd = (0,
|
|
31702
|
+
const scanFd = (0, import_fs62.openSync)(logPath, "r");
|
|
31352
31703
|
try {
|
|
31353
31704
|
let pos = 0;
|
|
31354
31705
|
const chunk = Buffer.allocUnsafe(SCAN_CHUNK);
|
|
31355
31706
|
while (pos < readFrom) {
|
|
31356
31707
|
const len = Math.min(SCAN_CHUNK, readFrom - pos);
|
|
31357
|
-
const n = (0,
|
|
31708
|
+
const n = (0, import_fs62.readSync)(scanFd, chunk, 0, len, pos);
|
|
31358
31709
|
if (n === 0) break;
|
|
31359
31710
|
for (let j = 0; j < n; j++) {
|
|
31360
31711
|
if (chunk[j] === 10) lineOffset++;
|
|
@@ -31362,7 +31713,7 @@ function logsHandler(projectRoot, query) {
|
|
|
31362
31713
|
pos += n;
|
|
31363
31714
|
}
|
|
31364
31715
|
} finally {
|
|
31365
|
-
(0,
|
|
31716
|
+
(0, import_fs62.closeSync)(scanFd);
|
|
31366
31717
|
}
|
|
31367
31718
|
}
|
|
31368
31719
|
const allLines = raw.split("\n").filter(Boolean);
|
|
@@ -31380,12 +31731,12 @@ function logsHandler(projectRoot, query) {
|
|
|
31380
31731
|
entries = entries.slice(-clampedTail);
|
|
31381
31732
|
return { entries, totalLines, fileSize, filter };
|
|
31382
31733
|
}
|
|
31383
|
-
var
|
|
31734
|
+
var import_fs62, import_path68, CATEGORY_PATTERNS2;
|
|
31384
31735
|
var init_api_logs = __esm({
|
|
31385
31736
|
"packages/relay/src/dashboard/api-logs.ts"() {
|
|
31386
31737
|
"use strict";
|
|
31387
|
-
|
|
31388
|
-
|
|
31738
|
+
import_fs62 = require("fs");
|
|
31739
|
+
import_path68 = require("path");
|
|
31389
31740
|
CATEGORY_PATTERNS2 = [
|
|
31390
31741
|
[/^\[worker:/, "worker"],
|
|
31391
31742
|
[/^\[Gemini\]/, "gemini"],
|
|
@@ -31417,11 +31768,11 @@ function violationsHandler(projectRoot, query) {
|
|
|
31417
31768
|
const page = Math.max(1, parseInt(query?.get("page") ?? "1", 10));
|
|
31418
31769
|
const pageSize = Math.min(100, Math.max(1, parseInt(query?.get("pageSize") ?? "25", 10)));
|
|
31419
31770
|
const agentFilter = query?.get("agentId") ?? null;
|
|
31420
|
-
const filePath = (0,
|
|
31421
|
-
if (!(0,
|
|
31771
|
+
const filePath = (0, import_path69.join)(projectRoot, FILE);
|
|
31772
|
+
if (!(0, import_fs63.existsSync)(filePath)) {
|
|
31422
31773
|
return { items: [], total: 0, page, pageSize };
|
|
31423
31774
|
}
|
|
31424
|
-
const raw = (0,
|
|
31775
|
+
const raw = (0, import_fs63.readFileSync)(filePath, "utf-8");
|
|
31425
31776
|
const lines = raw.trim().split("\n").filter(Boolean);
|
|
31426
31777
|
const entries = [];
|
|
31427
31778
|
for (const line of lines) {
|
|
@@ -31441,12 +31792,12 @@ function violationsHandler(projectRoot, query) {
|
|
|
31441
31792
|
const start = (page - 1) * pageSize;
|
|
31442
31793
|
return { items: entries.slice(start, start + pageSize), total, page, pageSize };
|
|
31443
31794
|
}
|
|
31444
|
-
var
|
|
31795
|
+
var import_fs63, import_path69, FILE;
|
|
31445
31796
|
var init_api_violations = __esm({
|
|
31446
31797
|
"packages/relay/src/dashboard/api-violations.ts"() {
|
|
31447
31798
|
"use strict";
|
|
31448
|
-
|
|
31449
|
-
|
|
31799
|
+
import_fs63 = require("fs");
|
|
31800
|
+
import_path69 = require("path");
|
|
31450
31801
|
FILE = ".gossip/process-violations.jsonl";
|
|
31451
31802
|
}
|
|
31452
31803
|
});
|
|
@@ -31454,15 +31805,15 @@ var init_api_violations = __esm({
|
|
|
31454
31805
|
// packages/relay/src/dashboard/routes.ts
|
|
31455
31806
|
function resolveDashboardRoot(projectRoot) {
|
|
31456
31807
|
const candidates = [
|
|
31457
|
-
(0,
|
|
31808
|
+
(0, import_path70.resolve)(__dirname, "..", "dist-dashboard"),
|
|
31458
31809
|
// bundled: dist-mcp/mcp-server.js → ../dist-dashboard
|
|
31459
|
-
(0,
|
|
31810
|
+
(0, import_path70.resolve)(__dirname, "..", "..", "..", "..", "dist-dashboard"),
|
|
31460
31811
|
// tsc dev: packages/relay/dist/dashboard → repo-root
|
|
31461
|
-
(0,
|
|
31812
|
+
(0, import_path70.join)(projectRoot, "dist-dashboard")
|
|
31462
31813
|
// legacy dev fallback (git-clone running from repo root)
|
|
31463
31814
|
];
|
|
31464
31815
|
for (const p of candidates) {
|
|
31465
|
-
if ((0,
|
|
31816
|
+
if ((0, import_fs64.existsSync)(p)) return p;
|
|
31466
31817
|
}
|
|
31467
31818
|
return null;
|
|
31468
31819
|
}
|
|
@@ -31489,7 +31840,7 @@ function readBody(req) {
|
|
|
31489
31840
|
});
|
|
31490
31841
|
});
|
|
31491
31842
|
}
|
|
31492
|
-
var
|
|
31843
|
+
var import_fs64, import_path70, import_crypto25, AUTH_MAX_ATTEMPTS, AUTH_LOCKOUT_MS, DashboardRouter, MAX_BODY_SIZE;
|
|
31493
31844
|
var init_routes = __esm({
|
|
31494
31845
|
"packages/relay/src/dashboard/routes.ts"() {
|
|
31495
31846
|
"use strict";
|
|
@@ -31502,6 +31853,7 @@ var init_routes = __esm({
|
|
|
31502
31853
|
init_api_native_memory();
|
|
31503
31854
|
init_api_gossip_memory();
|
|
31504
31855
|
init_api_consensus();
|
|
31856
|
+
init_api_consensus_flow();
|
|
31505
31857
|
init_api_signals();
|
|
31506
31858
|
init_api_finding();
|
|
31507
31859
|
init_api_open_findings();
|
|
@@ -31510,8 +31862,8 @@ var init_routes = __esm({
|
|
|
31510
31862
|
init_api_active_tasks();
|
|
31511
31863
|
init_api_logs();
|
|
31512
31864
|
init_api_violations();
|
|
31513
|
-
|
|
31514
|
-
|
|
31865
|
+
import_fs64 = require("fs");
|
|
31866
|
+
import_path70 = require("path");
|
|
31515
31867
|
import_crypto25 = require("crypto");
|
|
31516
31868
|
AUTH_MAX_ATTEMPTS = 10;
|
|
31517
31869
|
AUTH_LOCKOUT_MS = 6e4;
|
|
@@ -31574,6 +31926,11 @@ var init_routes = __esm({
|
|
|
31574
31926
|
if (url2 === "/dashboard") {
|
|
31575
31927
|
return this.serveDashboard(res);
|
|
31576
31928
|
}
|
|
31929
|
+
if (url2 === "/" || url2 === "") {
|
|
31930
|
+
res.writeHead(302, { Location: "/dashboard" });
|
|
31931
|
+
res.end();
|
|
31932
|
+
return true;
|
|
31933
|
+
}
|
|
31577
31934
|
this.json(res, 404, { error: "Not found" });
|
|
31578
31935
|
return true;
|
|
31579
31936
|
}
|
|
@@ -31690,6 +32047,24 @@ var init_routes = __esm({
|
|
|
31690
32047
|
this.json(res, 200, data);
|
|
31691
32048
|
return true;
|
|
31692
32049
|
}
|
|
32050
|
+
if (url2 === "/dashboard/api/consensus-flow" && req.method === "GET") {
|
|
32051
|
+
const consensusId = query?.get("consensusId")?.trim() ?? "";
|
|
32052
|
+
if (!consensusId) {
|
|
32053
|
+
this.json(res, 400, { error: "consensusId query parameter is required" });
|
|
32054
|
+
return true;
|
|
32055
|
+
}
|
|
32056
|
+
if (!isValidConsensusId(consensusId)) {
|
|
32057
|
+
this.json(res, 400, { error: "invalid consensusId shape (expected xxxxxxxx-xxxxxxxx hex)" });
|
|
32058
|
+
return true;
|
|
32059
|
+
}
|
|
32060
|
+
const data = consensusFlowHandler(this.projectRoot, query ?? void 0);
|
|
32061
|
+
if ("error" in data) {
|
|
32062
|
+
this.json(res, 404, data);
|
|
32063
|
+
return true;
|
|
32064
|
+
}
|
|
32065
|
+
this.json(res, 200, data);
|
|
32066
|
+
return true;
|
|
32067
|
+
}
|
|
31693
32068
|
if (url2 === "/dashboard/api/consensus-reports" && req.method === "GET") {
|
|
31694
32069
|
const page = parseInt(query?.get("page") || "1", 10);
|
|
31695
32070
|
const pageSize = parseInt(query?.get("pageSize") || "5", 10);
|
|
@@ -31792,13 +32167,13 @@ var init_routes = __esm({
|
|
|
31792
32167
|
res.end("Dashboard assets not found. Reinstall gossipcat or rebuild from source.");
|
|
31793
32168
|
return true;
|
|
31794
32169
|
}
|
|
31795
|
-
const htmlPath = (0,
|
|
31796
|
-
if (!(0,
|
|
32170
|
+
const htmlPath = (0, import_path70.join)(this.dashboardRoot, "index.html");
|
|
32171
|
+
if (!(0, import_fs64.existsSync)(htmlPath)) {
|
|
31797
32172
|
res.writeHead(503, { "Content-Type": "text/plain" });
|
|
31798
32173
|
res.end(`Dashboard index.html missing at ${this.dashboardRoot}. Reinstall gossipcat.`);
|
|
31799
32174
|
return true;
|
|
31800
32175
|
}
|
|
31801
|
-
const html = (0,
|
|
32176
|
+
const html = (0, import_fs64.readFileSync)(htmlPath, "utf-8");
|
|
31802
32177
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
31803
32178
|
res.end(html);
|
|
31804
32179
|
return true;
|
|
@@ -31824,16 +32199,16 @@ var init_routes = __esm({
|
|
|
31824
32199
|
const ext = "." + (relativePath.split(".").pop() || "");
|
|
31825
32200
|
const mime = MIME[ext];
|
|
31826
32201
|
if (!mime) return false;
|
|
31827
|
-
const filePath = (0,
|
|
32202
|
+
const filePath = (0, import_path70.join)(this.dashboardRoot, relativePath);
|
|
31828
32203
|
try {
|
|
31829
|
-
const realFile = (0,
|
|
31830
|
-
const realBase = (0,
|
|
32204
|
+
const realFile = (0, import_fs64.realpathSync)(filePath);
|
|
32205
|
+
const realBase = (0, import_fs64.realpathSync)(this.dashboardRoot);
|
|
31831
32206
|
if (!realFile.startsWith(realBase + "/")) {
|
|
31832
32207
|
res.writeHead(404);
|
|
31833
32208
|
res.end();
|
|
31834
32209
|
return true;
|
|
31835
32210
|
}
|
|
31836
|
-
const data = (0,
|
|
32211
|
+
const data = (0, import_fs64.readFileSync)(realFile);
|
|
31837
32212
|
res.writeHead(200, { "Content-Type": mime, "Cache-Control": "public, max-age=86400" });
|
|
31838
32213
|
res.end(data);
|
|
31839
32214
|
return true;
|
|
@@ -31848,8 +32223,8 @@ var init_routes = __esm({
|
|
|
31848
32223
|
return match ? match[1] : null;
|
|
31849
32224
|
}
|
|
31850
32225
|
getConsensusReports(page = 1, pageSize = 5) {
|
|
31851
|
-
const { readdirSync: readdirSync22, readFileSync:
|
|
31852
|
-
const reportsDir = (0,
|
|
32226
|
+
const { readdirSync: readdirSync22, readFileSync: readFileSync64, existsSync: existsSync70 } = require("fs");
|
|
32227
|
+
const reportsDir = (0, import_path70.join)(this.projectRoot, ".gossip", "consensus-reports");
|
|
31853
32228
|
let retractedConsensusIds = [];
|
|
31854
32229
|
let roundRetractions = [];
|
|
31855
32230
|
try {
|
|
@@ -31859,13 +32234,13 @@ var init_routes = __esm({
|
|
|
31859
32234
|
roundRetractions = reader.getRoundRetractions();
|
|
31860
32235
|
} catch {
|
|
31861
32236
|
}
|
|
31862
|
-
if (!
|
|
32237
|
+
if (!existsSync70(reportsDir)) return { reports: [], totalReports: 0, page, pageSize, retractedConsensusIds, roundRetractions };
|
|
31863
32238
|
try {
|
|
31864
|
-
const { statSync:
|
|
32239
|
+
const { statSync: statSync35 } = require("fs");
|
|
31865
32240
|
const allFiles = readdirSync22(reportsDir).filter((f) => f.endsWith(".json")).sort((a, b) => {
|
|
31866
32241
|
try {
|
|
31867
|
-
const aTime =
|
|
31868
|
-
const bTime =
|
|
32242
|
+
const aTime = statSync35((0, import_path70.join)(reportsDir, a)).mtimeMs;
|
|
32243
|
+
const bTime = statSync35((0, import_path70.join)(reportsDir, b)).mtimeMs;
|
|
31869
32244
|
return bTime - aTime;
|
|
31870
32245
|
} catch {
|
|
31871
32246
|
return 0;
|
|
@@ -31876,13 +32251,13 @@ var init_routes = __esm({
|
|
|
31876
32251
|
const clampedPage = Math.max(page, 1);
|
|
31877
32252
|
const start = (clampedPage - 1) * clampedPageSize;
|
|
31878
32253
|
const files = allFiles.slice(start, start + clampedPageSize);
|
|
31879
|
-
const realReportsDir = (0,
|
|
32254
|
+
const realReportsDir = (0, import_fs64.realpathSync)(reportsDir);
|
|
31880
32255
|
const reports = files.map((f) => {
|
|
31881
32256
|
try {
|
|
31882
|
-
const filePath = (0,
|
|
31883
|
-
const realFile = (0,
|
|
32257
|
+
const filePath = (0, import_path70.join)(reportsDir, f);
|
|
32258
|
+
const realFile = (0, import_fs64.realpathSync)(filePath);
|
|
31884
32259
|
if (!realFile.startsWith(realReportsDir + "/")) return null;
|
|
31885
|
-
return JSON.parse(
|
|
32260
|
+
return JSON.parse(readFileSync64(realFile, "utf-8"));
|
|
31886
32261
|
} catch {
|
|
31887
32262
|
return null;
|
|
31888
32263
|
}
|
|
@@ -31893,29 +32268,29 @@ var init_routes = __esm({
|
|
|
31893
32268
|
}
|
|
31894
32269
|
}
|
|
31895
32270
|
archiveFindings() {
|
|
31896
|
-
const { readdirSync: readdirSync22, readFileSync:
|
|
31897
|
-
const reportsDir = (0,
|
|
31898
|
-
const archiveDir = (0,
|
|
32271
|
+
const { readdirSync: readdirSync22, readFileSync: readFileSync64, renameSync: renameSync15, writeFileSync: writeFileSync34, mkdirSync: mkdirSync41, existsSync: existsSync70 } = require("fs");
|
|
32272
|
+
const reportsDir = (0, import_path70.join)(this.projectRoot, ".gossip", "consensus-reports");
|
|
32273
|
+
const archiveDir = (0, import_path70.join)(this.projectRoot, ".gossip", "consensus-reports-archive");
|
|
31899
32274
|
let archived = 0;
|
|
31900
|
-
if (
|
|
32275
|
+
if (existsSync70(reportsDir)) {
|
|
31901
32276
|
const files = readdirSync22(reportsDir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
31902
32277
|
if (files.length > 5) {
|
|
31903
32278
|
mkdirSync41(archiveDir, { recursive: true });
|
|
31904
32279
|
const toArchive = files.slice(5);
|
|
31905
32280
|
for (const f of toArchive) {
|
|
31906
32281
|
try {
|
|
31907
|
-
renameSync15((0,
|
|
32282
|
+
renameSync15((0, import_path70.join)(reportsDir, f), (0, import_path70.join)(archiveDir, f));
|
|
31908
32283
|
archived++;
|
|
31909
32284
|
} catch {
|
|
31910
32285
|
}
|
|
31911
32286
|
}
|
|
31912
32287
|
}
|
|
31913
32288
|
}
|
|
31914
|
-
const findingsPath = (0,
|
|
32289
|
+
const findingsPath = (0, import_path70.join)(this.projectRoot, ".gossip", "implementation-findings.jsonl");
|
|
31915
32290
|
let findingsCleared = 0;
|
|
31916
|
-
if (
|
|
32291
|
+
if (existsSync70(findingsPath)) {
|
|
31917
32292
|
try {
|
|
31918
|
-
const lines =
|
|
32293
|
+
const lines = readFileSync64(findingsPath, "utf-8").trim().split("\n").filter(Boolean);
|
|
31919
32294
|
const kept = lines.filter((line) => {
|
|
31920
32295
|
try {
|
|
31921
32296
|
const entry = JSON.parse(line);
|
|
@@ -31932,7 +32307,7 @@ var init_routes = __esm({
|
|
|
31932
32307
|
} catch {
|
|
31933
32308
|
}
|
|
31934
32309
|
}
|
|
31935
|
-
const remaining =
|
|
32310
|
+
const remaining = existsSync70(reportsDir) ? readdirSync22(reportsDir).filter((f) => f.endsWith(".json")).length : 0;
|
|
31936
32311
|
return { archived, remaining, findingsCleared };
|
|
31937
32312
|
}
|
|
31938
32313
|
json(res, status, data) {
|
|
@@ -31945,14 +32320,14 @@ var init_routes = __esm({
|
|
|
31945
32320
|
});
|
|
31946
32321
|
|
|
31947
32322
|
// packages/relay/src/dashboard/ws.ts
|
|
31948
|
-
var import_ws3,
|
|
32323
|
+
var import_ws3, import_fs65, import_fs66, import_path71, DashboardWs;
|
|
31949
32324
|
var init_ws = __esm({
|
|
31950
32325
|
"packages/relay/src/dashboard/ws.ts"() {
|
|
31951
32326
|
"use strict";
|
|
31952
32327
|
import_ws3 = require("ws");
|
|
31953
|
-
import_fs64 = require("fs");
|
|
31954
32328
|
import_fs65 = require("fs");
|
|
31955
|
-
|
|
32329
|
+
import_fs66 = require("fs");
|
|
32330
|
+
import_path71 = require("path");
|
|
31956
32331
|
DashboardWs = class {
|
|
31957
32332
|
clients = /* @__PURE__ */ new Set();
|
|
31958
32333
|
logWatcher = null;
|
|
@@ -31977,15 +32352,15 @@ var init_ws = __esm({
|
|
|
31977
32352
|
/** Start watching mcp.log for new lines and broadcasting them to connected clients. */
|
|
31978
32353
|
startLogWatcher(projectRoot) {
|
|
31979
32354
|
this.stopLogWatcher();
|
|
31980
|
-
this.logPath = (0,
|
|
31981
|
-
if (!(0,
|
|
32355
|
+
this.logPath = (0, import_path71.join)(projectRoot, ".gossip", "mcp.log");
|
|
32356
|
+
if (!(0, import_fs65.existsSync)(this.logPath)) return;
|
|
31982
32357
|
try {
|
|
31983
|
-
this.logOffset = (0,
|
|
32358
|
+
this.logOffset = (0, import_fs65.statSync)(this.logPath).size;
|
|
31984
32359
|
} catch {
|
|
31985
32360
|
this.logOffset = 0;
|
|
31986
32361
|
}
|
|
31987
32362
|
try {
|
|
31988
|
-
this.logWatcher = (0,
|
|
32363
|
+
this.logWatcher = (0, import_fs66.watch)(this.logPath, () => {
|
|
31989
32364
|
if (this.clients.size === 0) return;
|
|
31990
32365
|
this.readNewLines();
|
|
31991
32366
|
});
|
|
@@ -32002,7 +32377,7 @@ var init_ws = __esm({
|
|
|
32002
32377
|
if (this.logReading) return;
|
|
32003
32378
|
this.logReading = true;
|
|
32004
32379
|
try {
|
|
32005
|
-
const currentSize = (0,
|
|
32380
|
+
const currentSize = (0, import_fs65.statSync)(this.logPath).size;
|
|
32006
32381
|
if (currentSize < this.logOffset) {
|
|
32007
32382
|
this.logOffset = 0;
|
|
32008
32383
|
this.logCarry = "";
|
|
@@ -32015,7 +32390,7 @@ var init_ws = __esm({
|
|
|
32015
32390
|
const readFrom = capped ? (this.logCarry = "", this.logCapped = true, currentSize - 65536) : (this.logCapped = false, this.logOffset);
|
|
32016
32391
|
let stream;
|
|
32017
32392
|
try {
|
|
32018
|
-
stream = (0,
|
|
32393
|
+
stream = (0, import_fs65.createReadStream)(this.logPath, { start: readFrom, end: currentSize - 1 });
|
|
32019
32394
|
} catch {
|
|
32020
32395
|
this.logReading = false;
|
|
32021
32396
|
return;
|
|
@@ -32678,14 +33053,14 @@ __export(sandbox_exports, {
|
|
|
32678
33053
|
});
|
|
32679
33054
|
function rotateIfNeeded2(filePath, maxBytes) {
|
|
32680
33055
|
try {
|
|
32681
|
-
const st = (0,
|
|
33056
|
+
const st = (0, import_fs67.statSync)(filePath);
|
|
32682
33057
|
if (st.size < maxBytes) return;
|
|
32683
33058
|
const rotated = filePath + ".1";
|
|
32684
33059
|
try {
|
|
32685
|
-
if ((0,
|
|
33060
|
+
if ((0, import_fs67.existsSync)(rotated)) (0, import_fs67.unlinkSync)(rotated);
|
|
32686
33061
|
} catch {
|
|
32687
33062
|
}
|
|
32688
|
-
(0,
|
|
33063
|
+
(0, import_fs67.renameSync)(filePath, rotated);
|
|
32689
33064
|
} catch {
|
|
32690
33065
|
}
|
|
32691
33066
|
}
|
|
@@ -32758,9 +33133,9 @@ Tests passing is NOT sufficient verification \u2014 the 2026-04-22 incident had
|
|
|
32758
33133
|
}
|
|
32759
33134
|
function readSandboxMode(projectRoot) {
|
|
32760
33135
|
try {
|
|
32761
|
-
const p = (0,
|
|
32762
|
-
if (!(0,
|
|
32763
|
-
const raw = JSON.parse((0,
|
|
33136
|
+
const p = (0, import_path72.join)(projectRoot, ".gossip", "config.json");
|
|
33137
|
+
if (!(0, import_fs67.existsSync)(p)) return "warn";
|
|
33138
|
+
const raw = JSON.parse((0, import_fs67.readFileSync)(p, "utf-8"));
|
|
32764
33139
|
const mode = raw?.sandboxEnforcement;
|
|
32765
33140
|
if (mode === "off" || mode === "warn" || mode === "block") return mode;
|
|
32766
33141
|
return "warn";
|
|
@@ -32770,8 +33145,8 @@ function readSandboxMode(projectRoot) {
|
|
|
32770
33145
|
}
|
|
32771
33146
|
function recordDispatchMetadata(projectRoot, meta3) {
|
|
32772
33147
|
try {
|
|
32773
|
-
const dir = (0,
|
|
32774
|
-
(0,
|
|
33148
|
+
const dir = (0, import_path72.join)(projectRoot, ".gossip");
|
|
33149
|
+
(0, import_fs67.mkdirSync)(dir, { recursive: true });
|
|
32775
33150
|
const snapshotted = { ...meta3 };
|
|
32776
33151
|
if (meta3.writeMode === "scoped" || meta3.writeMode === "worktree") {
|
|
32777
33152
|
try {
|
|
@@ -32789,15 +33164,15 @@ function recordDispatchMetadata(projectRoot, meta3) {
|
|
|
32789
33164
|
} catch {
|
|
32790
33165
|
}
|
|
32791
33166
|
}
|
|
32792
|
-
(0,
|
|
33167
|
+
(0, import_fs67.appendFileSync)((0, import_path72.join)(dir, METADATA_FILE), JSON.stringify(snapshotted) + "\n");
|
|
32793
33168
|
} catch {
|
|
32794
33169
|
}
|
|
32795
33170
|
}
|
|
32796
33171
|
function updateDispatchMetadata(projectRoot, taskId, patch) {
|
|
32797
33172
|
try {
|
|
32798
|
-
const p = (0,
|
|
32799
|
-
if (!(0,
|
|
32800
|
-
const raw = (0,
|
|
33173
|
+
const p = (0, import_path72.join)(projectRoot, ".gossip", METADATA_FILE);
|
|
33174
|
+
if (!(0, import_fs67.existsSync)(p)) return false;
|
|
33175
|
+
const raw = (0, import_fs67.readFileSync)(p, "utf-8");
|
|
32801
33176
|
const lines = raw.split("\n");
|
|
32802
33177
|
let patched = false;
|
|
32803
33178
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
@@ -32815,7 +33190,7 @@ function updateDispatchMetadata(projectRoot, taskId, patch) {
|
|
|
32815
33190
|
}
|
|
32816
33191
|
}
|
|
32817
33192
|
if (!patched) return false;
|
|
32818
|
-
(0,
|
|
33193
|
+
(0, import_fs67.writeFileSync)(p, lines.join("\n"));
|
|
32819
33194
|
return true;
|
|
32820
33195
|
} catch {
|
|
32821
33196
|
return false;
|
|
@@ -32824,14 +33199,14 @@ function updateDispatchMetadata(projectRoot, taskId, patch) {
|
|
|
32824
33199
|
function stampTaskSentinel(projectRoot, taskId) {
|
|
32825
33200
|
if (!taskId) return null;
|
|
32826
33201
|
try {
|
|
32827
|
-
const dir = (0,
|
|
32828
|
-
(0,
|
|
33202
|
+
const dir = (0, import_path72.join)(projectRoot, ".gossip", SENTINEL_DIR);
|
|
33203
|
+
(0, import_fs67.mkdirSync)(dir, { recursive: true });
|
|
32829
33204
|
const slug = taskId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
32830
|
-
const path7 = (0,
|
|
32831
|
-
const fd = (0,
|
|
32832
|
-
(0,
|
|
33205
|
+
const path7 = (0, import_path72.join)(dir, `${slug}.sentinel`);
|
|
33206
|
+
const fd = (0, import_fs67.openSync)(path7, "w");
|
|
33207
|
+
(0, import_fs67.closeSync)(fd);
|
|
32833
33208
|
const stampTime = new Date(Date.now() - 2e3);
|
|
32834
|
-
(0,
|
|
33209
|
+
(0, import_fs67.utimesSync)(path7, stampTime, stampTime);
|
|
32835
33210
|
return path7;
|
|
32836
33211
|
} catch {
|
|
32837
33212
|
return null;
|
|
@@ -32840,15 +33215,15 @@ function stampTaskSentinel(projectRoot, taskId) {
|
|
|
32840
33215
|
function cleanupTaskSentinel(sentinelPath) {
|
|
32841
33216
|
if (!sentinelPath) return;
|
|
32842
33217
|
try {
|
|
32843
|
-
(0,
|
|
33218
|
+
(0, import_fs67.unlinkSync)(sentinelPath);
|
|
32844
33219
|
} catch {
|
|
32845
33220
|
}
|
|
32846
33221
|
}
|
|
32847
33222
|
function lookupDispatchMetadata(projectRoot, taskId) {
|
|
32848
33223
|
try {
|
|
32849
|
-
const p = (0,
|
|
32850
|
-
if (!(0,
|
|
32851
|
-
const raw = (0,
|
|
33224
|
+
const p = (0, import_path72.join)(projectRoot, ".gossip", METADATA_FILE);
|
|
33225
|
+
if (!(0, import_fs67.existsSync)(p)) return null;
|
|
33226
|
+
const raw = (0, import_fs67.readFileSync)(p, "utf-8");
|
|
32852
33227
|
const lines = raw.split("\n").filter(Boolean);
|
|
32853
33228
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
32854
33229
|
try {
|
|
@@ -32880,21 +33255,21 @@ function parseGitStatus(porcelain) {
|
|
|
32880
33255
|
function normalizeScope(scope, projectRoot) {
|
|
32881
33256
|
let s = scope.trim();
|
|
32882
33257
|
if (!s) return "";
|
|
32883
|
-
if ((0,
|
|
32884
|
-
s = (0,
|
|
33258
|
+
if ((0, import_path72.isAbsolute)(s)) {
|
|
33259
|
+
s = (0, import_path72.relative)(projectRoot, s);
|
|
32885
33260
|
} else if (s.startsWith("./")) {
|
|
32886
33261
|
s = s.slice(2);
|
|
32887
33262
|
}
|
|
32888
|
-
s = (0,
|
|
33263
|
+
s = (0, import_path72.normalize)(s).replace(/\/+$/, "");
|
|
32889
33264
|
if (s === "." || s === "") return "";
|
|
32890
33265
|
return s;
|
|
32891
33266
|
}
|
|
32892
33267
|
function isInsideScope(filePath, scope) {
|
|
32893
33268
|
if (!scope) return true;
|
|
32894
|
-
const f = (0,
|
|
33269
|
+
const f = (0, import_path72.normalize)(filePath).replace(/^\.\//, "");
|
|
32895
33270
|
const s = scope.replace(/^\.\//, "").replace(/\/+$/, "");
|
|
32896
33271
|
if (f === s) return true;
|
|
32897
|
-
return f.startsWith(s + "/") || f.startsWith(s +
|
|
33272
|
+
return f.startsWith(s + "/") || f.startsWith(s + import_path72.sep);
|
|
32898
33273
|
}
|
|
32899
33274
|
function detectBoundaryEscapes(meta3, modifiedFiles, projectRoot) {
|
|
32900
33275
|
const mode = meta3.writeMode;
|
|
@@ -32955,8 +33330,8 @@ function recordBoundaryEscape(projectRoot, meta3, violations, mode) {
|
|
|
32955
33330
|
} catch {
|
|
32956
33331
|
}
|
|
32957
33332
|
try {
|
|
32958
|
-
const dir = (0,
|
|
32959
|
-
(0,
|
|
33333
|
+
const dir = (0, import_path72.join)(projectRoot, ".gossip");
|
|
33334
|
+
(0, import_fs67.mkdirSync)(dir, { recursive: true });
|
|
32960
33335
|
const line = {
|
|
32961
33336
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32962
33337
|
taskId: meta3.taskId,
|
|
@@ -32967,15 +33342,15 @@ function recordBoundaryEscape(projectRoot, meta3, violations, mode) {
|
|
|
32967
33342
|
action: mode
|
|
32968
33343
|
// "warn" or "block"
|
|
32969
33344
|
};
|
|
32970
|
-
const escapeFile = (0,
|
|
33345
|
+
const escapeFile = (0, import_path72.join)(dir, BOUNDARY_ESCAPE_FILE);
|
|
32971
33346
|
rotateIfNeeded2(escapeFile, MAX_BOUNDARY_ESCAPE_BYTES);
|
|
32972
|
-
(0,
|
|
33347
|
+
(0, import_fs67.appendFileSync)(escapeFile, JSON.stringify(line) + "\n");
|
|
32973
33348
|
} catch {
|
|
32974
33349
|
}
|
|
32975
33350
|
}
|
|
32976
33351
|
function canonicalize(p) {
|
|
32977
33352
|
try {
|
|
32978
|
-
return (0,
|
|
33353
|
+
return (0, import_path72.resolve)(p).replace(/\/+$/, "") || "/";
|
|
32979
33354
|
} catch {
|
|
32980
33355
|
return p.replace(/\/+$/, "") || "/";
|
|
32981
33356
|
}
|
|
@@ -33186,7 +33561,7 @@ function buildAuditExclusions(projectRoot, ownWorktree, scope) {
|
|
|
33186
33561
|
for (const v of expandTmpVariants(wt)) excl.add(v);
|
|
33187
33562
|
}
|
|
33188
33563
|
if (scope) {
|
|
33189
|
-
const s = canonicalize((0,
|
|
33564
|
+
const s = canonicalize((0, import_path72.join)(projectRoot, scope));
|
|
33190
33565
|
for (const v of expandTmpVariants(s)) excl.add(v);
|
|
33191
33566
|
}
|
|
33192
33567
|
return Array.from(excl);
|
|
@@ -33240,12 +33615,12 @@ function auditFilesystemSinceSentinel(projectRoot, meta3, options = {}) {
|
|
|
33240
33615
|
return { violations: [], skipped: "win32" };
|
|
33241
33616
|
}
|
|
33242
33617
|
const sentinel = meta3.sentinelPath;
|
|
33243
|
-
if (!sentinel || !(0,
|
|
33618
|
+
if (!sentinel || !(0, import_fs67.existsSync)(sentinel)) {
|
|
33244
33619
|
return { violations: [], skipped: "sentinel missing" };
|
|
33245
33620
|
}
|
|
33246
33621
|
let sentinelMtimeMs = 0;
|
|
33247
33622
|
try {
|
|
33248
|
-
sentinelMtimeMs = (0,
|
|
33623
|
+
sentinelMtimeMs = (0, import_fs67.statSync)(sentinel).mtimeMs;
|
|
33249
33624
|
} catch {
|
|
33250
33625
|
}
|
|
33251
33626
|
if (sentinelMtimeMs === 0) {
|
|
@@ -33257,11 +33632,11 @@ function auditFilesystemSinceSentinel(projectRoot, meta3, options = {}) {
|
|
|
33257
33632
|
);
|
|
33258
33633
|
const exclusions = buildAuditExclusions(projectRoot, meta3.worktreePath, options.scope);
|
|
33259
33634
|
const findBin = options.findBinary ?? "find";
|
|
33260
|
-
const sentinelDir = canonicalize((0,
|
|
33635
|
+
const sentinelDir = canonicalize((0, import_path72.join)(projectRoot, ".gossip", SENTINEL_DIR));
|
|
33261
33636
|
const mainSet = /* @__PURE__ */ new Set();
|
|
33262
33637
|
const sensitiveSet = /* @__PURE__ */ new Set();
|
|
33263
33638
|
for (const root of scanRoots) {
|
|
33264
|
-
if (!(0,
|
|
33639
|
+
if (!(0, import_fs67.existsSync)(root)) continue;
|
|
33265
33640
|
const canonRoot = canonicalize(root);
|
|
33266
33641
|
const allExcl = [...exclusions, ...expandTmpVariants(sentinelDir)];
|
|
33267
33642
|
const args = buildFindPruneArgs(canonRoot, allExcl, sentinel);
|
|
@@ -33297,7 +33672,7 @@ function auditFilesystemSinceSentinel(projectRoot, meta3, options = {}) {
|
|
|
33297
33672
|
}
|
|
33298
33673
|
const sensitiveTargets = buildSensitiveTargets(platform2);
|
|
33299
33674
|
for (const target of sensitiveTargets) {
|
|
33300
|
-
if (!(0,
|
|
33675
|
+
if (!(0, import_fs67.existsSync)(target.path)) continue;
|
|
33301
33676
|
const canonTarget = canonicalize(target.path);
|
|
33302
33677
|
const args = buildSensitiveFindArgs(
|
|
33303
33678
|
canonTarget,
|
|
@@ -33353,8 +33728,8 @@ function auditFilesystemSinceSentinel(projectRoot, meta3, options = {}) {
|
|
|
33353
33728
|
}
|
|
33354
33729
|
function recordLayer3Violations(projectRoot, meta3, violations, source) {
|
|
33355
33730
|
try {
|
|
33356
|
-
const dir = (0,
|
|
33357
|
-
(0,
|
|
33731
|
+
const dir = (0, import_path72.join)(projectRoot, ".gossip");
|
|
33732
|
+
(0, import_fs67.mkdirSync)(dir, { recursive: true });
|
|
33358
33733
|
const ts2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
33359
33734
|
const lines = violations.map(
|
|
33360
33735
|
(path7) => JSON.stringify({
|
|
@@ -33365,9 +33740,9 @@ function recordLayer3Violations(projectRoot, meta3, violations, source) {
|
|
|
33365
33740
|
source
|
|
33366
33741
|
})
|
|
33367
33742
|
);
|
|
33368
|
-
const escapeFile = (0,
|
|
33743
|
+
const escapeFile = (0, import_path72.join)(dir, BOUNDARY_ESCAPE_FILE);
|
|
33369
33744
|
rotateIfNeeded2(escapeFile, MAX_BOUNDARY_ESCAPE_BYTES);
|
|
33370
|
-
(0,
|
|
33745
|
+
(0, import_fs67.appendFileSync)(escapeFile, lines.join("\n") + "\n");
|
|
33371
33746
|
} catch {
|
|
33372
33747
|
}
|
|
33373
33748
|
if (source === "layer3-sensitive" && violations.length > 0) {
|
|
@@ -33424,14 +33799,14 @@ function runLayer3Audit(projectRoot, taskId) {
|
|
|
33424
33799
|
}
|
|
33425
33800
|
return { blockError, warnPrefix };
|
|
33426
33801
|
}
|
|
33427
|
-
var import_child_process10,
|
|
33802
|
+
var import_child_process10, import_fs67, import_os5, import_path72, METADATA_FILE, BOUNDARY_ESCAPE_FILE, SENTINEL_DIR, MAX_BOUNDARY_ESCAPE_BYTES, MAX_PREMISE_VERIFICATION_BYTES, BOUNDARY_ALLOWLIST, SYSTEM_PREFIXES, SCOPE_NOTE, NUMERAL, TARGETS, MODIFIER, CLAIM_PATTERNS, UNVERIFIED_NOTE_SENTINEL, __test__;
|
|
33428
33803
|
var init_sandbox2 = __esm({
|
|
33429
33804
|
"apps/cli/src/sandbox.ts"() {
|
|
33430
33805
|
"use strict";
|
|
33431
33806
|
import_child_process10 = require("child_process");
|
|
33432
|
-
|
|
33807
|
+
import_fs67 = require("fs");
|
|
33433
33808
|
import_os5 = require("os");
|
|
33434
|
-
|
|
33809
|
+
import_path72 = require("path");
|
|
33435
33810
|
METADATA_FILE = "dispatch-metadata.jsonl";
|
|
33436
33811
|
BOUNDARY_ESCAPE_FILE = "boundary-escapes.jsonl";
|
|
33437
33812
|
SENTINEL_DIR = "sentinels";
|
|
@@ -33502,7 +33877,7 @@ __export(dispatch_prompt_storage_exports, {
|
|
|
33502
33877
|
writeDispatchPrompt: () => writeDispatchPrompt
|
|
33503
33878
|
});
|
|
33504
33879
|
function dispatchPromptsDir(projectRoot) {
|
|
33505
|
-
return (0,
|
|
33880
|
+
return (0, import_path73.join)(projectRoot, ".gossip", DISPATCH_PROMPTS_SUBDIR);
|
|
33506
33881
|
}
|
|
33507
33882
|
function assertSafeTaskId(taskId) {
|
|
33508
33883
|
if (typeof taskId !== "string" || taskId.length === 0) {
|
|
@@ -33515,35 +33890,35 @@ function assertSafeTaskId(taskId) {
|
|
|
33515
33890
|
function writeDispatchPrompt(projectRoot, taskId, body) {
|
|
33516
33891
|
assertSafeTaskId(taskId);
|
|
33517
33892
|
const dir = dispatchPromptsDir(projectRoot);
|
|
33518
|
-
(0,
|
|
33519
|
-
const finalPath = (0,
|
|
33520
|
-
const tmpPath = (0,
|
|
33893
|
+
(0, import_fs68.mkdirSync)(dir, { recursive: true });
|
|
33894
|
+
const finalPath = (0, import_path73.join)(dir, `${taskId}.txt`);
|
|
33895
|
+
const tmpPath = (0, import_path73.join)(dir, `${taskId}.txt.${(0, import_crypto27.randomUUID)().slice(0, 8)}.tmp`);
|
|
33521
33896
|
try {
|
|
33522
|
-
(0,
|
|
33523
|
-
(0,
|
|
33897
|
+
(0, import_fs68.writeFileSync)(tmpPath, body, "utf8");
|
|
33898
|
+
(0, import_fs68.renameSync)(tmpPath, finalPath);
|
|
33524
33899
|
} catch (err) {
|
|
33525
33900
|
try {
|
|
33526
|
-
(0,
|
|
33901
|
+
(0, import_fs68.unlinkSync)(tmpPath);
|
|
33527
33902
|
} catch {
|
|
33528
33903
|
}
|
|
33529
33904
|
throw err;
|
|
33530
33905
|
}
|
|
33531
|
-
return (0,
|
|
33906
|
+
return (0, import_path73.resolve)(finalPath);
|
|
33532
33907
|
}
|
|
33533
33908
|
function cleanupExpiredDispatchPrompts(projectRoot, maxAgeMs = DEFAULT_PROMPT_TTL_MS, capBytes = DISPATCH_PROMPT_CAP_BYTES) {
|
|
33534
33909
|
const dir = dispatchPromptsDir(projectRoot);
|
|
33535
|
-
if (!(0,
|
|
33910
|
+
if (!(0, import_fs68.existsSync)(dir)) return { evictedAge: 0, evictedCap: 0 };
|
|
33536
33911
|
const now = Date.now();
|
|
33537
33912
|
let entries = [];
|
|
33538
33913
|
try {
|
|
33539
|
-
for (const name of (0,
|
|
33540
|
-
const path7 = (0,
|
|
33914
|
+
for (const name of (0, import_fs68.readdirSync)(dir)) {
|
|
33915
|
+
const path7 = (0, import_path73.join)(dir, name);
|
|
33541
33916
|
try {
|
|
33542
|
-
const st = (0,
|
|
33917
|
+
const st = (0, import_fs68.statSync)(path7);
|
|
33543
33918
|
if (!st.isFile()) continue;
|
|
33544
33919
|
entries.push({ name, path: path7, mtimeMs: st.mtimeMs, size: st.size });
|
|
33545
33920
|
} catch (err) {
|
|
33546
|
-
process.stderr.write(`[gossipcat] dispatch-prompt stat failed for ${(0,
|
|
33921
|
+
process.stderr.write(`[gossipcat] dispatch-prompt stat failed for ${(0, import_path73.basename)(path7)}: ${err.message}
|
|
33547
33922
|
`);
|
|
33548
33923
|
}
|
|
33549
33924
|
}
|
|
@@ -33557,7 +33932,7 @@ function cleanupExpiredDispatchPrompts(projectRoot, maxAgeMs = DEFAULT_PROMPT_TT
|
|
|
33557
33932
|
for (const e of entries) {
|
|
33558
33933
|
if (now - e.mtimeMs > maxAgeMs) {
|
|
33559
33934
|
try {
|
|
33560
|
-
(0,
|
|
33935
|
+
(0, import_fs68.unlinkSync)(e.path);
|
|
33561
33936
|
evictedAge++;
|
|
33562
33937
|
} catch (err) {
|
|
33563
33938
|
process.stderr.write(`[gossipcat] dispatch-prompt unlink failed for ${e.name}: ${err.message}
|
|
@@ -33574,7 +33949,7 @@ function cleanupExpiredDispatchPrompts(projectRoot, maxAgeMs = DEFAULT_PROMPT_TT
|
|
|
33574
33949
|
for (const e of survivors) {
|
|
33575
33950
|
if (totalBytes <= capBytes) break;
|
|
33576
33951
|
try {
|
|
33577
|
-
(0,
|
|
33952
|
+
(0, import_fs68.unlinkSync)(e.path);
|
|
33578
33953
|
totalBytes -= e.size;
|
|
33579
33954
|
evictedCap++;
|
|
33580
33955
|
} catch (err) {
|
|
@@ -33587,18 +33962,18 @@ function cleanupExpiredDispatchPrompts(projectRoot, maxAgeMs = DEFAULT_PROMPT_TT
|
|
|
33587
33962
|
}
|
|
33588
33963
|
function pruneOrphanDispatchPrompts(projectRoot, knownTaskIds, maxAgeMs = DEFAULT_PROMPT_TTL_MS) {
|
|
33589
33964
|
const dir = dispatchPromptsDir(projectRoot);
|
|
33590
|
-
if (!(0,
|
|
33965
|
+
if (!(0, import_fs68.existsSync)(dir)) return { orphans: 0, aged: 0 };
|
|
33591
33966
|
const now = Date.now();
|
|
33592
33967
|
let orphans = 0;
|
|
33593
33968
|
let aged = 0;
|
|
33594
33969
|
try {
|
|
33595
|
-
for (const name of (0,
|
|
33970
|
+
for (const name of (0, import_fs68.readdirSync)(dir)) {
|
|
33596
33971
|
if (!name.endsWith(".txt")) continue;
|
|
33597
33972
|
const taskId = name.slice(0, -4);
|
|
33598
|
-
const path7 = (0,
|
|
33973
|
+
const path7 = (0, import_path73.join)(dir, name);
|
|
33599
33974
|
let mtimeMs = 0;
|
|
33600
33975
|
try {
|
|
33601
|
-
mtimeMs = (0,
|
|
33976
|
+
mtimeMs = (0, import_fs68.statSync)(path7).mtimeMs;
|
|
33602
33977
|
} catch {
|
|
33603
33978
|
continue;
|
|
33604
33979
|
}
|
|
@@ -33606,7 +33981,7 @@ function pruneOrphanDispatchPrompts(projectRoot, knownTaskIds, maxAgeMs = DEFAUL
|
|
|
33606
33981
|
const orphaned = !knownTaskIds.has(taskId);
|
|
33607
33982
|
if (tooOld || orphaned) {
|
|
33608
33983
|
try {
|
|
33609
|
-
(0,
|
|
33984
|
+
(0, import_fs68.unlinkSync)(path7);
|
|
33610
33985
|
if (orphaned) orphans++;
|
|
33611
33986
|
if (tooOld) aged++;
|
|
33612
33987
|
} catch (err) {
|
|
@@ -33623,14 +33998,14 @@ function pruneOrphanDispatchPrompts(projectRoot, knownTaskIds, maxAgeMs = DEFAUL
|
|
|
33623
33998
|
}
|
|
33624
33999
|
function dispatchPromptPath(projectRoot, taskId) {
|
|
33625
34000
|
assertSafeTaskId(taskId);
|
|
33626
|
-
return (0,
|
|
34001
|
+
return (0, import_path73.resolve)((0, import_path73.join)(dispatchPromptsDir(projectRoot), `${taskId}.txt`));
|
|
33627
34002
|
}
|
|
33628
|
-
var
|
|
34003
|
+
var import_fs68, import_path73, import_crypto27, SAFE_TASK_ID, DISPATCH_PROMPT_CAP_BYTES, DEFAULT_PROMPT_TTL_MS, DISPATCH_PROMPTS_SUBDIR;
|
|
33629
34004
|
var init_dispatch_prompt_storage = __esm({
|
|
33630
34005
|
"apps/cli/src/handlers/dispatch-prompt-storage.ts"() {
|
|
33631
34006
|
"use strict";
|
|
33632
|
-
|
|
33633
|
-
|
|
34007
|
+
import_fs68 = require("fs");
|
|
34008
|
+
import_path73 = require("path");
|
|
33634
34009
|
import_crypto27 = require("crypto");
|
|
33635
34010
|
SAFE_TASK_ID = /^(?!.*\.\.)[A-Za-z0-9._-]{1,64}$/;
|
|
33636
34011
|
DISPATCH_PROMPT_CAP_BYTES = 100 * 1024 * 1024;
|
|
@@ -33684,9 +34059,9 @@ function getCommitRange(preSha, postSha) {
|
|
|
33684
34059
|
function appendViolationRecord(record2) {
|
|
33685
34060
|
try {
|
|
33686
34061
|
const projectRoot = process.cwd();
|
|
33687
|
-
(0,
|
|
33688
|
-
const logPath = (0,
|
|
33689
|
-
(0,
|
|
34062
|
+
(0, import_fs69.mkdirSync)((0, import_path74.join)(projectRoot, ".gossip"), { recursive: true });
|
|
34063
|
+
const logPath = (0, import_path74.join)(projectRoot, PROCESS_VIOLATIONS_FILE);
|
|
34064
|
+
(0, import_fs69.appendFileSync)(logPath, JSON.stringify(record2) + "\n", "utf8");
|
|
33690
34065
|
} catch (err) {
|
|
33691
34066
|
process.stderr.write(`[gossipcat] ref-allowlist: failed to append violation record: ${err.message}
|
|
33692
34067
|
`);
|
|
@@ -33736,12 +34111,12 @@ Full audit trail at .gossip/process-violations.jsonl
|
|
|
33736
34111
|
`
|
|
33737
34112
|
);
|
|
33738
34113
|
}
|
|
33739
|
-
var
|
|
34114
|
+
var import_fs69, import_path74, import_child_process11, PROCESS_VIOLATIONS_FILE;
|
|
33740
34115
|
var init_ref_allowlist_detection = __esm({
|
|
33741
34116
|
"apps/cli/src/handlers/ref-allowlist-detection.ts"() {
|
|
33742
34117
|
"use strict";
|
|
33743
|
-
|
|
33744
|
-
|
|
34118
|
+
import_fs69 = require("fs");
|
|
34119
|
+
import_path74 = require("path");
|
|
33745
34120
|
import_child_process11 = require("child_process");
|
|
33746
34121
|
PROCESS_VIOLATIONS_FILE = ".gossip/process-violations.jsonl";
|
|
33747
34122
|
}
|
|
@@ -33827,10 +34202,10 @@ function taskWasInConsensusRound(taskId, agentId, rounds, recentTaskIds, recentA
|
|
|
33827
34202
|
function appendRelayWarning(projectRoot, entry) {
|
|
33828
34203
|
try {
|
|
33829
34204
|
const { appendFileSync: appendFileSync21, mkdirSync: mkdirSync41 } = require("fs");
|
|
33830
|
-
const { join:
|
|
33831
|
-
const dir =
|
|
34205
|
+
const { join: join83 } = require("path");
|
|
34206
|
+
const dir = join83(projectRoot, ".gossip");
|
|
33832
34207
|
mkdirSync41(dir, { recursive: true });
|
|
33833
|
-
appendFileSync21(
|
|
34208
|
+
appendFileSync21(join83(dir, RELAY_WARNINGS_FILE), JSON.stringify(entry) + "\n", "utf8");
|
|
33834
34209
|
} catch (err) {
|
|
33835
34210
|
process.stderr.write(`[gossipcat] append relay-warning failed: ${err.message}
|
|
33836
34211
|
`);
|
|
@@ -34557,7 +34932,7 @@ function computeSkillFingerprint(paths) {
|
|
|
34557
34932
|
const pairs = [];
|
|
34558
34933
|
for (const p of paths) {
|
|
34559
34934
|
try {
|
|
34560
|
-
const st = (0,
|
|
34935
|
+
const st = (0, import_fs70.statSync)(p);
|
|
34561
34936
|
pairs.push(`${p}:${st.mtimeMs}`);
|
|
34562
34937
|
} catch {
|
|
34563
34938
|
}
|
|
@@ -34592,7 +34967,7 @@ function setCachedPrompt(k, e) {
|
|
|
34592
34967
|
const evicted = promptCache.get(oldestKey);
|
|
34593
34968
|
promptCache.delete(oldestKey);
|
|
34594
34969
|
try {
|
|
34595
|
-
(0,
|
|
34970
|
+
(0, import_fs70.unlinkSync)(evicted.skillsSectionPath);
|
|
34596
34971
|
} catch {
|
|
34597
34972
|
}
|
|
34598
34973
|
const evictedAgentId = oldestKey.split("|")[0] ?? "_system";
|
|
@@ -34606,7 +34981,7 @@ function invalidateAgent(agentId) {
|
|
|
34606
34981
|
if (k.startsWith(`${agentId}|`)) {
|
|
34607
34982
|
promptCache.delete(k);
|
|
34608
34983
|
try {
|
|
34609
|
-
(0,
|
|
34984
|
+
(0, import_fs70.unlinkSync)(v.skillsSectionPath);
|
|
34610
34985
|
} catch {
|
|
34611
34986
|
}
|
|
34612
34987
|
emitCacheEvictedSignal(agentId, "invalidation");
|
|
@@ -34619,7 +34994,7 @@ function invalidateAll() {
|
|
|
34619
34994
|
const n = promptCache.size;
|
|
34620
34995
|
for (const v of promptCache.values()) {
|
|
34621
34996
|
try {
|
|
34622
|
-
(0,
|
|
34997
|
+
(0, import_fs70.unlinkSync)(v.skillsSectionPath);
|
|
34623
34998
|
} catch {
|
|
34624
34999
|
}
|
|
34625
35000
|
}
|
|
@@ -34666,29 +35041,29 @@ function writeCachedSkillsSection(projectRoot, fingerprint2, skillsSection) {
|
|
|
34666
35041
|
if (!/^[a-f0-9]{64}$/.test(fingerprint2)) {
|
|
34667
35042
|
throw new Error(`writeCachedSkillsSection: invalid fingerprint ${JSON.stringify(fingerprint2).slice(0, 32)}`);
|
|
34668
35043
|
}
|
|
34669
|
-
const dir = (0,
|
|
34670
|
-
(0,
|
|
34671
|
-
const finalPath = (0,
|
|
34672
|
-
const tmpPath = (0,
|
|
35044
|
+
const dir = (0, import_path75.join)(projectRoot, ".gossip", "dispatch-prompts", "cache");
|
|
35045
|
+
(0, import_fs70.mkdirSync)(dir, { recursive: true });
|
|
35046
|
+
const finalPath = (0, import_path75.join)(dir, `skills-${fingerprint2}.txt`);
|
|
35047
|
+
const tmpPath = (0, import_path75.join)(dir, `skills-${fingerprint2}.txt.${(0, import_crypto30.randomUUID)().slice(0, 8)}.tmp`);
|
|
34673
35048
|
try {
|
|
34674
|
-
(0,
|
|
34675
|
-
(0,
|
|
35049
|
+
(0, import_fs70.writeFileSync)(tmpPath, skillsSection, "utf8");
|
|
35050
|
+
(0, import_fs70.renameSync)(tmpPath, finalPath);
|
|
34676
35051
|
} catch (err) {
|
|
34677
35052
|
try {
|
|
34678
|
-
(0,
|
|
35053
|
+
(0, import_fs70.unlinkSync)(tmpPath);
|
|
34679
35054
|
} catch {
|
|
34680
35055
|
}
|
|
34681
35056
|
throw err;
|
|
34682
35057
|
}
|
|
34683
|
-
return (0,
|
|
35058
|
+
return (0, import_path75.resolve)(finalPath);
|
|
34684
35059
|
}
|
|
34685
|
-
var import_crypto29,
|
|
35060
|
+
var import_crypto29, import_fs70, import_path75, import_crypto30, DISPATCH_PROMPT_CACHE_MAX_ENTRIES, promptCache;
|
|
34686
35061
|
var init_dispatch_prompt_cache = __esm({
|
|
34687
35062
|
"apps/cli/src/handlers/dispatch-prompt-cache.ts"() {
|
|
34688
35063
|
"use strict";
|
|
34689
35064
|
import_crypto29 = require("crypto");
|
|
34690
|
-
|
|
34691
|
-
|
|
35065
|
+
import_fs70 = require("fs");
|
|
35066
|
+
import_path75 = require("path");
|
|
34692
35067
|
import_crypto30 = require("crypto");
|
|
34693
35068
|
DISPATCH_PROMPT_CACHE_MAX_ENTRIES = 64;
|
|
34694
35069
|
promptCache = /* @__PURE__ */ new Map();
|
|
@@ -34711,18 +35086,18 @@ __export(config_exports, {
|
|
|
34711
35086
|
function findConfigPath(projectRoot) {
|
|
34712
35087
|
const root = projectRoot || process.cwd();
|
|
34713
35088
|
const candidates = [
|
|
34714
|
-
(0,
|
|
34715
|
-
(0,
|
|
34716
|
-
(0,
|
|
34717
|
-
(0,
|
|
35089
|
+
(0, import_path76.resolve)(root, ".gossip", "config.json"),
|
|
35090
|
+
(0, import_path76.resolve)(root, "gossip.agents.json"),
|
|
35091
|
+
(0, import_path76.resolve)(root, "gossip.agents.yaml"),
|
|
35092
|
+
(0, import_path76.resolve)(root, "gossip.agents.yml")
|
|
34718
35093
|
];
|
|
34719
35094
|
for (const p of candidates) {
|
|
34720
|
-
if ((0,
|
|
35095
|
+
if ((0, import_fs71.existsSync)(p)) return p;
|
|
34721
35096
|
}
|
|
34722
35097
|
return null;
|
|
34723
35098
|
}
|
|
34724
35099
|
function loadConfig(configPath) {
|
|
34725
|
-
const raw = (0,
|
|
35100
|
+
const raw = (0, import_fs71.readFileSync)(configPath, "utf-8");
|
|
34726
35101
|
let parsed;
|
|
34727
35102
|
try {
|
|
34728
35103
|
parsed = JSON.parse(raw);
|
|
@@ -34812,19 +35187,19 @@ function configToAgentConfigs(config2) {
|
|
|
34812
35187
|
}
|
|
34813
35188
|
function loadClaudeSubagents(projectRoot, existingIds) {
|
|
34814
35189
|
const root = projectRoot || process.cwd();
|
|
34815
|
-
const agentsDir = (0,
|
|
34816
|
-
if (!(0,
|
|
35190
|
+
const agentsDir = (0, import_path76.join)(root, ".claude", "agents");
|
|
35191
|
+
if (!(0, import_fs71.existsSync)(agentsDir)) return [];
|
|
34817
35192
|
let files;
|
|
34818
35193
|
try {
|
|
34819
|
-
files = (0,
|
|
35194
|
+
files = (0, import_fs71.readdirSync)(agentsDir).filter((f) => f.endsWith(".md"));
|
|
34820
35195
|
} catch {
|
|
34821
35196
|
return [];
|
|
34822
35197
|
}
|
|
34823
35198
|
const agents = [];
|
|
34824
35199
|
for (const file2 of files) {
|
|
34825
|
-
const filePath = (0,
|
|
35200
|
+
const filePath = (0, import_path76.join)(agentsDir, file2);
|
|
34826
35201
|
try {
|
|
34827
|
-
const content = (0,
|
|
35202
|
+
const content = (0, import_fs71.readFileSync)(filePath, "utf-8");
|
|
34828
35203
|
const frontmatter = content.match(/^---\n([\s\S]*?)\n---/);
|
|
34829
35204
|
if (!frontmatter) continue;
|
|
34830
35205
|
const fm = frontmatter[1];
|
|
@@ -34879,12 +35254,12 @@ function inferSkills(description, name) {
|
|
|
34879
35254
|
if (skills.length === 0) skills.push("general");
|
|
34880
35255
|
return skills;
|
|
34881
35256
|
}
|
|
34882
|
-
var
|
|
35257
|
+
var import_fs71, import_path76, VALID_PROVIDERS, VALID_MAIN_PROVIDERS, CLAUDE_MODEL_MAP;
|
|
34883
35258
|
var init_config = __esm({
|
|
34884
35259
|
"apps/cli/src/config.ts"() {
|
|
34885
35260
|
"use strict";
|
|
34886
|
-
|
|
34887
|
-
|
|
35261
|
+
import_fs71 = require("fs");
|
|
35262
|
+
import_path76 = require("path");
|
|
34888
35263
|
VALID_PROVIDERS = ["anthropic", "openai", "openclaw", "google", "local", "native", "none"];
|
|
34889
35264
|
VALID_MAIN_PROVIDERS = VALID_PROVIDERS.filter((p) => p !== "native");
|
|
34890
35265
|
CLAUDE_MODEL_MAP = {
|
|
@@ -34954,11 +35329,11 @@ function startConsensusTimeout(consensusId) {
|
|
|
34954
35329
|
const report = await engine.synthesizeWithCrossReview(snapshot.allResults, allEntries, consensusId, snapshot.relayCrossReviewSkipped);
|
|
34955
35330
|
try {
|
|
34956
35331
|
const { writeFileSync: writeFileSync34, mkdirSync: mkdirSync41 } = require("fs");
|
|
34957
|
-
const { join:
|
|
34958
|
-
const reportsDir =
|
|
35332
|
+
const { join: join83 } = require("path");
|
|
35333
|
+
const reportsDir = join83(process.cwd(), ".gossip", "consensus-reports");
|
|
34959
35334
|
mkdirSync41(reportsDir, { recursive: true });
|
|
34960
35335
|
const topic = snapshot.allResults?.find((r) => r.task)?.task?.slice(0, 500) || "";
|
|
34961
|
-
writeFileSync34(
|
|
35336
|
+
writeFileSync34(join83(reportsDir, `${consensusId}.json`), JSON.stringify({
|
|
34962
35337
|
id: consensusId,
|
|
34963
35338
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34964
35339
|
topic,
|
|
@@ -35126,10 +35501,10 @@ async function handleRelayCrossReview(consensus_id, agent_id, result) {
|
|
|
35126
35501
|
);
|
|
35127
35502
|
try {
|
|
35128
35503
|
const { writeFileSync: writeFileSync34, mkdirSync: mkdirSync41 } = require("fs");
|
|
35129
|
-
const { join:
|
|
35130
|
-
const reportsDir =
|
|
35504
|
+
const { join: join83 } = require("path");
|
|
35505
|
+
const reportsDir = join83(process.cwd(), ".gossip", "consensus-reports");
|
|
35131
35506
|
mkdirSync41(reportsDir, { recursive: true });
|
|
35132
|
-
const reportPath =
|
|
35507
|
+
const reportPath = join83(reportsDir, `${consensus_id}.json`);
|
|
35133
35508
|
const topic = synthSnapshot.allResults?.find((r) => r.task)?.task?.slice(0, 500) || "";
|
|
35134
35509
|
writeFileSync34(reportPath, JSON.stringify({
|
|
35135
35510
|
id: consensus_id,
|
|
@@ -35175,8 +35550,8 @@ function persistPendingConsensus() {
|
|
|
35175
35550
|
const projectRoot = ctx.mainAgent?.projectRoot;
|
|
35176
35551
|
if (!projectRoot) return;
|
|
35177
35552
|
const { writeFileSync: writeFileSync34, mkdirSync: mkdirSync41 } = require("fs");
|
|
35178
|
-
const { join:
|
|
35179
|
-
const dir =
|
|
35553
|
+
const { join: join83 } = require("path");
|
|
35554
|
+
const dir = join83(projectRoot, ".gossip");
|
|
35180
35555
|
mkdirSync41(dir, { recursive: true });
|
|
35181
35556
|
const rounds = {};
|
|
35182
35557
|
for (const [id, round] of ctx.pendingConsensusRounds) {
|
|
@@ -35202,7 +35577,7 @@ function persistPendingConsensus() {
|
|
|
35202
35577
|
resolutionRoots: round.resolutionRoots ? [...round.resolutionRoots] : void 0
|
|
35203
35578
|
};
|
|
35204
35579
|
}
|
|
35205
|
-
writeFileSync34(
|
|
35580
|
+
writeFileSync34(join83(dir, CONSENSUS_FILE), JSON.stringify(rounds));
|
|
35206
35581
|
} catch (err) {
|
|
35207
35582
|
process.stderr.write(`[gossipcat] persistPendingConsensus failed: ${err.message}
|
|
35208
35583
|
`);
|
|
@@ -35210,11 +35585,11 @@ function persistPendingConsensus() {
|
|
|
35210
35585
|
}
|
|
35211
35586
|
function restorePendingConsensus(projectRoot) {
|
|
35212
35587
|
try {
|
|
35213
|
-
const { existsSync:
|
|
35214
|
-
const { join:
|
|
35215
|
-
const filePath =
|
|
35216
|
-
if (!
|
|
35217
|
-
const raw = JSON.parse(
|
|
35588
|
+
const { existsSync: existsSync70, readFileSync: readFileSync64, unlinkSync: unlinkSync13 } = require("fs");
|
|
35589
|
+
const { join: join83 } = require("path");
|
|
35590
|
+
const filePath = join83(projectRoot, ".gossip", CONSENSUS_FILE);
|
|
35591
|
+
if (!existsSync70(filePath)) return;
|
|
35592
|
+
const raw = JSON.parse(readFileSync64(filePath, "utf-8"));
|
|
35218
35593
|
const now = Date.now();
|
|
35219
35594
|
for (const [id, data] of Object.entries(raw)) {
|
|
35220
35595
|
if (now > data.deadline + 3e5) {
|
|
@@ -35322,31 +35697,31 @@ __export(check_effectiveness_runner_exports, {
|
|
|
35322
35697
|
runCheckEffectivenessForAllSkills: () => runCheckEffectivenessForAllSkills
|
|
35323
35698
|
});
|
|
35324
35699
|
function writeHealthAtomic(projectRoot, record2) {
|
|
35325
|
-
const dir = (0,
|
|
35326
|
-
const finalPath = (0,
|
|
35700
|
+
const dir = (0, import_path78.join)(projectRoot, ".gossip");
|
|
35701
|
+
const finalPath = (0, import_path78.join)(dir, "skill-runner-health.json");
|
|
35327
35702
|
const tmpPath = finalPath + ".tmp";
|
|
35328
35703
|
try {
|
|
35329
|
-
(0,
|
|
35330
|
-
(0,
|
|
35331
|
-
(0,
|
|
35704
|
+
(0, import_fs74.mkdirSync)(dir, { recursive: true });
|
|
35705
|
+
(0, import_fs74.writeFileSync)(tmpPath, JSON.stringify(record2, null, 2));
|
|
35706
|
+
(0, import_fs74.renameSync)(tmpPath, finalPath);
|
|
35332
35707
|
} catch (e) {
|
|
35333
35708
|
process.stderr.write(`[gossipcat] checkEffectiveness: health write failed: ${e.message}
|
|
35334
35709
|
`);
|
|
35335
35710
|
try {
|
|
35336
|
-
if ((0,
|
|
35711
|
+
if ((0, import_fs74.existsSync)(tmpPath)) (0, import_fs74.unlinkSync)(tmpPath);
|
|
35337
35712
|
} catch {
|
|
35338
35713
|
}
|
|
35339
35714
|
}
|
|
35340
35715
|
}
|
|
35341
35716
|
async function runCheckEffectivenessForAllSkills(opts) {
|
|
35342
35717
|
const startedAt = Date.now();
|
|
35343
|
-
const baseDir = (0,
|
|
35718
|
+
const baseDir = (0, import_path78.join)(opts.projectRoot, ".gossip", "agents");
|
|
35344
35719
|
let agentDirs = [];
|
|
35345
35720
|
let canonicalBaseDir;
|
|
35346
|
-
if ((0,
|
|
35721
|
+
if ((0, import_fs74.existsSync)(baseDir)) {
|
|
35347
35722
|
try {
|
|
35348
|
-
canonicalBaseDir = (0,
|
|
35349
|
-
agentDirs = (0,
|
|
35723
|
+
canonicalBaseDir = (0, import_fs74.realpathSync)(baseDir);
|
|
35724
|
+
agentDirs = (0, import_fs74.readdirSync)(canonicalBaseDir);
|
|
35350
35725
|
} catch {
|
|
35351
35726
|
}
|
|
35352
35727
|
}
|
|
@@ -35365,11 +35740,11 @@ async function runCheckEffectivenessForAllSkills(opts) {
|
|
|
35365
35740
|
for (const agentId of agentDirs) {
|
|
35366
35741
|
if (agentId.startsWith("_")) continue;
|
|
35367
35742
|
if (!SAFE_NAME2.test(agentId)) continue;
|
|
35368
|
-
const skillsDir = (0,
|
|
35369
|
-
if (!(0,
|
|
35743
|
+
const skillsDir = (0, import_path78.join)(canonicalBaseDir, agentId, "skills");
|
|
35744
|
+
if (!(0, import_fs74.existsSync)(skillsDir)) continue;
|
|
35370
35745
|
let canonicalSkillsDir;
|
|
35371
35746
|
try {
|
|
35372
|
-
canonicalSkillsDir = (0,
|
|
35747
|
+
canonicalSkillsDir = (0, import_fs74.realpathSync)(skillsDir);
|
|
35373
35748
|
} catch {
|
|
35374
35749
|
continue;
|
|
35375
35750
|
}
|
|
@@ -35380,7 +35755,7 @@ async function runCheckEffectivenessForAllSkills(opts) {
|
|
|
35380
35755
|
}
|
|
35381
35756
|
const role = opts.registryGet(agentId)?.role;
|
|
35382
35757
|
if (role === "implementer") continue;
|
|
35383
|
-
const files = (0,
|
|
35758
|
+
const files = (0, import_fs74.readdirSync)(canonicalSkillsDir).filter((f) => f.endsWith(".md"));
|
|
35384
35759
|
for (const file2 of files) {
|
|
35385
35760
|
const category = file2.replace(/\.md$/, "");
|
|
35386
35761
|
if (!SAFE_NAME2.test(category)) continue;
|
|
@@ -35427,12 +35802,12 @@ async function runCheckEffectivenessForAllSkills(opts) {
|
|
|
35427
35802
|
last_error: lastError
|
|
35428
35803
|
});
|
|
35429
35804
|
}
|
|
35430
|
-
var
|
|
35805
|
+
var import_fs74, import_path78, SAFE_NAME2;
|
|
35431
35806
|
var init_check_effectiveness_runner = __esm({
|
|
35432
35807
|
"apps/cli/src/handlers/check-effectiveness-runner.ts"() {
|
|
35433
35808
|
"use strict";
|
|
35434
|
-
|
|
35435
|
-
|
|
35809
|
+
import_fs74 = require("fs");
|
|
35810
|
+
import_path78 = require("path");
|
|
35436
35811
|
init_dispatch_prompt_cache();
|
|
35437
35812
|
SAFE_NAME2 = /^(?!.*\.\.)[a-zA-Z0-9._-]+$/;
|
|
35438
35813
|
}
|
|
@@ -35445,20 +35820,20 @@ __export(skill_develop_audit_exports, {
|
|
|
35445
35820
|
});
|
|
35446
35821
|
function appendSkillDevelopAudit(entry) {
|
|
35447
35822
|
try {
|
|
35448
|
-
const gossipDir = (0,
|
|
35449
|
-
(0,
|
|
35823
|
+
const gossipDir = (0, import_path79.join)(process.cwd(), ".gossip");
|
|
35824
|
+
(0, import_fs75.mkdirSync)(gossipDir, { recursive: true });
|
|
35450
35825
|
const line = JSON.stringify(entry) + "\n";
|
|
35451
|
-
(0,
|
|
35452
|
-
(0,
|
|
35826
|
+
(0, import_fs75.appendFileSync)((0, import_path79.join)(gossipDir, AUDIT_FILE2), line);
|
|
35827
|
+
(0, import_fs75.appendFileSync)((0, import_path79.join)(gossipDir, LEGACY_FILE), line);
|
|
35453
35828
|
} catch {
|
|
35454
35829
|
}
|
|
35455
35830
|
}
|
|
35456
|
-
var
|
|
35831
|
+
var import_fs75, import_path79, AUDIT_FILE2, LEGACY_FILE;
|
|
35457
35832
|
var init_skill_develop_audit = __esm({
|
|
35458
35833
|
"apps/cli/src/handlers/skill-develop-audit.ts"() {
|
|
35459
35834
|
"use strict";
|
|
35460
|
-
|
|
35461
|
-
|
|
35835
|
+
import_fs75 = require("fs");
|
|
35836
|
+
import_path79 = require("path");
|
|
35462
35837
|
AUDIT_FILE2 = "skill-develop-audit.jsonl";
|
|
35463
35838
|
LEGACY_FILE = "forced-skill-develops.jsonl";
|
|
35464
35839
|
}
|
|
@@ -35469,14 +35844,14 @@ var keychain_exports = {};
|
|
|
35469
35844
|
__export(keychain_exports, {
|
|
35470
35845
|
Keychain: () => Keychain
|
|
35471
35846
|
});
|
|
35472
|
-
var import_child_process12, import_os6,
|
|
35847
|
+
var import_child_process12, import_os6, import_fs79, import_path83, import_crypto32, DEFAULT_SERVICE_NAME, VALID_PROVIDERS2, ENCRYPTED_FILE, ALGO, Keychain;
|
|
35473
35848
|
var init_keychain = __esm({
|
|
35474
35849
|
"apps/cli/src/keychain.ts"() {
|
|
35475
35850
|
"use strict";
|
|
35476
35851
|
import_child_process12 = require("child_process");
|
|
35477
35852
|
import_os6 = require("os");
|
|
35478
|
-
|
|
35479
|
-
|
|
35853
|
+
import_fs79 = require("fs");
|
|
35854
|
+
import_path83 = require("path");
|
|
35480
35855
|
import_crypto32 = require("crypto");
|
|
35481
35856
|
DEFAULT_SERVICE_NAME = "gossip-mesh";
|
|
35482
35857
|
VALID_PROVIDERS2 = /^[a-zA-Z0-9_-]{1,32}$/;
|
|
@@ -35520,10 +35895,10 @@ var init_keychain = __esm({
|
|
|
35520
35895
|
return (0, import_crypto32.pbkdf2Sync)(seed, salt, 6e5, 32, "sha256");
|
|
35521
35896
|
}
|
|
35522
35897
|
loadEncryptedFile() {
|
|
35523
|
-
const filePath = (0,
|
|
35524
|
-
if (!(0,
|
|
35898
|
+
const filePath = (0, import_path83.join)(process.cwd(), ENCRYPTED_FILE);
|
|
35899
|
+
if (!(0, import_fs79.existsSync)(filePath)) return;
|
|
35525
35900
|
try {
|
|
35526
|
-
const raw = (0,
|
|
35901
|
+
const raw = (0, import_fs79.readFileSync)(filePath);
|
|
35527
35902
|
if (raw.length < 61) return;
|
|
35528
35903
|
const salt = raw.subarray(0, 32);
|
|
35529
35904
|
const iv = raw.subarray(32, 44);
|
|
@@ -35541,9 +35916,9 @@ var init_keychain = __esm({
|
|
|
35541
35916
|
}
|
|
35542
35917
|
}
|
|
35543
35918
|
saveEncryptedFile() {
|
|
35544
|
-
const filePath = (0,
|
|
35545
|
-
const dir = (0,
|
|
35546
|
-
if (!(0,
|
|
35919
|
+
const filePath = (0, import_path83.join)(process.cwd(), ENCRYPTED_FILE);
|
|
35920
|
+
const dir = (0, import_path83.join)(process.cwd(), ".gossip");
|
|
35921
|
+
if (!(0, import_fs79.existsSync)(dir)) (0, import_fs79.mkdirSync)(dir, { recursive: true });
|
|
35547
35922
|
const data = JSON.stringify(Object.fromEntries(this.inMemoryStore));
|
|
35548
35923
|
const salt = (0, import_crypto32.randomBytes)(32);
|
|
35549
35924
|
const iv = (0, import_crypto32.randomBytes)(12);
|
|
@@ -35551,7 +35926,7 @@ var init_keychain = __esm({
|
|
|
35551
35926
|
const cipher = (0, import_crypto32.createCipheriv)(ALGO, key, iv);
|
|
35552
35927
|
const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
|
|
35553
35928
|
const tag = cipher.getAuthTag();
|
|
35554
|
-
(0,
|
|
35929
|
+
(0, import_fs79.writeFileSync)(filePath, Buffer.concat([salt, iv, tag, encrypted]), { mode: 384 });
|
|
35555
35930
|
}
|
|
35556
35931
|
isKeychainAvailable() {
|
|
35557
35932
|
if ((0, import_os6.platform)() === "darwin") {
|
|
@@ -35651,17 +36026,17 @@ __export(identity_exports, {
|
|
|
35651
36026
|
normalizeGitUrl: () => normalizeGitUrl
|
|
35652
36027
|
});
|
|
35653
36028
|
function getOrCreateSalt(projectRoot) {
|
|
35654
|
-
const saltPath = (0,
|
|
36029
|
+
const saltPath = (0, import_path84.join)(projectRoot, ".gossip", "local-salt");
|
|
35655
36030
|
try {
|
|
35656
|
-
return (0,
|
|
36031
|
+
return (0, import_fs80.readFileSync)(saltPath, "utf-8").trim();
|
|
35657
36032
|
} catch {
|
|
35658
36033
|
const salt = (0, import_crypto33.randomBytes)(16).toString("hex");
|
|
35659
|
-
(0,
|
|
36034
|
+
(0, import_fs80.mkdirSync)((0, import_path84.join)(projectRoot, ".gossip"), { recursive: true });
|
|
35660
36035
|
try {
|
|
35661
|
-
(0,
|
|
36036
|
+
(0, import_fs80.writeFileSync)(saltPath, salt, { flag: "wx" });
|
|
35662
36037
|
return salt;
|
|
35663
36038
|
} catch {
|
|
35664
|
-
return (0,
|
|
36039
|
+
return (0, import_fs80.readFileSync)(saltPath, "utf-8").trim();
|
|
35665
36040
|
}
|
|
35666
36041
|
}
|
|
35667
36042
|
}
|
|
@@ -35711,12 +36086,12 @@ function getProjectId(projectRoot) {
|
|
|
35711
36086
|
}
|
|
35712
36087
|
return (0, import_crypto33.createHash)("sha256").update(projectRoot).digest("hex").slice(0, 16);
|
|
35713
36088
|
}
|
|
35714
|
-
var
|
|
36089
|
+
var import_fs80, import_path84, import_crypto33, import_child_process13;
|
|
35715
36090
|
var init_identity = __esm({
|
|
35716
36091
|
"apps/cli/src/identity.ts"() {
|
|
35717
36092
|
"use strict";
|
|
35718
|
-
|
|
35719
|
-
|
|
36093
|
+
import_fs80 = require("fs");
|
|
36094
|
+
import_path84 = require("path");
|
|
35720
36095
|
import_crypto33 = require("crypto");
|
|
35721
36096
|
import_child_process13 = require("child_process");
|
|
35722
36097
|
}
|
|
@@ -35738,9 +36113,9 @@ async function getLatestVersion() {
|
|
|
35738
36113
|
return data.version;
|
|
35739
36114
|
}
|
|
35740
36115
|
function detectInstallMethod() {
|
|
35741
|
-
const packageRoot = (0,
|
|
36116
|
+
const packageRoot = (0, import_path85.resolve)(__dirname, "..", "..", "..", "..");
|
|
35742
36117
|
if (process.env.npm_config_global === "true") return "global";
|
|
35743
|
-
if ((0,
|
|
36118
|
+
if ((0, import_fs81.existsSync)((0, import_path85.join)(packageRoot, ".git"))) return "git-clone";
|
|
35744
36119
|
return "local";
|
|
35745
36120
|
}
|
|
35746
36121
|
function updateCommand(method, version2) {
|
|
@@ -35795,7 +36170,7 @@ Check your internet connection or visit https://www.npmjs.com/package/gossipcat
|
|
|
35795
36170
|
try {
|
|
35796
36171
|
(0, import_child_process14.execSync)(command, {
|
|
35797
36172
|
stdio: "inherit",
|
|
35798
|
-
cwd: method === "git-clone" ? (0,
|
|
36173
|
+
cwd: method === "git-clone" ? (0, import_path85.resolve)(__dirname, "..", "..", "..", "..") : process.cwd(),
|
|
35799
36174
|
env: scrubbedEnv
|
|
35800
36175
|
});
|
|
35801
36176
|
} catch (err) {
|
|
@@ -35818,13 +36193,13 @@ Run /mcp reconnect in Claude Code to load the new version.`
|
|
|
35818
36193
|
}]
|
|
35819
36194
|
};
|
|
35820
36195
|
}
|
|
35821
|
-
var import_child_process14,
|
|
36196
|
+
var import_child_process14, import_fs81, import_path85;
|
|
35822
36197
|
var init_gossip_update = __esm({
|
|
35823
36198
|
"apps/cli/src/handlers/gossip-update.ts"() {
|
|
35824
36199
|
"use strict";
|
|
35825
36200
|
import_child_process14 = require("child_process");
|
|
35826
|
-
|
|
35827
|
-
|
|
36201
|
+
import_fs81 = require("fs");
|
|
36202
|
+
import_path85 = require("path");
|
|
35828
36203
|
init_version();
|
|
35829
36204
|
}
|
|
35830
36205
|
});
|
|
@@ -36035,8 +36410,8 @@ __export(mcp_server_sdk_exports, {
|
|
|
36035
36410
|
createMcpServer: () => createMcpServer
|
|
36036
36411
|
});
|
|
36037
36412
|
module.exports = __toCommonJS(mcp_server_sdk_exports);
|
|
36038
|
-
var
|
|
36039
|
-
var
|
|
36413
|
+
var import_fs82 = require("fs");
|
|
36414
|
+
var import_path86 = require("path");
|
|
36040
36415
|
|
|
36041
36416
|
// apps/cli/src/hook-run.ts
|
|
36042
36417
|
var import_fs = require("fs");
|
|
@@ -49939,15 +50314,15 @@ init_native_tasks();
|
|
|
49939
50314
|
|
|
49940
50315
|
// apps/cli/src/handlers/dispatch.ts
|
|
49941
50316
|
var import_crypto31 = require("crypto");
|
|
49942
|
-
var
|
|
49943
|
-
var
|
|
50317
|
+
var import_fs72 = require("fs");
|
|
50318
|
+
var import_path77 = require("path");
|
|
49944
50319
|
init_src4();
|
|
49945
50320
|
init_src3();
|
|
49946
50321
|
init_mcp_context();
|
|
49947
50322
|
init_native_tasks();
|
|
49948
50323
|
init_dispatch_prompt_storage();
|
|
49949
50324
|
init_dispatch_prompt_cache();
|
|
49950
|
-
var
|
|
50325
|
+
var import_fs73 = require("fs");
|
|
49951
50326
|
|
|
49952
50327
|
// apps/cli/src/handlers/relay-tasks.ts
|
|
49953
50328
|
init_mcp_context();
|
|
@@ -50060,7 +50435,7 @@ function tryWarmCacheHit(liveTaskBlock, cacheKey, promptFormat) {
|
|
|
50060
50435
|
const cached4 = getCachedPrompt(cacheKey);
|
|
50061
50436
|
if (!cached4) return null;
|
|
50062
50437
|
if (cached4.skillFingerprint !== cacheKey.skillFingerprint) return null;
|
|
50063
|
-
if (!(0,
|
|
50438
|
+
if (!(0, import_fs73.existsSync)(cached4.skillsSectionPath)) return null;
|
|
50064
50439
|
try {
|
|
50065
50440
|
const skillsSection = require("fs").readFileSync(cached4.skillsSectionPath, "utf8");
|
|
50066
50441
|
return skillsSection + liveTaskBlock;
|
|
@@ -50137,9 +50512,9 @@ function formatFalsifiedNote(block, verdicts) {
|
|
|
50137
50512
|
}
|
|
50138
50513
|
function writePremiseVerificationLog(projectRoot, taskId, result, opts) {
|
|
50139
50514
|
try {
|
|
50140
|
-
const logPath = (0,
|
|
50515
|
+
const logPath = (0, import_path77.join)(projectRoot, PREMISE_VERIFICATION_LOG);
|
|
50141
50516
|
rotateIfNeeded2(logPath, MAX_PREMISE_VERIFICATION_BYTES);
|
|
50142
|
-
(0,
|
|
50517
|
+
(0, import_fs72.mkdirSync)((0, import_path77.join)(projectRoot, ".gossip"), { recursive: true });
|
|
50143
50518
|
const row = {
|
|
50144
50519
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
50145
50520
|
consensus_id: null,
|
|
@@ -50153,7 +50528,7 @@ function writePremiseVerificationLog(projectRoot, taskId, result, opts) {
|
|
|
50153
50528
|
skill_bound: opts.skill_bound
|
|
50154
50529
|
};
|
|
50155
50530
|
if (opts.schema_lint) row.schema_lint = opts.schema_lint;
|
|
50156
|
-
(0,
|
|
50531
|
+
(0, import_fs72.appendFileSync)(logPath, JSON.stringify(row) + "\n");
|
|
50157
50532
|
} catch {
|
|
50158
50533
|
}
|
|
50159
50534
|
}
|
|
@@ -50265,7 +50640,7 @@ var AGENT_PROVIDER_MAP = {
|
|
|
50265
50640
|
};
|
|
50266
50641
|
function readQuotaState() {
|
|
50267
50642
|
try {
|
|
50268
|
-
const raw = (0,
|
|
50643
|
+
const raw = (0, import_fs72.readFileSync)((0, import_path77.join)(process.cwd(), ".gossip", "quota-state.json"), "utf8");
|
|
50269
50644
|
return JSON.parse(raw);
|
|
50270
50645
|
} catch {
|
|
50271
50646
|
return {};
|
|
@@ -51093,13 +51468,13 @@ function buildAutoVerifyDispatch(binding) {
|
|
|
51093
51468
|
var _autoResolverErrors = /* @__PURE__ */ new Set();
|
|
51094
51469
|
var _autoResolverLockWarned = false;
|
|
51095
51470
|
var CONSENSUS_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{8}$/;
|
|
51096
|
-
function
|
|
51471
|
+
function isValidConsensusId2(id) {
|
|
51097
51472
|
return typeof id === "string" && CONSENSUS_ID_RE.test(id);
|
|
51098
51473
|
}
|
|
51099
51474
|
function extractConsensusIdFromFindingId(findingId) {
|
|
51100
51475
|
if (typeof findingId !== "string") return void 0;
|
|
51101
51476
|
const first = findingId.split(":")[0];
|
|
51102
|
-
return
|
|
51477
|
+
return isValidConsensusId2(first) ? first : void 0;
|
|
51103
51478
|
}
|
|
51104
51479
|
function reconcilerFindingsAll(consensusReport) {
|
|
51105
51480
|
return [
|
|
@@ -51801,7 +52176,7 @@ ${np.user}
|
|
|
51801
52176
|
...consensusReport.unique || []
|
|
51802
52177
|
];
|
|
51803
52178
|
const authoritativeId = consensusReport?.signals?.[0]?.consensusId;
|
|
51804
|
-
const provisionalConsensusId = (
|
|
52179
|
+
const provisionalConsensusId = (isValidConsensusId2(authoritativeId) ? authoritativeId : void 0) ?? (allFindings.length > 0 ? extractConsensusIdFromFindingId(allFindings[0].id) : void 0);
|
|
51805
52180
|
const provisionalSignals = allFindings.filter((f) => !isFindingAlreadySignaled(alreadySignaled, f)).map((f) => {
|
|
51806
52181
|
const extracted = extractCategories2(f.finding || "");
|
|
51807
52182
|
const category = f.category || extracted[0] || void 0;
|
|
@@ -52049,19 +52424,19 @@ function filterWatchEvents(rawJsonl, opts) {
|
|
|
52049
52424
|
}
|
|
52050
52425
|
|
|
52051
52426
|
// apps/cli/src/stickyPort.ts
|
|
52052
|
-
var
|
|
52053
|
-
var
|
|
52427
|
+
var import_fs76 = require("fs");
|
|
52428
|
+
var import_path80 = require("path");
|
|
52054
52429
|
var import_net = require("net");
|
|
52055
|
-
var RELAY_STICKY_FILE = (0,
|
|
52056
|
-
var HTTP_MCP_STICKY_FILE = (0,
|
|
52430
|
+
var RELAY_STICKY_FILE = (0, import_path80.join)(".gossip", "relay.port");
|
|
52431
|
+
var HTTP_MCP_STICKY_FILE = (0, import_path80.join)(".gossip", "http-mcp.port");
|
|
52057
52432
|
function stickyPath(filename) {
|
|
52058
|
-
return (0,
|
|
52433
|
+
return (0, import_path80.join)(process.cwd(), filename);
|
|
52059
52434
|
}
|
|
52060
52435
|
function readStickyPort(filename) {
|
|
52061
52436
|
const p = stickyPath(filename);
|
|
52062
|
-
if (!(0,
|
|
52437
|
+
if (!(0, import_fs76.existsSync)(p)) return null;
|
|
52063
52438
|
try {
|
|
52064
|
-
const raw = (0,
|
|
52439
|
+
const raw = (0, import_fs76.readFileSync)(p, "utf-8").trim();
|
|
52065
52440
|
const n = parseInt(raw, 10);
|
|
52066
52441
|
if (!Number.isFinite(n) || n < 1 || n > 65535) return null;
|
|
52067
52442
|
return n;
|
|
@@ -52073,8 +52448,8 @@ function writeStickyPort(filename, port) {
|
|
|
52073
52448
|
if (!Number.isFinite(port) || port < 1 || port > 65535) return;
|
|
52074
52449
|
const p = stickyPath(filename);
|
|
52075
52450
|
try {
|
|
52076
|
-
(0,
|
|
52077
|
-
(0,
|
|
52451
|
+
(0, import_fs76.mkdirSync)((0, import_path80.dirname)(p), { recursive: true });
|
|
52452
|
+
(0, import_fs76.writeFileSync)(p, String(port), "utf-8");
|
|
52078
52453
|
} catch {
|
|
52079
52454
|
}
|
|
52080
52455
|
}
|
|
@@ -52138,22 +52513,22 @@ function buildDashboardAdvisory(input) {
|
|
|
52138
52513
|
}
|
|
52139
52514
|
|
|
52140
52515
|
// apps/cli/src/native-agent-cache.ts
|
|
52141
|
-
var
|
|
52142
|
-
var
|
|
52516
|
+
var import_fs77 = require("fs");
|
|
52517
|
+
var import_path81 = require("path");
|
|
52143
52518
|
var realFs = {
|
|
52144
|
-
existsSync:
|
|
52145
|
-
readFileSync:
|
|
52146
|
-
statSync: (p) => ({ mtimeMs: (0,
|
|
52519
|
+
existsSync: import_fs77.existsSync,
|
|
52520
|
+
readFileSync: import_fs77.readFileSync,
|
|
52521
|
+
statSync: (p) => ({ mtimeMs: (0, import_fs77.statSync)(p).mtimeMs })
|
|
52147
52522
|
};
|
|
52148
52523
|
function modelTierFromId(modelId) {
|
|
52149
52524
|
if (modelId.includes("opus")) return "opus";
|
|
52150
52525
|
if (modelId.includes("haiku")) return "haiku";
|
|
52151
52526
|
return "sonnet";
|
|
52152
52527
|
}
|
|
52153
|
-
function refreshNativeAgentFromDisk(ac,
|
|
52154
|
-
const claudeAgentPath = (0,
|
|
52155
|
-
const instrPath = (0,
|
|
52156
|
-
const prev =
|
|
52528
|
+
function refreshNativeAgentFromDisk(ac, cache3, projectRoot, fs6 = realFs) {
|
|
52529
|
+
const claudeAgentPath = (0, import_path81.join)(projectRoot, ".claude", "agents", `${ac.id}.md`);
|
|
52530
|
+
const instrPath = (0, import_path81.join)(projectRoot, ".gossip", "agents", ac.id, "instructions.md");
|
|
52531
|
+
const prev = cache3.get(ac.id);
|
|
52157
52532
|
let sourcePath = null;
|
|
52158
52533
|
let stripFrontmatter = false;
|
|
52159
52534
|
if (fs6.existsSync(claudeAgentPath)) {
|
|
@@ -52167,7 +52542,7 @@ function refreshNativeAgentFromDisk(ac, cache2, projectRoot, fs6 = realFs) {
|
|
|
52167
52542
|
if (prev && prev.instructions.length > 0) {
|
|
52168
52543
|
return;
|
|
52169
52544
|
}
|
|
52170
|
-
|
|
52545
|
+
cache3.set(ac.id, {
|
|
52171
52546
|
model: modelTierFromId(ac.model),
|
|
52172
52547
|
instructions: "",
|
|
52173
52548
|
description: ac.role || ac.preset || "",
|
|
@@ -52183,7 +52558,7 @@ function refreshNativeAgentFromDisk(ac, cache2, projectRoot, fs6 = realFs) {
|
|
|
52183
52558
|
if (prev && prev.instructions.length > 0) {
|
|
52184
52559
|
return;
|
|
52185
52560
|
}
|
|
52186
|
-
|
|
52561
|
+
cache3.set(ac.id, {
|
|
52187
52562
|
model: modelTierFromId(ac.model),
|
|
52188
52563
|
instructions: "",
|
|
52189
52564
|
description: ac.role || ac.preset || "",
|
|
@@ -52201,7 +52576,7 @@ function refreshNativeAgentFromDisk(ac, cache2, projectRoot, fs6 = realFs) {
|
|
|
52201
52576
|
if (instructions.length === 0 && prev && prev.instructions.length > 0) {
|
|
52202
52577
|
return;
|
|
52203
52578
|
}
|
|
52204
|
-
|
|
52579
|
+
cache3.set(ac.id, {
|
|
52205
52580
|
model: modelTierFromId(ac.model),
|
|
52206
52581
|
instructions,
|
|
52207
52582
|
description: ac.role || ac.preset || "",
|
|
@@ -52211,16 +52586,16 @@ function refreshNativeAgentFromDisk(ac, cache2, projectRoot, fs6 = realFs) {
|
|
|
52211
52586
|
}
|
|
52212
52587
|
|
|
52213
52588
|
// apps/cli/src/rules-content.ts
|
|
52214
|
-
var
|
|
52215
|
-
var
|
|
52589
|
+
var import_fs78 = require("fs");
|
|
52590
|
+
var import_path82 = require("path");
|
|
52216
52591
|
var AGENT_LIST_PLACEHOLDER = "{{AGENT_LIST}}";
|
|
52217
52592
|
function resolveRulesPath() {
|
|
52218
52593
|
const candidates = [
|
|
52219
|
-
(0,
|
|
52220
|
-
(0,
|
|
52221
|
-
(0,
|
|
52594
|
+
(0, import_path82.join)(process.cwd(), "docs", "RULES.md"),
|
|
52595
|
+
(0, import_path82.join)(__dirname, "..", "docs", "RULES.md"),
|
|
52596
|
+
(0, import_path82.join)(__dirname, "docs", "RULES.md")
|
|
52222
52597
|
];
|
|
52223
|
-
return candidates.find((p) => (0,
|
|
52598
|
+
return candidates.find((p) => (0, import_fs78.existsSync)(p)) ?? null;
|
|
52224
52599
|
}
|
|
52225
52600
|
function generateRulesContent(agentList) {
|
|
52226
52601
|
const rulesPath = resolveRulesPath();
|
|
@@ -52229,7 +52604,7 @@ function generateRulesContent(agentList) {
|
|
|
52229
52604
|
`[gossipcat] generateRulesContent: docs/RULES.md not found in any fallback path (cwd=${process.cwd()}, dirname=${__dirname}). Expected docs/RULES.md tracked in the gossipcat repo or shipped alongside the MCP bundle. If running from a fresh install, re-run \`npm run build:mcp\` to copy docs/RULES.md into dist-mcp/docs/.`
|
|
52230
52605
|
);
|
|
52231
52606
|
}
|
|
52232
|
-
const template = (0,
|
|
52607
|
+
const template = (0, import_fs78.readFileSync)(rulesPath, "utf-8");
|
|
52233
52608
|
return template.split(AGENT_LIST_PLACEHOLDER).join(agentList);
|
|
52234
52609
|
}
|
|
52235
52610
|
|
|
@@ -52299,12 +52674,12 @@ function isReservedAgentId(id) {
|
|
|
52299
52674
|
}
|
|
52300
52675
|
}
|
|
52301
52676
|
if (process.env.GOSSIPCAT_MCP_NO_MAIN !== "1") {
|
|
52302
|
-
const gossipDir = (0,
|
|
52677
|
+
const gossipDir = (0, import_path86.join)(process.cwd(), ".gossip");
|
|
52303
52678
|
try {
|
|
52304
|
-
(0,
|
|
52679
|
+
(0, import_fs82.mkdirSync)(gossipDir, { recursive: true });
|
|
52305
52680
|
} catch {
|
|
52306
52681
|
}
|
|
52307
|
-
const logStream = (0,
|
|
52682
|
+
const logStream = (0, import_fs82.createWriteStream)((0, import_path86.join)(gossipDir, "mcp.log"), { flags: "a" });
|
|
52308
52683
|
process.stderr.write = ((chunk, ...args) => {
|
|
52309
52684
|
return logStream.write(chunk, ...args);
|
|
52310
52685
|
});
|
|
@@ -52315,7 +52690,7 @@ try {
|
|
|
52315
52690
|
} catch {
|
|
52316
52691
|
}
|
|
52317
52692
|
function memoryDirForProject(cwd) {
|
|
52318
|
-
return (0,
|
|
52693
|
+
return (0, import_path86.join)((0, import_os7.homedir)(), ".claude", "projects", cwd.replaceAll("/", "-"), "memory");
|
|
52319
52694
|
}
|
|
52320
52695
|
function detectEnvironment() {
|
|
52321
52696
|
if (process.env.CLAUDECODE === "1" || process.env.CLAUDE_CODE_ENTRYPOINT) {
|
|
@@ -52370,14 +52745,14 @@ var _pendingPlanData = /* @__PURE__ */ new Map();
|
|
|
52370
52745
|
var _utilityGuardSnapshots = /* @__PURE__ */ new Map();
|
|
52371
52746
|
var _modules = null;
|
|
52372
52747
|
function lookupFindingSeverity(findingId, projectRoot) {
|
|
52373
|
-
const { existsSync:
|
|
52374
|
-
const { join:
|
|
52375
|
-
const reportsDir =
|
|
52376
|
-
if (!
|
|
52748
|
+
const { existsSync: existsSync70, readdirSync: readdirSync22, readFileSync: readFileSync64 } = require("fs");
|
|
52749
|
+
const { join: join83 } = require("path");
|
|
52750
|
+
const reportsDir = join83(projectRoot, ".gossip", "consensus-reports");
|
|
52751
|
+
if (!existsSync70(reportsDir)) return null;
|
|
52377
52752
|
try {
|
|
52378
52753
|
const files = readdirSync22(reportsDir).filter((f) => f.endsWith(".json"));
|
|
52379
52754
|
for (const file2 of files) {
|
|
52380
|
-
const report = JSON.parse(
|
|
52755
|
+
const report = JSON.parse(readFileSync64(join83(reportsDir, file2), "utf-8"));
|
|
52381
52756
|
for (const bucket of ["confirmed", "disputed", "unverified", "unique"]) {
|
|
52382
52757
|
for (const finding of report[bucket] || []) {
|
|
52383
52758
|
if (finding.id === findingId && finding.severity) {
|
|
@@ -52455,7 +52830,7 @@ async function doBoot() {
|
|
|
52455
52830
|
const agentConfigs = m.configToAgentConfigs(config2);
|
|
52456
52831
|
ctx.keychain = new m.Keychain();
|
|
52457
52832
|
const { existsSync: pidExists, readFileSync: readPid, writeFileSync: writePid, unlinkSync: delPid } = require("fs");
|
|
52458
|
-
const pidFile = (0,
|
|
52833
|
+
const pidFile = (0, import_path86.join)(process.cwd(), ".gossip", "relay.pid");
|
|
52459
52834
|
if (pidExists(pidFile)) {
|
|
52460
52835
|
const oldPid = parseInt(readPid(pidFile, "utf-8").trim(), 10);
|
|
52461
52836
|
if (!isNaN(oldPid) && oldPid !== process.pid) {
|
|
@@ -52565,10 +52940,10 @@ async function doBoot() {
|
|
|
52565
52940
|
}
|
|
52566
52941
|
const key = await ctx.keychain.getKey(ac.provider);
|
|
52567
52942
|
const llm = m.createProvider(ac.provider, ac.model, key ?? void 0, void 0, ac.base_url);
|
|
52568
|
-
const { existsSync:
|
|
52569
|
-
const { join:
|
|
52570
|
-
const instructionsPath =
|
|
52571
|
-
const baseInstructions =
|
|
52943
|
+
const { existsSync: existsSync70, readFileSync: readFileSync64 } = require("fs");
|
|
52944
|
+
const { join: join83 } = require("path");
|
|
52945
|
+
const instructionsPath = join83(process.cwd(), ".gossip", "agents", ac.id, "instructions.md");
|
|
52946
|
+
const baseInstructions = existsSync70(instructionsPath) ? readFileSync64(instructionsPath, "utf-8") : "";
|
|
52572
52947
|
const identity = ctx.identityRegistry.get(ac.id);
|
|
52573
52948
|
const identityBlock = identity ? m.formatIdentityBlock(identity) + "\n" : "";
|
|
52574
52949
|
const instructions = (identityBlock + baseInstructions).trim() || void 0;
|
|
@@ -53403,7 +53778,7 @@ Note: write-mode classification unavailable on this native-only install \u2014 a
|
|
|
53403
53778
|
}
|
|
53404
53779
|
try {
|
|
53405
53780
|
const { readFileSync: rfHealth } = await import("fs");
|
|
53406
|
-
const healthPath = (0,
|
|
53781
|
+
const healthPath = (0, import_path86.join)(process.cwd(), ".gossip", "skill-runner-health.json");
|
|
53407
53782
|
const raw = rfHealth(healthPath, "utf8");
|
|
53408
53783
|
const h = JSON.parse(raw);
|
|
53409
53784
|
const lastMs = h.last_run_at ? new Date(h.last_run_at).getTime() : NaN;
|
|
@@ -53419,9 +53794,9 @@ Note: write-mode classification unavailable on this native-only install \u2014 a
|
|
|
53419
53794
|
lines.push(" Skill graduation: never run since session start (expected after first gossip_collect)");
|
|
53420
53795
|
}
|
|
53421
53796
|
try {
|
|
53422
|
-
const { readFileSync:
|
|
53423
|
-
const quotaPath = (0,
|
|
53424
|
-
const quotaRaw =
|
|
53797
|
+
const { readFileSync: readFileSync64 } = await import("fs");
|
|
53798
|
+
const quotaPath = (0, import_path86.join)(process.cwd(), ".gossip", "quota-state.json");
|
|
53799
|
+
const quotaRaw = readFileSync64(quotaPath, "utf8");
|
|
53425
53800
|
const quotaState = JSON.parse(quotaRaw);
|
|
53426
53801
|
for (const [provider, state] of Object.entries(quotaState)) {
|
|
53427
53802
|
const now = Date.now();
|
|
@@ -53435,19 +53810,19 @@ Note: write-mode classification unavailable on this native-only install \u2014 a
|
|
|
53435
53810
|
} catch {
|
|
53436
53811
|
}
|
|
53437
53812
|
try {
|
|
53438
|
-
const { readdirSync: readdirSync22, statSync:
|
|
53813
|
+
const { readdirSync: readdirSync22, statSync: statSync35 } = await import("fs");
|
|
53439
53814
|
const { readJsonlWithRotated: readJsonlRotated1506 } = await Promise.resolve().then(() => (init_src4(), src_exports3));
|
|
53440
|
-
const reportsDir = (0,
|
|
53441
|
-
const perfPath = (0,
|
|
53442
|
-
const
|
|
53815
|
+
const reportsDir = (0, import_path86.join)(process.cwd(), ".gossip", "consensus-reports");
|
|
53816
|
+
const perfPath = (0, import_path86.join)(process.cwd(), ".gossip", "agent-performance.jsonl");
|
|
53817
|
+
const WINDOW_MS3 = 24 * 60 * 60 * 1e3;
|
|
53443
53818
|
const now = Date.now();
|
|
53444
53819
|
const recentReports = [];
|
|
53445
53820
|
try {
|
|
53446
53821
|
for (const fname of readdirSync22(reportsDir)) {
|
|
53447
53822
|
if (!fname.endsWith(".json")) continue;
|
|
53448
|
-
const fpath = (0,
|
|
53449
|
-
const st =
|
|
53450
|
-
if (now - st.mtimeMs >
|
|
53823
|
+
const fpath = (0, import_path86.join)(reportsDir, fname);
|
|
53824
|
+
const st = statSync35(fpath);
|
|
53825
|
+
if (now - st.mtimeMs > WINDOW_MS3) continue;
|
|
53451
53826
|
recentReports.push({ id: fname.replace(/\.json$/, ""), mtimeMs: st.mtimeMs });
|
|
53452
53827
|
}
|
|
53453
53828
|
} catch {
|
|
@@ -53811,8 +54186,8 @@ ${body}`
|
|
|
53811
54186
|
}
|
|
53812
54187
|
return { content: [{ type: "text", text: results.join("\n") }] };
|
|
53813
54188
|
}
|
|
53814
|
-
const { writeFileSync: writeFileSync34, mkdirSync: mkdirSync41, existsSync:
|
|
53815
|
-
const { join:
|
|
54189
|
+
const { writeFileSync: writeFileSync34, mkdirSync: mkdirSync41, existsSync: existsSync70 } = require("fs");
|
|
54190
|
+
const { join: join83 } = require("path");
|
|
53816
54191
|
const root = process.cwd();
|
|
53817
54192
|
const CLAUDE_MODEL_MAP2 = {
|
|
53818
54193
|
opus: { provider: "anthropic", model: "claude-opus-4-6" },
|
|
@@ -53826,8 +54201,8 @@ ${body}`
|
|
|
53826
54201
|
let existingAgents = {};
|
|
53827
54202
|
if (mode === "merge") {
|
|
53828
54203
|
try {
|
|
53829
|
-
const { readFileSync:
|
|
53830
|
-
const existing = JSON.parse(
|
|
54204
|
+
const { readFileSync: readFileSync64 } = require("fs");
|
|
54205
|
+
const existing = JSON.parse(readFileSync64(join83(root, ".gossip", "config.json"), "utf-8"));
|
|
53831
54206
|
existingAgents = existing.agents || {};
|
|
53832
54207
|
} catch {
|
|
53833
54208
|
}
|
|
@@ -53858,9 +54233,9 @@ ${body}`
|
|
|
53858
54233
|
"",
|
|
53859
54234
|
body
|
|
53860
54235
|
].join("\n");
|
|
53861
|
-
const agentsDir =
|
|
54236
|
+
const agentsDir = join83(root, ".claude", "agents");
|
|
53862
54237
|
mkdirSync41(agentsDir, { recursive: true });
|
|
53863
|
-
writeFileSync34(
|
|
54238
|
+
writeFileSync34(join83(agentsDir, `${agent.id}.md`), md, "utf-8");
|
|
53864
54239
|
nativeCreated.push(agent.id);
|
|
53865
54240
|
configAgents[agent.id] = {
|
|
53866
54241
|
provider: mapped.provider,
|
|
@@ -53878,8 +54253,8 @@ ${body}`
|
|
|
53878
54253
|
errors.push(`${agent.id}: custom agent requires "custom_model" field`);
|
|
53879
54254
|
continue;
|
|
53880
54255
|
}
|
|
53881
|
-
const nativeFile =
|
|
53882
|
-
const wasNative = existingAgents[agent.id]?.native ||
|
|
54256
|
+
const nativeFile = join83(root, ".claude", "agents", `${agent.id}.md`);
|
|
54257
|
+
const wasNative = existingAgents[agent.id]?.native || existsSync70(nativeFile);
|
|
53883
54258
|
if (wasNative) {
|
|
53884
54259
|
errors.push(`${agent.id}: cannot re-register native agent as custom \u2014 .claude/agents/${agent.id}.md exists. Remove the file first or keep it as native.`);
|
|
53885
54260
|
continue;
|
|
@@ -53893,9 +54268,9 @@ ${body}`
|
|
|
53893
54268
|
};
|
|
53894
54269
|
customCreated.push(agent.id);
|
|
53895
54270
|
if (agent.instructions) {
|
|
53896
|
-
const instrDir =
|
|
54271
|
+
const instrDir = join83(root, ".gossip", "agents", agent.id);
|
|
53897
54272
|
mkdirSync41(instrDir, { recursive: true });
|
|
53898
|
-
writeFileSync34(
|
|
54273
|
+
writeFileSync34(join83(instrDir, "instructions.md"), agent.instructions, "utf-8");
|
|
53899
54274
|
}
|
|
53900
54275
|
}
|
|
53901
54276
|
}
|
|
@@ -53909,8 +54284,8 @@ ${body}`
|
|
|
53909
54284
|
} catch (err) {
|
|
53910
54285
|
return { content: [{ type: "text", text: `Invalid config: ${err.message}` }] };
|
|
53911
54286
|
}
|
|
53912
|
-
mkdirSync41(
|
|
53913
|
-
writeFileSync34(
|
|
54287
|
+
mkdirSync41(join83(root, ".gossip"), { recursive: true });
|
|
54288
|
+
writeFileSync34(join83(root, ".gossip", "config.json"), JSON.stringify(config2, null, 2));
|
|
53914
54289
|
let hookSummary = "";
|
|
53915
54290
|
try {
|
|
53916
54291
|
const { installWorktreeSandboxHook: installWorktreeSandboxHook2, writeOrchestratorRoleMarker: writeOrchestratorRoleMarker2 } = (init_src4(), __toCommonJS(src_exports3));
|
|
@@ -53987,8 +54362,8 @@ ${body}`
|
|
|
53987
54362
|
}
|
|
53988
54363
|
}
|
|
53989
54364
|
const agentList = Object.entries(config2.agents).map(([id, a]) => `- ${id}: ${a.provider}/${a.model} (${a.preset || "custom"})${a.native ? " \u2014 native" : ""}`).join("\n");
|
|
53990
|
-
const rulesDir =
|
|
53991
|
-
const rulesFile =
|
|
54365
|
+
const rulesDir = join83(root, env.rulesDir);
|
|
54366
|
+
const rulesFile = join83(root, env.rulesFile);
|
|
53992
54367
|
mkdirSync41(rulesDir, { recursive: true });
|
|
53993
54368
|
writeFileSync34(rulesFile, generateRulesContent(agentList));
|
|
53994
54369
|
const lines = [`Host: ${env.host}`, ""];
|
|
@@ -54285,11 +54660,11 @@ The original signal remains in the audit log but will be excluded from scoring.`
|
|
|
54285
54660
|
const fid = finding_id.trim();
|
|
54286
54661
|
const cwd = process.cwd();
|
|
54287
54662
|
const findingsPath = require("path").join(cwd, ".gossip", "implementation-findings.jsonl");
|
|
54288
|
-
const { readFileSync:
|
|
54289
|
-
if (!
|
|
54663
|
+
const { readFileSync: readFileSync64, existsSync: existsSync70, writeFileSync: writeFileSync34, renameSync: renameSync15 } = require("fs");
|
|
54664
|
+
if (!existsSync70(findingsPath)) {
|
|
54290
54665
|
return { content: [{ type: "text", text: `No implementation-findings.jsonl found at ${findingsPath}` }] };
|
|
54291
54666
|
}
|
|
54292
|
-
const lines =
|
|
54667
|
+
const lines = readFileSync64(findingsPath, "utf-8").split("\n");
|
|
54293
54668
|
let matched = false;
|
|
54294
54669
|
let alreadyTarget = false;
|
|
54295
54670
|
let matchedEntry = null;
|
|
@@ -54377,18 +54752,18 @@ The original signal remains in the audit log but will be excluded from scoring.`
|
|
|
54377
54752
|
return { content: [{ type: "text", text: "Error: consensus_id is required for bulk_from_consensus." }] };
|
|
54378
54753
|
}
|
|
54379
54754
|
try {
|
|
54380
|
-
const { readFileSync:
|
|
54381
|
-
const { join:
|
|
54382
|
-
const reportPath =
|
|
54755
|
+
const { readFileSync: readFileSync64 } = await import("fs");
|
|
54756
|
+
const { join: join83 } = await import("path");
|
|
54757
|
+
const reportPath = join83(process.cwd(), ".gossip", "consensus-reports", `${consensus_id}.json`);
|
|
54383
54758
|
let report;
|
|
54384
54759
|
try {
|
|
54385
|
-
report = JSON.parse(
|
|
54760
|
+
report = JSON.parse(readFileSync64(reportPath, "utf-8"));
|
|
54386
54761
|
} catch {
|
|
54387
54762
|
return { content: [{ type: "text", text: `Error: consensus report not found: ${consensus_id}` }] };
|
|
54388
54763
|
}
|
|
54389
54764
|
const existingFindingIds = /* @__PURE__ */ new Set();
|
|
54390
54765
|
try {
|
|
54391
|
-
const perfPath =
|
|
54766
|
+
const perfPath = join83(process.cwd(), ".gossip", "agent-performance.jsonl");
|
|
54392
54767
|
const { readJsonlWithRotated: readJsonlRotated2570 } = await Promise.resolve().then(() => (init_src4(), src_exports3));
|
|
54393
54768
|
const lines = readJsonlRotated2570(perfPath).split("\n").filter(Boolean);
|
|
54394
54769
|
for (const line of lines) {
|
|
@@ -55404,16 +55779,16 @@ ${preview}` }]
|
|
|
55404
55779
|
const { SkillGapTracker: SkillGapTracker2, parseSkillFrontmatter: parseSkillFrontmatter2, normalizeSkillName: normalizeSkillName2 } = await Promise.resolve().then(() => (init_src4(), src_exports3));
|
|
55405
55780
|
const tracker = new SkillGapTracker2(process.cwd());
|
|
55406
55781
|
if (skills && skills.length > 0) {
|
|
55407
|
-
const { writeFileSync: writeFileSync34, mkdirSync: mkdirSync41, existsSync:
|
|
55408
|
-
const { join:
|
|
55409
|
-
const dir =
|
|
55782
|
+
const { writeFileSync: writeFileSync34, mkdirSync: mkdirSync41, existsSync: existsSync70, readFileSync: readFileSync64 } = require("fs");
|
|
55783
|
+
const { join: join83 } = require("path");
|
|
55784
|
+
const dir = join83(process.cwd(), ".gossip", "skills");
|
|
55410
55785
|
mkdirSync41(dir, { recursive: true });
|
|
55411
55786
|
const results = [];
|
|
55412
55787
|
for (const sk of skills) {
|
|
55413
55788
|
const name = normalizeSkillName2(sk.name);
|
|
55414
|
-
const filePath =
|
|
55415
|
-
if (
|
|
55416
|
-
const existing =
|
|
55789
|
+
const filePath = join83(dir, `${name}.md`);
|
|
55790
|
+
if (existsSync70(filePath)) {
|
|
55791
|
+
const existing = readFileSync64(filePath, "utf-8");
|
|
55417
55792
|
const fm = parseSkillFrontmatter2(existing);
|
|
55418
55793
|
if (fm) {
|
|
55419
55794
|
if (fm.generated_by === "manual") {
|
|
@@ -56249,9 +56624,9 @@ ${p.user}
|
|
|
56249
56624
|
max_events: external_exports.number().int().positive().max(WATCH_MAX_EVENTS).optional().describe(`Cap events returned (default ${WATCH_MAX_EVENTS}).`)
|
|
56250
56625
|
},
|
|
56251
56626
|
async ({ cursor, max_events }) => {
|
|
56252
|
-
const { join:
|
|
56627
|
+
const { join: join83 } = await import("node:path");
|
|
56253
56628
|
const { readJsonlWithRotated: readJsonlWithRotated2 } = await Promise.resolve().then(() => (init_src4(), src_exports3));
|
|
56254
|
-
const perfPath =
|
|
56629
|
+
const perfPath = join83(process.cwd(), ".gossip", "agent-performance.jsonl");
|
|
56255
56630
|
const raw = readJsonlWithRotated2(perfPath);
|
|
56256
56631
|
const result = filterWatchEvents(raw, { cursor, maxEvents: max_events });
|
|
56257
56632
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|