opencode-swarm 6.28.0 → 6.29.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 +225 -29
- package/dist/config/constants.d.ts +19 -0
- package/dist/config/evidence-schema.d.ts +6 -0
- package/dist/config/schema.d.ts +41 -0
- package/dist/hooks/diff-scope.d.ts +12 -0
- package/dist/hooks/diff-scope.test.d.ts +1 -0
- package/dist/hooks/incremental-verify.d.ts +18 -0
- package/dist/hooks/incremental-verify.test.d.ts +1 -0
- package/dist/hooks/loop-detector.d.ts +17 -0
- package/dist/hooks/loop-detector.test.d.ts +1 -0
- package/dist/hooks/slop-detector.d.ts +17 -0
- package/dist/hooks/slop-detector.test.d.ts +1 -0
- package/dist/index.js +1199 -476
- package/dist/services/compaction-service.d.ts +23 -0
- package/dist/services/compaction-service.test.d.ts +1 -0
- package/dist/services/status-service.d.ts +6 -0
- package/dist/state.d.ts +15 -0
- package/dist/tools/lint.d.ts +7 -1
- package/dist/tools/test-runner.d.ts +1 -1
- package/dist/tools/update-task-status.d.ts +8 -0
- package/dist/tools/write-retro.d.ts +2 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -14011,14 +14011,16 @@ var init_evidence_schema = __esm(() => {
|
|
|
14011
14011
|
});
|
|
14012
14012
|
RetrospectiveEvidenceSchema = BaseEvidenceSchema.extend({
|
|
14013
14013
|
type: exports_external.literal("retrospective"),
|
|
14014
|
-
phase_number: exports_external.number().int().min(0),
|
|
14015
|
-
total_tool_calls: exports_external.number().int().min(0),
|
|
14016
|
-
coder_revisions: exports_external.number().int().min(0),
|
|
14017
|
-
reviewer_rejections: exports_external.number().int().min(0),
|
|
14018
|
-
|
|
14019
|
-
|
|
14020
|
-
|
|
14021
|
-
|
|
14014
|
+
phase_number: exports_external.number().int().min(0).max(99),
|
|
14015
|
+
total_tool_calls: exports_external.number().int().min(0).max(9999),
|
|
14016
|
+
coder_revisions: exports_external.number().int().min(0).max(999),
|
|
14017
|
+
reviewer_rejections: exports_external.number().int().min(0).max(999),
|
|
14018
|
+
loop_detections: exports_external.number().int().min(0).max(9999).optional(),
|
|
14019
|
+
circuit_breaker_trips: exports_external.number().int().min(0).max(9999).optional(),
|
|
14020
|
+
test_failures: exports_external.number().int().min(0).max(9999),
|
|
14021
|
+
security_findings: exports_external.number().int().min(0).max(999),
|
|
14022
|
+
integration_issues: exports_external.number().int().min(0).max(999),
|
|
14023
|
+
task_count: exports_external.number().int().min(1).max(9999),
|
|
14022
14024
|
task_complexity: exports_external.enum(["trivial", "simple", "moderate", "complex"]),
|
|
14023
14025
|
top_rejection_reasons: exports_external.array(exports_external.string()).default([]),
|
|
14024
14026
|
lessons_learned: exports_external.array(exports_external.string()).max(5).default([]),
|
|
@@ -17209,6 +17211,25 @@ var CuratorConfigSchema = exports_external.object({
|
|
|
17209
17211
|
suppress_warnings: exports_external.boolean().default(true),
|
|
17210
17212
|
drift_inject_max_chars: exports_external.number().min(100).max(2000).default(500)
|
|
17211
17213
|
});
|
|
17214
|
+
var SlopDetectorConfigSchema = exports_external.object({
|
|
17215
|
+
enabled: exports_external.boolean().default(true),
|
|
17216
|
+
classThreshold: exports_external.number().int().min(1).default(3),
|
|
17217
|
+
commentStripThreshold: exports_external.number().int().min(1).default(5),
|
|
17218
|
+
diffLineThreshold: exports_external.number().int().min(10).default(200)
|
|
17219
|
+
});
|
|
17220
|
+
var IncrementalVerifyConfigSchema = exports_external.object({
|
|
17221
|
+
enabled: exports_external.boolean().default(true),
|
|
17222
|
+
command: exports_external.string().nullable().default(null),
|
|
17223
|
+
timeoutMs: exports_external.number().int().min(1000).max(300000).default(30000),
|
|
17224
|
+
triggerAgents: exports_external.array(exports_external.string()).default(["coder"])
|
|
17225
|
+
});
|
|
17226
|
+
var CompactionConfigSchema = exports_external.object({
|
|
17227
|
+
enabled: exports_external.boolean().default(true),
|
|
17228
|
+
observationThreshold: exports_external.number().min(1).max(99).default(40),
|
|
17229
|
+
reflectionThreshold: exports_external.number().min(1).max(99).default(60),
|
|
17230
|
+
emergencyThreshold: exports_external.number().min(1).max(99).default(80),
|
|
17231
|
+
preserveLastNTurns: exports_external.number().int().min(1).default(5)
|
|
17232
|
+
});
|
|
17212
17233
|
var PluginConfigSchema = exports_external.object({
|
|
17213
17234
|
agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional(),
|
|
17214
17235
|
swarms: exports_external.record(exports_external.string(), SwarmConfigSchema).optional(),
|
|
@@ -17242,7 +17263,10 @@ var PluginConfigSchema = exports_external.object({
|
|
|
17242
17263
|
truncation_enabled: exports_external.boolean().default(true),
|
|
17243
17264
|
max_lines: exports_external.number().min(10).max(500).default(150),
|
|
17244
17265
|
per_tool: exports_external.record(exports_external.string(), exports_external.number()).optional()
|
|
17245
|
-
}).optional()
|
|
17266
|
+
}).optional(),
|
|
17267
|
+
slop_detector: SlopDetectorConfigSchema.optional(),
|
|
17268
|
+
incremental_verify: IncrementalVerifyConfigSchema.optional(),
|
|
17269
|
+
compaction_service: CompactionConfigSchema.optional()
|
|
17246
17270
|
});
|
|
17247
17271
|
|
|
17248
17272
|
// src/config/loader.ts
|
|
@@ -17428,6 +17452,7 @@ var swarmState = {
|
|
|
17428
17452
|
activeAgent: new Map,
|
|
17429
17453
|
delegationChains: new Map,
|
|
17430
17454
|
pendingEvents: 0,
|
|
17455
|
+
lastBudgetPct: 0,
|
|
17431
17456
|
agentSessions: new Map
|
|
17432
17457
|
};
|
|
17433
17458
|
function getAgentSession(sessionId) {
|
|
@@ -32989,7 +33014,15 @@ function detectAdditionalLinter(cwd) {
|
|
|
32989
33014
|
return "rubocop";
|
|
32990
33015
|
return null;
|
|
32991
33016
|
}
|
|
32992
|
-
async function detectAvailableLinter() {
|
|
33017
|
+
async function detectAvailableLinter(directory) {
|
|
33018
|
+
const DETECT_TIMEOUT = 2000;
|
|
33019
|
+
const projectDir = directory ?? process.cwd();
|
|
33020
|
+
const isWindows = process.platform === "win32";
|
|
33021
|
+
const biomeBin = isWindows ? path11.join(projectDir, "node_modules", ".bin", "biome.EXE") : path11.join(projectDir, "node_modules", ".bin", "biome");
|
|
33022
|
+
const eslintBin = isWindows ? path11.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path11.join(projectDir, "node_modules", ".bin", "eslint");
|
|
33023
|
+
return _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
33024
|
+
}
|
|
33025
|
+
async function _detectAvailableLinter(projectDir, biomeBin, eslintBin) {
|
|
32993
33026
|
const DETECT_TIMEOUT = 2000;
|
|
32994
33027
|
try {
|
|
32995
33028
|
const biomeProc = Bun.spawn(["npx", "biome", "--version"], {
|
|
@@ -33001,7 +33034,7 @@ async function detectAvailableLinter() {
|
|
|
33001
33034
|
const result = await Promise.race([biomeExit, timeout]);
|
|
33002
33035
|
if (result === "timeout") {
|
|
33003
33036
|
biomeProc.kill();
|
|
33004
|
-
} else if (biomeProc.exitCode === 0) {
|
|
33037
|
+
} else if (biomeProc.exitCode === 0 && fs3.existsSync(biomeBin)) {
|
|
33005
33038
|
return "biome";
|
|
33006
33039
|
}
|
|
33007
33040
|
} catch {}
|
|
@@ -33015,7 +33048,7 @@ async function detectAvailableLinter() {
|
|
|
33015
33048
|
const result = await Promise.race([eslintExit, timeout]);
|
|
33016
33049
|
if (result === "timeout") {
|
|
33017
33050
|
eslintProc.kill();
|
|
33018
|
-
} else if (eslintProc.exitCode === 0) {
|
|
33051
|
+
} else if (eslintProc.exitCode === 0 && fs3.existsSync(eslintBin)) {
|
|
33019
33052
|
return "eslint";
|
|
33020
33053
|
}
|
|
33021
33054
|
} catch {}
|
|
@@ -33161,7 +33194,7 @@ var lint = createSwarmTool({
|
|
|
33161
33194
|
}
|
|
33162
33195
|
const { mode } = args;
|
|
33163
33196
|
const cwd = directory;
|
|
33164
|
-
const linter = await detectAvailableLinter();
|
|
33197
|
+
const linter = await detectAvailableLinter(directory);
|
|
33165
33198
|
if (linter) {
|
|
33166
33199
|
const result = await runLint(linter, mode, directory);
|
|
33167
33200
|
return JSON.stringify(result, null, 2);
|
|
@@ -33766,10 +33799,7 @@ var secretscan = tool({
|
|
|
33766
33799
|
const excludeExact = new Set(DEFAULT_EXCLUDE_DIRS);
|
|
33767
33800
|
const excludeGlobs = [];
|
|
33768
33801
|
const ignoreFilePatterns = loadSecretScanIgnore(scanDir);
|
|
33769
|
-
const allUserPatterns = [
|
|
33770
|
-
...exclude ?? [],
|
|
33771
|
-
...ignoreFilePatterns
|
|
33772
|
-
];
|
|
33802
|
+
const allUserPatterns = [...exclude ?? [], ...ignoreFilePatterns];
|
|
33773
33803
|
for (const exc of allUserPatterns) {
|
|
33774
33804
|
if (exc.length === 0)
|
|
33775
33805
|
continue;
|
|
@@ -34017,7 +34047,7 @@ function detectMinitest(cwd) {
|
|
|
34017
34047
|
return fs5.existsSync(path13.join(cwd, "test")) && (fs5.existsSync(path13.join(cwd, "Gemfile")) || fs5.existsSync(path13.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
34018
34048
|
}
|
|
34019
34049
|
async function detectTestFramework(cwd) {
|
|
34020
|
-
const baseDir = cwd
|
|
34050
|
+
const baseDir = cwd;
|
|
34021
34051
|
try {
|
|
34022
34052
|
const packageJsonPath = path13.join(baseDir, "package.json");
|
|
34023
34053
|
if (fs5.existsSync(packageJsonPath)) {
|
|
@@ -35632,6 +35662,19 @@ function extractCurrentPhaseFromPlan2(plan) {
|
|
|
35632
35662
|
// src/services/status-service.ts
|
|
35633
35663
|
init_utils2();
|
|
35634
35664
|
init_manager2();
|
|
35665
|
+
|
|
35666
|
+
// src/services/context-budget-service.ts
|
|
35667
|
+
init_utils2();
|
|
35668
|
+
var DEFAULT_CONTEXT_BUDGET_CONFIG = {
|
|
35669
|
+
enabled: true,
|
|
35670
|
+
budgetTokens: 40000,
|
|
35671
|
+
warningPct: 70,
|
|
35672
|
+
criticalPct: 90,
|
|
35673
|
+
warningMode: "once",
|
|
35674
|
+
warningIntervalTurns: 20
|
|
35675
|
+
};
|
|
35676
|
+
|
|
35677
|
+
// src/services/status-service.ts
|
|
35635
35678
|
async function getStatusData(directory, agents) {
|
|
35636
35679
|
const plan = await loadPlan(directory);
|
|
35637
35680
|
if (plan && plan.migration_status !== "migration_failed") {
|
|
@@ -35653,7 +35696,10 @@ async function getStatusData(directory, agents) {
|
|
|
35653
35696
|
totalTasks: totalTasks2,
|
|
35654
35697
|
agentCount: agentCount2,
|
|
35655
35698
|
isLegacy: false,
|
|
35656
|
-
turboMode: hasActiveTurboMode()
|
|
35699
|
+
turboMode: hasActiveTurboMode(),
|
|
35700
|
+
contextBudgetPct: swarmState.lastBudgetPct > 0 ? swarmState.lastBudgetPct : null,
|
|
35701
|
+
compactionCount: 0,
|
|
35702
|
+
lastSnapshotAt: null
|
|
35657
35703
|
};
|
|
35658
35704
|
}
|
|
35659
35705
|
const planContent = await readSwarmFileAsync(directory, "plan.md");
|
|
@@ -35665,7 +35711,10 @@ async function getStatusData(directory, agents) {
|
|
|
35665
35711
|
totalTasks: 0,
|
|
35666
35712
|
agentCount: Object.keys(agents).length,
|
|
35667
35713
|
isLegacy: true,
|
|
35668
|
-
turboMode: hasActiveTurboMode()
|
|
35714
|
+
turboMode: hasActiveTurboMode(),
|
|
35715
|
+
contextBudgetPct: swarmState.lastBudgetPct > 0 ? swarmState.lastBudgetPct : null,
|
|
35716
|
+
compactionCount: 0,
|
|
35717
|
+
lastSnapshotAt: null
|
|
35669
35718
|
};
|
|
35670
35719
|
}
|
|
35671
35720
|
const currentPhase = extractCurrentPhase(planContent) || "Unknown";
|
|
@@ -35680,7 +35729,10 @@ async function getStatusData(directory, agents) {
|
|
|
35680
35729
|
totalTasks,
|
|
35681
35730
|
agentCount,
|
|
35682
35731
|
isLegacy: true,
|
|
35683
|
-
turboMode: hasActiveTurboMode()
|
|
35732
|
+
turboMode: hasActiveTurboMode(),
|
|
35733
|
+
contextBudgetPct: swarmState.lastBudgetPct > 0 ? swarmState.lastBudgetPct : null,
|
|
35734
|
+
compactionCount: 0,
|
|
35735
|
+
lastSnapshotAt: null
|
|
35684
35736
|
};
|
|
35685
35737
|
}
|
|
35686
35738
|
function formatStatusMarkdown(status) {
|
|
@@ -35694,6 +35746,18 @@ function formatStatusMarkdown(status) {
|
|
|
35694
35746
|
if (status.turboMode) {
|
|
35695
35747
|
lines.push("", `**TURBO MODE**: active`);
|
|
35696
35748
|
}
|
|
35749
|
+
if (status.contextBudgetPct !== null && status.contextBudgetPct > 0) {
|
|
35750
|
+
const pct = status.contextBudgetPct.toFixed(1);
|
|
35751
|
+
const budgetTokens = DEFAULT_CONTEXT_BUDGET_CONFIG.budgetTokens;
|
|
35752
|
+
const est = Math.round(status.contextBudgetPct / 100 * budgetTokens);
|
|
35753
|
+
lines.push("", `**Context**: ${pct}% used (est. ${est.toLocaleString()} / ${budgetTokens.toLocaleString()} tokens)`);
|
|
35754
|
+
if (status.compactionCount > 0) {
|
|
35755
|
+
lines.push(`**Compaction events**: ${status.compactionCount} triggered`);
|
|
35756
|
+
}
|
|
35757
|
+
if (status.lastSnapshotAt) {
|
|
35758
|
+
lines.push(`**Last snapshot**: ${status.lastSnapshotAt}`);
|
|
35759
|
+
}
|
|
35760
|
+
}
|
|
35697
35761
|
return lines.join(`
|
|
35698
35762
|
`);
|
|
35699
35763
|
}
|
|
@@ -35786,6 +35850,132 @@ async function executeWriteRetro(args, directory) {
|
|
|
35786
35850
|
message: "Invalid task_count: must be a positive integer >= 1"
|
|
35787
35851
|
}, null, 2);
|
|
35788
35852
|
}
|
|
35853
|
+
if (!Number.isInteger(args.total_tool_calls) || args.total_tool_calls < 0) {
|
|
35854
|
+
return JSON.stringify({
|
|
35855
|
+
success: false,
|
|
35856
|
+
phase,
|
|
35857
|
+
message: "Invalid total_tool_calls: must be a non-negative integer"
|
|
35858
|
+
}, null, 2);
|
|
35859
|
+
}
|
|
35860
|
+
if (!Number.isInteger(args.coder_revisions) || args.coder_revisions < 0) {
|
|
35861
|
+
return JSON.stringify({
|
|
35862
|
+
success: false,
|
|
35863
|
+
phase,
|
|
35864
|
+
message: "Invalid coder_revisions: must be a non-negative integer"
|
|
35865
|
+
}, null, 2);
|
|
35866
|
+
}
|
|
35867
|
+
if (!Number.isInteger(args.reviewer_rejections) || args.reviewer_rejections < 0) {
|
|
35868
|
+
return JSON.stringify({
|
|
35869
|
+
success: false,
|
|
35870
|
+
phase,
|
|
35871
|
+
message: "Invalid reviewer_rejections: must be a non-negative integer"
|
|
35872
|
+
}, null, 2);
|
|
35873
|
+
}
|
|
35874
|
+
if (!Number.isInteger(args.test_failures) || args.test_failures < 0) {
|
|
35875
|
+
return JSON.stringify({
|
|
35876
|
+
success: false,
|
|
35877
|
+
phase,
|
|
35878
|
+
message: "Invalid test_failures: must be a non-negative integer"
|
|
35879
|
+
}, null, 2);
|
|
35880
|
+
}
|
|
35881
|
+
if (!Number.isInteger(args.security_findings) || args.security_findings < 0) {
|
|
35882
|
+
return JSON.stringify({
|
|
35883
|
+
success: false,
|
|
35884
|
+
phase,
|
|
35885
|
+
message: "Invalid security_findings: must be a non-negative integer"
|
|
35886
|
+
}, null, 2);
|
|
35887
|
+
}
|
|
35888
|
+
if (!Number.isInteger(args.integration_issues) || args.integration_issues < 0) {
|
|
35889
|
+
return JSON.stringify({
|
|
35890
|
+
success: false,
|
|
35891
|
+
phase,
|
|
35892
|
+
message: "Invalid integration_issues: must be a non-negative integer"
|
|
35893
|
+
}, null, 2);
|
|
35894
|
+
}
|
|
35895
|
+
if (args.loop_detections !== undefined && (!Number.isInteger(args.loop_detections) || args.loop_detections < 0)) {
|
|
35896
|
+
return JSON.stringify({
|
|
35897
|
+
success: false,
|
|
35898
|
+
phase,
|
|
35899
|
+
message: "Invalid loop_detections: must be a non-negative integer"
|
|
35900
|
+
}, null, 2);
|
|
35901
|
+
}
|
|
35902
|
+
if (args.circuit_breaker_trips !== undefined && (!Number.isInteger(args.circuit_breaker_trips) || args.circuit_breaker_trips < 0)) {
|
|
35903
|
+
return JSON.stringify({
|
|
35904
|
+
success: false,
|
|
35905
|
+
phase,
|
|
35906
|
+
message: "Invalid circuit_breaker_trips: must be a non-negative integer"
|
|
35907
|
+
}, null, 2);
|
|
35908
|
+
}
|
|
35909
|
+
if (args.phase > 99) {
|
|
35910
|
+
return JSON.stringify({
|
|
35911
|
+
success: false,
|
|
35912
|
+
phase,
|
|
35913
|
+
message: "Invalid phase: must be <= 99"
|
|
35914
|
+
}, null, 2);
|
|
35915
|
+
}
|
|
35916
|
+
if (args.task_count > 9999) {
|
|
35917
|
+
return JSON.stringify({
|
|
35918
|
+
success: false,
|
|
35919
|
+
phase,
|
|
35920
|
+
message: "Invalid task_count: must be <= 9999"
|
|
35921
|
+
}, null, 2);
|
|
35922
|
+
}
|
|
35923
|
+
if (args.total_tool_calls > 9999) {
|
|
35924
|
+
return JSON.stringify({
|
|
35925
|
+
success: false,
|
|
35926
|
+
phase,
|
|
35927
|
+
message: "Invalid total_tool_calls: must be <= 9999"
|
|
35928
|
+
}, null, 2);
|
|
35929
|
+
}
|
|
35930
|
+
if (args.coder_revisions > 999) {
|
|
35931
|
+
return JSON.stringify({
|
|
35932
|
+
success: false,
|
|
35933
|
+
phase,
|
|
35934
|
+
message: "Invalid coder_revisions: must be <= 999"
|
|
35935
|
+
}, null, 2);
|
|
35936
|
+
}
|
|
35937
|
+
if (args.reviewer_rejections > 999) {
|
|
35938
|
+
return JSON.stringify({
|
|
35939
|
+
success: false,
|
|
35940
|
+
phase,
|
|
35941
|
+
message: "Invalid reviewer_rejections: must be <= 999"
|
|
35942
|
+
}, null, 2);
|
|
35943
|
+
}
|
|
35944
|
+
if (args.loop_detections !== undefined && args.loop_detections > 9999) {
|
|
35945
|
+
return JSON.stringify({
|
|
35946
|
+
success: false,
|
|
35947
|
+
phase,
|
|
35948
|
+
message: "Invalid loop_detections: must be <= 9999"
|
|
35949
|
+
}, null, 2);
|
|
35950
|
+
}
|
|
35951
|
+
if (args.circuit_breaker_trips !== undefined && args.circuit_breaker_trips > 9999) {
|
|
35952
|
+
return JSON.stringify({
|
|
35953
|
+
success: false,
|
|
35954
|
+
phase,
|
|
35955
|
+
message: "Invalid circuit_breaker_trips: must be <= 9999"
|
|
35956
|
+
}, null, 2);
|
|
35957
|
+
}
|
|
35958
|
+
if (args.test_failures > 9999) {
|
|
35959
|
+
return JSON.stringify({
|
|
35960
|
+
success: false,
|
|
35961
|
+
phase,
|
|
35962
|
+
message: "Invalid test_failures: must be <= 9999"
|
|
35963
|
+
}, null, 2);
|
|
35964
|
+
}
|
|
35965
|
+
if (args.security_findings > 999) {
|
|
35966
|
+
return JSON.stringify({
|
|
35967
|
+
success: false,
|
|
35968
|
+
phase,
|
|
35969
|
+
message: "Invalid security_findings: must be <= 999"
|
|
35970
|
+
}, null, 2);
|
|
35971
|
+
}
|
|
35972
|
+
if (args.integration_issues > 999) {
|
|
35973
|
+
return JSON.stringify({
|
|
35974
|
+
success: false,
|
|
35975
|
+
phase,
|
|
35976
|
+
message: "Invalid integration_issues: must be <= 999"
|
|
35977
|
+
}, null, 2);
|
|
35978
|
+
}
|
|
35789
35979
|
const summary = args.summary;
|
|
35790
35980
|
if (typeof summary !== "string" || summary.trim().length === 0) {
|
|
35791
35981
|
return JSON.stringify({
|
|
@@ -35807,6 +35997,8 @@ async function executeWriteRetro(args, directory) {
|
|
|
35807
35997
|
total_tool_calls: args.total_tool_calls,
|
|
35808
35998
|
coder_revisions: args.coder_revisions,
|
|
35809
35999
|
reviewer_rejections: args.reviewer_rejections,
|
|
36000
|
+
loop_detections: args.loop_detections,
|
|
36001
|
+
circuit_breaker_trips: args.circuit_breaker_trips,
|
|
35810
36002
|
test_failures: args.test_failures,
|
|
35811
36003
|
security_findings: args.security_findings,
|
|
35812
36004
|
integration_issues: args.integration_issues,
|
|
@@ -35836,16 +36028,18 @@ async function executeWriteRetro(args, directory) {
|
|
|
35836
36028
|
var write_retro = createSwarmTool({
|
|
35837
36029
|
description: "Write a retrospective evidence bundle for a completed phase. " + "Accepts flat retro fields and writes a correctly-wrapped EvidenceBundle to " + ".swarm/evidence/retro-{phase}/evidence.json. " + "Use this instead of manually writing retro JSON to avoid schema validation failures in phase_complete.",
|
|
35838
36030
|
args: {
|
|
35839
|
-
phase: tool.schema.number().int().positive().describe("The phase number being completed (e.g., 1, 2, 3)"),
|
|
36031
|
+
phase: tool.schema.number().int().positive().max(99).describe("The phase number being completed (e.g., 1, 2, 3)"),
|
|
35840
36032
|
summary: tool.schema.string().describe("Human-readable summary of the phase"),
|
|
35841
|
-
task_count: tool.schema.number().int().min(1).describe("Count of tasks completed in this phase"),
|
|
36033
|
+
task_count: tool.schema.number().int().min(1).max(9999).describe("Count of tasks completed in this phase"),
|
|
35842
36034
|
task_complexity: tool.schema.enum(["trivial", "simple", "moderate", "complex"]).describe("Complexity level of the completed tasks"),
|
|
35843
|
-
total_tool_calls: tool.schema.number().int().min(0).describe("Total number of tool calls in this phase"),
|
|
35844
|
-
coder_revisions: tool.schema.number().int().min(0).describe("Number of coder revisions made"),
|
|
35845
|
-
reviewer_rejections: tool.schema.number().int().min(0).describe("Number of reviewer rejections received"),
|
|
35846
|
-
|
|
35847
|
-
|
|
35848
|
-
|
|
36035
|
+
total_tool_calls: tool.schema.number().int().min(0).max(9999).describe("Total number of tool calls in this phase"),
|
|
36036
|
+
coder_revisions: tool.schema.number().int().min(0).max(999).describe("Number of coder revisions made"),
|
|
36037
|
+
reviewer_rejections: tool.schema.number().int().min(0).max(999).describe("Number of reviewer rejections received"),
|
|
36038
|
+
loop_detections: tool.schema.number().int().min(0).max(9999).optional().describe("Number of loop detection events in this phase"),
|
|
36039
|
+
circuit_breaker_trips: tool.schema.number().int().min(0).max(9999).optional().describe("Number of circuit breaker trips in this phase"),
|
|
36040
|
+
test_failures: tool.schema.number().int().min(0).max(9999).describe("Number of test failures encountered"),
|
|
36041
|
+
security_findings: tool.schema.number().int().min(0).max(999).describe("Number of security findings"),
|
|
36042
|
+
integration_issues: tool.schema.number().int().min(0).max(999).describe("Number of integration issues"),
|
|
35849
36043
|
lessons_learned: tool.schema.array(tool.schema.string()).max(5).optional().describe("Key lessons learned from this phase (max 5)"),
|
|
35850
36044
|
top_rejection_reasons: tool.schema.array(tool.schema.string()).optional().describe("Top reasons for reviewer rejections"),
|
|
35851
36045
|
task_id: tool.schema.string().optional().describe("Optional custom task ID (defaults to retro-{phase})"),
|
|
@@ -35862,6 +36056,8 @@ var write_retro = createSwarmTool({
|
|
|
35862
36056
|
total_tool_calls: Number(args.total_tool_calls),
|
|
35863
36057
|
coder_revisions: Number(args.coder_revisions),
|
|
35864
36058
|
reviewer_rejections: Number(args.reviewer_rejections),
|
|
36059
|
+
loop_detections: args.loop_detections != null ? Number(args.loop_detections) : undefined,
|
|
36060
|
+
circuit_breaker_trips: args.circuit_breaker_trips != null ? Number(args.circuit_breaker_trips) : undefined,
|
|
35865
36061
|
test_failures: Number(args.test_failures),
|
|
35866
36062
|
security_findings: Number(args.security_findings),
|
|
35867
36063
|
integration_issues: Number(args.integration_issues),
|
|
@@ -35,3 +35,22 @@ export declare const LOW_CAPABILITY_MODELS: readonly ["mini", "nano", "small", "
|
|
|
35
35
|
* @returns true if the model is considered low capability, false otherwise
|
|
36
36
|
*/
|
|
37
37
|
export declare function isLowCapabilityModel(modelId: string): boolean;
|
|
38
|
+
export declare const SLOP_DETECTOR_DEFAULTS: {
|
|
39
|
+
readonly enabled: true;
|
|
40
|
+
readonly classThreshold: 3;
|
|
41
|
+
readonly commentStripThreshold: 5;
|
|
42
|
+
readonly diffLineThreshold: 200;
|
|
43
|
+
};
|
|
44
|
+
export declare const INCREMENTAL_VERIFY_DEFAULTS: {
|
|
45
|
+
readonly enabled: true;
|
|
46
|
+
readonly command: null;
|
|
47
|
+
readonly timeoutMs: 30000;
|
|
48
|
+
readonly triggerAgents: readonly ["coder"];
|
|
49
|
+
};
|
|
50
|
+
export declare const COMPACTION_DEFAULTS: {
|
|
51
|
+
readonly enabled: true;
|
|
52
|
+
readonly observationThreshold: 40;
|
|
53
|
+
readonly reflectionThreshold: 60;
|
|
54
|
+
readonly emergencyThreshold: 80;
|
|
55
|
+
readonly preserveLastNTurns: 5;
|
|
56
|
+
};
|
|
@@ -179,6 +179,8 @@ export declare const RetrospectiveEvidenceSchema: z.ZodObject<{
|
|
|
179
179
|
total_tool_calls: z.ZodNumber;
|
|
180
180
|
coder_revisions: z.ZodNumber;
|
|
181
181
|
reviewer_rejections: z.ZodNumber;
|
|
182
|
+
loop_detections: z.ZodOptional<z.ZodNumber>;
|
|
183
|
+
circuit_breaker_trips: z.ZodOptional<z.ZodNumber>;
|
|
182
184
|
test_failures: z.ZodNumber;
|
|
183
185
|
security_findings: z.ZodNumber;
|
|
184
186
|
integration_issues: z.ZodNumber;
|
|
@@ -547,6 +549,8 @@ export declare const EvidenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
547
549
|
total_tool_calls: z.ZodNumber;
|
|
548
550
|
coder_revisions: z.ZodNumber;
|
|
549
551
|
reviewer_rejections: z.ZodNumber;
|
|
552
|
+
loop_detections: z.ZodOptional<z.ZodNumber>;
|
|
553
|
+
circuit_breaker_trips: z.ZodOptional<z.ZodNumber>;
|
|
550
554
|
test_failures: z.ZodNumber;
|
|
551
555
|
security_findings: z.ZodNumber;
|
|
552
556
|
integration_issues: z.ZodNumber;
|
|
@@ -906,6 +910,8 @@ export declare const EvidenceBundleSchema: z.ZodObject<{
|
|
|
906
910
|
total_tool_calls: z.ZodNumber;
|
|
907
911
|
coder_revisions: z.ZodNumber;
|
|
908
912
|
reviewer_rejections: z.ZodNumber;
|
|
913
|
+
loop_detections: z.ZodOptional<z.ZodNumber>;
|
|
914
|
+
circuit_breaker_trips: z.ZodOptional<z.ZodNumber>;
|
|
909
915
|
test_failures: z.ZodNumber;
|
|
910
916
|
security_findings: z.ZodNumber;
|
|
911
917
|
integration_issues: z.ZodNumber;
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -425,6 +425,28 @@ export declare const CuratorConfigSchema: z.ZodObject<{
|
|
|
425
425
|
drift_inject_max_chars: z.ZodDefault<z.ZodNumber>;
|
|
426
426
|
}, z.core.$strip>;
|
|
427
427
|
export type CuratorConfig = z.infer<typeof CuratorConfigSchema>;
|
|
428
|
+
export declare const SlopDetectorConfigSchema: z.ZodObject<{
|
|
429
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
430
|
+
classThreshold: z.ZodDefault<z.ZodNumber>;
|
|
431
|
+
commentStripThreshold: z.ZodDefault<z.ZodNumber>;
|
|
432
|
+
diffLineThreshold: z.ZodDefault<z.ZodNumber>;
|
|
433
|
+
}, z.core.$strip>;
|
|
434
|
+
export type SlopDetectorConfig = z.infer<typeof SlopDetectorConfigSchema>;
|
|
435
|
+
export declare const IncrementalVerifyConfigSchema: z.ZodObject<{
|
|
436
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
437
|
+
command: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
438
|
+
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
439
|
+
triggerAgents: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
440
|
+
}, z.core.$strip>;
|
|
441
|
+
export type IncrementalVerifyConfig = z.infer<typeof IncrementalVerifyConfigSchema>;
|
|
442
|
+
export declare const CompactionConfigSchema: z.ZodObject<{
|
|
443
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
444
|
+
observationThreshold: z.ZodDefault<z.ZodNumber>;
|
|
445
|
+
reflectionThreshold: z.ZodDefault<z.ZodNumber>;
|
|
446
|
+
emergencyThreshold: z.ZodDefault<z.ZodNumber>;
|
|
447
|
+
preserveLastNTurns: z.ZodDefault<z.ZodNumber>;
|
|
448
|
+
}, z.core.$strip>;
|
|
449
|
+
export type CompactionConfig = z.infer<typeof CompactionConfigSchema>;
|
|
428
450
|
export declare const PluginConfigSchema: z.ZodObject<{
|
|
429
451
|
agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
430
452
|
model: z.ZodOptional<z.ZodString>;
|
|
@@ -695,6 +717,25 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
695
717
|
max_lines: z.ZodDefault<z.ZodNumber>;
|
|
696
718
|
per_tool: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
697
719
|
}, z.core.$strip>>;
|
|
720
|
+
slop_detector: z.ZodOptional<z.ZodObject<{
|
|
721
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
722
|
+
classThreshold: z.ZodDefault<z.ZodNumber>;
|
|
723
|
+
commentStripThreshold: z.ZodDefault<z.ZodNumber>;
|
|
724
|
+
diffLineThreshold: z.ZodDefault<z.ZodNumber>;
|
|
725
|
+
}, z.core.$strip>>;
|
|
726
|
+
incremental_verify: z.ZodOptional<z.ZodObject<{
|
|
727
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
728
|
+
command: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
729
|
+
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
730
|
+
triggerAgents: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
731
|
+
}, z.core.$strip>>;
|
|
732
|
+
compaction_service: z.ZodOptional<z.ZodObject<{
|
|
733
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
734
|
+
observationThreshold: z.ZodDefault<z.ZodNumber>;
|
|
735
|
+
reflectionThreshold: z.ZodDefault<z.ZodNumber>;
|
|
736
|
+
emergencyThreshold: z.ZodDefault<z.ZodNumber>;
|
|
737
|
+
preserveLastNTurns: z.ZodDefault<z.ZodNumber>;
|
|
738
|
+
}, z.core.$strip>>;
|
|
698
739
|
}, z.core.$strip>;
|
|
699
740
|
export type PluginConfig = z.infer<typeof PluginConfigSchema>;
|
|
700
741
|
export type { AgentName, PipelineAgentName, QAAgentName, } from './constants';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff scope validator — compares files changed in git against the declared scope
|
|
3
|
+
* for a given task in plan.json. Returns a warning string if undeclared files
|
|
4
|
+
* were modified, or null if in-scope, no scope declared, or git unavailable.
|
|
5
|
+
* Never throws.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Validate that git-changed files match the declared scope for a task.
|
|
9
|
+
* Returns a warning string if undeclared files were modified, null otherwise.
|
|
10
|
+
* Never throws.
|
|
11
|
+
*/
|
|
12
|
+
export declare function validateDiffScope(taskId: string, directory: string): Promise<string | null>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental verification hook — runs a typecheck after each coder Task delegation.
|
|
3
|
+
* Fires in tool.execute.after when input.tool === 'Task' and the delegated agent was 'coder'.
|
|
4
|
+
* Advisory only — never blocks. 30-second hard timeout. Uses directory from context.
|
|
5
|
+
*/
|
|
6
|
+
import type { IncrementalVerifyConfig } from '../config/schema';
|
|
7
|
+
export type { IncrementalVerifyConfig };
|
|
8
|
+
export interface IncrementalVerifyHook {
|
|
9
|
+
toolAfter: (input: {
|
|
10
|
+
tool: string;
|
|
11
|
+
sessionID: string;
|
|
12
|
+
args?: unknown;
|
|
13
|
+
}, output: {
|
|
14
|
+
output?: unknown;
|
|
15
|
+
args?: unknown;
|
|
16
|
+
}) => Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export declare function createIncrementalVerifyHook(config: IncrementalVerifyConfig, projectDir: string, injectMessage: (sessionId: string, message: string) => void): IncrementalVerifyHook;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loop detector for Task tool delegations.
|
|
3
|
+
* Tracks the last 10 delegation patterns per session using a sliding window.
|
|
4
|
+
* Detects loops when the same (toolName + targetAgent + firstArgKey) hash
|
|
5
|
+
* appears 3 or more consecutive times.
|
|
6
|
+
*/
|
|
7
|
+
export interface LoopDetectResult {
|
|
8
|
+
looping: boolean;
|
|
9
|
+
count: number;
|
|
10
|
+
pattern: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Detect delegation loops for a session.
|
|
14
|
+
* Only tracks Task tool calls (agent delegations).
|
|
15
|
+
* Returns the current loop state after recording this call.
|
|
16
|
+
*/
|
|
17
|
+
export declare function detectLoop(sessionId: string, toolName: string, args: unknown): LoopDetectResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slop detector — PostToolUse hook that checks for AI code quality anti-patterns.
|
|
3
|
+
* Fires after Write and Edit tool calls. Runs 4 heuristics and emits an advisory
|
|
4
|
+
* system message when findings are detected. Non-blocking, <500ms.
|
|
5
|
+
*/
|
|
6
|
+
import type { SlopDetectorConfig } from '../config/schema';
|
|
7
|
+
export type { SlopDetectorConfig };
|
|
8
|
+
export interface SlopDetectorHook {
|
|
9
|
+
toolAfter: (input: {
|
|
10
|
+
tool: string;
|
|
11
|
+
sessionID: string;
|
|
12
|
+
}, output: {
|
|
13
|
+
output?: unknown;
|
|
14
|
+
args?: unknown;
|
|
15
|
+
}) => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare function createSlopDetectorHook(config: SlopDetectorConfig, projectDir: string, injectSystemMessage: (sessionId: string, message: string) => void): SlopDetectorHook;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|