opencode-swarm 7.126.2 → 7.126.3
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/engineering-conventions/SKILL.md +1 -1
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +14 -3
- package/.opencode/skills/swarm-pr-review/SKILL.md +28 -7
- package/dist/background/pr-event-delivery.d.ts +1 -1
- package/dist/cli/{curator-qfh9xty4.js → curator-jm9ehfkg.js} +1 -1
- package/dist/cli/{curator-llm-factory-0rf29gfq.js → curator-llm-factory-3cy0h9yw.js} +1 -1
- package/dist/cli/{guardrail-explain-jsrjqps1.js → guardrail-explain-va0kj05m.js} +2 -2
- package/dist/cli/{hive-promoter-ktt17fyf.js → hive-promoter-h9c4kyv0.js} +1 -1
- package/dist/cli/{index-d88y17ht.js → index-5n868tw8.js} +28 -15
- package/dist/cli/{index-z8ftpav0.js → index-6t5sa6v0.js} +1 -1
- package/dist/cli/{index-5nq8dp63.js → index-b16153py.js} +2 -2
- package/dist/cli/index.js +1 -1
- package/dist/config/bundled-skills.d.ts +3 -2
- package/dist/hooks/init-orphan-recovery.d.ts +1 -1
- package/dist/hooks/pr-workflow-auto-wake.d.ts +31 -0
- package/dist/hooks/pr-workflow-gate.d.ts +1 -1
- package/dist/hooks/pr-workflow-response-gate.d.ts +4 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +142 -142
- package/dist/tools/repo-graph/builder.d.ts +5 -4
- package/dist/utils/timeout.d.ts +8 -4
- package/package.json +1 -1
|
@@ -35,7 +35,7 @@ If you are not sure whether you are touching one of these, you are touching one
|
|
|
35
35
|
The full list of 12 invariants is in `AGENTS.md`. The four that have caused the most recent production regressions:
|
|
36
36
|
|
|
37
37
|
1. **Plugin initialization is bounded and fail-open.** Every awaited operation on the plugin-init path must be wrapped in `withTimeout(...)` and degrade non-fatally on timeout. Issue #704 (v7.0.3) and the v7.3.3 git-hygiene regression both stem from violating this. The OpenCode plugin host silently drops a plugin whose entry never resolves; users see "no agents in TUI / GUI" with no error.
|
|
38
|
-
- **Bounded is not free:** `withTimeout` only prevents an *unbounded* hang — the awaited work's latency still counts toward the ~400 ms repro-704 init deadline.
|
|
38
|
+
- **Bounded is not free:** `withTimeout` only prevents an *unbounded* hang — the awaited work's latency still counts toward the ~400 ms repro-704 init deadline. Register non-trivial init I/O in the wrapper-owned post-resolution task queue when nothing downstream needs it before `server()` resolves. Do not use `queueMicrotask` inside the initializer: it can run during a later `await` while `server()` is still unresolved.
|
|
39
39
|
2. **Subprocesses are bounded, non-interactive, and killable.** Every `bunSpawn(['<bin>', ...])` call must pass `cwd`, `stdin: 'ignore'` (unless intentionally interactive), `timeout: <ms>`, bounded stdio, and call `proc.kill()` in a `finally`. An outer `withTimeout` is not enough — it lets the awaiter proceed but does not abort the child.
|
|
40
40
|
3. **Runtime portability — Node-ESM-loadable + v1 plugin shape.** No top-level `bun:` imports in `dist/index.js`. Default export is `{ id, server }`. All `Bun.*` calls go through `src/utils/bun-compat.ts`. v6.86.8 / v6.86.9 are the cautionary tales.
|
|
41
41
|
4. **Test mock isolation.** `mock.module(...)` leaks across files in Bun's shared test-runner process. Prefer, in order: (a) `_test_exports` for pure function testing with zero mocks, (b) `_internals` dependency-injection seam for within-module mocking (see `src/utils/gitignore-warning.ts:_internals` and `src/hooks/diff-scope.ts:_internals`), (c) `mock.module` only when unavoidable. Restore in `afterEach`. The writing-tests skill covers all three tiers in detail; load it before modifying tests.
|
|
@@ -144,7 +144,7 @@ tree:
|
|
|
144
144
|
tracked path. It creates an auditable, path-scoped stash and returns its
|
|
145
145
|
recovery command. Do not issue `git stash` through shell. The controller never
|
|
146
146
|
stashes untracked files; move or remove those manually, or abort the checkout.
|
|
147
|
-
- **Check out the head branch locally.** Feedback verification reads the working-tree
|
|
147
|
+
- **Check out the head branch locally before dispatching feedback lanes.** Feedback verification reads the working-tree
|
|
148
148
|
filesystem (`Read`/`Glob`/`Grep`), and fixes must land on the PR branch — without a
|
|
149
149
|
checkout you would verify and patch the base branch's code instead. Record the
|
|
150
150
|
exact `merge_base...head_ref` range for diff-scoped inspection.
|
|
@@ -159,6 +159,15 @@ tree:
|
|
|
159
159
|
the upstream of an existing local branch with
|
|
160
160
|
`git branch --set-upstream-to=<remote>/<remote-branch> <local-branch>`).
|
|
161
161
|
Branch creation/tracking is blocked after the immutable head is bound.
|
|
162
|
+
- `gh pr checkout` is permitted only in its non-force, non-submodule form with
|
|
163
|
+
the PR number/URL and optional `--repo` or `--branch` flags. Never use
|
|
164
|
+
`--force`, `--recurse-submodules`, or detached checkout during this
|
|
165
|
+
transition.
|
|
166
|
+
- Before the first feedback verification dispatch binds the head, prove that
|
|
167
|
+
`git rev-parse HEAD` equals the authoritative full `pr_head_sha`,
|
|
168
|
+
`git status --porcelain` is empty, and the current branch tracks the intended
|
|
169
|
+
PR head remote/branch. A detached checkout is valid for review, not feedback
|
|
170
|
+
publication.
|
|
162
171
|
|
|
163
172
|
When a verification lane result includes `output_ref`, treat `output` as a
|
|
164
173
|
preview and call `retrieve_lane_output` before using it to classify, resolve,
|
|
@@ -733,8 +742,10 @@ the independently approved digest, the exact approved commit remains current,
|
|
|
733
742
|
its bound upstream remote-tracking ref points to that exact commit, every
|
|
734
743
|
feedback ID has exact-provenance evidence, and no PR-workflow lanes remain
|
|
735
744
|
open. While the gate remains active, the runtime replaces architect
|
|
736
|
-
final-response text with a mechanical blocked notice and re-wakes an
|
|
737
|
-
parent session.
|
|
745
|
+
final-response text with a mechanical blocked notice and normally re-wakes an
|
|
746
|
+
idle parent session. A user interruption pauses automatic wakes until a later
|
|
747
|
+
explicit user turn settles; the durable gate remains available to continue or
|
|
748
|
+
abort.
|
|
738
749
|
|
|
739
750
|
Report:
|
|
740
751
|
|
|
@@ -134,9 +134,26 @@ If scope cannot be determined, review the narrowest safe scope available and sta
|
|
|
134
134
|
|
|
135
135
|
### Pre-flight git ref availability
|
|
136
136
|
|
|
137
|
-
Before launching explorers (Phase 3),
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
Before launching explorers (Phase 3), perform this exact standalone sequence:
|
|
138
|
+
|
|
139
|
+
1. Resolve and retain the authoritative full `pr_head_sha` from PR metadata.
|
|
140
|
+
2. Verify the working tree is clean with `git status --porcelain`. If tracked
|
|
141
|
+
changes exist, call `prepare_pr_workflow_checkout` with every explicit dirty
|
|
142
|
+
tracked path. Do not issue `git stash` through shell. The controller never
|
|
143
|
+
stashes untracked files; move or remove those manually, or abort.
|
|
144
|
+
3. Fetch the PR head as one standalone command, for example
|
|
145
|
+
`git fetch origin refs/pull/<N>/head`. Do not compose fetch and checkout.
|
|
146
|
+
4. Prove the full commit exists locally with
|
|
147
|
+
`git cat-file -e <full_pr_head_sha>^{commit}`.
|
|
148
|
+
5. Check out the exact PR filesystem with
|
|
149
|
+
`git switch --detach <full_pr_head_sha>`. Do not use `--track FETCH_HEAD`:
|
|
150
|
+
`FETCH_HEAD` is not a remote-tracking branch.
|
|
151
|
+
6. Confirm `git rev-parse HEAD` equals the full `pr_head_sha`, bind that exact
|
|
152
|
+
head through the first PR-review controller call, and finish this before dispatching explorer lanes.
|
|
153
|
+
|
|
154
|
+
Explorer agents read files from the working tree, not from git history. Passing
|
|
155
|
+
the commit range in a prompt cannot substitute for this checkout because
|
|
156
|
+
`Read` / `Glob` / `Grep` operate on the filesystem.
|
|
140
157
|
- Explicitly pass the verified merge-base range (`base_sha...pr_head_sha`) in every explorer delegation so explorers inspect exactly the controller-bound PR diff. Include `base_ref` only as the live ref used to recompute `base_sha`; do not substitute a two-dot branch-tip range.
|
|
141
158
|
|
|
142
159
|
If refs cannot be fetched or checked out, state the limitation in the context pack.
|
|
@@ -1405,7 +1422,9 @@ the same exact
|
|
|
1405
1422
|
`pr_head_sha`. The tool refuses to clear the session gate while required base,
|
|
1406
1423
|
trigger, declared reviewer/critic, or open-lane obligations remain incomplete.
|
|
1407
1424
|
While the gate remains active, the runtime replaces architect final-response
|
|
1408
|
-
text with a mechanical blocked notice and re-wakes an idle parent session.
|
|
1425
|
+
text with a mechanical blocked notice and re-wakes an idle parent session. A
|
|
1426
|
+
user interruption pauses every automatic wake path until a later explicit user
|
|
1427
|
+
turn settles; the durable gate remains available to continue or abort. Only
|
|
1409
1428
|
emit the final report after the completion tool confirms that the gate cleared.
|
|
1410
1429
|
|
|
1411
1430
|
## Aborting an unrecoverable review
|
|
@@ -1419,9 +1438,11 @@ the merge-base bind can never verify. In that state the response gate
|
|
|
1419
1438
|
suspends further auto-resumes after a small number of consecutive
|
|
1420
1439
|
unproductive wakes, and the only exits are:
|
|
1421
1440
|
|
|
1422
|
-
1. **Diagnose and retry
|
|
1423
|
-
`git fetch origin refs/pull/<N>/head
|
|
1424
|
-
`git
|
|
1441
|
+
1. **Diagnose and retry the canonical standalone sequence.** Run
|
|
1442
|
+
`git fetch origin refs/pull/<N>/head`, verify
|
|
1443
|
+
`git cat-file -e <full_pr_head_sha>^{commit}`, then run
|
|
1444
|
+
`git switch --detach <full_pr_head_sha>`. Do not use `--track FETCH_HEAD`.
|
|
1445
|
+
Confirm `git rev-parse HEAD` equals the authoritative PR head, then recompute the exact
|
|
1425
1446
|
merge base with `git merge-base -- <base_ref> <pr_head_sha>` (single
|
|
1426
1447
|
command) and retry the `swarm-pr-review:base` dispatch with the exact
|
|
1427
1448
|
`pr_head_sha`, `base_sha`, and `base_ref`.
|
|
@@ -89,7 +89,7 @@ export declare function buildWakeMessage(events: FormattedPrEvent[]): string;
|
|
|
89
89
|
* clients that lack it. Bounded by withTimeout; returns false on any
|
|
90
90
|
* failure or timeout. Never throws.
|
|
91
91
|
*/
|
|
92
|
-
declare function sendWakePrompt(sessionID: string, events: FormattedPrEvent[]): Promise<boolean>;
|
|
92
|
+
declare function sendWakePrompt(sessionID: string, events: FormattedPrEvent[], messageID: string): Promise<boolean>;
|
|
93
93
|
export declare const _internals: {
|
|
94
94
|
sendWakePrompt: typeof sendWakePrompt;
|
|
95
95
|
withTimeout: typeof withTimeout;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
4
|
+
} from "./index-6t5sa6v0.js";
|
|
5
|
+
import"./index-5n868tw8.js";
|
|
6
6
|
import"./index-gxw20m1d.js";
|
|
7
7
|
import"./index-3xd9a2g7.js";
|
|
8
8
|
import"./index-kk1scggc.js";
|
|
@@ -940,8 +940,11 @@ async function bindPrWorkflowHead(directory, sessionID, prHeadSha) {
|
|
|
940
940
|
const state = await requireAnyActiveState(directory, sessionID);
|
|
941
941
|
const normalizedHead = normalizePrHeadSha(prHeadSha);
|
|
942
942
|
assertCurrentCheckoutHead(directory, normalizedHead);
|
|
943
|
-
if (state.
|
|
944
|
-
assertPrReviewCleanCheckout(directory);
|
|
943
|
+
if (!state.prHeadSha)
|
|
944
|
+
assertPrReviewCleanCheckout(directory, state.mode);
|
|
945
|
+
if (!state.prHeadSha && state.mode === "PR_FEEDBACK") {
|
|
946
|
+
assertPrFeedbackTrackingCheckout(directory, normalizedHead);
|
|
947
|
+
}
|
|
945
948
|
if (state.prHeadSha && state.prHeadSha !== normalizedHead) {
|
|
946
949
|
throw new Error(`BLOCKED: active ${state.mode} workflow is bound to PR head "${state.prHeadSha}"; received "${normalizedHead}"`);
|
|
947
950
|
}
|
|
@@ -966,9 +969,19 @@ function assertCurrentCheckoutHead(directory, expectedHead) {
|
|
|
966
969
|
}
|
|
967
970
|
return normalizedExpected;
|
|
968
971
|
}
|
|
969
|
-
function assertPrReviewCleanCheckout(directory) {
|
|
972
|
+
function assertPrReviewCleanCheckout(directory, mode = "PR_REVIEW") {
|
|
970
973
|
if (_test_exports.resolveIsWorkingTreeClean(directory) !== true) {
|
|
971
|
-
throw new Error(
|
|
974
|
+
throw new Error(`BLOCKED: ${mode} requires a clean index and working tree at the exact PR head`);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
function assertPrFeedbackTrackingCheckout(directory, prHeadSha) {
|
|
978
|
+
const upstream = _test_exports.resolveCurrentUpstreamPushTarget(directory);
|
|
979
|
+
if (!upstream) {
|
|
980
|
+
throw new Error("BLOCKED: PR_FEEDBACK requires a current local branch bound to an exact remote name, remote branch ref, and remote-tracking ref before the first head bind; detached or non-tracking checkouts are not allowed");
|
|
981
|
+
}
|
|
982
|
+
const matchingRemoteRefs = _test_exports.resolveRemoteRefsContainingHead(directory, prHeadSha);
|
|
983
|
+
if (!matchingRemoteRefs?.includes(upstream.remoteTrackingRef)) {
|
|
984
|
+
throw new Error(`BLOCKED: PR_FEEDBACK upstream "${upstream.remoteTrackingRef}" must point to the exact intake PR head "${prHeadSha}" before the first head bind`);
|
|
972
985
|
}
|
|
973
986
|
}
|
|
974
987
|
var _test_exports = {
|
|
@@ -12267,11 +12280,11 @@ var _internals15 = {
|
|
|
12267
12280
|
}
|
|
12268
12281
|
},
|
|
12269
12282
|
applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
|
|
12270
|
-
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-
|
|
12283
|
+
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-jm9ehfkg.js");
|
|
12271
12284
|
return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
|
|
12272
12285
|
},
|
|
12273
12286
|
checkHivePromotions: async (entries, knowledgeConfig, directory) => {
|
|
12274
|
-
const { checkHivePromotions } = await import("./hive-promoter-
|
|
12287
|
+
const { checkHivePromotions } = await import("./hive-promoter-h9c4kyv0.js");
|
|
12275
12288
|
return checkHivePromotions(entries, knowledgeConfig, directory);
|
|
12276
12289
|
},
|
|
12277
12290
|
applyProposalTriage: async (directory, triage) => {
|
|
@@ -20138,8 +20151,8 @@ var _internals28 = {
|
|
|
20138
20151
|
loadCuratorDeps: async () => {
|
|
20139
20152
|
const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
|
|
20140
20153
|
import("./schema-fa033pqw.js"),
|
|
20141
|
-
import("./curator-
|
|
20142
|
-
import("./curator-llm-factory-
|
|
20154
|
+
import("./curator-jm9ehfkg.js"),
|
|
20155
|
+
import("./curator-llm-factory-3cy0h9yw.js")
|
|
20143
20156
|
]);
|
|
20144
20157
|
return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
|
|
20145
20158
|
}
|
|
@@ -20638,7 +20651,7 @@ import { fileURLToPath } from "url";
|
|
|
20638
20651
|
// package.json
|
|
20639
20652
|
var package_default = {
|
|
20640
20653
|
name: "opencode-swarm",
|
|
20641
|
-
version: "7.126.
|
|
20654
|
+
version: "7.126.3",
|
|
20642
20655
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
20643
20656
|
main: "dist/index.js",
|
|
20644
20657
|
types: "dist/index.d.ts",
|
|
@@ -41188,7 +41201,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
41188
41201
|
async function handleHelpCommand(ctx) {
|
|
41189
41202
|
const targetCommand = ctx.args.join(" ");
|
|
41190
41203
|
if (!targetCommand) {
|
|
41191
|
-
const { buildHelpText } = await import("./index-
|
|
41204
|
+
const { buildHelpText } = await import("./index-b16153py.js");
|
|
41192
41205
|
return buildHelpText();
|
|
41193
41206
|
}
|
|
41194
41207
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -41197,7 +41210,7 @@ async function handleHelpCommand(ctx) {
|
|
|
41197
41210
|
return _internals62.buildDetailedHelp(resolved.key, resolved.entry);
|
|
41198
41211
|
}
|
|
41199
41212
|
const similar = _internals62.findSimilarCommands(targetCommand);
|
|
41200
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
41213
|
+
const { buildHelpText: fullHelp } = await import("./index-b16153py.js");
|
|
41201
41214
|
if (similar.length > 0) {
|
|
41202
41215
|
return `Command '/swarm ${targetCommand}' not found.
|
|
41203
41216
|
|
|
@@ -41336,7 +41349,7 @@ var COMMAND_REGISTRY = {
|
|
|
41336
41349
|
},
|
|
41337
41350
|
"guardrail explain": {
|
|
41338
41351
|
handler: async (ctx) => {
|
|
41339
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
41352
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-va0kj05m.js");
|
|
41340
41353
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
41341
41354
|
},
|
|
41342
41355
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -41346,7 +41359,7 @@ var COMMAND_REGISTRY = {
|
|
|
41346
41359
|
},
|
|
41347
41360
|
"guardrail-explain": {
|
|
41348
41361
|
handler: async (ctx) => {
|
|
41349
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
41362
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-va0kj05m.js");
|
|
41350
41363
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
41351
41364
|
},
|
|
41352
41365
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -43140,7 +43153,7 @@ HARD CONSTRAINTS (apply regardless of skill load success):
|
|
|
43140
43153
|
- Test execution, explorer lanes, reviewer dispatch, and critic challenge are all permitted within this mode
|
|
43141
43154
|
- Quality is the only metric \u2014 there is no speed, efficiency, or time exception; time, tokens, and agent dispatches are irrelevant to correctness
|
|
43142
43155
|
- FOLLOW THE SKILL EXACTLY: execute every phase of the loaded SKILL.md in order with no shortcuts, no phase-skipping, and no premature synthesis. If a required coverage phase cannot complete, apply the skill's coverage gate (retry or verified equivalent alternative). If the gap still cannot be closed, stop and surface the lane failure to the user as BLOCKED; do not produce a degraded review, partial verdict, or final synthesis.
|
|
43143
|
-
- CHECK OUT THE PR
|
|
43156
|
+
- CHECK OUT THE EXACT PR HEAD LOCALLY before dispatching explorer lanes: resolve the authoritative full PR head SHA, verify the working tree is clean (git status --porcelain), and if tracked changes exist call \`prepare_pr_workflow_checkout\` with every explicit dirty tracked path before checkout. It returns an auditable stash OID and recovery command; it never stashes untracked files, which must be moved or removed manually. Do NOT run \`git stash\` through shell. Then use standalone commands: fetch the PR head, verify \`git cat-file -e <full_pr_head_sha>^{commit}\`, run \`git switch --detach <full_pr_head_sha>\`, confirm HEAD equals that SHA, and bind it through the PR-review controller. Do not use \`--track FETCH_HEAD\`. Explorers read the working-tree filesystem (Read/Glob/Grep), so without this checkout they read the base branch and produce invalid candidates. Always pass the base..head commit range in explorer delegations.
|
|
43144
43157
|
- RUN ALL BASE LANES: the default PR_REVIEW path always launches exactly six repository-agnostic base check-type lanes from the skill. Use \`mode: "swarm-pr-review:base"\` and the exact six \`workflow_lane\` identifiers. The runtime rejects partial, duplicate, or mislabelled waves. Do not collapse, omit, or scale down the base lanes for a small, docs-only, or CI-only PR.
|
|
43145
43158
|
- RETRY STRUCTURALLY: retry only failed base obligations in later \`swarm-pr-review:base\` async batches with the same exact \`pr_head_sha\`. Blocking \`dispatch_lanes\` and direct Task explorer/reviewer/critic dispatch are not provenance-equivalent and are rejected.
|
|
43146
43159
|
- USE ASYNC DISPATCH WITHOUT IDLING: launch the base lanes with one \`dispatch_lanes_async\` call when available, record the \`batch_id\`, then keep doing non-dependent architect work while they run. Poll with \`collect_lane_results\` without \`wait\` (or \`wait: false\`) to process settled lanes and continue independent work between polls; use \`wait: true\` only as the final join when no independent work remains.
|
|
@@ -43159,7 +43172,7 @@ ACTION: Load skill ${bundledProjectSkillFileReference("swarm-pr-feedback")} imme
|
|
|
43159
43172
|
|
|
43160
43173
|
HARD CONSTRAINTS (apply regardless of skill load success):
|
|
43161
43174
|
- FOLLOW THE SKILL EXACTLY: build the complete feedback ledger from all available sources before editing, and execute every phase in order with no shortcuts.
|
|
43162
|
-
- CHECK OUT THE PR BRANCH LOCALLY before verifying feedback or making fixes: fetch the PR head ref if absent, verify the working tree is clean (git status --porcelain), and if tracked changes exist call \`prepare_pr_workflow_checkout\` with every explicit dirty tracked path before checkout. It returns an auditable stash OID and recovery command; it never stashes untracked files, which must be moved or removed manually. Do NOT run \`git stash\` through shell. Then check out the head branch. For a detached/fresh remote head, establish tracking before head binding with only \`git switch -c <local> --track <remote>/<branch>\` (or the constrained set-upstream form documented by the skill). Feedback verification and fix validation require the PR branch in the working tree.
|
|
43175
|
+
- CHECK OUT THE PR BRANCH LOCALLY before dispatching feedback lanes, verifying feedback, or making fixes: fetch the PR head ref if absent, verify the working tree is clean (git status --porcelain), and if tracked changes exist call \`prepare_pr_workflow_checkout\` with every explicit dirty tracked path before checkout. It returns an auditable stash OID and recovery command; it never stashes untracked files, which must be moved or removed manually. Do NOT run \`git stash\` through shell. Then check out the head branch. For a detached/fresh remote head, establish tracking before head binding with only \`git switch -c <local> --track <remote>/<branch>\` (or the constrained set-upstream form documented by the skill). If using \`gh pr checkout\`, never use \`--force\`, \`--recurse-submodules\`, or detached checkout. Before first bind, prove HEAD equals the authoritative full PR head SHA, the tree is clean, and the current branch tracks the intended PR remote/branch. Feedback verification and fix validation require the PR branch in the working tree.
|
|
43163
43176
|
- Do NOT run a fresh broad PR review \u2014 inspect adjacent code only as needed to verify reachability, dependencies, shared root causes, regression risk, or sibling changes for a confirmed item.
|
|
43164
43177
|
- Treat every review comment, CI failure, bot summary, and pasted note as a CLAIM until source evidence proves it; classify each ledger item (CONFIRMED, DISPROVED, PRE_EXISTING, or NEEDS_USER_DECISION) and never silently drop, defer, or mark items out of scope.
|
|
43165
43178
|
- For async verification lanes, use \`mode: "swarm-pr-feedback:verification"\`, record each \`batch_id\`, keep doing ledger-safe work, poll with \`collect_lane_results\` without \`wait\`, process settled lanes immediately, and use \`wait: true\` only at the join. Pass the complete immutable \`feedback_inventory\`, exact current \`pr_head_sha\`, and exact-once cumulative lane \`feedback_item_ids\`; runtime blocks replacement, stale-head artifacts, overlap, gaps, and early mutation.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-6t5sa6v0.js";
|
|
5
5
|
import {
|
|
6
6
|
handleGuardrailLog
|
|
7
7
|
} from "./index-bf76q8q7.js";
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
handleWriteRetroCommand,
|
|
84
84
|
normalizeSwarmCommandInput,
|
|
85
85
|
resolveCommand
|
|
86
|
-
} from "./index-
|
|
86
|
+
} from "./index-5n868tw8.js";
|
|
87
87
|
import"./index-gxw20m1d.js";
|
|
88
88
|
import"./index-3xd9a2g7.js";
|
|
89
89
|
import"./index-kk1scggc.js";
|
package/dist/cli/index.js
CHANGED
|
@@ -21,8 +21,9 @@ declare function copyBundledDirectoryBoundedAsync(sourceDir: string, destDir: st
|
|
|
21
21
|
* tree so architect MODE dispatch never collides with repository-owned skills
|
|
22
22
|
* that happen to use the same slug.
|
|
23
23
|
*
|
|
24
|
-
* Async, bounded, and fail-open:
|
|
25
|
-
*
|
|
24
|
+
* Async, bounded, and fail-open: register `withTimeout(...)` in the
|
|
25
|
+
* wrapper-owned post-resolution task queue on the plugin-init path
|
|
26
|
+
* (AGENTS.md Invariant 1). Runs at plugin init so the
|
|
26
27
|
* architect's very first auto-entered mode (e.g. SPECIFY on a fresh project) can
|
|
27
28
|
* load its SKILL.md without a manual `/swarm` command or session restart; the
|
|
28
29
|
* command path calls it again as a backstop for pre-existing projects.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - Calls cleanupOrphanedBranches(ctx.directory, []) at plugin init (no sessions active → all swarm-lane branches are orphans)
|
|
7
7
|
* - Writes results to `<directory>/.swarm/advisories/init-orphan-recovery.json`
|
|
8
8
|
* - Is wrapped in `withTimeout` so it never blocks plugin init
|
|
9
|
-
* - Runs
|
|
9
|
+
* - Runs from the wrapper-owned post-resolution queue after `server()` can settle (precedent: repoGraphHook.init)
|
|
10
10
|
*
|
|
11
11
|
* This module intentionally lives in `src/hooks/` so that `src/index.ts` can import
|
|
12
12
|
* it without matching the forbidden `worktree/` or `merge-back/` patterns.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { readPrWorkflowGateState } from './pr-workflow-gate.js';
|
|
2
|
+
export declare const _internals: {
|
|
3
|
+
readPrWorkflowGateState: typeof readPrWorkflowGateState;
|
|
4
|
+
};
|
|
5
|
+
/** Bound module state: every entry is keyed by project plus parent session. */
|
|
6
|
+
export declare const MAX_TRACKED_PR_WORKFLOW_WAKE_STATES = 200;
|
|
7
|
+
export declare const PLUGIN_WAKE_MARKER_TTL_MS = 60000;
|
|
8
|
+
type PausePhase = 'awaiting-idle' | 'paused' | 'resuming';
|
|
9
|
+
export interface PrWorkflowAutoWakeDecision {
|
|
10
|
+
sessionID?: string;
|
|
11
|
+
suppressWake: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Mark a plugin-authored prompt until its synthetic user event is observed. */
|
|
14
|
+
export declare function markPrWorkflowPluginWake(directory: string, sessionID: string): string;
|
|
15
|
+
/** Remove a marker only when the host definitively rejected the prompt. */
|
|
16
|
+
export declare function cancelPrWorkflowPluginWake(directory: string, sessionID: string, messageID: string): void;
|
|
17
|
+
export declare function isPrWorkflowAutoWakeSuppressed(directory: string, sessionID: string): boolean;
|
|
18
|
+
export declare function clearPrWorkflowAutoWakeState(directory: string, sessionID: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* Observe host events that distinguish a user interruption from an ordinary
|
|
21
|
+
* idle boundary. The durable workflow gate remains intact; only automatic
|
|
22
|
+
* prompts pause. A later real user turn re-enables wakes after that turn's
|
|
23
|
+
* idle boundary.
|
|
24
|
+
*/
|
|
25
|
+
export declare function observePrWorkflowAutoWakeEvent(directory: string, rawEvent: unknown): Promise<PrWorkflowAutoWakeDecision>;
|
|
26
|
+
export declare const _test_exports: {
|
|
27
|
+
reset(): void;
|
|
28
|
+
getPausePhase(directory: string, sessionID: string): PausePhase | undefined;
|
|
29
|
+
getPluginWakeMarkerCount(directory: string, sessionID: string, now?: number): number;
|
|
30
|
+
};
|
|
31
|
+
export {};
|
|
@@ -191,7 +191,7 @@ export declare function bindPrReviewBase(directory: string, sessionID: string, o
|
|
|
191
191
|
/** Prove that caller-provided PR identity equals the actual checked-out commit. */
|
|
192
192
|
export declare function assertCurrentCheckoutHead(directory: string, expectedHead: string): string;
|
|
193
193
|
/** Prove that every PR-review lane reads the immutable checked-out PR tree. */
|
|
194
|
-
export declare function assertPrReviewCleanCheckout(directory: string): void;
|
|
194
|
+
export declare function assertPrReviewCleanCheckout(directory: string, mode?: PrWorkflowMode): void;
|
|
195
195
|
export declare function enforcePrWorkflowDispatchLanesAsync(directory: string, sessionID: string, toolName: string): Promise<PrWorkflowGateState | null>;
|
|
196
196
|
export declare function enforcePrReviewBaseDimensions(directory: string, sessionID: string, lanes: readonly PrWorkflowLaneSpec[], options: {
|
|
197
197
|
batchId: string;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { readPrWorkflowGateState } from './pr-workflow-gate.js';
|
|
2
|
+
export declare const _internals: {
|
|
3
|
+
readPrWorkflowGateState: typeof readPrWorkflowGateState;
|
|
4
|
+
};
|
|
1
5
|
/**
|
|
2
6
|
* Maximum number of consecutive unproductive auto-resumes per gated session
|
|
3
7
|
* before the response gate suspends further wakes. "Unproductive" means the
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Plugin } from '@opencode-ai/plugin';
|
|
2
|
+
import { createRepoGraphBuilderHook } from './hooks';
|
|
2
3
|
/**
|
|
3
4
|
* FIFO-cap a session-keyed Map to at most `max` entries, evicting oldest first.
|
|
4
5
|
* Values tracked by these maps are plain data (timestamps/usage snapshots), never
|
|
@@ -6,6 +7,19 @@ import type { Plugin } from '@opencode-ai/plugin';
|
|
|
6
7
|
* unit testing of the cap invariant; used by the heartbeat throttle path below.
|
|
7
8
|
*/
|
|
8
9
|
export declare function capSessionMap<K, V>(map: Map<K, V>, max: number): void;
|
|
10
|
+
type PostResolutionTask = () => void | Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Start detached initialization work only after the plugin manifest promise can
|
|
13
|
+
* settle. A microtask queued from inside `initializeOpenCodeSwarm` is not truly
|
|
14
|
+
* deferred when that function still has later awaits: the microtask can start
|
|
15
|
+
* expensive filesystem work while `server()` remains unresolved (issue #704).
|
|
16
|
+
*/
|
|
17
|
+
declare function schedulePostResolutionTasks(tasks: readonly PostResolutionTask[]): void;
|
|
18
|
+
export declare function overrideIndexInternalsForTest(overrides: {
|
|
19
|
+
createRepoGraphBuilderHook?: typeof createRepoGraphBuilderHook;
|
|
20
|
+
schedulePostResolutionTasks?: typeof schedulePostResolutionTasks;
|
|
21
|
+
}): () => void;
|
|
22
|
+
export declare function schedulePostResolutionTasksForTest(tasks: readonly PostResolutionTask[]): void;
|
|
9
23
|
declare const _default: {
|
|
10
24
|
id: "opencode-swarm";
|
|
11
25
|
server: Plugin;
|