opencode-swarm 7.132.1 → 7.132.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/skills/swarm-pr-review/SKILL.md +15 -5
- package/dist/cli/{curator-28hcw9hx.js → curator-h067mrcc.js} +1 -1
- package/dist/cli/{curator-llm-factory-rd0s95fw.js → curator-llm-factory-605d08hf.js} +1 -1
- package/dist/cli/{guardrail-explain-742dhpec.js → guardrail-explain-s7vzm6z7.js} +2 -2
- package/dist/cli/{hive-promoter-8whgvcry.js → hive-promoter-nv0m5rzk.js} +1 -1
- package/dist/cli/{index-x3p6ktva.js → index-8d3m0ge3.js} +2 -2
- package/dist/cli/{index-b21a4zw4.js → index-f6480ee6.js} +9 -9
- package/dist/cli/{index-4hapy63e.js → index-k4tmx21m.js} +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/hooks/guardrails/index.d.ts +32 -0
- package/dist/hooks/guardrails/messages-transform.d.ts +7 -0
- package/dist/hooks/guardrails.d.ts +1 -1
- package/dist/hooks/pr-workflow-response-gate.d.ts +44 -26
- package/dist/index.js +13 -13
- package/package.json +1 -1
|
@@ -173,7 +173,9 @@ Exception: in explicit Council mode only, the main thread may act as the indepen
|
|
|
173
173
|
Determine review scope using this priority:
|
|
174
174
|
|
|
175
175
|
1. explicit user-provided PR URL, PR number, commit, branch, or file scope,
|
|
176
|
-
2. current feature branch diff vs
|
|
176
|
+
2. current feature branch diff vs the remote-tracking base ref (`origin/main`,
|
|
177
|
+
`origin/master`; a local `main`/`master` only as a last resort — it is only as
|
|
178
|
+
fresh as the last fetch and yields a different merge base),
|
|
177
179
|
3. staged changes,
|
|
178
180
|
4. latest commit,
|
|
179
181
|
5. user-specified files or directories.
|
|
@@ -211,6 +213,11 @@ Before launching explorers (Phase 3), perform this exact standalone sequence:
|
|
|
211
213
|
`git stash` through shell.
|
|
212
214
|
3. Fetch the PR head as one standalone command, for example
|
|
213
215
|
`git fetch origin refs/pull/<N>/head`. Do not compose fetch and checkout.
|
|
216
|
+
3a. Fetch the base branch as its own standalone command, for example
|
|
217
|
+
`git fetch origin main`. Skipping this is the single most common cause of a
|
|
218
|
+
rejected dispatch: the merge base is recomputed against `base_ref`, and a
|
|
219
|
+
local `main`/`refs/heads/main` that was never refreshed resolves to a
|
|
220
|
+
different commit than `origin/main` for the same `base_sha`.
|
|
214
221
|
4. Prove the full commit exists locally with
|
|
215
222
|
`git cat-file -e <full_pr_head_sha>^{commit}`.
|
|
216
223
|
5. Check out the exact PR filesystem with
|
|
@@ -775,8 +782,10 @@ Under Profile A, launch all base lanes with `dispatch_lanes_async`. Pass the six
|
|
|
775
782
|
lane specs together, set `mode: "swarm-pr-review:base"`, assign each lane its
|
|
776
783
|
exact `workflow_lane` identifier from the table below, set `max_concurrent` to
|
|
777
784
|
`6`, bind the batch with the exact current `pr_head_sha`, record the returned
|
|
778
|
-
`batch_id`, and pass the exact reviewed merge base and its
|
|
779
|
-
`base_sha` and `base_ref`.
|
|
785
|
+
`batch_id`, and pass the exact reviewed merge base and its base ref as
|
|
786
|
+
`base_sha` and `base_ref`. Use the REMOTE-TRACKING form for `base_ref`
|
|
787
|
+
(`origin/main`, not `main` or `refs/heads/main`) and compute `base_sha` against
|
|
788
|
+
that same ref, so the controller's recomputation matches yours. Every later base retry, micro, council, reviewer, and
|
|
780
789
|
critic dispatch repeats those same exact bindings. The controller recomputes
|
|
781
790
|
`git merge-base -- <base_ref> <pr_head_sha>`, rejects mismatches, and replaces
|
|
782
791
|
caller `scope` text with the complete verified `base_sha...pr_head_sha` PR diff;
|
|
@@ -1683,8 +1692,9 @@ mode `PR_REVIEW` and the same exact
|
|
|
1683
1692
|
`pr_head_sha`. The tool refuses to clear the session gate while required base,
|
|
1684
1693
|
trigger, declared reviewer/critic, or open-lane obligations remain incomplete.
|
|
1685
1694
|
While the gate remains active, the runtime prepends a workflow-active banner
|
|
1686
|
-
to
|
|
1687
|
-
|
|
1695
|
+
to the first substantive text part of each architect message (the model's text
|
|
1696
|
+
is preserved below the banner; later parts of the same message, and blank
|
|
1697
|
+
parts, are left untouched) and re-wakes an idle parent session. A
|
|
1688
1698
|
user interruption pauses every automatic wake path until a later explicit user
|
|
1689
1699
|
turn settles; the durable gate remains available to continue or abort. Only
|
|
1690
1700
|
emit the final report after the completion tool confirms that the gate cleared.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
4
|
+
} from "./index-k4tmx21m.js";
|
|
5
|
+
import"./index-f6480ee6.js";
|
|
6
6
|
import"./index-yvv1wt2h.js";
|
|
7
7
|
import"./index-630badhp.js";
|
|
8
8
|
import"./index-03zyn94g.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-k4tmx21m.js";
|
|
5
5
|
import {
|
|
6
6
|
handleGuardrailLog
|
|
7
7
|
} from "./index-fgcmxjp7.js";
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
handleWriteRetroCommand,
|
|
84
84
|
normalizeSwarmCommandInput,
|
|
85
85
|
resolveCommand
|
|
86
|
-
} from "./index-
|
|
86
|
+
} from "./index-f6480ee6.js";
|
|
87
87
|
import"./index-yvv1wt2h.js";
|
|
88
88
|
import"./index-630badhp.js";
|
|
89
89
|
import"./index-03zyn94g.js";
|
|
@@ -16810,11 +16810,11 @@ var _internals22 = {
|
|
|
16810
16810
|
}
|
|
16811
16811
|
},
|
|
16812
16812
|
applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
|
|
16813
|
-
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-
|
|
16813
|
+
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-h067mrcc.js");
|
|
16814
16814
|
return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
|
|
16815
16815
|
},
|
|
16816
16816
|
checkHivePromotions: async (entries, knowledgeConfig, directory) => {
|
|
16817
|
-
const { checkHivePromotions } = await import("./hive-promoter-
|
|
16817
|
+
const { checkHivePromotions } = await import("./hive-promoter-nv0m5rzk.js");
|
|
16818
16818
|
return checkHivePromotions(entries, knowledgeConfig, directory);
|
|
16819
16819
|
},
|
|
16820
16820
|
applyProposalTriage: async (directory, triage) => {
|
|
@@ -24916,8 +24916,8 @@ var _internals36 = {
|
|
|
24916
24916
|
loadCuratorDeps: async () => {
|
|
24917
24917
|
const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
|
|
24918
24918
|
import("./schema-023gwne7.js"),
|
|
24919
|
-
import("./curator-
|
|
24920
|
-
import("./curator-llm-factory-
|
|
24919
|
+
import("./curator-h067mrcc.js"),
|
|
24920
|
+
import("./curator-llm-factory-605d08hf.js")
|
|
24921
24921
|
]);
|
|
24922
24922
|
return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
|
|
24923
24923
|
}
|
|
@@ -25422,7 +25422,7 @@ import { fileURLToPath } from "url";
|
|
|
25422
25422
|
// package.json
|
|
25423
25423
|
var package_default = {
|
|
25424
25424
|
name: "opencode-swarm",
|
|
25425
|
-
version: "7.132.
|
|
25425
|
+
version: "7.132.2",
|
|
25426
25426
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
25427
25427
|
main: "dist/index.js",
|
|
25428
25428
|
types: "dist/index.d.ts",
|
|
@@ -45957,7 +45957,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
45957
45957
|
async function handleHelpCommand(ctx) {
|
|
45958
45958
|
const targetCommand = ctx.args.join(" ");
|
|
45959
45959
|
if (!targetCommand) {
|
|
45960
|
-
const { buildHelpText } = await import("./index-
|
|
45960
|
+
const { buildHelpText } = await import("./index-8d3m0ge3.js");
|
|
45961
45961
|
return buildHelpText();
|
|
45962
45962
|
}
|
|
45963
45963
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -45966,7 +45966,7 @@ async function handleHelpCommand(ctx) {
|
|
|
45966
45966
|
return _internals9.buildDetailedHelp(resolved.key, resolved.entry);
|
|
45967
45967
|
}
|
|
45968
45968
|
const similar = _internals9.findSimilarCommands(targetCommand);
|
|
45969
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
45969
|
+
const { buildHelpText: fullHelp } = await import("./index-8d3m0ge3.js");
|
|
45970
45970
|
if (similar.length > 0) {
|
|
45971
45971
|
return `Command '/swarm ${targetCommand}' not found.
|
|
45972
45972
|
|
|
@@ -46105,7 +46105,7 @@ var COMMAND_REGISTRY = {
|
|
|
46105
46105
|
},
|
|
46106
46106
|
"guardrail explain": {
|
|
46107
46107
|
handler: async (ctx) => {
|
|
46108
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
46108
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-s7vzm6z7.js");
|
|
46109
46109
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
46110
46110
|
},
|
|
46111
46111
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -46115,7 +46115,7 @@ var COMMAND_REGISTRY = {
|
|
|
46115
46115
|
},
|
|
46116
46116
|
"guardrail-explain": {
|
|
46117
46117
|
handler: async (ctx) => {
|
|
46118
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
46118
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-s7vzm6z7.js");
|
|
46119
46119
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
46120
46120
|
},
|
|
46121
46121
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
package/dist/cli/index.js
CHANGED
|
@@ -19,6 +19,13 @@ export declare const _internals: {
|
|
|
19
19
|
resolveFallbackModel: typeof resolveFallbackModel;
|
|
20
20
|
dcCheckJunctionCreation: typeof dcCheckJunctionCreation;
|
|
21
21
|
extractErrorSignal: typeof extractErrorSignal;
|
|
22
|
+
/**
|
|
23
|
+
* Test/inspection seams for the no-op detector's bounded session state
|
|
24
|
+
* (invariant 8). Production code does not call these; they exist so the
|
|
25
|
+
* eviction bound can be asserted without exporting the maps themselves.
|
|
26
|
+
*/
|
|
27
|
+
noOpStateSize: () => number;
|
|
28
|
+
hasNoOpState: (sessionID: string) => boolean;
|
|
22
29
|
};
|
|
23
30
|
/**
|
|
24
31
|
* Issue #853 Layer B: tools that are structurally blocked while
|
|
@@ -36,6 +43,31 @@ export declare function enforceSpecDriftGate(directory: string | undefined, tool
|
|
|
36
43
|
* Extracts bounded provider/error signal from unknown hook error payloads.
|
|
37
44
|
*/
|
|
38
45
|
declare function extractErrorSignal(errorContent: unknown): string;
|
|
46
|
+
/**
|
|
47
|
+
* v6.33.1: No-op work detector state.
|
|
48
|
+
*
|
|
49
|
+
* AGENTS.md invariant 8: module-level, session-keyed state must have an explicit
|
|
50
|
+
* eviction strategy. Both containers below are keyed by `sessionID` and were
|
|
51
|
+
* previously unbounded — they grew for the lifetime of the plugin process, since
|
|
52
|
+
* nothing removed a key when a session ended. `noOpWarningIssued` was only ever
|
|
53
|
+
* `delete`d on a reset, and `toolCallsSinceLastWrite` never shrank at all.
|
|
54
|
+
*
|
|
55
|
+
* Bounded LRU, evicting the LEAST-RECENTLY-TOUCHED session.
|
|
56
|
+
*
|
|
57
|
+
* Plain insertion-order (FIFO) eviction is wrong here and actively harmful.
|
|
58
|
+
* `Map.set()` on an EXISTING key does not move it, so the first session created
|
|
59
|
+
* in the process stays permanently at the front of the iteration order. In an
|
|
60
|
+
* OpenCode plugin process that first session is the architect — the very session
|
|
61
|
+
* this detector exists to watch — making it the guaranteed first eviction victim
|
|
62
|
+
* while a session touched once and abandoned later survives. Measured: with a
|
|
63
|
+
* FIFO bound, an architect climbing toward the threshold had its counter evicted
|
|
64
|
+
* and reset mid-climb, and its 15th consecutive no-write call produced ZERO
|
|
65
|
+
* warnings. A bound must not silence the detector it was added to protect.
|
|
66
|
+
*
|
|
67
|
+
* {@link touchNoOpSession} therefore deletes before setting, moving the key to
|
|
68
|
+
* the back on every touch, so eviction genuinely targets quiet sessions.
|
|
69
|
+
*/
|
|
70
|
+
export declare const MAX_TRACKED_NO_OP_SESSIONS = 200;
|
|
39
71
|
/**
|
|
40
72
|
* Redacts sensitive values from a shell command string before audit logging.
|
|
41
73
|
* Single-sourced from ./helpers (which additionally redacts home paths).
|
|
@@ -32,6 +32,13 @@ type ChatMessageLike = {
|
|
|
32
32
|
text?: unknown;
|
|
33
33
|
}>;
|
|
34
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Shared by the runaway-output advisory's TEXT and its once-per-drain dedupe
|
|
37
|
+
* predicate, so the two can never drift apart again. They previously did: the
|
|
38
|
+
* predicate tested for the string 'runaway output', which the pushed message
|
|
39
|
+
* never contained, making the guard permanently inert.
|
|
40
|
+
*/
|
|
41
|
+
export declare const RUNAWAY_OUTPUT_ADVISORY_MARKER = "Model is generating analysis without taking action";
|
|
35
42
|
export declare function getMostRecentAssistantText(messages: ChatMessageLike[]): string;
|
|
36
43
|
export declare function isTransientProviderFailureText(text: string): boolean;
|
|
37
44
|
export declare function getProviderFailureFingerprint(text: string): string;
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* - Layer 2 (Hard Block @ 100%): Throws error in toolBefore to block further calls, injects STOP message
|
|
11
11
|
*/
|
|
12
12
|
export { type AgentRule, type AttestationRecord, buildEffectiveRules, checkFileAuthority, checkFileAuthorityWithRules, checkWriteTargetForSymlink, clearGuardrailsCaches, DEFAULT_AGENT_AUTHORITY_RULES, getGlobMatcher, hashArgs, isOnDifferentFilesystemRoot, normalizePathWithCache, recordAttestation, validateAndRecordAttestation, validateAttestation, } from './guardrails/file-authority';
|
|
13
|
-
export { _internals, createGuardrailsHooks, enforceSpecDriftGate, redactShellCommand, SPEC_DRIFT_BLOCKED_TOOLS, } from './guardrails/index';
|
|
13
|
+
export { _internals, createGuardrailsHooks, enforceSpecDriftGate, MAX_TRACKED_NO_OP_SESSIONS, redactShellCommand, SPEC_DRIFT_BLOCKED_TOOLS, } from './guardrails/index';
|
|
14
14
|
export { deleteStoredInputArgs, getStoredInputArgs, setStoredInputArgs, } from './guardrails/stored-input-args';
|
|
@@ -26,26 +26,38 @@ export declare const DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES = 5;
|
|
|
26
26
|
*/
|
|
27
27
|
export declare const DEFAULT_WAKE_COOLDOWN_MS = 30000;
|
|
28
28
|
/**
|
|
29
|
-
* Minimum time between FULL workflow banners
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* short one-line marker is prepended instead; the full banner (and its
|
|
35
|
-
* suspension/interruption recovery notices) returns once the cooldown elapses.
|
|
29
|
+
* Minimum time between FULL workflow banners for a single session. The banner
|
|
30
|
+
* is injected at most once per assistant MESSAGE (see the `banneredMessages`
|
|
31
|
+
* map in {@link createPrWorkflowResponseGate}); this cooldown only chooses
|
|
32
|
+
* whether that one injection is the full multi-line banner or the short
|
|
33
|
+
* one-line marker.
|
|
36
34
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* invariant-10 operational notices that must appear in full on every part.
|
|
35
|
+
* Suspended and user-interrupted states BYPASS the cooldown: those are
|
|
36
|
+
* invariant-10 operational notices that must not be downgraded to the short
|
|
37
|
+
* marker. They are still subject to the per-message dedupe — "always visible"
|
|
38
|
+
* means visible on every user-facing turn, not repeated on every part of it.
|
|
42
39
|
* Overridable via `createPrWorkflowResponseGate({ bannerCooldownMs })`.
|
|
43
40
|
*/
|
|
44
41
|
export declare const DEFAULT_BANNER_COOLDOWN_MS = 20000;
|
|
42
|
+
/**
|
|
43
|
+
* Absolute per-session injection ceiling used ONLY when the host does not
|
|
44
|
+
* supply `messageID`. The pinned host contract
|
|
45
|
+
* (`@opencode-ai/plugin` `index.d.ts`: `experimental.text.complete` receives
|
|
46
|
+
* `{ sessionID, messageID, partID }`, all required) always supplies it, so this
|
|
47
|
+
* path is defensive. Without a ceiling, a host that omitted `messageID` would
|
|
48
|
+
* fall back to the wall-clock window alone — which is exactly the behavior that
|
|
49
|
+
* produced the measured flood (968 marker-only lines, 55.3% of a real review
|
|
50
|
+
* transcript), because a cooldown only downgrades an injection, it never
|
|
51
|
+
* suppresses one.
|
|
52
|
+
*/
|
|
53
|
+
export declare const MAX_FALLBACK_BANNER_INJECTIONS_PER_SESSION = 20;
|
|
45
54
|
/**
|
|
46
55
|
* Bounded FIFO map of tracked wake budgets. Invariant 8 (session/global
|
|
47
|
-
* state): module-level state must have an explicit eviction strategy.
|
|
48
|
-
*
|
|
56
|
+
* state): module-level state must have an explicit eviction strategy. Three
|
|
57
|
+
* further per-session maps share this same bound and the same FIFO discipline:
|
|
58
|
+
* `bannerStamps` (instant of the last full banner), `banneredMessages` (the
|
|
59
|
+
* assistant message already carrying a banner), and `fallbackInjections` (the
|
|
60
|
+
* injection count on the messageID-less path).
|
|
49
61
|
*/
|
|
50
62
|
export declare const MAX_TRACKED_WAKE_SESSIONS = 200;
|
|
51
63
|
interface PrWorkflowResponseGateClient {
|
|
@@ -59,19 +71,23 @@ interface WakeBudget {
|
|
|
59
71
|
}
|
|
60
72
|
/**
|
|
61
73
|
* Prevent an architect from masquerading a premature text output as a terminal
|
|
62
|
-
* verdict. The text-complete hook prepends a workflow-active banner to
|
|
63
|
-
*
|
|
64
|
-
* original text is preserved below the banner.
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
74
|
+
* verdict. The text-complete hook prepends a workflow-active banner to the
|
|
75
|
+
* FIRST substantive text part of each architect message while the durable gate
|
|
76
|
+
* exists; the model's original text is preserved below the banner.
|
|
77
|
+
*
|
|
78
|
+
* Injection is bounded on three independent axes, because a banner that is
|
|
79
|
+
* merely throttled is still injected on every part:
|
|
80
|
+
* 1. blank parts are never decorated (a banner labelling no content is noise);
|
|
81
|
+
* 2. a part that already opens with a banner is never re-decorated;
|
|
82
|
+
* 3. at most ONE injection per assistant `messageID`.
|
|
83
|
+
* The wall-clock cooldown (see DEFAULT_BANNER_COOLDOWN_MS) then only chooses
|
|
84
|
+
* whether that single injection is the full banner or the short marker.
|
|
69
85
|
*
|
|
70
|
-
* The resume loop is bounded
|
|
71
|
-
* so a session that cannot make
|
|
72
|
-
* forever. Suspended and user-interrupted
|
|
73
|
-
*
|
|
74
|
-
*
|
|
86
|
+
* session.idle mechanically resumes a gated session. The resume loop is bounded
|
|
87
|
+
* (see DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES) so a session that cannot make
|
|
88
|
+
* progress suspends instead of spinning forever. Suspended and user-interrupted
|
|
89
|
+
* messages bypass the cooldown so their recovery notices are never downgraded to
|
|
90
|
+
* the short marker.
|
|
75
91
|
*/
|
|
76
92
|
export declare function createPrWorkflowResponseGate(options: {
|
|
77
93
|
directory: string;
|
|
@@ -86,6 +102,8 @@ export declare function createPrWorkflowResponseGate(options: {
|
|
|
86
102
|
}) => Promise<void>;
|
|
87
103
|
textComplete: (input: {
|
|
88
104
|
sessionID?: string;
|
|
105
|
+
messageID?: string;
|
|
106
|
+
partID?: string;
|
|
89
107
|
}, output: {
|
|
90
108
|
text: string;
|
|
91
109
|
}) => Promise<void>;
|