opencode-swarm 6.35.4 → 6.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +34 -13
- package/dist/config/constants.d.ts +2 -2
- package/dist/hooks/curator-drift.d.ts +2 -2
- package/dist/hooks/knowledge-curator.d.ts +6 -1
- package/dist/hooks/knowledge-types.d.ts +1 -1
- package/dist/index.js +277 -250
- package/dist/state.d.ts +5 -3
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -14422,7 +14422,7 @@ async function loadEvidence(directory, taskId) {
|
|
|
14422
14422
|
return { status: "found", bundle: validated };
|
|
14423
14423
|
} catch (error49) {
|
|
14424
14424
|
warn(`Wrapped flat retrospective failed validation for task ${sanitizedTaskId}: ${error49 instanceof Error ? error49.message : String(error49)}`);
|
|
14425
|
-
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [String(error49)];
|
|
14425
|
+
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [error49 instanceof Error ? error49.message : String(error49)];
|
|
14426
14426
|
return { status: "invalid_schema", errors: errors3 };
|
|
14427
14427
|
}
|
|
14428
14428
|
}
|
|
@@ -14431,7 +14431,7 @@ async function loadEvidence(directory, taskId) {
|
|
|
14431
14431
|
return { status: "found", bundle: validated };
|
|
14432
14432
|
} catch (error49) {
|
|
14433
14433
|
warn(`Evidence bundle validation failed for task ${sanitizedTaskId}: ${error49 instanceof Error ? error49.message : String(error49)}`);
|
|
14434
|
-
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [String(error49)];
|
|
14434
|
+
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [error49 instanceof Error ? error49.message : String(error49)];
|
|
14435
14435
|
return { status: "invalid_schema", errors: errors3 };
|
|
14436
14436
|
}
|
|
14437
14437
|
}
|
|
@@ -17633,6 +17633,7 @@ var ALL_SUBAGENT_NAMES = [
|
|
|
17633
17633
|
"docs",
|
|
17634
17634
|
"designer",
|
|
17635
17635
|
"critic_sounding_board",
|
|
17636
|
+
"critic_drift_verifier",
|
|
17636
17637
|
...QA_AGENTS,
|
|
17637
17638
|
...PIPELINE_AGENTS
|
|
17638
17639
|
];
|
|
@@ -17731,6 +17732,13 @@ var AGENT_TOOL_MAP = {
|
|
|
17731
17732
|
"retrieve_summary",
|
|
17732
17733
|
"symbols"
|
|
17733
17734
|
],
|
|
17735
|
+
critic_drift_verifier: [
|
|
17736
|
+
"complexity_hotspots",
|
|
17737
|
+
"detect_domains",
|
|
17738
|
+
"imports",
|
|
17739
|
+
"retrieve_summary",
|
|
17740
|
+
"symbols"
|
|
17741
|
+
],
|
|
17734
17742
|
docs: [
|
|
17735
17743
|
"detect_domains",
|
|
17736
17744
|
"extract_code_blocks",
|
|
@@ -18444,7 +18452,11 @@ var swarmState = {
|
|
|
18444
18452
|
function getAgentSession(sessionId) {
|
|
18445
18453
|
return swarmState.agentSessions.get(sessionId);
|
|
18446
18454
|
}
|
|
18447
|
-
function hasActiveTurboMode() {
|
|
18455
|
+
function hasActiveTurboMode(sessionID) {
|
|
18456
|
+
if (sessionID) {
|
|
18457
|
+
const session = swarmState.agentSessions.get(sessionID);
|
|
18458
|
+
return session?.turboMode === true;
|
|
18459
|
+
}
|
|
18448
18460
|
for (const [_sessionId, session] of swarmState.agentSessions) {
|
|
18449
18461
|
if (session.turboMode === true) {
|
|
18450
18462
|
return true;
|
|
@@ -31104,7 +31116,16 @@ function createSwarmTool(opts) {
|
|
|
31104
31116
|
args: opts.args,
|
|
31105
31117
|
execute: async (args, ctx) => {
|
|
31106
31118
|
const directory = ctx?.directory ?? process.cwd();
|
|
31107
|
-
|
|
31119
|
+
try {
|
|
31120
|
+
return await opts.execute(args, directory, ctx);
|
|
31121
|
+
} catch (error93) {
|
|
31122
|
+
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
31123
|
+
return JSON.stringify({
|
|
31124
|
+
success: false,
|
|
31125
|
+
message: "Tool execution failed",
|
|
31126
|
+
errors: [message]
|
|
31127
|
+
}, null, 2);
|
|
31128
|
+
}
|
|
31108
31129
|
}
|
|
31109
31130
|
});
|
|
31110
31131
|
}
|
|
@@ -32314,7 +32335,7 @@ async function handleCurateCommand(directory, _args) {
|
|
|
32314
32335
|
if (error93 instanceof Error) {
|
|
32315
32336
|
return `\u274C Curation failed: ${error93.message}`;
|
|
32316
32337
|
}
|
|
32317
|
-
return `\u274C Curation failed: ${String(error93)}`;
|
|
32338
|
+
return `\u274C Curation failed: ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
32318
32339
|
}
|
|
32319
32340
|
}
|
|
32320
32341
|
function formatCurationSummary(summary) {
|
|
@@ -32702,7 +32723,7 @@ async function handleDarkMatterCommand(directory, args) {
|
|
|
32702
32723
|
[${entries.length} dark matter finding(s) saved to .swarm/knowledge.jsonl]`;
|
|
32703
32724
|
}
|
|
32704
32725
|
} catch (err) {
|
|
32705
|
-
console.warn("dark-matter: failed to save knowledge entries:", err);
|
|
32726
|
+
console.warn("dark-matter: failed to save knowledge entries:", err instanceof Error ? err.message : String(err));
|
|
32706
32727
|
return output;
|
|
32707
32728
|
}
|
|
32708
32729
|
}
|
|
@@ -34461,7 +34482,7 @@ async function handleKnowledgeQuarantineCommand(directory, args) {
|
|
|
34461
34482
|
await quarantineEntry(directory, entryId, reason, "user");
|
|
34462
34483
|
return `\u2705 Entry ${entryId} quarantined successfully.`;
|
|
34463
34484
|
} catch (error93) {
|
|
34464
|
-
console.warn("[knowledge-command] quarantineEntry error:", error93);
|
|
34485
|
+
console.warn("[knowledge-command] quarantineEntry error:", error93 instanceof Error ? error93.message : String(error93));
|
|
34465
34486
|
return `\u274C Failed to quarantine entry. Check the entry ID and try again.`;
|
|
34466
34487
|
}
|
|
34467
34488
|
}
|
|
@@ -34477,7 +34498,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
|
|
|
34477
34498
|
await restoreEntry(directory, entryId);
|
|
34478
34499
|
return `\u2705 Entry ${entryId} restored successfully.`;
|
|
34479
34500
|
} catch (error93) {
|
|
34480
|
-
console.warn("[knowledge-command] restoreEntry error:", error93);
|
|
34501
|
+
console.warn("[knowledge-command] restoreEntry error:", error93 instanceof Error ? error93.message : String(error93));
|
|
34481
34502
|
return `\u274C Failed to restore entry. Check the entry ID and try again.`;
|
|
34482
34503
|
}
|
|
34483
34504
|
}
|
|
@@ -34499,7 +34520,7 @@ async function handleKnowledgeMigrateCommand(directory, args) {
|
|
|
34499
34520
|
}
|
|
34500
34521
|
return `\u2705 Migration complete: ${result.entriesMigrated} entries added, ${result.entriesDropped} dropped (validation/dedup), ${result.entriesTotal} total processed.`;
|
|
34501
34522
|
} catch (error93) {
|
|
34502
|
-
console.warn("[knowledge-command] migrateContextToKnowledge error:", error93);
|
|
34523
|
+
console.warn("[knowledge-command] migrateContextToKnowledge error:", error93 instanceof Error ? error93.message : String(error93));
|
|
34503
34524
|
return "\u274C Migration failed. Check .swarm/context.md is readable.";
|
|
34504
34525
|
}
|
|
34505
34526
|
}
|
|
@@ -34526,7 +34547,7 @@ async function handleKnowledgeListCommand(directory, _args) {
|
|
|
34526
34547
|
return lines.join(`
|
|
34527
34548
|
`);
|
|
34528
34549
|
} catch (error93) {
|
|
34529
|
-
console.warn("[knowledge-command] list error:", error93);
|
|
34550
|
+
console.warn("[knowledge-command] list error:", error93 instanceof Error ? error93.message : String(error93));
|
|
34530
34551
|
return "\u274C Failed to list knowledge entries. Ensure .swarm/knowledge.jsonl exists.";
|
|
34531
34552
|
}
|
|
34532
34553
|
}
|
|
@@ -38632,7 +38653,7 @@ async function handlePromoteCommand(directory, args) {
|
|
|
38632
38653
|
if (error93 instanceof Error) {
|
|
38633
38654
|
return error93.message;
|
|
38634
38655
|
}
|
|
38635
|
-
return `Failed to promote lesson: ${String(error93)}`;
|
|
38656
|
+
return `Failed to promote lesson: ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
38636
38657
|
}
|
|
38637
38658
|
}
|
|
38638
38659
|
try {
|
|
@@ -38641,7 +38662,7 @@ async function handlePromoteCommand(directory, args) {
|
|
|
38641
38662
|
if (error93 instanceof Error) {
|
|
38642
38663
|
return error93.message;
|
|
38643
38664
|
}
|
|
38644
|
-
return `Failed to promote lesson: ${String(error93)}`;
|
|
38665
|
+
return `Failed to promote lesson: ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
38645
38666
|
}
|
|
38646
38667
|
}
|
|
38647
38668
|
|
|
@@ -39575,7 +39596,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
39575
39596
|
fs12.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
|
|
39576
39597
|
`);
|
|
39577
39598
|
} catch (error93) {
|
|
39578
|
-
console.error("Failed to write rollback event:", error93);
|
|
39599
|
+
console.error("Failed to write rollback event:", error93 instanceof Error ? error93.message : String(error93));
|
|
39579
39600
|
}
|
|
39580
39601
|
return `Rolled back to phase ${targetPhase}: ${checkpoint2.label || "no label"}`;
|
|
39581
39602
|
}
|
|
@@ -2,8 +2,8 @@ import type { ToolName } from '../tools/tool-names';
|
|
|
2
2
|
export declare const QA_AGENTS: readonly ["reviewer", "critic"];
|
|
3
3
|
export declare const PIPELINE_AGENTS: readonly ["explorer", "coder", "test_engineer"];
|
|
4
4
|
export declare const ORCHESTRATOR_NAME: "architect";
|
|
5
|
-
export declare const ALL_SUBAGENT_NAMES: readonly ["sme", "docs", "designer", "critic_sounding_board", "reviewer", "critic", "explorer", "coder", "test_engineer"];
|
|
6
|
-
export declare const ALL_AGENT_NAMES: readonly ["architect", "sme", "docs", "designer", "critic_sounding_board", "reviewer", "critic", "explorer", "coder", "test_engineer"];
|
|
5
|
+
export declare const ALL_SUBAGENT_NAMES: readonly ["sme", "docs", "designer", "critic_sounding_board", "critic_drift_verifier", "reviewer", "critic", "explorer", "coder", "test_engineer"];
|
|
6
|
+
export declare const ALL_AGENT_NAMES: readonly ["architect", "sme", "docs", "designer", "critic_sounding_board", "critic_drift_verifier", "reviewer", "critic", "explorer", "coder", "test_engineer"];
|
|
7
7
|
export type QAAgentName = (typeof QA_AGENTS)[number];
|
|
8
8
|
export type PipelineAgentName = (typeof PIPELINE_AGENTS)[number];
|
|
9
9
|
export type AgentName = (typeof ALL_AGENT_NAMES)[number];
|
|
@@ -12,14 +12,14 @@ export declare function readPriorDriftReports(directory: string): Promise<DriftR
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function writeDriftReport(directory: string, report: DriftReport): Promise<string>;
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Deterministic drift check for the given phase.
|
|
16
16
|
* Builds a structured DriftReport from curator data, plan, spec, and prior reports.
|
|
17
17
|
* Writes the report to .swarm/drift-report-phase-N.json.
|
|
18
18
|
* Emits 'curator.drift.completed' event on success.
|
|
19
19
|
* On any error: emits 'curator.error' event and returns a safe default result.
|
|
20
20
|
* NEVER throws — drift failures must not block phase_complete.
|
|
21
21
|
*/
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function runDeterministicDriftCheck(directory: string, phase: number, curatorResult: CuratorPhaseResult, config: CuratorConfig, injectAdvisory?: (message: string) => void): Promise<CriticDriftResult>;
|
|
23
23
|
/**
|
|
24
24
|
* Build a truncated summary suitable for architect context injection.
|
|
25
25
|
* Format: "<drift_report>Phase N: {alignment} ({drift_score}) — {key finding}. {correction if any}.</drift_report>"
|
|
@@ -7,10 +7,15 @@ import type { KnowledgeConfig } from './knowledge-types.js';
|
|
|
7
7
|
export declare function isWriteToEvidenceFile(input: unknown): boolean;
|
|
8
8
|
/**
|
|
9
9
|
* Curate and store swarm knowledge entries from lessons.
|
|
10
|
+
* @returns Promise resolving to an object with counts of stored, skipped, and rejected lessons.
|
|
10
11
|
*/
|
|
11
12
|
export declare function curateAndStoreSwarm(lessons: string[], projectName: string, phaseInfo: {
|
|
12
13
|
phase_number: number;
|
|
13
|
-
}, directory: string, config: KnowledgeConfig): Promise<
|
|
14
|
+
}, directory: string, config: KnowledgeConfig): Promise<{
|
|
15
|
+
stored: number;
|
|
16
|
+
skipped: number;
|
|
17
|
+
rejected: number;
|
|
18
|
+
}>;
|
|
14
19
|
/**
|
|
15
20
|
* Auto-promote swarm entries based on phase confirmations and age.
|
|
16
21
|
*/
|
|
@@ -24,7 +24,7 @@ export interface KnowledgeEntryBase {
|
|
|
24
24
|
tags: string[];
|
|
25
25
|
scope: string;
|
|
26
26
|
confidence: number;
|
|
27
|
-
status: 'candidate' | 'established' | 'promoted';
|
|
27
|
+
status: 'candidate' | 'established' | 'promoted' | 'archived';
|
|
28
28
|
confirmed_by: PhaseConfirmationRecord[] | ProjectConfirmationRecord[];
|
|
29
29
|
retrieval_outcomes: RetrievalOutcome;
|
|
30
30
|
schema_version: number;
|
package/dist/index.js
CHANGED
|
@@ -134,6 +134,7 @@ var init_constants = __esm(() => {
|
|
|
134
134
|
"docs",
|
|
135
135
|
"designer",
|
|
136
136
|
"critic_sounding_board",
|
|
137
|
+
"critic_drift_verifier",
|
|
137
138
|
...QA_AGENTS,
|
|
138
139
|
...PIPELINE_AGENTS
|
|
139
140
|
];
|
|
@@ -232,6 +233,13 @@ var init_constants = __esm(() => {
|
|
|
232
233
|
"retrieve_summary",
|
|
233
234
|
"symbols"
|
|
234
235
|
],
|
|
236
|
+
critic_drift_verifier: [
|
|
237
|
+
"complexity_hotspots",
|
|
238
|
+
"detect_domains",
|
|
239
|
+
"imports",
|
|
240
|
+
"retrieve_summary",
|
|
241
|
+
"symbols"
|
|
242
|
+
],
|
|
235
243
|
docs: [
|
|
236
244
|
"detect_domains",
|
|
237
245
|
"extract_code_blocks",
|
|
@@ -258,6 +266,7 @@ var init_constants = __esm(() => {
|
|
|
258
266
|
sme: "opencode/trinity-large-preview-free",
|
|
259
267
|
critic: "opencode/trinity-large-preview-free",
|
|
260
268
|
critic_sounding_board: "opencode/trinity-large-preview-free",
|
|
269
|
+
critic_drift_verifier: "opencode/trinity-large-preview-free",
|
|
261
270
|
docs: "opencode/trinity-large-preview-free",
|
|
262
271
|
designer: "opencode/trinity-large-preview-free",
|
|
263
272
|
default: "opencode/trinity-large-preview-free"
|
|
@@ -15689,7 +15698,7 @@ async function loadEvidence(directory, taskId) {
|
|
|
15689
15698
|
return { status: "found", bundle: validated };
|
|
15690
15699
|
} catch (error49) {
|
|
15691
15700
|
warn(`Wrapped flat retrospective failed validation for task ${sanitizedTaskId}: ${error49 instanceof Error ? error49.message : String(error49)}`);
|
|
15692
|
-
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [String(error49)];
|
|
15701
|
+
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [error49 instanceof Error ? error49.message : String(error49)];
|
|
15693
15702
|
return { status: "invalid_schema", errors: errors3 };
|
|
15694
15703
|
}
|
|
15695
15704
|
}
|
|
@@ -15698,7 +15707,7 @@ async function loadEvidence(directory, taskId) {
|
|
|
15698
15707
|
return { status: "found", bundle: validated };
|
|
15699
15708
|
} catch (error49) {
|
|
15700
15709
|
warn(`Evidence bundle validation failed for task ${sanitizedTaskId}: ${error49 instanceof Error ? error49.message : String(error49)}`);
|
|
15701
|
-
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [String(error49)];
|
|
15710
|
+
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [error49 instanceof Error ? error49.message : String(error49)];
|
|
15702
15711
|
return { status: "invalid_schema", errors: errors3 };
|
|
15703
15712
|
}
|
|
15704
15713
|
}
|
|
@@ -30024,7 +30033,16 @@ function createSwarmTool(opts) {
|
|
|
30024
30033
|
args: opts.args,
|
|
30025
30034
|
execute: async (args2, ctx) => {
|
|
30026
30035
|
const directory = ctx?.directory ?? process.cwd();
|
|
30027
|
-
|
|
30036
|
+
try {
|
|
30037
|
+
return await opts.execute(args2, directory, ctx);
|
|
30038
|
+
} catch (error93) {
|
|
30039
|
+
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
30040
|
+
return JSON.stringify({
|
|
30041
|
+
success: false,
|
|
30042
|
+
message: "Tool execution failed",
|
|
30043
|
+
errors: [message]
|
|
30044
|
+
}, null, 2);
|
|
30045
|
+
}
|
|
30028
30046
|
}
|
|
30029
30047
|
});
|
|
30030
30048
|
}
|
|
@@ -36621,6 +36639,175 @@ var init_preflight_integration = __esm(() => {
|
|
|
36621
36639
|
init_preflight_service();
|
|
36622
36640
|
});
|
|
36623
36641
|
|
|
36642
|
+
// src/hooks/curator-drift.ts
|
|
36643
|
+
var exports_curator_drift = {};
|
|
36644
|
+
__export(exports_curator_drift, {
|
|
36645
|
+
writeDriftReport: () => writeDriftReport,
|
|
36646
|
+
runDeterministicDriftCheck: () => runDeterministicDriftCheck,
|
|
36647
|
+
readPriorDriftReports: () => readPriorDriftReports,
|
|
36648
|
+
buildDriftInjectionText: () => buildDriftInjectionText
|
|
36649
|
+
});
|
|
36650
|
+
import * as fs26 from "fs";
|
|
36651
|
+
import * as path37 from "path";
|
|
36652
|
+
async function readPriorDriftReports(directory) {
|
|
36653
|
+
const swarmDir = path37.join(directory, ".swarm");
|
|
36654
|
+
const entries = await fs26.promises.readdir(swarmDir).catch(() => null);
|
|
36655
|
+
if (entries === null)
|
|
36656
|
+
return [];
|
|
36657
|
+
const reportFiles = entries.filter((name2) => name2.startsWith(DRIFT_REPORT_PREFIX) && name2.endsWith(".json")).sort();
|
|
36658
|
+
const reports = [];
|
|
36659
|
+
for (const filename of reportFiles) {
|
|
36660
|
+
const content = await readSwarmFileAsync(directory, filename);
|
|
36661
|
+
if (content === null)
|
|
36662
|
+
continue;
|
|
36663
|
+
try {
|
|
36664
|
+
const report = JSON.parse(content);
|
|
36665
|
+
if (typeof report.phase !== "number" || typeof report.alignment !== "string") {
|
|
36666
|
+
console.warn(`[curator-drift] Skipping corrupt drift report: ${filename}`);
|
|
36667
|
+
continue;
|
|
36668
|
+
}
|
|
36669
|
+
reports.push(report);
|
|
36670
|
+
} catch {
|
|
36671
|
+
console.warn(`[curator-drift] Skipping unreadable drift report: ${filename}`);
|
|
36672
|
+
}
|
|
36673
|
+
}
|
|
36674
|
+
reports.sort((a, b) => a.phase - b.phase);
|
|
36675
|
+
return reports;
|
|
36676
|
+
}
|
|
36677
|
+
async function writeDriftReport(directory, report) {
|
|
36678
|
+
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
36679
|
+
const filePath = validateSwarmPath(directory, filename);
|
|
36680
|
+
const swarmDir = path37.dirname(filePath);
|
|
36681
|
+
await fs26.promises.mkdir(swarmDir, { recursive: true });
|
|
36682
|
+
try {
|
|
36683
|
+
await fs26.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
36684
|
+
} catch (err2) {
|
|
36685
|
+
throw new Error(`[curator-drift] Failed to write drift report to ${filePath}: ${String(err2)}`);
|
|
36686
|
+
}
|
|
36687
|
+
return filePath;
|
|
36688
|
+
}
|
|
36689
|
+
async function runDeterministicDriftCheck(directory, phase, curatorResult, config3, injectAdvisory) {
|
|
36690
|
+
try {
|
|
36691
|
+
const planMd = await readSwarmFileAsync(directory, "plan.md");
|
|
36692
|
+
const specMd = await readSwarmFileAsync(directory, "spec.md");
|
|
36693
|
+
const priorReports = await readPriorDriftReports(directory);
|
|
36694
|
+
const complianceCount = curatorResult.compliance.length;
|
|
36695
|
+
const warningCompliance = curatorResult.compliance.filter((obs) => obs.severity === "warning");
|
|
36696
|
+
let alignment = "ALIGNED";
|
|
36697
|
+
let driftScore = 0;
|
|
36698
|
+
if (!planMd) {
|
|
36699
|
+
alignment = "MINOR_DRIFT";
|
|
36700
|
+
driftScore = 0.3;
|
|
36701
|
+
} else if (warningCompliance.length >= 3) {
|
|
36702
|
+
alignment = "MAJOR_DRIFT";
|
|
36703
|
+
driftScore = Math.min(0.9, 0.5 + warningCompliance.length * 0.1);
|
|
36704
|
+
} else if (warningCompliance.length >= 1 || complianceCount >= 3) {
|
|
36705
|
+
alignment = "MINOR_DRIFT";
|
|
36706
|
+
driftScore = Math.min(0.49, 0.2 + complianceCount * 0.05);
|
|
36707
|
+
}
|
|
36708
|
+
const priorSummaries = priorReports.map((r) => r.injection_summary).filter(Boolean);
|
|
36709
|
+
const keyCorrections = warningCompliance.map((obs) => obs.description);
|
|
36710
|
+
const firstDeviation = warningCompliance.length > 0 ? {
|
|
36711
|
+
phase,
|
|
36712
|
+
task: "unknown",
|
|
36713
|
+
description: warningCompliance[0]?.description ?? ""
|
|
36714
|
+
} : null;
|
|
36715
|
+
const payloadLines = [
|
|
36716
|
+
`CURATOR_DIGEST: ${JSON.stringify(curatorResult.digest)}`,
|
|
36717
|
+
`CURATOR_COMPLIANCE: ${JSON.stringify(curatorResult.compliance)}`,
|
|
36718
|
+
`PLAN: ${planMd ?? "none"}`,
|
|
36719
|
+
`SPEC: ${specMd ?? "none"}`,
|
|
36720
|
+
`PRIOR_DRIFT_REPORTS: ${JSON.stringify(priorSummaries)}`
|
|
36721
|
+
];
|
|
36722
|
+
const payload = payloadLines.join(`
|
|
36723
|
+
`);
|
|
36724
|
+
const requirementsChecked = curatorResult.digest.tasks_total;
|
|
36725
|
+
const requirementsSatisfied = curatorResult.digest.tasks_completed;
|
|
36726
|
+
const injectionSummaryRaw = `Phase ${phase}: ${alignment} (${driftScore.toFixed(2)}) \u2014 ${firstDeviation ? firstDeviation.description : "all requirements on track"}.${keyCorrections.length > 0 ? `Correction: ${keyCorrections[0] ?? ""}.` : ""}`;
|
|
36727
|
+
const injectionSummary = injectionSummaryRaw.slice(0, config3.drift_inject_max_chars);
|
|
36728
|
+
const report = {
|
|
36729
|
+
schema_version: 1,
|
|
36730
|
+
phase,
|
|
36731
|
+
timestamp: new Date().toISOString(),
|
|
36732
|
+
alignment,
|
|
36733
|
+
drift_score: driftScore,
|
|
36734
|
+
first_deviation: firstDeviation,
|
|
36735
|
+
compounding_effects: priorReports.filter((r) => r.alignment !== "ALIGNED").map((r) => `Phase ${r.phase}: ${r.alignment}`).slice(0, 5),
|
|
36736
|
+
corrections: keyCorrections.slice(0, 5),
|
|
36737
|
+
requirements_checked: requirementsChecked,
|
|
36738
|
+
requirements_satisfied: requirementsSatisfied,
|
|
36739
|
+
scope_additions: [],
|
|
36740
|
+
injection_summary: injectionSummary
|
|
36741
|
+
};
|
|
36742
|
+
const reportPath = await writeDriftReport(directory, report);
|
|
36743
|
+
getGlobalEventBus().publish("curator.drift.completed", {
|
|
36744
|
+
phase,
|
|
36745
|
+
alignment,
|
|
36746
|
+
drift_score: driftScore,
|
|
36747
|
+
report_path: reportPath
|
|
36748
|
+
});
|
|
36749
|
+
if (injectAdvisory && alignment !== "ALIGNED" && driftScore > 0) {
|
|
36750
|
+
try {
|
|
36751
|
+
const advisoryText = `CURATOR DRIFT DETECTED (phase ${phase}, score ${driftScore.toFixed(2)}): ${injectionSummary.slice(0, 300)}. Review .swarm/${DRIFT_REPORT_PREFIX}${phase}.json and address spec alignment before proceeding.`;
|
|
36752
|
+
injectAdvisory(advisoryText);
|
|
36753
|
+
} catch {}
|
|
36754
|
+
}
|
|
36755
|
+
const injectionText = injectionSummary;
|
|
36756
|
+
return {
|
|
36757
|
+
phase,
|
|
36758
|
+
report,
|
|
36759
|
+
report_path: reportPath,
|
|
36760
|
+
injection_text: injectionText
|
|
36761
|
+
};
|
|
36762
|
+
} catch (err2) {
|
|
36763
|
+
getGlobalEventBus().publish("curator.error", {
|
|
36764
|
+
operation: "drift",
|
|
36765
|
+
phase,
|
|
36766
|
+
error: String(err2)
|
|
36767
|
+
});
|
|
36768
|
+
const defaultReport = {
|
|
36769
|
+
schema_version: 1,
|
|
36770
|
+
phase,
|
|
36771
|
+
timestamp: new Date().toISOString(),
|
|
36772
|
+
alignment: "ALIGNED",
|
|
36773
|
+
drift_score: 0,
|
|
36774
|
+
first_deviation: null,
|
|
36775
|
+
compounding_effects: [],
|
|
36776
|
+
corrections: [],
|
|
36777
|
+
requirements_checked: 0,
|
|
36778
|
+
requirements_satisfied: 0,
|
|
36779
|
+
scope_additions: [],
|
|
36780
|
+
injection_summary: `Phase ${phase}: drift analysis unavailable (${String(err2)})`
|
|
36781
|
+
};
|
|
36782
|
+
return {
|
|
36783
|
+
phase,
|
|
36784
|
+
report: defaultReport,
|
|
36785
|
+
report_path: "",
|
|
36786
|
+
injection_text: ""
|
|
36787
|
+
};
|
|
36788
|
+
}
|
|
36789
|
+
}
|
|
36790
|
+
function buildDriftInjectionText(report, maxChars) {
|
|
36791
|
+
if (maxChars <= 0) {
|
|
36792
|
+
return "";
|
|
36793
|
+
}
|
|
36794
|
+
let text;
|
|
36795
|
+
if (report.alignment === "ALIGNED" && report.drift_score < 0.1) {
|
|
36796
|
+
text = `<drift_report>Phase ${report.phase}: ALIGNED, all requirements on track.</drift_report>`;
|
|
36797
|
+
} else {
|
|
36798
|
+
const keyFinding = report.first_deviation?.description ?? "no deviation recorded";
|
|
36799
|
+
const score = report.drift_score ?? 0;
|
|
36800
|
+
const correctionClause = report.corrections?.[0] ? `Correction: ${report.corrections[0]}.` : "";
|
|
36801
|
+
text = `<drift_report>Phase ${report.phase}: ${report.alignment} (${score.toFixed(2)}) \u2014 ${keyFinding}. ${correctionClause}</drift_report>`;
|
|
36802
|
+
}
|
|
36803
|
+
return text.slice(0, maxChars);
|
|
36804
|
+
}
|
|
36805
|
+
var DRIFT_REPORT_PREFIX = "drift-report-phase-";
|
|
36806
|
+
var init_curator_drift = __esm(() => {
|
|
36807
|
+
init_event_bus();
|
|
36808
|
+
init_utils2();
|
|
36809
|
+
});
|
|
36810
|
+
|
|
36624
36811
|
// node_modules/web-tree-sitter/tree-sitter.js
|
|
36625
36812
|
function assertInternal(x) {
|
|
36626
36813
|
if (x !== INTERNAL)
|
|
@@ -40272,7 +40459,11 @@ async function rehydrateSessionFromDisk(directory, session) {
|
|
|
40272
40459
|
await buildRehydrationCache(directory);
|
|
40273
40460
|
applyRehydrationCache(session);
|
|
40274
40461
|
}
|
|
40275
|
-
function hasActiveTurboMode() {
|
|
40462
|
+
function hasActiveTurboMode(sessionID) {
|
|
40463
|
+
if (sessionID) {
|
|
40464
|
+
const session = swarmState.agentSessions.get(sessionID);
|
|
40465
|
+
return session?.turboMode === true;
|
|
40466
|
+
}
|
|
40276
40467
|
for (const [_sessionId, session] of swarmState.agentSessions) {
|
|
40277
40468
|
if (session.turboMode === true) {
|
|
40278
40469
|
return true;
|
|
@@ -41187,10 +41378,10 @@ The tool will automatically write the retrospective to \`.swarm/evidence/retro-{
|
|
|
41187
41378
|
4. Write retrospective evidence: record phase, total_tool_calls, coder_revisions, reviewer_rejections, test_failures, security_findings, integration_issues, task_count, task_complexity, top_rejection_reasons, lessons_learned to .swarm/evidence/ via write_retro. Reset Phase Metrics in context.md to 0.
|
|
41188
41379
|
4.5. Run \`evidence_check\` to verify all completed tasks have required evidence (review + test). If gaps found, note in retrospective lessons_learned. Optionally run \`pkg_audit\` if dependencies were modified during this phase. Optionally run \`schema_drift\` if API routes were modified during this phase.
|
|
41189
41380
|
5. Run \`sbom_generate\` with scope='changed' to capture post-implementation dependency snapshot (saved to \`.swarm/evidence/sbom/\`). This is a non-blocking step - always proceeds to summary.
|
|
41190
|
-
5.5. **
|
|
41381
|
+
5.5. **Drift verification**: Delegate to {{AGENT_PREFIX}}critic_drift_verifier for phase drift review BEFORE calling phase_complete. The critic_drift_verifier will read every target file, verify described changes exist, and produce drift evidence. Persist critic drift evidence at \`.swarm/evidence/{phase}/drift-verifier.json\`. Only then call phase_complete. If the critic returns needs_revision, address the missing items before retrying phase_complete. If spec.md does not exist: skip the critic delegation. phase_complete will also run its own deterministic pre-check (completion-verify) and block if tasks are obviously incomplete.
|
|
41191
41382
|
5.6. **Mandatory gate evidence**: Before calling phase_complete, ensure:
|
|
41192
41383
|
- \`.swarm/evidence/{phase}/completion-verify.json\` exists (written automatically by the completion-verify gate)
|
|
41193
|
-
- \`.swarm/evidence/{phase}/drift-verifier.json\` exists with verdict 'approved' (written by the
|
|
41384
|
+
- \`.swarm/evidence/{phase}/drift-verifier.json\` exists with verdict 'approved' (written by the critic_drift_verifier delegation in step 5.5)
|
|
41194
41385
|
If either is missing, run the missing gate first. Turbo mode skips both gates automatically.
|
|
41195
41386
|
6. Summarize to user
|
|
41196
41387
|
7. Ask: "Ready for Phase [N+1]?"
|
|
@@ -41270,7 +41461,7 @@ While Turbo Mode is active:
|
|
|
41270
41461
|
- **Stage A gates** (lint, imports, pre_check_batch) are still REQUIRED for ALL tasks
|
|
41271
41462
|
- **Tier 3 tasks** (security-sensitive files matching: architect*.ts, delegation*.ts, guardrails*.ts, adversarial*.ts, sanitiz*.ts, auth*, permission*, crypto*, secret*, security) still require FULL review (Stage B)
|
|
41272
41463
|
- **Tier 0-2 tasks** can skip Stage B (reviewer, test_engineer) to speed up execution
|
|
41273
|
-
- **Phase completion gates** (completion-verify and drift verification gate) are automatically bypassed \u2014 phase_complete will succeed without drift verification evidence when turbo is active
|
|
41464
|
+
- **Phase completion gates** (completion-verify and drift verification gate) are automatically bypassed \u2014 phase_complete will succeed without drift verification evidence when turbo is active. Note: turbo bypass is session-scoped; one session's turbo does not affect other sessions.
|
|
41274
41465
|
|
|
41275
41466
|
Classification still determines the pipeline:
|
|
41276
41467
|
- TIER 0 (metadata): lint + diff only \u2014 no change
|
|
@@ -42816,6 +43007,11 @@ If you call @coder instead of @${swarmId}_coder, the call will FAIL or go to the
|
|
|
42816
43007
|
critic.name = prefixName("critic_sounding_board");
|
|
42817
43008
|
agents.push(applyOverrides(critic, swarmAgents, swarmPrefix));
|
|
42818
43009
|
}
|
|
43010
|
+
if (!isAgentDisabled("critic_drift_verifier", swarmAgents, swarmPrefix)) {
|
|
43011
|
+
const critic = createCriticAgent(swarmAgents?.critic_drift_verifier?.model ?? getModel("critic"), undefined, undefined, "phase_drift_verifier");
|
|
43012
|
+
critic.name = prefixName("critic_drift_verifier");
|
|
43013
|
+
agents.push(applyOverrides(critic, swarmAgents, swarmPrefix));
|
|
43014
|
+
}
|
|
42819
43015
|
if (!isAgentDisabled("test_engineer", swarmAgents, swarmPrefix)) {
|
|
42820
43016
|
const testPrompts = getPrompts("test_engineer");
|
|
42821
43017
|
const testEngineer = createTestEngineerAgent(getModel("test_engineer"), testPrompts.prompt, testPrompts.appendPrompt);
|
|
@@ -45533,7 +45729,7 @@ async function handleCurateCommand(directory, _args) {
|
|
|
45533
45729
|
if (error93 instanceof Error) {
|
|
45534
45730
|
return `\u274C Curation failed: ${error93.message}`;
|
|
45535
45731
|
}
|
|
45536
|
-
return `\u274C Curation failed: ${String(error93)}`;
|
|
45732
|
+
return `\u274C Curation failed: ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
45537
45733
|
}
|
|
45538
45734
|
}
|
|
45539
45735
|
function formatCurationSummary(summary) {
|
|
@@ -45923,7 +46119,7 @@ async function handleDarkMatterCommand(directory, args2) {
|
|
|
45923
46119
|
[${entries.length} dark matter finding(s) saved to .swarm/knowledge.jsonl]`;
|
|
45924
46120
|
}
|
|
45925
46121
|
} catch (err2) {
|
|
45926
|
-
console.warn("dark-matter: failed to save knowledge entries:", err2);
|
|
46122
|
+
console.warn("dark-matter: failed to save knowledge entries:", err2 instanceof Error ? err2.message : String(err2));
|
|
45927
46123
|
return output;
|
|
45928
46124
|
}
|
|
45929
46125
|
}
|
|
@@ -47697,7 +47893,7 @@ async function handleKnowledgeQuarantineCommand(directory, args2) {
|
|
|
47697
47893
|
await quarantineEntry(directory, entryId, reason, "user");
|
|
47698
47894
|
return `\u2705 Entry ${entryId} quarantined successfully.`;
|
|
47699
47895
|
} catch (error93) {
|
|
47700
|
-
console.warn("[knowledge-command] quarantineEntry error:", error93);
|
|
47896
|
+
console.warn("[knowledge-command] quarantineEntry error:", error93 instanceof Error ? error93.message : String(error93));
|
|
47701
47897
|
return `\u274C Failed to quarantine entry. Check the entry ID and try again.`;
|
|
47702
47898
|
}
|
|
47703
47899
|
}
|
|
@@ -47713,7 +47909,7 @@ async function handleKnowledgeRestoreCommand(directory, args2) {
|
|
|
47713
47909
|
await restoreEntry(directory, entryId);
|
|
47714
47910
|
return `\u2705 Entry ${entryId} restored successfully.`;
|
|
47715
47911
|
} catch (error93) {
|
|
47716
|
-
console.warn("[knowledge-command] restoreEntry error:", error93);
|
|
47912
|
+
console.warn("[knowledge-command] restoreEntry error:", error93 instanceof Error ? error93.message : String(error93));
|
|
47717
47913
|
return `\u274C Failed to restore entry. Check the entry ID and try again.`;
|
|
47718
47914
|
}
|
|
47719
47915
|
}
|
|
@@ -47735,7 +47931,7 @@ async function handleKnowledgeMigrateCommand(directory, args2) {
|
|
|
47735
47931
|
}
|
|
47736
47932
|
return `\u2705 Migration complete: ${result.entriesMigrated} entries added, ${result.entriesDropped} dropped (validation/dedup), ${result.entriesTotal} total processed.`;
|
|
47737
47933
|
} catch (error93) {
|
|
47738
|
-
console.warn("[knowledge-command] migrateContextToKnowledge error:", error93);
|
|
47934
|
+
console.warn("[knowledge-command] migrateContextToKnowledge error:", error93 instanceof Error ? error93.message : String(error93));
|
|
47739
47935
|
return "\u274C Migration failed. Check .swarm/context.md is readable.";
|
|
47740
47936
|
}
|
|
47741
47937
|
}
|
|
@@ -47762,7 +47958,7 @@ async function handleKnowledgeListCommand(directory, _args) {
|
|
|
47762
47958
|
return lines.join(`
|
|
47763
47959
|
`);
|
|
47764
47960
|
} catch (error93) {
|
|
47765
|
-
console.warn("[knowledge-command] list error:", error93);
|
|
47961
|
+
console.warn("[knowledge-command] list error:", error93 instanceof Error ? error93.message : String(error93));
|
|
47766
47962
|
return "\u274C Failed to list knowledge entries. Ensure .swarm/knowledge.jsonl exists.";
|
|
47767
47963
|
}
|
|
47768
47964
|
}
|
|
@@ -47953,7 +48149,7 @@ async function handlePromoteCommand(directory, args2) {
|
|
|
47953
48149
|
if (error93 instanceof Error) {
|
|
47954
48150
|
return error93.message;
|
|
47955
48151
|
}
|
|
47956
|
-
return `Failed to promote lesson: ${String(error93)}`;
|
|
48152
|
+
return `Failed to promote lesson: ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
47957
48153
|
}
|
|
47958
48154
|
}
|
|
47959
48155
|
try {
|
|
@@ -47962,7 +48158,7 @@ async function handlePromoteCommand(directory, args2) {
|
|
|
47962
48158
|
if (error93 instanceof Error) {
|
|
47963
48159
|
return error93.message;
|
|
47964
48160
|
}
|
|
47965
|
-
return `Failed to promote lesson: ${String(error93)}`;
|
|
48161
|
+
return `Failed to promote lesson: ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
47966
48162
|
}
|
|
47967
48163
|
}
|
|
47968
48164
|
|
|
@@ -48248,7 +48444,7 @@ async function handleRollbackCommand(directory, args2) {
|
|
|
48248
48444
|
fs18.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
|
|
48249
48445
|
`);
|
|
48250
48446
|
} catch (error93) {
|
|
48251
|
-
console.error("Failed to write rollback event:", error93);
|
|
48447
|
+
console.error("Failed to write rollback event:", error93 instanceof Error ? error93.message : String(error93));
|
|
48252
48448
|
}
|
|
48253
48449
|
return `Rolled back to phase ${targetPhase}: ${checkpoint2.label || "no label"}`;
|
|
48254
48450
|
}
|
|
@@ -51450,7 +51646,7 @@ function createDelegationGateHook(config3, directory) {
|
|
|
51450
51646
|
const rawTaskId = directArgs?.task_id;
|
|
51451
51647
|
const evidenceTaskId = typeof rawTaskId === "string" && rawTaskId.length <= 20 && /^\d+\.\d+$/.test(rawTaskId.trim()) ? rawTaskId.trim() : await getEvidenceTaskId(session, directory);
|
|
51452
51648
|
if (evidenceTaskId) {
|
|
51453
|
-
const turbo = hasActiveTurboMode();
|
|
51649
|
+
const turbo = hasActiveTurboMode(input.sessionID);
|
|
51454
51650
|
const gateAgents = [
|
|
51455
51651
|
"reviewer",
|
|
51456
51652
|
"test_engineer",
|
|
@@ -51569,7 +51765,7 @@ function createDelegationGateHook(config3, directory) {
|
|
|
51569
51765
|
const rawTaskId = directArgs?.task_id;
|
|
51570
51766
|
const evidenceTaskId = typeof rawTaskId === "string" && rawTaskId.length <= 20 && /^\d+\.\d+$/.test(rawTaskId.trim()) ? rawTaskId.trim() : await getEvidenceTaskId(session, directory);
|
|
51571
51767
|
if (evidenceTaskId) {
|
|
51572
|
-
const turbo = hasActiveTurboMode();
|
|
51768
|
+
const turbo = hasActiveTurboMode(input.sessionID);
|
|
51573
51769
|
if (hasReviewer) {
|
|
51574
51770
|
const { recordGateEvidence: recordGateEvidence2 } = await Promise.resolve().then(() => (init_gate_evidence(), exports_gate_evidence));
|
|
51575
51771
|
await recordGateEvidence2(directory, evidenceTaskId, "reviewer", input.sessionID, turbo);
|
|
@@ -54395,13 +54591,28 @@ async function processRetractions(retractions, directory) {
|
|
|
54395
54591
|
async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, config3) {
|
|
54396
54592
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
54397
54593
|
const existingEntries = await readKnowledge(knowledgePath) ?? [];
|
|
54594
|
+
let stored = 0;
|
|
54595
|
+
let skipped = 0;
|
|
54596
|
+
let rejected = 0;
|
|
54597
|
+
const categoryByTag = new Map([
|
|
54598
|
+
["process", "process"],
|
|
54599
|
+
["architecture", "architecture"],
|
|
54600
|
+
["tooling", "tooling"],
|
|
54601
|
+
["security", "security"],
|
|
54602
|
+
["testing", "testing"],
|
|
54603
|
+
["debugging", "debugging"],
|
|
54604
|
+
["performance", "performance"],
|
|
54605
|
+
["integration", "integration"],
|
|
54606
|
+
["other", "other"]
|
|
54607
|
+
]);
|
|
54398
54608
|
for (const lesson of lessons) {
|
|
54399
54609
|
const tags = inferTags(lesson);
|
|
54400
54610
|
let category = "process";
|
|
54401
|
-
|
|
54402
|
-
|
|
54403
|
-
|
|
54404
|
-
|
|
54611
|
+
for (const tag of tags) {
|
|
54612
|
+
if (categoryByTag.has(tag)) {
|
|
54613
|
+
category = categoryByTag.get(tag);
|
|
54614
|
+
break;
|
|
54615
|
+
}
|
|
54405
54616
|
}
|
|
54406
54617
|
const meta3 = {
|
|
54407
54618
|
category,
|
|
@@ -54410,18 +54621,20 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
|
|
|
54410
54621
|
};
|
|
54411
54622
|
const result = validateLesson(lesson, existingEntries.map((e) => e.lesson), meta3);
|
|
54412
54623
|
if (result.valid === false || result.severity === "error") {
|
|
54413
|
-
const
|
|
54624
|
+
const rejectedLesson = {
|
|
54414
54625
|
id: crypto.randomUUID(),
|
|
54415
54626
|
lesson,
|
|
54416
54627
|
rejection_reason: result.reason ?? "unknown",
|
|
54417
54628
|
rejected_at: new Date().toISOString(),
|
|
54418
54629
|
rejection_layer: result.layer ?? 1
|
|
54419
54630
|
};
|
|
54420
|
-
await appendRejectedLesson(directory,
|
|
54631
|
+
await appendRejectedLesson(directory, rejectedLesson);
|
|
54632
|
+
rejected++;
|
|
54421
54633
|
continue;
|
|
54422
54634
|
}
|
|
54423
54635
|
const duplicate = findNearDuplicate(lesson, existingEntries, config3.dedup_threshold);
|
|
54424
54636
|
if (duplicate) {
|
|
54637
|
+
skipped++;
|
|
54425
54638
|
continue;
|
|
54426
54639
|
}
|
|
54427
54640
|
const entry = {
|
|
@@ -54452,9 +54665,11 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
|
|
|
54452
54665
|
auto_generated: true
|
|
54453
54666
|
};
|
|
54454
54667
|
await appendKnowledge(knowledgePath, entry);
|
|
54668
|
+
stored++;
|
|
54455
54669
|
existingEntries.push(entry);
|
|
54456
54670
|
}
|
|
54457
54671
|
await runAutoPromotion(directory, config3);
|
|
54672
|
+
return { stored, skipped, rejected };
|
|
54458
54673
|
}
|
|
54459
54674
|
async function runAutoPromotion(directory, config3) {
|
|
54460
54675
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
@@ -54670,200 +54885,8 @@ Use this data to avoid repeating known failure patterns.`;
|
|
|
54670
54885
|
return prefix + summaryText + suffix;
|
|
54671
54886
|
}
|
|
54672
54887
|
|
|
54673
|
-
// src/hooks/curator-drift.ts
|
|
54674
|
-
init_event_bus();
|
|
54675
|
-
init_utils2();
|
|
54676
|
-
import * as fs26 from "fs";
|
|
54677
|
-
import * as fsSync from "fs";
|
|
54678
|
-
import * as path37 from "path";
|
|
54679
|
-
var DRIFT_REPORT_PREFIX = "drift-report-phase-";
|
|
54680
|
-
async function readPriorDriftReports(directory) {
|
|
54681
|
-
const swarmDir = path37.join(directory, ".swarm");
|
|
54682
|
-
const entries = await fs26.promises.readdir(swarmDir).catch(() => null);
|
|
54683
|
-
if (entries === null)
|
|
54684
|
-
return [];
|
|
54685
|
-
const reportFiles = entries.filter((name2) => name2.startsWith(DRIFT_REPORT_PREFIX) && name2.endsWith(".json")).sort();
|
|
54686
|
-
const reports = [];
|
|
54687
|
-
for (const filename of reportFiles) {
|
|
54688
|
-
const content = await readSwarmFileAsync(directory, filename);
|
|
54689
|
-
if (content === null)
|
|
54690
|
-
continue;
|
|
54691
|
-
try {
|
|
54692
|
-
const report = JSON.parse(content);
|
|
54693
|
-
if (typeof report.phase !== "number" || typeof report.alignment !== "string") {
|
|
54694
|
-
console.warn(`[curator-drift] Skipping corrupt drift report: ${filename}`);
|
|
54695
|
-
continue;
|
|
54696
|
-
}
|
|
54697
|
-
reports.push(report);
|
|
54698
|
-
} catch {
|
|
54699
|
-
console.warn(`[curator-drift] Skipping unreadable drift report: ${filename}`);
|
|
54700
|
-
}
|
|
54701
|
-
}
|
|
54702
|
-
reports.sort((a, b) => a.phase - b.phase);
|
|
54703
|
-
return reports;
|
|
54704
|
-
}
|
|
54705
|
-
async function writeDriftReport(directory, report) {
|
|
54706
|
-
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
54707
|
-
const filePath = validateSwarmPath(directory, filename);
|
|
54708
|
-
const swarmDir = path37.dirname(filePath);
|
|
54709
|
-
await fs26.promises.mkdir(swarmDir, { recursive: true });
|
|
54710
|
-
try {
|
|
54711
|
-
await fs26.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
54712
|
-
} catch (err2) {
|
|
54713
|
-
throw new Error(`[curator-drift] Failed to write drift report to ${filePath}: ${String(err2)}`);
|
|
54714
|
-
}
|
|
54715
|
-
return filePath;
|
|
54716
|
-
}
|
|
54717
|
-
async function runCriticDriftCheck(directory, phase, curatorResult, config3, injectAdvisory) {
|
|
54718
|
-
try {
|
|
54719
|
-
const planMd = await readSwarmFileAsync(directory, "plan.md");
|
|
54720
|
-
const specMd = await readSwarmFileAsync(directory, "spec.md");
|
|
54721
|
-
const priorReports = await readPriorDriftReports(directory);
|
|
54722
|
-
const complianceCount = curatorResult.compliance.length;
|
|
54723
|
-
const warningCompliance = curatorResult.compliance.filter((obs) => obs.severity === "warning");
|
|
54724
|
-
let alignment = "ALIGNED";
|
|
54725
|
-
let driftScore = 0;
|
|
54726
|
-
if (!planMd) {
|
|
54727
|
-
alignment = "MINOR_DRIFT";
|
|
54728
|
-
driftScore = 0.3;
|
|
54729
|
-
} else if (warningCompliance.length >= 3) {
|
|
54730
|
-
alignment = "MAJOR_DRIFT";
|
|
54731
|
-
driftScore = Math.min(0.9, 0.5 + warningCompliance.length * 0.1);
|
|
54732
|
-
} else if (warningCompliance.length >= 1 || complianceCount >= 3) {
|
|
54733
|
-
alignment = "MINOR_DRIFT";
|
|
54734
|
-
driftScore = Math.min(0.49, 0.2 + complianceCount * 0.05);
|
|
54735
|
-
}
|
|
54736
|
-
const priorSummaries = priorReports.map((r) => r.injection_summary).filter(Boolean);
|
|
54737
|
-
const keyCorrections = warningCompliance.map((obs) => obs.description);
|
|
54738
|
-
const firstDeviation = warningCompliance.length > 0 ? {
|
|
54739
|
-
phase,
|
|
54740
|
-
task: "unknown",
|
|
54741
|
-
description: warningCompliance[0]?.description ?? ""
|
|
54742
|
-
} : null;
|
|
54743
|
-
const payloadLines = [
|
|
54744
|
-
`CURATOR_DIGEST: ${JSON.stringify(curatorResult.digest)}`,
|
|
54745
|
-
`CURATOR_COMPLIANCE: ${JSON.stringify(curatorResult.compliance)}`,
|
|
54746
|
-
`PLAN: ${planMd ?? "none"}`,
|
|
54747
|
-
`SPEC: ${specMd ?? "none"}`,
|
|
54748
|
-
`PRIOR_DRIFT_REPORTS: ${JSON.stringify(priorSummaries)}`
|
|
54749
|
-
];
|
|
54750
|
-
const payload = payloadLines.join(`
|
|
54751
|
-
`);
|
|
54752
|
-
const requirementsChecked = curatorResult.digest.tasks_total;
|
|
54753
|
-
const requirementsSatisfied = curatorResult.digest.tasks_completed;
|
|
54754
|
-
const injectionSummaryRaw = `Phase ${phase}: ${alignment} (${driftScore.toFixed(2)}) \u2014 ${firstDeviation ? firstDeviation.description : "all requirements on track"}.${keyCorrections.length > 0 ? `Correction: ${keyCorrections[0] ?? ""}.` : ""}`;
|
|
54755
|
-
const injectionSummary = injectionSummaryRaw.slice(0, config3.drift_inject_max_chars);
|
|
54756
|
-
const report = {
|
|
54757
|
-
schema_version: 1,
|
|
54758
|
-
phase,
|
|
54759
|
-
timestamp: new Date().toISOString(),
|
|
54760
|
-
alignment,
|
|
54761
|
-
drift_score: driftScore,
|
|
54762
|
-
first_deviation: firstDeviation,
|
|
54763
|
-
compounding_effects: priorReports.filter((r) => r.alignment !== "ALIGNED").map((r) => `Phase ${r.phase}: ${r.alignment}`).slice(0, 5),
|
|
54764
|
-
corrections: keyCorrections.slice(0, 5),
|
|
54765
|
-
requirements_checked: requirementsChecked,
|
|
54766
|
-
requirements_satisfied: requirementsSatisfied,
|
|
54767
|
-
scope_additions: [],
|
|
54768
|
-
injection_summary: injectionSummary
|
|
54769
|
-
};
|
|
54770
|
-
const reportPath = await writeDriftReport(directory, report);
|
|
54771
|
-
try {
|
|
54772
|
-
const evidenceDir = path37.join(directory, ".swarm", "evidence", String(phase));
|
|
54773
|
-
fsSync.mkdirSync(evidenceDir, { recursive: true });
|
|
54774
|
-
const evidencePath = path37.join(evidenceDir, "drift-verifier.json");
|
|
54775
|
-
let verdict;
|
|
54776
|
-
let summary;
|
|
54777
|
-
if (alignment === "MAJOR_DRIFT") {
|
|
54778
|
-
verdict = "rejected";
|
|
54779
|
-
summary = `Major drift detected (score: ${driftScore.toFixed(2)}): ${firstDeviation ? firstDeviation.description : "alignment issues detected"}`;
|
|
54780
|
-
} else if (alignment === "MINOR_DRIFT") {
|
|
54781
|
-
verdict = "approved";
|
|
54782
|
-
summary = `Minor drift detected (score: ${driftScore.toFixed(2)}): ${firstDeviation ? firstDeviation.description : "minor alignment issues"}`;
|
|
54783
|
-
} else {
|
|
54784
|
-
verdict = "approved";
|
|
54785
|
-
summary = "Drift check passed: all requirements aligned";
|
|
54786
|
-
}
|
|
54787
|
-
const evidence = {
|
|
54788
|
-
entries: [
|
|
54789
|
-
{
|
|
54790
|
-
type: "drift-verification",
|
|
54791
|
-
verdict,
|
|
54792
|
-
summary,
|
|
54793
|
-
timestamp: new Date().toISOString(),
|
|
54794
|
-
agent: "curator-drift",
|
|
54795
|
-
session_id: "curator"
|
|
54796
|
-
}
|
|
54797
|
-
]
|
|
54798
|
-
};
|
|
54799
|
-
fsSync.writeFileSync(evidencePath, JSON.stringify(evidence, null, 2), "utf-8");
|
|
54800
|
-
} catch (driftWriteErr) {
|
|
54801
|
-
console.warn(`[curator-drift] drift-verifier evidence write failed: ${driftWriteErr instanceof Error ? driftWriteErr.message : String(driftWriteErr)}`);
|
|
54802
|
-
}
|
|
54803
|
-
getGlobalEventBus().publish("curator.drift.completed", {
|
|
54804
|
-
phase,
|
|
54805
|
-
alignment,
|
|
54806
|
-
drift_score: driftScore,
|
|
54807
|
-
report_path: reportPath
|
|
54808
|
-
});
|
|
54809
|
-
if (injectAdvisory && alignment !== "ALIGNED" && driftScore > 0) {
|
|
54810
|
-
try {
|
|
54811
|
-
const advisoryText = `CURATOR DRIFT DETECTED (phase ${phase}, score ${driftScore.toFixed(2)}): ${injectionSummary.slice(0, 300)}. Review .swarm/${DRIFT_REPORT_PREFIX}${phase}.json and address spec alignment before proceeding.`;
|
|
54812
|
-
injectAdvisory(advisoryText);
|
|
54813
|
-
} catch {}
|
|
54814
|
-
}
|
|
54815
|
-
const injectionText = injectionSummary;
|
|
54816
|
-
return {
|
|
54817
|
-
phase,
|
|
54818
|
-
report,
|
|
54819
|
-
report_path: reportPath,
|
|
54820
|
-
injection_text: injectionText
|
|
54821
|
-
};
|
|
54822
|
-
} catch (err2) {
|
|
54823
|
-
getGlobalEventBus().publish("curator.error", {
|
|
54824
|
-
operation: "drift",
|
|
54825
|
-
phase,
|
|
54826
|
-
error: String(err2)
|
|
54827
|
-
});
|
|
54828
|
-
const defaultReport = {
|
|
54829
|
-
schema_version: 1,
|
|
54830
|
-
phase,
|
|
54831
|
-
timestamp: new Date().toISOString(),
|
|
54832
|
-
alignment: "ALIGNED",
|
|
54833
|
-
drift_score: 0,
|
|
54834
|
-
first_deviation: null,
|
|
54835
|
-
compounding_effects: [],
|
|
54836
|
-
corrections: [],
|
|
54837
|
-
requirements_checked: 0,
|
|
54838
|
-
requirements_satisfied: 0,
|
|
54839
|
-
scope_additions: [],
|
|
54840
|
-
injection_summary: `Phase ${phase}: drift analysis unavailable (${String(err2)})`
|
|
54841
|
-
};
|
|
54842
|
-
return {
|
|
54843
|
-
phase,
|
|
54844
|
-
report: defaultReport,
|
|
54845
|
-
report_path: "",
|
|
54846
|
-
injection_text: ""
|
|
54847
|
-
};
|
|
54848
|
-
}
|
|
54849
|
-
}
|
|
54850
|
-
function buildDriftInjectionText(report, maxChars) {
|
|
54851
|
-
if (maxChars <= 0) {
|
|
54852
|
-
return "";
|
|
54853
|
-
}
|
|
54854
|
-
let text;
|
|
54855
|
-
if (report.alignment === "ALIGNED" && report.drift_score < 0.1) {
|
|
54856
|
-
text = `<drift_report>Phase ${report.phase}: ALIGNED, all requirements on track.</drift_report>`;
|
|
54857
|
-
} else {
|
|
54858
|
-
const keyFinding = report.first_deviation?.description ?? "no deviation recorded";
|
|
54859
|
-
const score = report.drift_score ?? 0;
|
|
54860
|
-
const correctionClause = report.corrections?.[0] ? `Correction: ${report.corrections[0]}.` : "";
|
|
54861
|
-
text = `<drift_report>Phase ${report.phase}: ${report.alignment} (${score.toFixed(2)}) \u2014 ${keyFinding}. ${correctionClause}</drift_report>`;
|
|
54862
|
-
}
|
|
54863
|
-
return text.slice(0, maxChars);
|
|
54864
|
-
}
|
|
54865
|
-
|
|
54866
54888
|
// src/hooks/knowledge-injector.ts
|
|
54889
|
+
init_curator_drift();
|
|
54867
54890
|
init_utils2();
|
|
54868
54891
|
function formatStars(confidence) {
|
|
54869
54892
|
if (confidence >= 0.9)
|
|
@@ -55745,7 +55768,7 @@ var build_check = createSwarmTool({
|
|
|
55745
55768
|
try {
|
|
55746
55769
|
await saveEvidence(workingDir, "build", evidence);
|
|
55747
55770
|
} catch (error93) {
|
|
55748
|
-
console.error("Failed to save build evidence:", error93);
|
|
55771
|
+
console.error("Failed to save build evidence:", error93 instanceof Error ? error93.message : String(error93));
|
|
55749
55772
|
}
|
|
55750
55773
|
return JSON.stringify(result, null, 2);
|
|
55751
55774
|
}
|
|
@@ -55932,14 +55955,6 @@ init_utils2();
|
|
|
55932
55955
|
import * as fs30 from "fs";
|
|
55933
55956
|
import * as path41 from "path";
|
|
55934
55957
|
init_create_tool();
|
|
55935
|
-
function hasActiveTurboMode2() {
|
|
55936
|
-
for (const [_sessionId, session] of swarmState.agentSessions) {
|
|
55937
|
-
if (session.turboMode === true) {
|
|
55938
|
-
return true;
|
|
55939
|
-
}
|
|
55940
|
-
}
|
|
55941
|
-
return false;
|
|
55942
|
-
}
|
|
55943
55958
|
function extractMatches(regex, text) {
|
|
55944
55959
|
return Array.from(text.matchAll(regex));
|
|
55945
55960
|
}
|
|
@@ -56004,7 +56019,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
56004
56019
|
};
|
|
56005
56020
|
return JSON.stringify(result2, null, 2);
|
|
56006
56021
|
}
|
|
56007
|
-
if (
|
|
56022
|
+
if (hasActiveTurboMode(args2.sessionID)) {
|
|
56008
56023
|
const result2 = {
|
|
56009
56024
|
success: true,
|
|
56010
56025
|
phase,
|
|
@@ -56535,7 +56550,7 @@ var curator_analyze = createSwarmTool({
|
|
|
56535
56550
|
}, null, 2);
|
|
56536
56551
|
} catch (error93) {
|
|
56537
56552
|
return JSON.stringify({
|
|
56538
|
-
error: String(error93),
|
|
56553
|
+
error: error93 instanceof Error ? error93.message : String(error93),
|
|
56539
56554
|
phase: typedArgs.phase
|
|
56540
56555
|
}, null, 2);
|
|
56541
56556
|
}
|
|
@@ -58759,7 +58774,7 @@ init_telemetry();
|
|
|
58759
58774
|
init_create_tool();
|
|
58760
58775
|
function safeWarn(message, error93) {
|
|
58761
58776
|
try {
|
|
58762
|
-
console.warn(message, error93);
|
|
58777
|
+
console.warn(message, error93 instanceof Error ? error93.message : String(error93));
|
|
58763
58778
|
} catch {}
|
|
58764
58779
|
}
|
|
58765
58780
|
function collectCrossSessionDispatchedAgents(phaseReferenceTimestamp, callerSessionId) {
|
|
@@ -58949,7 +58964,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
58949
58964
|
]
|
|
58950
58965
|
}, null, 2);
|
|
58951
58966
|
}
|
|
58952
|
-
if (hasActiveTurboMode()) {
|
|
58967
|
+
if (hasActiveTurboMode(sessionID)) {
|
|
58953
58968
|
console.warn(`[phase_complete] Turbo mode active \u2014 skipping completion-verify and drift-verifier gates for phase ${phase}`);
|
|
58954
58969
|
} else {
|
|
58955
58970
|
try {
|
|
@@ -59010,7 +59025,23 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
59010
59025
|
const specPath = path48.join(dir, ".swarm", "spec.md");
|
|
59011
59026
|
const specExists = fs37.existsSync(specPath);
|
|
59012
59027
|
if (!specExists) {
|
|
59013
|
-
|
|
59028
|
+
let incompleteTaskCount = 0;
|
|
59029
|
+
let planPhaseFound = false;
|
|
59030
|
+
try {
|
|
59031
|
+
const planPath = validateSwarmPath(dir, "plan.json");
|
|
59032
|
+
const planRaw = fs37.readFileSync(planPath, "utf-8");
|
|
59033
|
+
const plan = JSON.parse(planRaw);
|
|
59034
|
+
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
59035
|
+
if (targetPhase) {
|
|
59036
|
+
planPhaseFound = true;
|
|
59037
|
+
incompleteTaskCount = targetPhase.tasks.filter((t) => t.status !== "completed").length;
|
|
59038
|
+
}
|
|
59039
|
+
} catch {}
|
|
59040
|
+
if (incompleteTaskCount > 0 || !planPhaseFound) {
|
|
59041
|
+
warnings.push(`No spec.md found and drift verification evidence missing. Phase ${phase} has ${incompleteTaskCount} incomplete task(s) in plan.json \u2014 consider running critic_drift_verifier before phase completion.`);
|
|
59042
|
+
} else {
|
|
59043
|
+
warnings.push(`No spec.md found. Phase ${phase} tasks are all completed in plan.json. Drift verification was skipped.`);
|
|
59044
|
+
}
|
|
59014
59045
|
} else {
|
|
59015
59046
|
return JSON.stringify({
|
|
59016
59047
|
success: false,
|
|
@@ -59076,17 +59107,21 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
59076
59107
|
const curatorConfig = CuratorConfigSchema.parse(config3.curator ?? {});
|
|
59077
59108
|
if (curatorConfig.enabled && curatorConfig.phase_enabled) {
|
|
59078
59109
|
const curatorResult = await runCuratorPhase(dir, phase, agentsDispatched, curatorConfig, {});
|
|
59079
|
-
await applyCuratorKnowledgeUpdates(dir, curatorResult.knowledge_recommendations, knowledgeConfig);
|
|
59080
|
-
const driftResult = await runCriticDriftCheck(dir, phase, curatorResult, curatorConfig);
|
|
59110
|
+
const knowledgeResult = await applyCuratorKnowledgeUpdates(dir, curatorResult.knowledge_recommendations, knowledgeConfig);
|
|
59081
59111
|
const callerSessionState = swarmState.agentSessions.get(sessionID);
|
|
59082
59112
|
if (callerSessionState) {
|
|
59083
59113
|
callerSessionState.pendingAdvisoryMessages ??= [];
|
|
59084
59114
|
const digestSummary = curatorResult.digest?.summary ? curatorResult.digest.summary.slice(0, 200) : "Phase analysis complete";
|
|
59085
59115
|
const complianceNote = curatorResult.compliance.length > 0 ? ` (${curatorResult.compliance.length} compliance observation(s))` : "";
|
|
59086
|
-
callerSessionState.pendingAdvisoryMessages.push(`[CURATOR] Phase ${phase} digest: ${digestSummary}${complianceNote}. Call curator_analyze with recommendations to apply knowledge updates from this phase.`);
|
|
59087
|
-
|
|
59088
|
-
|
|
59089
|
-
|
|
59116
|
+
callerSessionState.pendingAdvisoryMessages.push(`[CURATOR] Phase ${phase} digest: ${digestSummary}${complianceNote}. Knowledge: ${knowledgeResult.applied} applied, ${knowledgeResult.skipped} skipped. Call curator_analyze with recommendations to apply knowledge updates from this phase.`);
|
|
59117
|
+
try {
|
|
59118
|
+
const { readPriorDriftReports: readPriorDriftReports2 } = await Promise.resolve().then(() => (init_curator_drift(), exports_curator_drift));
|
|
59119
|
+
const priorReports = await readPriorDriftReports2(dir);
|
|
59120
|
+
const phaseReport = priorReports.filter((r) => r.phase === phase).pop();
|
|
59121
|
+
if (phaseReport && phaseReport.drift_score > 0) {
|
|
59122
|
+
callerSessionState.pendingAdvisoryMessages.push(`[CURATOR DRIFT DETECTED (phase ${phase}, score ${phaseReport.drift_score})]: Consider running critic_drift_verifier before phase completion to get a proper drift review. Review drift report for phase ${phase} and address spec alignment if applicable.`);
|
|
59123
|
+
}
|
|
59124
|
+
} catch {}
|
|
59090
59125
|
}
|
|
59091
59126
|
if (curatorResult.compliance.length > 0 && !curatorConfig.suppress_warnings) {
|
|
59092
59127
|
const complianceLines = curatorResult.compliance.map((obs) => `[${obs.severity.toUpperCase()}] ${obs.description}`).slice(0, 5);
|
|
@@ -59222,7 +59257,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
59222
59257
|
return JSON.stringify({ ...result, timestamp: event.timestamp, duration_ms: durationMs }, null, 2);
|
|
59223
59258
|
}
|
|
59224
59259
|
var phase_complete = createSwarmTool({
|
|
59225
|
-
description: "Mark a phase as complete and track which agents were dispatched.
|
|
59260
|
+
description: "Mark a phase as complete and track which agents were dispatched. Used for phase completion gating and tracking. Accepts phase number and optional summary. Returns list of agents that were dispatched.",
|
|
59226
59261
|
args: {
|
|
59227
59262
|
phase: tool.schema.number().describe("The phase number being completed (e.g., 1, 2, 3)"),
|
|
59228
59263
|
summary: tool.schema.string().optional().describe("Optional summary of what was accomplished in this phase"),
|
|
@@ -63220,7 +63255,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
63220
63255
|
return {
|
|
63221
63256
|
success: false,
|
|
63222
63257
|
message: "Failed to save plan: retry with save_plan after resolving the error above",
|
|
63223
|
-
errors: [String(error93)],
|
|
63258
|
+
errors: [error93 instanceof Error ? error93.message : String(error93)],
|
|
63224
63259
|
recovery_guidance: "Use save_plan with corrected inputs to create or restructure plans. Never write .swarm/plan.json or .swarm/plan.md directly."
|
|
63225
63260
|
};
|
|
63226
63261
|
}
|
|
@@ -65381,17 +65416,9 @@ function matchesTier3Pattern(files) {
|
|
|
65381
65416
|
}
|
|
65382
65417
|
return false;
|
|
65383
65418
|
}
|
|
65384
|
-
function hasActiveTurboMode3() {
|
|
65385
|
-
for (const [_sessionId, session] of swarmState.agentSessions) {
|
|
65386
|
-
if (session.turboMode === true) {
|
|
65387
|
-
return true;
|
|
65388
|
-
}
|
|
65389
|
-
}
|
|
65390
|
-
return false;
|
|
65391
|
-
}
|
|
65392
65419
|
function checkReviewerGate(taskId, workingDirectory) {
|
|
65393
65420
|
try {
|
|
65394
|
-
if (
|
|
65421
|
+
if (hasActiveTurboMode()) {
|
|
65395
65422
|
const resolvedDir2 = workingDirectory;
|
|
65396
65423
|
try {
|
|
65397
65424
|
const planPath = path59.join(resolvedDir2, ".swarm", "plan.json");
|
|
@@ -65428,7 +65455,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
65428
65455
|
};
|
|
65429
65456
|
}
|
|
65430
65457
|
} catch (error93) {
|
|
65431
|
-
console.warn(`[gate-evidence] Evidence file for task ${taskId} is corrupt or unreadable:`, error93);
|
|
65458
|
+
console.warn(`[gate-evidence] Evidence file for task ${taskId} is corrupt or unreadable:`, error93 instanceof Error ? error93.message : String(error93));
|
|
65432
65459
|
telemetry.gateFailed("", "qa_gate", taskId, `Evidence file corrupt or unreadable`);
|
|
65433
65460
|
return {
|
|
65434
65461
|
blocked: true,
|
|
@@ -65721,7 +65748,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
65721
65748
|
return {
|
|
65722
65749
|
success: false,
|
|
65723
65750
|
message: "Failed to update task status",
|
|
65724
|
-
errors: [String(error93)]
|
|
65751
|
+
errors: [error93 instanceof Error ? error93.message : String(error93)]
|
|
65725
65752
|
};
|
|
65726
65753
|
}
|
|
65727
65754
|
}
|
package/dist/state.d.ts
CHANGED
|
@@ -331,7 +331,9 @@ export declare function applyRehydrationCache(session: AgentSessionState): void;
|
|
|
331
331
|
*/
|
|
332
332
|
export declare function rehydrateSessionFromDisk(directory: string, session: AgentSessionState): Promise<void>;
|
|
333
333
|
/**
|
|
334
|
-
* Check if
|
|
335
|
-
* @
|
|
334
|
+
* Check if Turbo Mode is enabled for a specific session or ANY session.
|
|
335
|
+
* @param sessionID - Optional session ID to check. If provided, checks only that session.
|
|
336
|
+
* If omitted, checks all sessions (backward-compatible global behavior).
|
|
337
|
+
* @returns true if the specified session has turboMode: true, or if any session has turboMode: true when no sessionID provided
|
|
336
338
|
*/
|
|
337
|
-
export declare function hasActiveTurboMode(): boolean;
|
|
339
|
+
export declare function hasActiveTurboMode(sessionID?: string): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.36.0",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|