opencode-swarm 7.113.4 → 7.114.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/.opencode/skills/test-file-split/SKILL.md +1 -1
- package/.opencode/skills/writing-tests/SKILL.md +1 -1
- package/dist/cli/{curator-llm-factory-b3g0g0cd.js → curator-llm-factory-awp6xgvt.js} +1 -1
- package/dist/cli/{curator-nh9raf1a.js → curator-wvv628sv.js} +1 -1
- package/dist/cli/{guardrail-explain-wpv5eskq.js → guardrail-explain-hhdtrm60.js} +2 -2
- package/dist/cli/{hive-promoter-c0fd3j02.js → hive-promoter-1qkybw79.js} +1 -1
- package/dist/cli/{index-10v7hrkj.js → index-jhdv0jdf.js} +1 -1
- package/dist/cli/{index-5yzr9fk6.js → index-p35ayncy.js} +2 -2
- package/dist/cli/{index-ct9e0y0q.js → index-zezjy05g.js} +51 -14
- package/dist/cli/index.js +1 -1
- package/dist/config/skill-mirrors.d.ts +13 -3
- package/dist/full-auto/state.d.ts +26 -0
- package/dist/index.js +6 -6
- package/dist/services/status-service.d.ts +16 -1
- package/dist/state.d.ts +9 -0
- package/dist/tools/create-tool.d.ts +9 -0
- package/package.json +2 -1
- package/dist/output/agent-writer.d.ts +0 -27
- package/dist/output/index.d.ts +0 -1
- package/dist/tools/knowledge-ack.d.ts +0 -15
|
@@ -6,7 +6,7 @@ description: Protocol for splitting test files that exceed the FR-006 500-line h
|
|
|
6
6
|
|
|
7
7
|
# Test File Split Protocol (FR-006)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
`scripts/check-test-file-cap.sh` enforces the **500-line cap** per test file (FR-006 / SC-006.1) as a **diff-scoped ratchet**: new test files over 500 lines and existing over-cap files that grew fail the quality gate and block PR merge. Pre-existing over-cap files not touched by the PR are non-blocking. Escape hatch: `TEST_CAP_ENFORCE=0` soft-warns. This skill covers the complete splitting protocol.
|
|
10
10
|
|
|
11
11
|
Read first: `.opencode/skills/writing-tests/SKILL.md` (or `.claude/skills/writing-tests/SKILL.md`) for bun:test framework rules, mock isolation patterns, and file placement conventions.
|
|
12
12
|
|
|
@@ -613,7 +613,7 @@ authority checks:
|
|
|
613
613
|
|
|
614
614
|
## FR-006: Test File Size Limit (500 lines)
|
|
615
615
|
|
|
616
|
-
|
|
616
|
+
`scripts/check-test-file-cap.sh` enforces the **500-line cap** per test file (FR-006) as a **diff-scoped ratchet**: new test files over 500 lines and existing over-cap files that grew fail the quality gate and block PR merge. Pre-existing over-cap files not touched by the PR are non-blocking. Escape hatch: `TEST_CAP_ENFORCE=0` soft-warns (use only for a deliberate growth PR).
|
|
617
617
|
|
|
618
618
|
### Checking file length
|
|
619
619
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
4
|
+
} from "./index-jhdv0jdf.js";
|
|
5
|
+
import"./index-zezjy05g.js";
|
|
6
6
|
import"./index-g6va6n3t.js";
|
|
7
7
|
import"./index-c8s9a3zh.js";
|
|
8
8
|
import"./index-2148358e.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-jhdv0jdf.js";
|
|
5
5
|
import {
|
|
6
6
|
handleGuardrailLog
|
|
7
7
|
} from "./index-xbe1wtme.js";
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
handleWriteRetroCommand,
|
|
82
82
|
normalizeSwarmCommandInput,
|
|
83
83
|
resolveCommand
|
|
84
|
-
} from "./index-
|
|
84
|
+
} from "./index-zezjy05g.js";
|
|
85
85
|
import"./index-g6va6n3t.js";
|
|
86
86
|
import"./index-c8s9a3zh.js";
|
|
87
87
|
import"./index-2148358e.js";
|
|
@@ -10432,11 +10432,11 @@ var _internals12 = {
|
|
|
10432
10432
|
return KnowledgeConfigSchema2.parse({});
|
|
10433
10433
|
},
|
|
10434
10434
|
applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig) => {
|
|
10435
|
-
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-
|
|
10435
|
+
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-wvv628sv.js");
|
|
10436
10436
|
return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig);
|
|
10437
10437
|
},
|
|
10438
10438
|
checkHivePromotions: async (entries, knowledgeConfig) => {
|
|
10439
|
-
const { checkHivePromotions } = await import("./hive-promoter-
|
|
10439
|
+
const { checkHivePromotions } = await import("./hive-promoter-1qkybw79.js");
|
|
10440
10440
|
return checkHivePromotions(entries, knowledgeConfig);
|
|
10441
10441
|
},
|
|
10442
10442
|
applyProposalTriage: async (directory, triage) => {
|
|
@@ -17586,8 +17586,8 @@ var _internals24 = {
|
|
|
17586
17586
|
loadCuratorDeps: async () => {
|
|
17587
17587
|
const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
|
|
17588
17588
|
import("./schema-e5kd993s.js"),
|
|
17589
|
-
import("./curator-
|
|
17590
|
-
import("./curator-llm-factory-
|
|
17589
|
+
import("./curator-wvv628sv.js"),
|
|
17590
|
+
import("./curator-llm-factory-awp6xgvt.js")
|
|
17591
17591
|
]);
|
|
17592
17592
|
return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
|
|
17593
17593
|
}
|
|
@@ -18083,7 +18083,7 @@ import { fileURLToPath } from "url";
|
|
|
18083
18083
|
// package.json
|
|
18084
18084
|
var package_default = {
|
|
18085
18085
|
name: "opencode-swarm",
|
|
18086
|
-
version: "7.
|
|
18086
|
+
version: "7.114.0",
|
|
18087
18087
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
18088
18088
|
main: "dist/index.js",
|
|
18089
18089
|
types: "dist/index.d.ts",
|
|
@@ -18177,6 +18177,7 @@ var package_default = {
|
|
|
18177
18177
|
"lint:ci": "biome ci .",
|
|
18178
18178
|
"test:unit:ci": "bun scripts/ci/run-unit-tests-local.ts",
|
|
18179
18179
|
"drift:check": "bun run scripts/drift-check.ts",
|
|
18180
|
+
"drift:fix": "bun run scripts/drift-check.ts --fix --confirm",
|
|
18180
18181
|
format: "biome format . --write",
|
|
18181
18182
|
check: "biome check --write .",
|
|
18182
18183
|
dev: "bun run build && opencode",
|
|
@@ -32211,7 +32212,9 @@ var DEFAULT_CONTEXT_BUDGET_CONFIG = {
|
|
|
32211
32212
|
var _internals47 = {
|
|
32212
32213
|
loadLeanTurboRunState,
|
|
32213
32214
|
hasActiveLeanTurbo,
|
|
32214
|
-
hasActiveFullAuto
|
|
32215
|
+
hasActiveFullAuto,
|
|
32216
|
+
getActiveFullAutoSessionID,
|
|
32217
|
+
loadFullAutoRunState
|
|
32215
32218
|
};
|
|
32216
32219
|
function readSpecStalenessSnapshot(directory) {
|
|
32217
32220
|
try {
|
|
@@ -32309,6 +32312,21 @@ async function getStatusData(directory, agents) {
|
|
|
32309
32312
|
status.pendingProposals = await countProposals(directory);
|
|
32310
32313
|
status.unactionableQueueDepth = await safeLineCount(resolveUnactionablePath(directory));
|
|
32311
32314
|
status.insightCandidatesPending = await safeLineCount(validateSwarmPath(directory, "insight-candidates.jsonl"));
|
|
32315
|
+
status.fullAutoActive = _internals47.hasActiveFullAuto();
|
|
32316
|
+
if (status.fullAutoActive) {
|
|
32317
|
+
const sid = _internals47.getActiveFullAutoSessionID();
|
|
32318
|
+
if (sid) {
|
|
32319
|
+
const runState = _internals47.loadFullAutoRunState(directory, sid);
|
|
32320
|
+
if (runState?.lastEscalation) {
|
|
32321
|
+
status.fullAutoEscalation = {
|
|
32322
|
+
reason: runState.lastEscalation.reason,
|
|
32323
|
+
interactionCount: runState.lastEscalation.interactionCount,
|
|
32324
|
+
deadlockCount: runState.lastEscalation.deadlockCount,
|
|
32325
|
+
phase: runState.lastEscalation.phase
|
|
32326
|
+
};
|
|
32327
|
+
}
|
|
32328
|
+
}
|
|
32329
|
+
}
|
|
32312
32330
|
return enrichWithLeanTurbo(status, directory);
|
|
32313
32331
|
}
|
|
32314
32332
|
function enrichWithLeanTurbo(status, directory) {
|
|
@@ -32364,7 +32382,6 @@ function enrichWithLeanTurbo(status, directory) {
|
|
|
32364
32382
|
}
|
|
32365
32383
|
}
|
|
32366
32384
|
}
|
|
32367
|
-
status.fullAutoActive = _internals47.hasActiveFullAuto();
|
|
32368
32385
|
return status;
|
|
32369
32386
|
}
|
|
32370
32387
|
function formatStatusMarkdown(status) {
|
|
@@ -32405,13 +32422,19 @@ function formatStatusMarkdown(status) {
|
|
|
32405
32422
|
} else {
|
|
32406
32423
|
lines.push(`**Turbo**: standard`);
|
|
32407
32424
|
}
|
|
32408
|
-
if (status.fullAutoActive) {
|
|
32409
|
-
lines.push(`**Full-Auto**: active`);
|
|
32410
|
-
}
|
|
32411
32425
|
} else if (status.turboStrategy === undefined && status.turboMode === true) {
|
|
32412
32426
|
lines.push("");
|
|
32413
32427
|
lines.push("**TURBO MODE**: active");
|
|
32414
32428
|
}
|
|
32429
|
+
if (status.fullAutoActive) {
|
|
32430
|
+
lines.push("");
|
|
32431
|
+
lines.push("**Full-Auto**: active");
|
|
32432
|
+
if (status.fullAutoEscalation) {
|
|
32433
|
+
const e = status.fullAutoEscalation;
|
|
32434
|
+
const phaseStr = e.phase !== undefined ? ` | Phase ${e.phase}` : "";
|
|
32435
|
+
lines.push(` - Escalation: ${e.reason} (interactions=${e.interactionCount}, deadlocks=${e.deadlockCount}${phaseStr})`);
|
|
32436
|
+
}
|
|
32437
|
+
}
|
|
32415
32438
|
if (status.contextBudgetPct !== null && status.contextBudgetPct > 0) {
|
|
32416
32439
|
const pct = status.contextBudgetPct.toFixed(1);
|
|
32417
32440
|
const budgetTokens = DEFAULT_CONTEXT_BUDGET_CONFIG.budgetTokens;
|
|
@@ -32949,7 +32972,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
32949
32972
|
async function handleHelpCommand(ctx) {
|
|
32950
32973
|
const targetCommand = ctx.args.join(" ");
|
|
32951
32974
|
if (!targetCommand) {
|
|
32952
|
-
const { buildHelpText } = await import("./index-
|
|
32975
|
+
const { buildHelpText } = await import("./index-p35ayncy.js");
|
|
32953
32976
|
return buildHelpText();
|
|
32954
32977
|
}
|
|
32955
32978
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -32958,7 +32981,7 @@ async function handleHelpCommand(ctx) {
|
|
|
32958
32981
|
return _internals49.buildDetailedHelp(resolved.key, resolved.entry);
|
|
32959
32982
|
}
|
|
32960
32983
|
const similar = _internals49.findSimilarCommands(targetCommand);
|
|
32961
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
32984
|
+
const { buildHelpText: fullHelp } = await import("./index-p35ayncy.js");
|
|
32962
32985
|
if (similar.length > 0) {
|
|
32963
32986
|
return `Command '/swarm ${targetCommand}' not found.
|
|
32964
32987
|
|
|
@@ -33091,7 +33114,7 @@ var COMMAND_REGISTRY = {
|
|
|
33091
33114
|
},
|
|
33092
33115
|
"guardrail explain": {
|
|
33093
33116
|
handler: async (ctx) => {
|
|
33094
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
33117
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-hhdtrm60.js");
|
|
33095
33118
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
33096
33119
|
},
|
|
33097
33120
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -33101,7 +33124,7 @@ var COMMAND_REGISTRY = {
|
|
|
33101
33124
|
},
|
|
33102
33125
|
"guardrail-explain": {
|
|
33103
33126
|
handler: async (ctx) => {
|
|
33104
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
33127
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-hhdtrm60.js");
|
|
33105
33128
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
33106
33129
|
},
|
|
33107
33130
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -39053,6 +39076,20 @@ function hasActiveFullAuto(sessionID) {
|
|
|
39053
39076
|
}
|
|
39054
39077
|
return false;
|
|
39055
39078
|
}
|
|
39079
|
+
function getActiveFullAutoSessionID() {
|
|
39080
|
+
let activeId;
|
|
39081
|
+
let activeLastToolCall = -1;
|
|
39082
|
+
for (const [id, session] of swarmState.agentSessions) {
|
|
39083
|
+
if (session.fullAutoMode !== true)
|
|
39084
|
+
continue;
|
|
39085
|
+
const lastToolCall = session.lastToolCallTime ?? 0;
|
|
39086
|
+
if (activeId === undefined || lastToolCall > activeLastToolCall) {
|
|
39087
|
+
activeId = id;
|
|
39088
|
+
activeLastToolCall = lastToolCall;
|
|
39089
|
+
}
|
|
39090
|
+
}
|
|
39091
|
+
return activeId;
|
|
39092
|
+
}
|
|
39056
39093
|
function hasActiveLeanTurbo(sessionID) {
|
|
39057
39094
|
if (sessionID) {
|
|
39058
39095
|
const session = swarmState.agentSessions.get(sessionID);
|
package/dist/cli/index.js
CHANGED
|
@@ -14,10 +14,20 @@
|
|
|
14
14
|
* Architect MODE skills whose `.opencode` and `.claude` mirrors must be
|
|
15
15
|
* byte-identical. `.opencode` is the operative protocol loaded by
|
|
16
16
|
* `src/agents/architect.ts` MODE stubs; the `.claude` mirror must match so
|
|
17
|
-
* Claude Code and OpenCode sessions cannot diverge silently.
|
|
18
|
-
*
|
|
17
|
+
* Claude Code and OpenCode sessions cannot diverge silently.
|
|
18
|
+
*
|
|
19
|
+
* `canonical` records which side wins when they drift (fix direction only;
|
|
20
|
+
* detection is symmetric). For architect MODE skills `.opencode` is always
|
|
21
|
+
* canonical because it is the operative protocol the MODE stubs load. Issue
|
|
22
|
+
* #1781 E3 added this field so `drift:fix` can copy the canonical side to the
|
|
23
|
+
* mirror without guessing.
|
|
19
24
|
*/
|
|
20
|
-
export declare const MIRRORED_ARCHITECT_MODE_SKILLS:
|
|
25
|
+
export declare const MIRRORED_ARCHITECT_MODE_SKILLS: Array<{
|
|
26
|
+
slug: string;
|
|
27
|
+
opencodePath: string;
|
|
28
|
+
claudePath: string;
|
|
29
|
+
canonical: '.opencode' | '.claude';
|
|
30
|
+
}>;
|
|
21
31
|
/**
|
|
22
32
|
* Architect MODE skills where `.opencode` is the full operative protocol and
|
|
23
33
|
* `.claude` is an intentionally different surface. Both must exist; byte
|
|
@@ -37,6 +37,19 @@ export interface FullAutoRunState {
|
|
|
37
37
|
terminateReason?: string;
|
|
38
38
|
/** Consecutive oversight dispatch failures for auto-degrade. */
|
|
39
39
|
consecutiveOversightFailures?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Issue #1781 E2: the most recent oversight-escalation detail, persisted so
|
|
42
|
+
* `/swarm status` can surface the reason + interaction/deadlock counts +
|
|
43
|
+
* phase without parsing the human-readable `.swarm/escalation-report.md`.
|
|
44
|
+
* Updated atomically by `recordFullAutoEscalation` at escalation time.
|
|
45
|
+
*/
|
|
46
|
+
lastEscalation?: {
|
|
47
|
+
reason: string;
|
|
48
|
+
interactionCount: number;
|
|
49
|
+
deadlockCount: number;
|
|
50
|
+
phase?: number;
|
|
51
|
+
escalatedAt: string;
|
|
52
|
+
};
|
|
40
53
|
}
|
|
41
54
|
export interface FullAutoPersistedState {
|
|
42
55
|
version: 2;
|
|
@@ -129,6 +142,19 @@ export declare function resetFullAutoDenials(directory: string, sessionID: strin
|
|
|
129
142
|
*/
|
|
130
143
|
export declare function nextFullAutoOversightSequence(directory: string): number;
|
|
131
144
|
export declare function recordFullAutoOversight(directory: string, sessionID: string, verdict: string, reason: string): FullAutoRunState | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Issue #1781 E2: persist the most recent oversight-escalation detail
|
|
147
|
+
* (reason, interaction/deadlock counts, phase) to the durable run state so
|
|
148
|
+
* `/swarm status` can surface it. Called from `handleEscalation` in
|
|
149
|
+
* `src/hooks/full-auto-intercept.ts` alongside the existing pause/terminate
|
|
150
|
+
* state writes — those writes spread `...state`, so this field survives them.
|
|
151
|
+
*/
|
|
152
|
+
export declare function recordFullAutoEscalation(directory: string, sessionID: string, detail: {
|
|
153
|
+
reason: string;
|
|
154
|
+
interactionCount: number;
|
|
155
|
+
deadlockCount: number;
|
|
156
|
+
phase?: number;
|
|
157
|
+
}): FullAutoRunState | undefined;
|
|
132
158
|
export interface DenialLimitDecision {
|
|
133
159
|
pause: boolean;
|
|
134
160
|
reason?: string;
|