gossipcat 0.4.16 → 0.4.17
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.
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<link rel="icon" type="image/png" href="/dashboard/favicon.png" />
|
|
23
23
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
24
24
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
25
|
-
<script type="module" crossorigin src="/dashboard/assets/index-
|
|
25
|
+
<script type="module" crossorigin src="/dashboard/assets/index-1D2tBkyY.js"></script>
|
|
26
26
|
<link rel="stylesheet" crossorigin href="/dashboard/assets/index-B2_6u4lC.css">
|
|
27
27
|
</head>
|
|
28
28
|
<body>
|
package/dist-mcp/mcp-server.js
CHANGED
|
@@ -5618,7 +5618,7 @@ var init_gossip_agent = __esm({
|
|
|
5618
5618
|
}
|
|
5619
5619
|
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
5620
5620
|
connect() {
|
|
5621
|
-
return new Promise((
|
|
5621
|
+
return new Promise((resolve26, reject) => {
|
|
5622
5622
|
const ws = new import_ws2.default(this.config.relayUrl);
|
|
5623
5623
|
const timeout = setTimeout(() => {
|
|
5624
5624
|
ws.removeAllListeners();
|
|
@@ -5651,7 +5651,7 @@ var init_gossip_agent = __esm({
|
|
|
5651
5651
|
ws.on("error", (err) => this.emit("error", err));
|
|
5652
5652
|
this.startKeepAlive();
|
|
5653
5653
|
this.emit("connect", msg.sessionId);
|
|
5654
|
-
|
|
5654
|
+
resolve26();
|
|
5655
5655
|
} else if (msg.type === "error") {
|
|
5656
5656
|
clearTimeout(timeout);
|
|
5657
5657
|
ws.removeAllListeners();
|
|
@@ -5677,7 +5677,7 @@ var init_gossip_agent = __esm({
|
|
|
5677
5677
|
this.reconnectTimer = null;
|
|
5678
5678
|
}
|
|
5679
5679
|
if (!this.ws) return;
|
|
5680
|
-
return new Promise((
|
|
5680
|
+
return new Promise((resolve26) => {
|
|
5681
5681
|
this.intentionalDisconnect = true;
|
|
5682
5682
|
this._connected = false;
|
|
5683
5683
|
const ws = this.ws;
|
|
@@ -5688,7 +5688,7 @@ var init_gossip_agent = __esm({
|
|
|
5688
5688
|
settled = true;
|
|
5689
5689
|
this.intentionalDisconnect = false;
|
|
5690
5690
|
this.emit("disconnect", code);
|
|
5691
|
-
|
|
5691
|
+
resolve26();
|
|
5692
5692
|
};
|
|
5693
5693
|
const timer = setTimeout(() => done(1e3), 2e3);
|
|
5694
5694
|
ws.once("close", (code) => {
|
|
@@ -5727,8 +5727,8 @@ var init_gossip_agent = __esm({
|
|
|
5727
5727
|
throw new Error("Not connected to relay");
|
|
5728
5728
|
}
|
|
5729
5729
|
const encoded = Buffer.from(this.codec.encode(envelope));
|
|
5730
|
-
return new Promise((
|
|
5731
|
-
this.ws.send(encoded, (err) => err ? reject(err) :
|
|
5730
|
+
return new Promise((resolve26, reject) => {
|
|
5731
|
+
this.ws.send(encoded, (err) => err ? reject(err) : resolve26());
|
|
5732
5732
|
});
|
|
5733
5733
|
}
|
|
5734
5734
|
// ─── Internal ────────────────────────────────────────────────────────────────
|
|
@@ -6178,7 +6178,7 @@ ${context}` : ""}
|
|
|
6178
6178
|
this.memoryQueryCalled = true;
|
|
6179
6179
|
}
|
|
6180
6180
|
const requestId = (0, import_crypto6.randomUUID)();
|
|
6181
|
-
const resultPromise = new Promise((
|
|
6181
|
+
const resultPromise = new Promise((resolve26, reject) => {
|
|
6182
6182
|
const timer = setTimeout(() => {
|
|
6183
6183
|
if (this.pendingToolCalls.has(requestId)) {
|
|
6184
6184
|
this.pendingToolCalls.delete(requestId);
|
|
@@ -6189,7 +6189,7 @@ ${context}` : ""}
|
|
|
6189
6189
|
this.pendingToolCalls.set(requestId, {
|
|
6190
6190
|
resolve: (r) => {
|
|
6191
6191
|
clearTimeout(timer);
|
|
6192
|
-
|
|
6192
|
+
resolve26(r);
|
|
6193
6193
|
},
|
|
6194
6194
|
reject: (e) => {
|
|
6195
6195
|
clearTimeout(timer);
|
|
@@ -11526,7 +11526,7 @@ ${truncateAtLine(fullDiff, 3e3)}`;
|
|
|
11526
11526
|
}
|
|
11527
11527
|
async requestPeerReview(callerId, diff, testResult) {
|
|
11528
11528
|
const requestId = (0, import_crypto8.randomUUID)();
|
|
11529
|
-
const reviewPromise = new Promise((
|
|
11529
|
+
const reviewPromise = new Promise((resolve26, reject) => {
|
|
11530
11530
|
const timer = setTimeout(() => {
|
|
11531
11531
|
this.pendingReviews.delete(requestId);
|
|
11532
11532
|
reject(new Error("Review timed out"));
|
|
@@ -11535,7 +11535,7 @@ ${truncateAtLine(fullDiff, 3e3)}`;
|
|
|
11535
11535
|
this.pendingReviews.set(requestId, {
|
|
11536
11536
|
resolve: (r) => {
|
|
11537
11537
|
clearTimeout(timer);
|
|
11538
|
-
|
|
11538
|
+
resolve26(r);
|
|
11539
11539
|
},
|
|
11540
11540
|
reject: (e) => {
|
|
11541
11541
|
clearTimeout(timer);
|
|
@@ -12714,7 +12714,7 @@ var init_skill_loader = __esm({
|
|
|
12714
12714
|
});
|
|
12715
12715
|
|
|
12716
12716
|
// packages/orchestrator/src/finding-tag-schema.ts
|
|
12717
|
-
var FINDING_TAG_SCHEMA, CONSENSUS_OUTPUT_FORMAT;
|
|
12717
|
+
var FINDING_TAG_SCHEMA, OUTPUT_DELIVERY_PROTOCOL, CONSENSUS_OUTPUT_FORMAT;
|
|
12718
12718
|
var init_finding_tag_schema = __esm({
|
|
12719
12719
|
"packages/orchestrator/src/finding-tag-schema.ts"() {
|
|
12720
12720
|
"use strict";
|
|
@@ -12724,6 +12724,7 @@ var init_finding_tag_schema = __esm({
|
|
|
12724
12724
|
- severity (findings only): critical | high | medium | low
|
|
12725
12725
|
- Do NOT invent new types (e.g., "approval", "concern", "risk", "recommendation", "confirmed", "issue", "bug", "warning") \u2014 they will not appear in any dashboard, score, or signal.
|
|
12726
12726
|
- Cite source files inline: <cite tag="file">path:line</cite>`;
|
|
12727
|
+
OUTPUT_DELIVERY_PROTOCOL = `OUTPUT DELIVERY \u2014 emit findings as TEXT in your response. The orchestrator captures your response and calls gossip_relay on your behalf. Do NOT call gossip_relay, gossip_relay_cross_review, or any gossip_* tool yourself \u2014 these are orchestrator-only. Stop when your findings are written; do not try to "submit" or "finalize".`;
|
|
12727
12728
|
CONSENSUS_OUTPUT_FORMAT = `\u26A0 UNKNOWN TYPES ARE SILENTLY DROPPED \u2014 only type="finding", type="suggestion", type="insight" are accepted. Any other type value (e.g. approval, concern, risk, recommendation, confirmed) will NOT appear in the dashboard, scores, or signals.
|
|
12728
12729
|
|
|
12729
12730
|
${FINDING_TAG_SCHEMA}
|
|
@@ -12878,6 +12879,9 @@ ${CONSENSUS_OUTPUT_FORMAT}
|
|
|
12878
12879
|
|
|
12879
12880
|
This section will be used for cross-review with peer agents.
|
|
12880
12881
|
--- END CONSENSUS OUTPUT FORMAT ---` });
|
|
12882
|
+
suffix.push({ priority: 0, text: `
|
|
12883
|
+
|
|
12884
|
+
${OUTPUT_DELIVERY_PROTOCOL}` });
|
|
12881
12885
|
} else {
|
|
12882
12886
|
const hasAnyMeaningfulPart = !!(parts.identity || parts.instructions || parts.memory || parts.memoryDir || parts.lens || parts.skills || parts.context || parts.sessionContext || parts.chainContext || parts.specReviewContext || parts.projectStructure || parts.task || parts.consensusFindings && parts.consensusFindings.length > 0);
|
|
12883
12887
|
if (hasAnyMeaningfulPart) {
|
|
@@ -12886,6 +12890,9 @@ This section will be used for cross-review with peer agents.
|
|
|
12886
12890
|
--- FINDING TAG SCHEMA ---
|
|
12887
12891
|
${FINDING_TAG_SCHEMA}
|
|
12888
12892
|
--- END FINDING TAG SCHEMA ---` });
|
|
12893
|
+
suffix.push({ priority: 0, text: `
|
|
12894
|
+
|
|
12895
|
+
${OUTPUT_DELIVERY_PROTOCOL}` });
|
|
12889
12896
|
}
|
|
12890
12897
|
}
|
|
12891
12898
|
if (parts.lens) {
|
|
@@ -13304,7 +13311,9 @@ var init_memory_compactor = __esm({
|
|
|
13304
13311
|
(0, import_fs22.writeFileSync)(archivePath, archiveLines.slice(-MAX_ARCHIVE_LINES).join("\n") + "\n");
|
|
13305
13312
|
}
|
|
13306
13313
|
}
|
|
13307
|
-
} catch {
|
|
13314
|
+
} catch (err) {
|
|
13315
|
+
process.stderr.write(`[memory-compactor] archive truncation failed for ${agentId}: ${err.message}
|
|
13316
|
+
`);
|
|
13308
13317
|
}
|
|
13309
13318
|
(0, import_fs22.writeFileSync)(tasksPath, toKeep.map((e) => e.line).join("\n") + "\n");
|
|
13310
13319
|
return { archived: toArchive.length, dropped: dropped || void 0, message: `Compacted ${toArchive.length} memories for ${agentId}${dropped ? ` (${dropped} malformed lines dropped)` : ""}` };
|
|
@@ -13489,6 +13498,14 @@ ${cleanSummary}` : cleanSummary;
|
|
|
13489
13498
|
body = facts.body;
|
|
13490
13499
|
}
|
|
13491
13500
|
const accuracyLine = data.agentAccuracy !== void 0 ? `agentAccuracy: ${data.agentAccuracy.toFixed(2)}` : null;
|
|
13501
|
+
const citations = this.validateCitations(body, data.resolutionRoots);
|
|
13502
|
+
const citationLines = [`citationsVerified: ${citations.verified}/${citations.total}`];
|
|
13503
|
+
if (citations.unverified.length > 0) {
|
|
13504
|
+
citationLines.push("citationsFabricated:");
|
|
13505
|
+
for (const u of citations.unverified) {
|
|
13506
|
+
citationLines.push(` - "${u}"`);
|
|
13507
|
+
}
|
|
13508
|
+
}
|
|
13492
13509
|
const content = [
|
|
13493
13510
|
"---",
|
|
13494
13511
|
`name: ${truncateAtWord(data.task, 80).replace(/\n/g, " ")}`,
|
|
@@ -13497,6 +13514,7 @@ ${cleanSummary}` : cleanSummary;
|
|
|
13497
13514
|
...accuracyLine ? [accuracyLine] : [],
|
|
13498
13515
|
`lastAccessed: ${today}`,
|
|
13499
13516
|
`accessCount: 0`,
|
|
13517
|
+
...citationLines,
|
|
13500
13518
|
"---",
|
|
13501
13519
|
"",
|
|
13502
13520
|
...data.agentAccuracy !== void 0 && data.agentAccuracy < 0.4 ? ["> \u26A0 This agent has low accuracy (" + (data.agentAccuracy * 100).toFixed(0) + "%). Treat factual claims as unverified.\n"] : [],
|
|
@@ -13504,6 +13522,60 @@ ${cleanSummary}` : cleanSummary;
|
|
|
13504
13522
|
].join("\n");
|
|
13505
13523
|
(0, import_fs24.writeFileSync)((0, import_path25.join)(knowledgeDir, filename), content);
|
|
13506
13524
|
}
|
|
13525
|
+
/**
|
|
13526
|
+
* Annotation-only citation check: scans `body` for file-like tokens (optionally
|
|
13527
|
+
* with a `:NN` line-number suffix), resolves each against `projectRoot` plus any
|
|
13528
|
+
* supplied `resolutionRoots`, and reports how many are real. Never drops or
|
|
13529
|
+
* mutates content — the caller records the counts in frontmatter for later
|
|
13530
|
+
* analysis.
|
|
13531
|
+
*/
|
|
13532
|
+
validateCitations(body, resolutionRoots) {
|
|
13533
|
+
const fileRegex = /(?:^|[\s`"'(\[<])([a-zA-Z0-9_/.-]+\.[a-z]{1,7})(?::(\d+))?(?=[\s`"'):,\]>]|$)/gm;
|
|
13534
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13535
|
+
const citations = [];
|
|
13536
|
+
let m;
|
|
13537
|
+
while ((m = fileRegex.exec(body)) !== null) {
|
|
13538
|
+
const path2 = m[1];
|
|
13539
|
+
const before = body.slice(Math.max(0, m.index - 8), m.index + 1);
|
|
13540
|
+
if (/https?:\/\//.test(before) || /https?:\/\//.test(path2)) continue;
|
|
13541
|
+
const line = m[2] ? parseInt(m[2], 10) : void 0;
|
|
13542
|
+
const key = line !== void 0 ? `${path2}:${line}` : path2;
|
|
13543
|
+
if (seen.has(key)) continue;
|
|
13544
|
+
seen.add(key);
|
|
13545
|
+
citations.push({ path: path2, line, key });
|
|
13546
|
+
}
|
|
13547
|
+
const roots = [this.projectRoot, ...resolutionRoots ?? []];
|
|
13548
|
+
const unverified = [];
|
|
13549
|
+
let verified = 0;
|
|
13550
|
+
for (const c of citations) {
|
|
13551
|
+
let hit = null;
|
|
13552
|
+
for (const root of roots) {
|
|
13553
|
+
const abs = (0, import_path25.resolve)(root, c.path);
|
|
13554
|
+
if ((0, import_fs24.existsSync)(abs)) {
|
|
13555
|
+
hit = abs;
|
|
13556
|
+
break;
|
|
13557
|
+
}
|
|
13558
|
+
}
|
|
13559
|
+
if (!hit) {
|
|
13560
|
+
unverified.push(c.key);
|
|
13561
|
+
continue;
|
|
13562
|
+
}
|
|
13563
|
+
if (c.line !== void 0) {
|
|
13564
|
+
try {
|
|
13565
|
+
const lineCount = (0, import_fs24.readFileSync)(hit, "utf8").split("\n").length;
|
|
13566
|
+
if (c.line > lineCount || c.line < 1) {
|
|
13567
|
+
unverified.push(c.key);
|
|
13568
|
+
continue;
|
|
13569
|
+
}
|
|
13570
|
+
} catch {
|
|
13571
|
+
unverified.push(c.key);
|
|
13572
|
+
continue;
|
|
13573
|
+
}
|
|
13574
|
+
}
|
|
13575
|
+
verified++;
|
|
13576
|
+
}
|
|
13577
|
+
return { total: citations.length, verified, unverified };
|
|
13578
|
+
}
|
|
13507
13579
|
/**
|
|
13508
13580
|
* Generate a cognitive summary — what the agent learned, not just what it saw.
|
|
13509
13581
|
* Uses the utility LLM (cheapest available model).
|
|
@@ -25193,7 +25265,7 @@ function resolveDashboardRoot(projectRoot) {
|
|
|
25193
25265
|
return null;
|
|
25194
25266
|
}
|
|
25195
25267
|
function readBody(req) {
|
|
25196
|
-
return new Promise((
|
|
25268
|
+
return new Promise((resolve26, reject) => {
|
|
25197
25269
|
const chunks = [];
|
|
25198
25270
|
let size = 0;
|
|
25199
25271
|
let tooLarge = false;
|
|
@@ -25208,7 +25280,7 @@ function readBody(req) {
|
|
|
25208
25280
|
chunks.push(chunk);
|
|
25209
25281
|
});
|
|
25210
25282
|
req.on("end", () => {
|
|
25211
|
-
if (!tooLarge)
|
|
25283
|
+
if (!tooLarge) resolve26(Buffer.concat(chunks).toString("utf-8"));
|
|
25212
25284
|
});
|
|
25213
25285
|
req.on("error", (err) => {
|
|
25214
25286
|
if (!tooLarge) reject(err);
|
|
@@ -25837,7 +25909,7 @@ var init_server = __esm({
|
|
|
25837
25909
|
return this.heartbeatRunning;
|
|
25838
25910
|
}
|
|
25839
25911
|
async start() {
|
|
25840
|
-
return new Promise((
|
|
25912
|
+
return new Promise((resolve26) => {
|
|
25841
25913
|
this.httpServer = (0, import_http.createServer)(this.handleHttp.bind(this));
|
|
25842
25914
|
if (this.config.dashboard) {
|
|
25843
25915
|
this.dashboardAuth = new DashboardAuth();
|
|
@@ -25883,7 +25955,7 @@ var init_server = __esm({
|
|
|
25883
25955
|
this.httpServer.listen(this.config.port, this.config.host ?? "127.0.0.1", () => {
|
|
25884
25956
|
const addr = this.httpServer.address();
|
|
25885
25957
|
this._port = addr.port;
|
|
25886
|
-
|
|
25958
|
+
resolve26();
|
|
25887
25959
|
});
|
|
25888
25960
|
});
|
|
25889
25961
|
}
|
|
@@ -25903,9 +25975,9 @@ var init_server = __esm({
|
|
|
25903
25975
|
for (const client of this.wss.clients) {
|
|
25904
25976
|
client.close(1001, "Server shutting down");
|
|
25905
25977
|
}
|
|
25906
|
-
return new Promise((
|
|
25978
|
+
return new Promise((resolve26) => {
|
|
25907
25979
|
this.wss.close(() => {
|
|
25908
|
-
this.httpServer.close(() =>
|
|
25980
|
+
this.httpServer.close(() => resolve26());
|
|
25909
25981
|
});
|
|
25910
25982
|
});
|
|
25911
25983
|
}
|
|
@@ -42902,8 +42974,8 @@ async function handleDispatchConsensus(taskDefs, _utility_task_id, dispatchResol
|
|
|
42902
42974
|
});
|
|
42903
42975
|
const lenses = await Promise.race([
|
|
42904
42976
|
lensPromise,
|
|
42905
|
-
new Promise((
|
|
42906
|
-
timerId = setTimeout(() =>
|
|
42977
|
+
new Promise((resolve26) => {
|
|
42978
|
+
timerId = setTimeout(() => resolve26(null), LENS_TIMEOUT_MS);
|
|
42907
42979
|
})
|
|
42908
42980
|
]);
|
|
42909
42981
|
if (timerId) clearTimeout(timerId);
|
|
@@ -43115,7 +43187,7 @@ Relay may be down. Check gossip_status() for connection state.` }] };
|
|
|
43115
43187
|
process.stderr.write(`[gossipcat] \u23F3 Consensus: ${doneCount}/${pendingNativeIds.length} agents complete (${agentStatus})
|
|
43116
43188
|
`);
|
|
43117
43189
|
}
|
|
43118
|
-
await new Promise((
|
|
43190
|
+
await new Promise((resolve26) => setTimeout(resolve26, POLL_INTERVAL));
|
|
43119
43191
|
}
|
|
43120
43192
|
const arrived = pendingNativeIds.filter((id) => ctx.nativeResultMap.has(id)).length;
|
|
43121
43193
|
const timedOutCount = pendingNativeIds.filter((id) => {
|
|
@@ -43786,7 +43858,7 @@ function writeStickyPort(filename, port) {
|
|
|
43786
43858
|
}
|
|
43787
43859
|
}
|
|
43788
43860
|
function probePort(port, host = "127.0.0.1") {
|
|
43789
|
-
return new Promise((
|
|
43861
|
+
return new Promise((resolve26) => {
|
|
43790
43862
|
const srv = (0, import_net.createServer)();
|
|
43791
43863
|
let settled = false;
|
|
43792
43864
|
const done = (ok) => {
|
|
@@ -43796,7 +43868,7 @@ function probePort(port, host = "127.0.0.1") {
|
|
|
43796
43868
|
srv.close();
|
|
43797
43869
|
} catch {
|
|
43798
43870
|
}
|
|
43799
|
-
|
|
43871
|
+
resolve26(ok);
|
|
43800
43872
|
};
|
|
43801
43873
|
srv.once("error", () => done(false));
|
|
43802
43874
|
try {
|
|
@@ -47691,10 +47763,10 @@ async function startHttpMcpTransport() {
|
|
|
47691
47763
|
}
|
|
47692
47764
|
let body;
|
|
47693
47765
|
if (req.method === "POST") {
|
|
47694
|
-
const raw = await new Promise((
|
|
47766
|
+
const raw = await new Promise((resolve26, reject) => {
|
|
47695
47767
|
const chunks = [];
|
|
47696
47768
|
req.on("data", (c) => chunks.push(c));
|
|
47697
|
-
req.on("end", () =>
|
|
47769
|
+
req.on("end", () => resolve26(Buffer.concat(chunks).toString("utf-8")));
|
|
47698
47770
|
req.on("error", reject);
|
|
47699
47771
|
});
|
|
47700
47772
|
try {
|
package/package.json
CHANGED