opencode-swarm 7.65.3 → 7.66.1
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/brainstorm/SKILL.md +1 -0
- package/.opencode/skills/phase-wrap/SKILL.md +8 -1
- package/.opencode/skills/specify/SKILL.md +1 -0
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +47 -0
- package/README.md +3 -1
- package/dist/cli/index.js +87 -23
- package/dist/commands/auto-proceed.d.ts +13 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/registry.d.ts +7 -0
- package/dist/commands/tool-policy.d.ts +1 -1
- package/dist/config/constants.d.ts +2 -0
- package/dist/config/plan-schema.d.ts +2 -0
- package/dist/index.js +160 -46
- package/dist/session/snapshot-writer.d.ts +4 -0
- package/dist/state.d.ts +13 -0
- package/dist/tools/resolve-working-directory.d.ts +1 -1
- package/dist/tools/save-plan.d.ts +2 -0
- package/dist/tools/update-task-status.d.ts +13 -0
- package/package.json +1 -1
|
@@ -78,6 +78,7 @@ Present the eleven gates with their defaults (DEFAULT_QA_GATES), parallel coder
|
|
|
78
78
|
Additionally, present these two sub-items as part of the same exchange:
|
|
79
79
|
- Parallel coders (default: 1, range: 1-4) -- how many coders should run in parallel.
|
|
80
80
|
- Commit frequency (default: phase-level only) -- optional per-task checkpoint commit after each task completion.
|
|
81
|
+
- auto_proceed (boolean, default: false) -- when true, auto-advance to the next phase without asking "Ready for Phase N+1?"; runtime toggle via /swarm auto-proceed on|off.
|
|
81
82
|
|
|
82
83
|
The user answers all three (gates, parallel coders, commit frequency) in one exchange. Wait for the user's response.
|
|
83
84
|
|
|
@@ -117,7 +117,14 @@ The tool will automatically write the retrospective to \`.swarm/evidence/retro-{
|
|
|
117
117
|
6. Do NOT call `phase_complete` or `/swarm close` until `.swarm/evidence/final-council.json` exists with an approved, plan-bound, quorumed final-council verdict. When `final_council` is enabled, `phase_complete` will block until that evidence exists.
|
|
118
118
|
If enabled but NOT the last phase, skip silently - final council only runs once, after all phases.
|
|
119
119
|
6. Summarize to user
|
|
120
|
-
7.
|
|
120
|
+
7. Check the AUTO_PROCEED STATUS banner (injected into your context by the system-enhancer). The banner shows:
|
|
121
|
+
- `auto-proceed: <on|off>` — the current effective value
|
|
122
|
+
- `source: <session|plan-or-default>` — which side it came from
|
|
123
|
+
- `nudge: <true|false>` — whether the FR-004 first-boundary nudge has already been done
|
|
124
|
+
Then branch:
|
|
125
|
+
- If `auto-proceed: on`: call `phase_complete`, then advance to the first task of the next phase. Do NOT ask the user.
|
|
126
|
+
- If `auto-proceed: off` AND `nudge: false`: after the user confirms the phase transition, suggest enabling auto-proceed. Use the swarm_command tool to record the user's answer: `swarm_command({ command: "auto-proceed", args: ["on"] })` for yes, `swarm_command({ command: "auto-proceed", args: ["off"] })` for no. Either call sets nudge to true and prevents re-nudging.
|
|
127
|
+
- If `auto-proceed: off` AND `nudge: true`: Ask "Ready for Phase [N+1]?" and wait for user confirmation before proceeding.
|
|
121
128
|
|
|
122
129
|
CATASTROPHIC VIOLATION CHECK — ask yourself at EVERY phase boundary (MODE: PHASE-WRAP):
|
|
123
130
|
"Have I delegated to the active swarm's reviewer agent at least once this phase?"
|
|
@@ -49,6 +49,7 @@ Present the eleven gates with their defaults (DEFAULT_QA_GATES), parallel coder
|
|
|
49
49
|
Additionally, present these two sub-items as part of the same exchange:
|
|
50
50
|
- Parallel coders (default: 1, range: 1-4) -- how many coders should run in parallel.
|
|
51
51
|
- Commit frequency (default: phase-level only) -- optional per-task checkpoint commit after each task completion.
|
|
52
|
+
- auto_proceed (boolean, default: false) -- when true, auto-advance to the next phase without asking "Ready for Phase N+1?"; runtime toggle via /swarm auto-proceed on|off.
|
|
52
53
|
|
|
53
54
|
The user answers all three (gates, parallel coders, commit frequency) in one exchange. Wait for the user's response.
|
|
54
55
|
|
|
@@ -5,6 +5,8 @@ description: >
|
|
|
5
5
|
Use when addressing pasted PR feedback, GitHub review comments or threads,
|
|
6
6
|
requested changes, CI/check failures, merge conflicts, stale PR branches, or
|
|
7
7
|
PR follow-up work that must close all known issues without dropping findings.
|
|
8
|
+
Supports multi-round bot reviews (the repository's bot posts a new review
|
|
9
|
+
after every push) via the iterative pattern documented in the body.
|
|
8
10
|
---
|
|
9
11
|
|
|
10
12
|
# Swarm PR Feedback
|
|
@@ -14,6 +16,51 @@ Use this skill to close known PR feedback. This is not a fresh broad PR review.
|
|
|
14
16
|
feedback surfaces, verifies each claim, clusters related problems, fixes confirmed
|
|
15
17
|
issues, validates the branch, and reports closure status for every item.
|
|
16
18
|
|
|
19
|
+
## Multi-Round Bot Reviews (Iterative Pattern)
|
|
20
|
+
|
|
21
|
+
The repository's bot reviewer (`hermes-pr-review` / Qwen3.6 + Gemma-4 dual-model)
|
|
22
|
+
posts a new review comment after **every push** to the PR branch, not just the
|
|
23
|
+
final state. Expect N rounds of review for N pushes, and budget for it.
|
|
24
|
+
|
|
25
|
+
**Round N+1 deltas vs Round N:**
|
|
26
|
+
- Fresh `FB-###` ledger IDs for new findings (do not reuse IDs from earlier rounds)
|
|
27
|
+
- Findings from prior rounds that remain unfixed will reappear with the same evidence
|
|
28
|
+
- Findings you marked DISPROVED with new evidence may reappear if the bot disagrees
|
|
29
|
+
- New findings may be introduced that the prior round did not see (the bot's read scope
|
|
30
|
+
is the new commit, not the full diff history)
|
|
31
|
+
|
|
32
|
+
**Operating principles for multi-round triage:**
|
|
33
|
+
|
|
34
|
+
1. **Continue the ledger, do not start over.** Append to the same `FB-###` counter
|
|
35
|
+
across rounds. Track each finding's state per round (open, fixed, disproved,
|
|
36
|
+
awaiting-decision, repeated).
|
|
37
|
+
2. **Carry forward unresolved items.** Findings you marked `PARTIAL` or `NEEDS_USER_DECISION`
|
|
38
|
+
in round N will still be open in round N+1. The closure ledger should show their
|
|
39
|
+
evolution (e.g., "PARTIAL round 1 → CONFIRMED round 2 after evidence collected").
|
|
40
|
+
3. **Apply the 3-strikes-then-defense-in-depth rule.** When the same finding is
|
|
41
|
+
raised 3+ times across rounds, prefer to add the suggested code change with a
|
|
42
|
+
defense-in-depth rationale comment rather than continue to debate. One extra
|
|
43
|
+
condition is cheap; per-round debate is expensive. Document the parent-vs-inner
|
|
44
|
+
relationship inline so future readers see the rationale.
|
|
45
|
+
4. **Verify bot fix-direction suggestions against actual file structure.** Bots
|
|
46
|
+
read files linearly and can miss parent-block guards. For any "add an X check"
|
|
47
|
+
suggestion, read the surrounding function/block to confirm the check is genuinely
|
|
48
|
+
missing or already exists at a higher scope.
|
|
49
|
+
5. **Each round produces its own closure ledger as a PR comment.** Prefix with
|
|
50
|
+
"Round N" so the bot and reviewers can see progression. Maintain a running
|
|
51
|
+
summary table at the end of each comment showing totals across rounds
|
|
52
|
+
(confirmed+fixed / disproved / partial / awaiting-decision).
|
|
53
|
+
6. **Stop the cycle deliberately.** If a finding is disproved with code evidence 3+
|
|
54
|
+
times and the bot keeps re-raising it, leave the comment, post the closure
|
|
55
|
+
ledger with the cumulative evidence, and surface the disagreement to the user
|
|
56
|
+
rather than continuing to push fixes. The user can resolve persistent
|
|
57
|
+
reviewer-AI disagreement.
|
|
58
|
+
|
|
59
|
+
**Why this matters:** Without the multi-round pattern, each round looks like
|
|
60
|
+
"start over, re-triage everything." With it, the rounds become incremental:
|
|
61
|
+
each round's work is bounded by new findings + carried-forward items only.
|
|
62
|
+
This matches how the bot actually behaves and avoids wasted cycles.
|
|
63
|
+
|
|
17
64
|
## Operating Stance
|
|
18
65
|
|
|
19
66
|
Treat every review comment, CI failure, bot summary, PR body claim, and pasted note
|
package/README.md
CHANGED
|
@@ -134,6 +134,8 @@ Swarm has two independent mode systems:
|
|
|
134
134
|
| **Lean Turbo** | High | Fast | Parallel lanes for non-conflicting tasks (up to `max_parallel_coders` coders) |
|
|
135
135
|
| **Full-Auto** | Deterministic policy + critic oversight | Fast | Unattended multi-interaction runs |
|
|
136
136
|
|
|
137
|
+
**Auto-proceed** — a session toggle (`/swarm auto-proceed [on|off]`) that skips the "Ready for Phase N+1?" prompt at phase boundaries. Defaults to `false`; set as a plan default via `execution_profile.auto_proceed` during QA GATE SELECTION. Session override always wins. Independent of Full-Auto.
|
|
138
|
+
|
|
137
139
|
Full-Auto reduces approval friction by deterministically allowing safe operations (read-only tools, in-scope writes, safe shell) and routing every ambiguous or high-risk action (writes to plugin/build/guardrail paths, network, dependency changes, plan/phase mutations, subagent delegation) through the read-only `critic_oversight` agent before it executes. Denials are returned to the agent as structured signals so it can choose a safer path; repeated denials pause the run; phase completion requires an APPROVED oversight record. See [docs/modes.md](docs/modes.md#full-auto) for `mode`, `permission_policy`, `denials`, and `oversight` config keys, fail-closed semantics, and recovery from a paused run.
|
|
138
140
|
|
|
139
141
|
**Project mode** — persistent via `execution_mode` config key:
|
|
@@ -144,7 +146,7 @@ Full-Auto reduces approval friction by deterministically allowing safe operation
|
|
|
144
146
|
| `balanced` (default) | Standard hooks |
|
|
145
147
|
| `fast` | Skips compaction service — for short sessions under context pressure |
|
|
146
148
|
|
|
147
|
-
Switch session modes with `/swarm turbo [on|off]` or `/swarm full-auto [on|off]`. Set project mode in config. Lean Turbo is configured in `turbo.lean.*` in config and composes with all session modes. See [docs/modes.md](docs/modes.md).
|
|
149
|
+
Switch session modes with `/swarm turbo [on|off]` or `/swarm full-auto [on|off]`. Control phase-boundary auto-proceed with `/swarm auto-proceed [on|off]`. Set project mode in config. Lean Turbo is configured in `turbo.lean.*` in config and composes with all session modes. See [docs/modes.md](docs/modes.md).
|
|
148
150
|
|
|
149
151
|
---
|
|
150
152
|
|
package/dist/cli/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "opencode-swarm",
|
|
55
|
-
version: "7.
|
|
55
|
+
version: "7.66.1",
|
|
56
56
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
57
57
|
main: "dist/index.js",
|
|
58
58
|
types: "dist/index.d.ts",
|
|
@@ -14700,7 +14700,8 @@ var init_plan_schema = __esm(() => {
|
|
|
14700
14700
|
parallelization_enabled: exports_external.boolean().default(false),
|
|
14701
14701
|
max_concurrent_tasks: exports_external.number().int().min(1).max(64).default(1),
|
|
14702
14702
|
council_parallel: exports_external.boolean().default(false),
|
|
14703
|
-
locked: exports_external.boolean().default(false)
|
|
14703
|
+
locked: exports_external.boolean().default(false),
|
|
14704
|
+
auto_proceed: exports_external.boolean().default(false)
|
|
14704
14705
|
});
|
|
14705
14706
|
TaskStatusSchema = exports_external.enum([
|
|
14706
14707
|
"pending",
|
|
@@ -22753,6 +22754,45 @@ var init_state = __esm(() => {
|
|
|
22753
22754
|
};
|
|
22754
22755
|
});
|
|
22755
22756
|
|
|
22757
|
+
// src/commands/auto-proceed.ts
|
|
22758
|
+
async function handleAutoProceedCommand(_directory, args, sessionID) {
|
|
22759
|
+
if (!sessionID || sessionID.trim() === "") {
|
|
22760
|
+
return "Error: No active session context. Auto-proceed requires an active session. Use /swarm auto-proceed from within an OpenCode session, or start a session first.";
|
|
22761
|
+
}
|
|
22762
|
+
const session = getAgentSession(sessionID);
|
|
22763
|
+
if (!session) {
|
|
22764
|
+
return "Error: No active session. Auto-proceed requires an active session to operate.";
|
|
22765
|
+
}
|
|
22766
|
+
if (stripKnownSwarmPrefix(session.agentName) !== "architect") {
|
|
22767
|
+
return `Error: Auto-proceed can only be toggled from the architect session. Currently active session is: ${session.agentName}`;
|
|
22768
|
+
}
|
|
22769
|
+
const arg = args[0]?.toLowerCase();
|
|
22770
|
+
const wasUndefinedBefore = session.autoProceedOverride === undefined;
|
|
22771
|
+
let newAutoProceedOverride;
|
|
22772
|
+
if (arg === "on") {
|
|
22773
|
+
newAutoProceedOverride = true;
|
|
22774
|
+
} else if (arg === "off") {
|
|
22775
|
+
newAutoProceedOverride = false;
|
|
22776
|
+
} else if (arg === undefined) {
|
|
22777
|
+
newAutoProceedOverride = !session.autoProceedOverride;
|
|
22778
|
+
} else {
|
|
22779
|
+
return 'Error: Invalid argument for /swarm auto-proceed. Valid options: "on", "off", or omit the argument to toggle.';
|
|
22780
|
+
}
|
|
22781
|
+
session.autoProceedOverride = newAutoProceedOverride;
|
|
22782
|
+
if (arg === "on" || arg === "off" || arg === undefined && wasUndefinedBefore) {
|
|
22783
|
+
session.autoProceedNudgeDone = true;
|
|
22784
|
+
}
|
|
22785
|
+
if (newAutoProceedOverride) {
|
|
22786
|
+
return "Auto-proceed is now ON. Phase boundaries will advance automatically.";
|
|
22787
|
+
} else {
|
|
22788
|
+
return "Auto-proceed is now OFF. You will be asked before advancing to the next phase.";
|
|
22789
|
+
}
|
|
22790
|
+
}
|
|
22791
|
+
var init_auto_proceed = __esm(() => {
|
|
22792
|
+
init_schema();
|
|
22793
|
+
init_state();
|
|
22794
|
+
});
|
|
22795
|
+
|
|
22756
22796
|
// src/commands/benchmark.ts
|
|
22757
22797
|
async function handleBenchmarkCommand(directory, args) {
|
|
22758
22798
|
let cumulative = args.includes("--cumulative");
|
|
@@ -48893,6 +48933,12 @@ function serializeAgentSession(s) {
|
|
|
48893
48933
|
...Object.keys(stageBCompletion).length > 0 && { stageBCompletion },
|
|
48894
48934
|
...s.maxConcurrencyOverride !== undefined && {
|
|
48895
48935
|
maxConcurrencyOverride: s.maxConcurrencyOverride
|
|
48936
|
+
},
|
|
48937
|
+
...s.autoProceedOverride !== undefined && {
|
|
48938
|
+
autoProceedOverride: s.autoProceedOverride
|
|
48939
|
+
},
|
|
48940
|
+
...s.autoProceedNudgeDone !== undefined && {
|
|
48941
|
+
autoProceedNudgeDone: s.autoProceedNudgeDone
|
|
48896
48942
|
}
|
|
48897
48943
|
};
|
|
48898
48944
|
}
|
|
@@ -56263,8 +56309,20 @@ import * as fs24 from "fs";
|
|
|
56263
56309
|
import * as path50 from "path";
|
|
56264
56310
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
56265
56311
|
if (workingDirectory == null || workingDirectory === "") {
|
|
56312
|
+
if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
|
|
56313
|
+
return {
|
|
56314
|
+
success: false,
|
|
56315
|
+
message: "Invalid working_directory: no explicit working_directory was provided and fallbackDirectory is missing or not a string"
|
|
56316
|
+
};
|
|
56317
|
+
}
|
|
56266
56318
|
return { success: true, directory: fallbackDirectory };
|
|
56267
56319
|
}
|
|
56320
|
+
if (typeof workingDirectory !== "string") {
|
|
56321
|
+
return {
|
|
56322
|
+
success: false,
|
|
56323
|
+
message: "Invalid working_directory: path must be a string"
|
|
56324
|
+
};
|
|
56325
|
+
}
|
|
56268
56326
|
if (workingDirectory.includes("\x00")) {
|
|
56269
56327
|
return {
|
|
56270
56328
|
success: false,
|
|
@@ -56280,14 +56338,14 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
56280
56338
|
};
|
|
56281
56339
|
}
|
|
56282
56340
|
}
|
|
56283
|
-
const
|
|
56284
|
-
|
|
56285
|
-
if (pathParts.includes("..")) {
|
|
56341
|
+
const rawPathParts = workingDirectory.split(path50.sep);
|
|
56342
|
+
if (rawPathParts.includes("..")) {
|
|
56286
56343
|
return {
|
|
56287
56344
|
success: false,
|
|
56288
56345
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
56289
56346
|
};
|
|
56290
56347
|
}
|
|
56348
|
+
const normalizedDir = path50.normalize(workingDirectory);
|
|
56291
56349
|
const resolvedDir = path50.resolve(normalizedDir);
|
|
56292
56350
|
let statResult;
|
|
56293
56351
|
try {
|
|
@@ -56304,6 +56362,9 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
56304
56362
|
message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
|
|
56305
56363
|
};
|
|
56306
56364
|
}
|
|
56365
|
+
if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
|
|
56366
|
+
return { success: true, directory: resolvedDir };
|
|
56367
|
+
}
|
|
56307
56368
|
const resolvedFallback = path50.resolve(fallbackDirectory);
|
|
56308
56369
|
let fallbackExists = false;
|
|
56309
56370
|
try {
|
|
@@ -56312,23 +56373,14 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
56312
56373
|
} catch {
|
|
56313
56374
|
fallbackExists = false;
|
|
56314
56375
|
}
|
|
56315
|
-
if (
|
|
56316
|
-
|
|
56317
|
-
|
|
56318
|
-
|
|
56319
|
-
|
|
56320
|
-
|
|
56321
|
-
|
|
56322
|
-
};
|
|
56323
|
-
}
|
|
56376
|
+
if (fallbackExists) {
|
|
56377
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path50.sep);
|
|
56378
|
+
if (isSubdirectory) {
|
|
56379
|
+
return {
|
|
56380
|
+
success: false,
|
|
56381
|
+
message: `Invalid working_directory: "${workingDirectory}" resolves to "${resolvedDir}" ` + `which is a subdirectory of fallback "${resolvedFallback}". ` + `Pass the project root path or omit working_directory entirely.`
|
|
56382
|
+
};
|
|
56324
56383
|
}
|
|
56325
|
-
return { success: true, directory: resolvedDir };
|
|
56326
|
-
}
|
|
56327
|
-
if (resolvedDir !== resolvedFallback) {
|
|
56328
|
-
return {
|
|
56329
|
-
success: false,
|
|
56330
|
-
message: `Invalid working_directory: path resolves to "${resolvedDir}" but fallbackDirectory ` + `"${resolvedFallback}" is not the project root. ` + `This may indicate CWD mismatch. Pass the project root path explicitly.`
|
|
56331
|
-
};
|
|
56332
56384
|
}
|
|
56333
56385
|
return { success: true, directory: resolvedDir };
|
|
56334
56386
|
}
|
|
@@ -61755,7 +61807,8 @@ var init_tool_policy = __esm(() => {
|
|
|
61755
61807
|
"sdd validate",
|
|
61756
61808
|
"sdd project",
|
|
61757
61809
|
"sync-plan",
|
|
61758
|
-
"export"
|
|
61810
|
+
"export",
|
|
61811
|
+
"auto-proceed"
|
|
61759
61812
|
];
|
|
61760
61813
|
SWARM_COMMAND_TOOL_ALLOWLIST = new Set([
|
|
61761
61814
|
"agents",
|
|
@@ -61784,7 +61837,8 @@ var init_tool_policy = __esm(() => {
|
|
|
61784
61837
|
"sdd status",
|
|
61785
61838
|
"sdd validate",
|
|
61786
61839
|
"sync-plan",
|
|
61787
|
-
"export"
|
|
61840
|
+
"export",
|
|
61841
|
+
"auto-proceed"
|
|
61788
61842
|
]);
|
|
61789
61843
|
HUMAN_ONLY_SWARM_COMMANDS = new Set([
|
|
61790
61844
|
"acknowledge-spec-drift",
|
|
@@ -61878,6 +61932,7 @@ __export(exports_commands, {
|
|
|
61878
61932
|
handleCheckpointCommand: () => handleCheckpointCommand,
|
|
61879
61933
|
handleBrainstormCommand: () => handleBrainstormCommand,
|
|
61880
61934
|
handleBenchmarkCommand: () => handleBenchmarkCommand,
|
|
61935
|
+
handleAutoProceedCommand: () => handleAutoProceedCommand,
|
|
61881
61936
|
handleArchiveCommand: () => handleArchiveCommand,
|
|
61882
61937
|
handleAnalyzeCommand: () => handleAnalyzeCommand,
|
|
61883
61938
|
handleAgentsCommand: () => handleAgentsCommand,
|
|
@@ -62130,6 +62185,7 @@ var init_commands = __esm(() => {
|
|
|
62130
62185
|
init_acknowledge_spec_drift();
|
|
62131
62186
|
init_agents();
|
|
62132
62187
|
init_archive();
|
|
62188
|
+
init_auto_proceed();
|
|
62133
62189
|
init_benchmark();
|
|
62134
62190
|
init_checkpoint2();
|
|
62135
62191
|
init_close();
|
|
@@ -62362,6 +62418,7 @@ var init_registry = __esm(() => {
|
|
|
62362
62418
|
init_acknowledge_spec_drift();
|
|
62363
62419
|
init_agents();
|
|
62364
62420
|
init_archive();
|
|
62421
|
+
init_auto_proceed();
|
|
62365
62422
|
init_benchmark();
|
|
62366
62423
|
init_checkpoint2();
|
|
62367
62424
|
init_close();
|
|
@@ -62839,6 +62896,13 @@ Subcommands:
|
|
|
62839
62896
|
details: 'Toggles Full-Auto Mode which enables autonomous execution without confirmation prompts. When enabled, the architect proceeds through implementation steps automatically. Session-scoped \u2014 resets on new session. Use "on" or "off" to set explicitly, or toggle with no argument.',
|
|
62840
62897
|
category: "utility"
|
|
62841
62898
|
},
|
|
62899
|
+
"auto-proceed": {
|
|
62900
|
+
handler: (ctx) => handleAutoProceedCommand(ctx.directory, ctx.args, ctx.sessionID),
|
|
62901
|
+
description: "Toggle or set auto-proceed override for the active session",
|
|
62902
|
+
args: "[on|off]",
|
|
62903
|
+
category: "config",
|
|
62904
|
+
details: 'Without argument, toggles auto-proceed mode. With "on" or "off", sets the state explicitly.'
|
|
62905
|
+
},
|
|
62842
62906
|
"write-retro": {
|
|
62843
62907
|
handler: (ctx) => handleWriteRetroCommand(ctx.directory, ctx.args),
|
|
62844
62908
|
description: "Write a retrospective evidence bundle for a completed phase <json>",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles the /swarm auto-proceed command.
|
|
3
|
+
* Sets or toggles the auto-proceed override for the active session.
|
|
4
|
+
*
|
|
5
|
+
* Unlike full-auto, this command has no config-level enablement requirement,
|
|
6
|
+
* no durable state, and no v2 oversight infrastructure.
|
|
7
|
+
*
|
|
8
|
+
* @param directory - Project directory (accepted for signature consistency with other command handlers; unused)
|
|
9
|
+
* @param args - Optional argument: "on" | "off" | undefined (toggle behavior)
|
|
10
|
+
* @param sessionID - Session ID for accessing active session state
|
|
11
|
+
* @returns Feedback message about auto-proceed override state
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleAutoProceedCommand(_directory: string, args: string[], sessionID: string): Promise<string>;
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { handleAcknowledgeSpecDriftCommand } from './acknowledge-spec-drift';
|
|
|
3
3
|
export { handleAgentsCommand } from './agents';
|
|
4
4
|
export { handleAnalyzeCommand } from './analyze';
|
|
5
5
|
export { handleArchiveCommand } from './archive';
|
|
6
|
+
export { handleAutoProceedCommand } from './auto-proceed';
|
|
6
7
|
export { handleBenchmarkCommand } from './benchmark';
|
|
7
8
|
export { handleBrainstormCommand } from './brainstorm';
|
|
8
9
|
export { handleCheckpointCommand } from './checkpoint';
|
|
@@ -457,6 +457,13 @@ export declare const COMMAND_REGISTRY: {
|
|
|
457
457
|
readonly details: "Toggles Full-Auto Mode which enables autonomous execution without confirmation prompts. When enabled, the architect proceeds through implementation steps automatically. Session-scoped — resets on new session. Use \"on\" or \"off\" to set explicitly, or toggle with no argument.";
|
|
458
458
|
readonly category: "utility";
|
|
459
459
|
};
|
|
460
|
+
readonly 'auto-proceed': {
|
|
461
|
+
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
462
|
+
readonly description: "Toggle or set auto-proceed override for the active session";
|
|
463
|
+
readonly args: "[on|off]";
|
|
464
|
+
readonly category: "config";
|
|
465
|
+
readonly details: "Without argument, toggles auto-proceed mode. With \"on\" or \"off\", sets the state explicitly.";
|
|
466
|
+
};
|
|
460
467
|
readonly 'write-retro': {
|
|
461
468
|
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
462
469
|
readonly description: "Write a retrospective evidence bundle for a completed phase <json>";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ResolvedSwarmCommand, SwarmCommandPolicyResult } from './command-dispatch.js';
|
|
2
|
-
export declare const SWARM_COMMAND_TOOL_COMMANDS: readonly ["agents", "config", "config doctor", "doctor tools", "status", "show-plan", "help", "history", "evidence", "evidence summary", "retrieve", "diagnose", "preflight", "benchmark", "knowledge", "memory", "memory status", "memory pending", "memory recall-log", "memory compact", "memory stale", "memory export", "memory evaluate", "memory import", "memory migrate", "sdd", "sdd status", "sdd validate", "sdd project", "sync-plan", "export"];
|
|
2
|
+
export declare const SWARM_COMMAND_TOOL_COMMANDS: readonly ["agents", "config", "config doctor", "doctor tools", "status", "show-plan", "help", "history", "evidence", "evidence summary", "retrieve", "diagnose", "preflight", "benchmark", "knowledge", "memory", "memory status", "memory pending", "memory recall-log", "memory compact", "memory stale", "memory export", "memory evaluate", "memory import", "memory migrate", "sdd", "sdd status", "sdd validate", "sdd project", "sync-plan", "export", "auto-proceed"];
|
|
3
3
|
export type SwarmCommandToolInputCommand = (typeof SWARM_COMMAND_TOOL_COMMANDS)[number];
|
|
4
4
|
export declare const SWARM_COMMAND_TOOL_ALLOWLIST: Set<string>;
|
|
5
5
|
/**
|
|
@@ -73,8 +73,10 @@ export declare const COMPACTION_DEFAULTS: {
|
|
|
73
73
|
};
|
|
74
74
|
export declare const TURBO_MODE_BANNER = "## \uD83D\uDE80 TURBO MODE ACTIVE\n\n**Speed optimization enabled for this session.**\n\nWhile Turbo Mode is active:\n- **Stage A gates** (lint, imports, pre_check_batch) are still REQUIRED for ALL tasks\n- **Tier 3 tasks** (security-sensitive files matching: architect*.ts, delegation*.ts, guardrails*.ts, adversarial*.ts, sanitiz*.ts, auth*, permission*, crypto*, secret*, security) still require FULL review (Stage B)\n- **Tier 0-2 tasks** can skip Stage B (reviewer, test_engineer) to speed up execution\n- **Phase completion gates** (completion-verify and drift verification gate) are automatically bypassed \u2014 phase_complete will succeed without drift verification evidence when turbo is active. Note: turbo bypass is session-scoped; one session's turbo does not affect other sessions.\n\nClassification still determines the pipeline:\n- TIER 0 (metadata): lint + diff only \u2014 no change\n- TIER 1 (docs): Stage A + reviewer \u2014 no change\n- TIER 2 (standard code): Stage A + reviewer + test_engineer \u2014 CAN SKIP Stage B with turboMode\n- TIER 3 (critical): Stage A + 2x reviewer + 2x test_engineer \u2014 Stage B REQUIRED (no turbo bypass)\n\nDo NOT skip Stage A gates. Do NOT skip Stage B for TIER 3.\n";
|
|
75
75
|
export declare const FULL_AUTO_BANNER = "## \u26A1 FULL-AUTO MODE ACTIVE\n\nYou are operating without a human in the loop. All escalations route to the Autonomous Oversight Critic instead of a user.\n\nBehavioral changes:\n- TIER 3 escalations go to the critic, not a human. Frame your questions technically, not conversationally.\n- Phase completion approval comes from the critic. Ensure all evidence is written before requesting.\n- The critic defaults to REJECT. Do not attempt to pressure, negotiate, or shortcut. Complete the evidence trail.\n- If the critic returns ESCALATE_TO_HUMAN, the session will pause or terminate. Only the critic can trigger this.\n- Do NOT ask \"Ready for Phase N+1?\" \u2014 call phase_complete directly. The critic reviews automatically.\n";
|
|
76
|
+
export declare const AUTO_PROCEED_BANNER = "## \u23ED\uFE0F AUTO-PROCEED STATUS\n\nAuto-proceed controls whether the architect advances to the next phase automatically (skipping the \"Ready for Phase N+1?\" confirmation).\n\nBehavioral rules:\n- Session override (set via /swarm auto-proceed on|off) wins over the plan default.\n- If neither is set, auto-proceed defaults to OFF and the architect asks before advancing.\n- Full-auto mode (critic oversight) is independent \u2014 it has its own auto-advance mechanism.\n- autoProceedNudgeDone prevents the FR-004 first-boundary nudge from re-firing in this session.\n\nTo toggle at runtime: call swarm_command({ command: \"auto-proceed\", args: [\"on\"|\"off\"] }) from the architect.\n";
|
|
76
77
|
/**
|
|
77
78
|
* Canonical default Lean Turbo configuration.
|
|
79
|
+
|
|
78
80
|
*
|
|
79
81
|
* This is the single source of truth for all LeanTurboConfig fields.
|
|
80
82
|
* Consumers MUST reference this constant instead of hardcoding their own
|
|
@@ -4,6 +4,7 @@ export declare const ExecutionProfileSchema: z.ZodObject<{
|
|
|
4
4
|
max_concurrent_tasks: z.ZodDefault<z.ZodNumber>;
|
|
5
5
|
council_parallel: z.ZodDefault<z.ZodBoolean>;
|
|
6
6
|
locked: z.ZodDefault<z.ZodBoolean>;
|
|
7
|
+
auto_proceed: z.ZodDefault<z.ZodBoolean>;
|
|
7
8
|
}, z.core.$strip>;
|
|
8
9
|
export type ExecutionProfile = z.infer<typeof ExecutionProfileSchema>;
|
|
9
10
|
export declare const TaskStatusSchema: z.ZodEnum<{
|
|
@@ -166,6 +167,7 @@ export declare const PlanSchema: z.ZodObject<{
|
|
|
166
167
|
max_concurrent_tasks: z.ZodDefault<z.ZodNumber>;
|
|
167
168
|
council_parallel: z.ZodDefault<z.ZodBoolean>;
|
|
168
169
|
locked: z.ZodDefault<z.ZodBoolean>;
|
|
170
|
+
auto_proceed: z.ZodDefault<z.ZodBoolean>;
|
|
169
171
|
}, z.core.$strip>>;
|
|
170
172
|
}, z.core.$strip>;
|
|
171
173
|
export type Plan = z.infer<typeof PlanSchema>;
|
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ var package_default;
|
|
|
69
69
|
var init_package = __esm(() => {
|
|
70
70
|
package_default = {
|
|
71
71
|
name: "opencode-swarm",
|
|
72
|
-
version: "7.
|
|
72
|
+
version: "7.66.1",
|
|
73
73
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
74
74
|
main: "dist/index.js",
|
|
75
75
|
types: "dist/index.d.ts",
|
|
@@ -851,6 +851,17 @@ Behavioral changes:
|
|
|
851
851
|
- The critic defaults to REJECT. Do not attempt to pressure, negotiate, or shortcut. Complete the evidence trail.
|
|
852
852
|
- If the critic returns ESCALATE_TO_HUMAN, the session will pause or terminate. Only the critic can trigger this.
|
|
853
853
|
- Do NOT ask "Ready for Phase N+1?" — call phase_complete directly. The critic reviews automatically.
|
|
854
|
+
`, AUTO_PROCEED_BANNER = `## ⏭️ AUTO-PROCEED STATUS
|
|
855
|
+
|
|
856
|
+
Auto-proceed controls whether the architect advances to the next phase automatically (skipping the "Ready for Phase N+1?" confirmation).
|
|
857
|
+
|
|
858
|
+
Behavioral rules:
|
|
859
|
+
- Session override (set via /swarm auto-proceed on|off) wins over the plan default.
|
|
860
|
+
- If neither is set, auto-proceed defaults to OFF and the architect asks before advancing.
|
|
861
|
+
- Full-auto mode (critic oversight) is independent — it has its own auto-advance mechanism.
|
|
862
|
+
- autoProceedNudgeDone prevents the FR-004 first-boundary nudge from re-firing in this session.
|
|
863
|
+
|
|
864
|
+
To toggle at runtime: call swarm_command({ command: "auto-proceed", args: ["on"|"off"] }) from the architect.
|
|
854
865
|
`, DEFAULT_LEAN_TURBO_CONFIG, DEFAULT_WORKTREE_ISOLATION_CONFIG, LEAN_TURBO_BANNER = `## \uD83D\uDEE4️ LEAN TURBO ACTIVE
|
|
855
866
|
|
|
856
867
|
Lane-based parallel execution is enabled for this phase.
|
|
@@ -16568,7 +16579,8 @@ var init_plan_schema = __esm(() => {
|
|
|
16568
16579
|
parallelization_enabled: exports_external.boolean().default(false),
|
|
16569
16580
|
max_concurrent_tasks: exports_external.number().int().min(1).max(64).default(1),
|
|
16570
16581
|
council_parallel: exports_external.boolean().default(false),
|
|
16571
|
-
locked: exports_external.boolean().default(false)
|
|
16582
|
+
locked: exports_external.boolean().default(false),
|
|
16583
|
+
auto_proceed: exports_external.boolean().default(false)
|
|
16572
16584
|
});
|
|
16573
16585
|
TaskStatusSchema = exports_external.enum([
|
|
16574
16586
|
"pending",
|
|
@@ -43164,6 +43176,7 @@ __export(exports_state, {
|
|
|
43164
43176
|
getTaskState: () => getTaskState,
|
|
43165
43177
|
getSessionEnvironment: () => getSessionEnvironment,
|
|
43166
43178
|
getRunContext: () => getRunContext,
|
|
43179
|
+
getResolvedAutoProceed: () => getResolvedAutoProceed,
|
|
43167
43180
|
getAgentSession: () => getAgentSession,
|
|
43168
43181
|
getActiveWindow: () => getActiveWindow,
|
|
43169
43182
|
ensureSessionEnvironment: () => ensureSessionEnvironment,
|
|
@@ -43873,6 +43886,9 @@ function hasActiveLeanTurbo(sessionID) {
|
|
|
43873
43886
|
}
|
|
43874
43887
|
return false;
|
|
43875
43888
|
}
|
|
43889
|
+
function getResolvedAutoProceed(session, planAutoProceed) {
|
|
43890
|
+
return session.autoProceedOverride ?? planAutoProceed ?? false;
|
|
43891
|
+
}
|
|
43876
43892
|
function setSessionEnvironment(sessionId, profile) {
|
|
43877
43893
|
swarmState.environmentProfiles.set(sessionId, profile);
|
|
43878
43894
|
}
|
|
@@ -43979,6 +43995,45 @@ var init_state = __esm(() => {
|
|
|
43979
43995
|
};
|
|
43980
43996
|
});
|
|
43981
43997
|
|
|
43998
|
+
// src/commands/auto-proceed.ts
|
|
43999
|
+
async function handleAutoProceedCommand(_directory, args2, sessionID) {
|
|
44000
|
+
if (!sessionID || sessionID.trim() === "") {
|
|
44001
|
+
return "Error: No active session context. Auto-proceed requires an active session. Use /swarm auto-proceed from within an OpenCode session, or start a session first.";
|
|
44002
|
+
}
|
|
44003
|
+
const session = getAgentSession(sessionID);
|
|
44004
|
+
if (!session) {
|
|
44005
|
+
return "Error: No active session. Auto-proceed requires an active session to operate.";
|
|
44006
|
+
}
|
|
44007
|
+
if (stripKnownSwarmPrefix(session.agentName) !== "architect") {
|
|
44008
|
+
return `Error: Auto-proceed can only be toggled from the architect session. Currently active session is: ${session.agentName}`;
|
|
44009
|
+
}
|
|
44010
|
+
const arg = args2[0]?.toLowerCase();
|
|
44011
|
+
const wasUndefinedBefore = session.autoProceedOverride === undefined;
|
|
44012
|
+
let newAutoProceedOverride;
|
|
44013
|
+
if (arg === "on") {
|
|
44014
|
+
newAutoProceedOverride = true;
|
|
44015
|
+
} else if (arg === "off") {
|
|
44016
|
+
newAutoProceedOverride = false;
|
|
44017
|
+
} else if (arg === undefined) {
|
|
44018
|
+
newAutoProceedOverride = !session.autoProceedOverride;
|
|
44019
|
+
} else {
|
|
44020
|
+
return 'Error: Invalid argument for /swarm auto-proceed. Valid options: "on", "off", or omit the argument to toggle.';
|
|
44021
|
+
}
|
|
44022
|
+
session.autoProceedOverride = newAutoProceedOverride;
|
|
44023
|
+
if (arg === "on" || arg === "off" || arg === undefined && wasUndefinedBefore) {
|
|
44024
|
+
session.autoProceedNudgeDone = true;
|
|
44025
|
+
}
|
|
44026
|
+
if (newAutoProceedOverride) {
|
|
44027
|
+
return "Auto-proceed is now ON. Phase boundaries will advance automatically.";
|
|
44028
|
+
} else {
|
|
44029
|
+
return "Auto-proceed is now OFF. You will be asked before advancing to the next phase.";
|
|
44030
|
+
}
|
|
44031
|
+
}
|
|
44032
|
+
var init_auto_proceed = __esm(() => {
|
|
44033
|
+
init_schema();
|
|
44034
|
+
init_state();
|
|
44035
|
+
});
|
|
44036
|
+
|
|
43982
44037
|
// src/commands/benchmark.ts
|
|
43983
44038
|
async function handleBenchmarkCommand(directory, args2) {
|
|
43984
44039
|
let cumulative = args2.includes("--cumulative");
|
|
@@ -72140,6 +72195,12 @@ function serializeAgentSession(s) {
|
|
|
72140
72195
|
...Object.keys(stageBCompletion).length > 0 && { stageBCompletion },
|
|
72141
72196
|
...s.maxConcurrencyOverride !== undefined && {
|
|
72142
72197
|
maxConcurrencyOverride: s.maxConcurrencyOverride
|
|
72198
|
+
},
|
|
72199
|
+
...s.autoProceedOverride !== undefined && {
|
|
72200
|
+
autoProceedOverride: s.autoProceedOverride
|
|
72201
|
+
},
|
|
72202
|
+
...s.autoProceedNudgeDone !== undefined && {
|
|
72203
|
+
autoProceedNudgeDone: s.autoProceedNudgeDone
|
|
72143
72204
|
}
|
|
72144
72205
|
};
|
|
72145
72206
|
}
|
|
@@ -80553,8 +80614,20 @@ import * as fs35 from "node:fs";
|
|
|
80553
80614
|
import * as path67 from "node:path";
|
|
80554
80615
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
80555
80616
|
if (workingDirectory == null || workingDirectory === "") {
|
|
80617
|
+
if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
|
|
80618
|
+
return {
|
|
80619
|
+
success: false,
|
|
80620
|
+
message: "Invalid working_directory: no explicit working_directory was provided and fallbackDirectory is missing or not a string"
|
|
80621
|
+
};
|
|
80622
|
+
}
|
|
80556
80623
|
return { success: true, directory: fallbackDirectory };
|
|
80557
80624
|
}
|
|
80625
|
+
if (typeof workingDirectory !== "string") {
|
|
80626
|
+
return {
|
|
80627
|
+
success: false,
|
|
80628
|
+
message: "Invalid working_directory: path must be a string"
|
|
80629
|
+
};
|
|
80630
|
+
}
|
|
80558
80631
|
if (workingDirectory.includes("\x00")) {
|
|
80559
80632
|
return {
|
|
80560
80633
|
success: false,
|
|
@@ -80570,14 +80643,14 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
80570
80643
|
};
|
|
80571
80644
|
}
|
|
80572
80645
|
}
|
|
80573
|
-
const
|
|
80574
|
-
|
|
80575
|
-
if (pathParts.includes("..")) {
|
|
80646
|
+
const rawPathParts = workingDirectory.split(path67.sep);
|
|
80647
|
+
if (rawPathParts.includes("..")) {
|
|
80576
80648
|
return {
|
|
80577
80649
|
success: false,
|
|
80578
80650
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
80579
80651
|
};
|
|
80580
80652
|
}
|
|
80653
|
+
const normalizedDir = path67.normalize(workingDirectory);
|
|
80581
80654
|
const resolvedDir = path67.resolve(normalizedDir);
|
|
80582
80655
|
let statResult;
|
|
80583
80656
|
try {
|
|
@@ -80594,6 +80667,9 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
80594
80667
|
message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
|
|
80595
80668
|
};
|
|
80596
80669
|
}
|
|
80670
|
+
if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
|
|
80671
|
+
return { success: true, directory: resolvedDir };
|
|
80672
|
+
}
|
|
80597
80673
|
const resolvedFallback = path67.resolve(fallbackDirectory);
|
|
80598
80674
|
let fallbackExists = false;
|
|
80599
80675
|
try {
|
|
@@ -80602,23 +80678,14 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
80602
80678
|
} catch {
|
|
80603
80679
|
fallbackExists = false;
|
|
80604
80680
|
}
|
|
80605
|
-
if (
|
|
80606
|
-
|
|
80607
|
-
|
|
80608
|
-
|
|
80609
|
-
|
|
80610
|
-
|
|
80611
|
-
|
|
80612
|
-
};
|
|
80613
|
-
}
|
|
80681
|
+
if (fallbackExists) {
|
|
80682
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path67.sep);
|
|
80683
|
+
if (isSubdirectory) {
|
|
80684
|
+
return {
|
|
80685
|
+
success: false,
|
|
80686
|
+
message: `Invalid working_directory: "${workingDirectory}" resolves to "${resolvedDir}" ` + `which is a subdirectory of fallback "${resolvedFallback}". ` + `Pass the project root path or omit working_directory entirely.`
|
|
80687
|
+
};
|
|
80614
80688
|
}
|
|
80615
|
-
return { success: true, directory: resolvedDir };
|
|
80616
|
-
}
|
|
80617
|
-
if (resolvedDir !== resolvedFallback) {
|
|
80618
|
-
return {
|
|
80619
|
-
success: false,
|
|
80620
|
-
message: `Invalid working_directory: path resolves to "${resolvedDir}" but fallbackDirectory ` + `"${resolvedFallback}" is not the project root. ` + `This may indicate CWD mismatch. Pass the project root path explicitly.`
|
|
80621
|
-
};
|
|
80622
80689
|
}
|
|
80623
80690
|
return { success: true, directory: resolvedDir };
|
|
80624
80691
|
}
|
|
@@ -86457,7 +86524,8 @@ var init_tool_policy = __esm(() => {
|
|
|
86457
86524
|
"sdd validate",
|
|
86458
86525
|
"sdd project",
|
|
86459
86526
|
"sync-plan",
|
|
86460
|
-
"export"
|
|
86527
|
+
"export",
|
|
86528
|
+
"auto-proceed"
|
|
86461
86529
|
];
|
|
86462
86530
|
SWARM_COMMAND_TOOL_ALLOWLIST = new Set([
|
|
86463
86531
|
"agents",
|
|
@@ -86486,7 +86554,8 @@ var init_tool_policy = __esm(() => {
|
|
|
86486
86554
|
"sdd status",
|
|
86487
86555
|
"sdd validate",
|
|
86488
86556
|
"sync-plan",
|
|
86489
|
-
"export"
|
|
86557
|
+
"export",
|
|
86558
|
+
"auto-proceed"
|
|
86490
86559
|
]);
|
|
86491
86560
|
HUMAN_ONLY_SWARM_COMMANDS = new Set([
|
|
86492
86561
|
"acknowledge-spec-drift",
|
|
@@ -86580,6 +86649,7 @@ __export(exports_commands, {
|
|
|
86580
86649
|
handleCheckpointCommand: () => handleCheckpointCommand,
|
|
86581
86650
|
handleBrainstormCommand: () => handleBrainstormCommand,
|
|
86582
86651
|
handleBenchmarkCommand: () => handleBenchmarkCommand,
|
|
86652
|
+
handleAutoProceedCommand: () => handleAutoProceedCommand,
|
|
86583
86653
|
handleArchiveCommand: () => handleArchiveCommand,
|
|
86584
86654
|
handleAnalyzeCommand: () => handleAnalyzeCommand,
|
|
86585
86655
|
handleAgentsCommand: () => handleAgentsCommand,
|
|
@@ -86832,6 +86902,7 @@ var init_commands = __esm(() => {
|
|
|
86832
86902
|
init_acknowledge_spec_drift();
|
|
86833
86903
|
init_agents();
|
|
86834
86904
|
init_archive();
|
|
86905
|
+
init_auto_proceed();
|
|
86835
86906
|
init_benchmark();
|
|
86836
86907
|
init_checkpoint2();
|
|
86837
86908
|
init_close();
|
|
@@ -87064,6 +87135,7 @@ var init_registry = __esm(() => {
|
|
|
87064
87135
|
init_acknowledge_spec_drift();
|
|
87065
87136
|
init_agents();
|
|
87066
87137
|
init_archive();
|
|
87138
|
+
init_auto_proceed();
|
|
87067
87139
|
init_benchmark();
|
|
87068
87140
|
init_checkpoint2();
|
|
87069
87141
|
init_close();
|
|
@@ -87541,6 +87613,13 @@ Subcommands:
|
|
|
87541
87613
|
details: 'Toggles Full-Auto Mode which enables autonomous execution without confirmation prompts. When enabled, the architect proceeds through implementation steps automatically. Session-scoped — resets on new session. Use "on" or "off" to set explicitly, or toggle with no argument.',
|
|
87542
87614
|
category: "utility"
|
|
87543
87615
|
},
|
|
87616
|
+
"auto-proceed": {
|
|
87617
|
+
handler: (ctx) => handleAutoProceedCommand(ctx.directory, ctx.args, ctx.sessionID),
|
|
87618
|
+
description: "Toggle or set auto-proceed override for the active session",
|
|
87619
|
+
args: "[on|off]",
|
|
87620
|
+
category: "config",
|
|
87621
|
+
details: 'Without argument, toggles auto-proceed mode. With "on" or "off", sets the state explicitly.'
|
|
87622
|
+
},
|
|
87544
87623
|
"write-retro": {
|
|
87545
87624
|
handler: (ctx) => handleWriteRetroCommand(ctx.directory, ctx.args),
|
|
87546
87625
|
description: "Write a retrospective evidence bundle for a completed phase <json>",
|
|
@@ -89004,6 +89083,9 @@ INLINE GATE SELECTION -- no pending section found in context.md. You MUST ask no
|
|
|
89004
89083
|
|
|
89005
89084
|
MANDATORY PAUSE: Present the gate question. Wait for the user's answer.
|
|
89006
89085
|
Do NOT call \`set_qa_gates\` until the user has responded.
|
|
89086
|
+
|
|
89087
|
+
Execution preferences (auto-proceed phase transitions):
|
|
89088
|
+
- \`auto_proceed\` (boolean, default false): When true, the architect auto-advances to the next phase without asking "Ready for Phase N+1?". Runtime toggle via /swarm auto-proceed on|off.
|
|
89007
89089
|
<!-- BEHAVIORAL_GUIDANCE_END -->
|
|
89008
89090
|
- Preserve task granularity, test task deduplication, phase count guidance, and TRACEABILITY CHECK rules from the loaded skill.
|
|
89009
89091
|
|
|
@@ -89049,6 +89131,17 @@ ACTION: Load skill file:.opencode/skills/phase-wrap/SKILL.md immediately. Follow
|
|
|
89049
89131
|
|
|
89050
89132
|
HARD CONSTRAINTS:
|
|
89051
89133
|
- Complete retrospective evidence with \`write_retro\` before \`phase_complete\`.
|
|
89134
|
+
- Before step 7 (phase transition): read the AUTO_PROCEED STATUS banner injected into your context. The banner tells you:
|
|
89135
|
+
- auto-proceed state (on/off)
|
|
89136
|
+
- source (session override vs plan-or-default)
|
|
89137
|
+
- nudge flag (true if user has already been asked or has explicitly toggled)
|
|
89138
|
+
- If auto-proceed is ON (banner shows "on"): call \`phase_complete\`, then advance to the first task of the next phase. Do NOT ask the user.
|
|
89139
|
+
- If auto-proceed is OFF (banner shows "off") AND nudge flag is false: after the user confirms the phase transition, suggest enabling auto-proceed with: "Auto-proceed is currently disabled. Would you like me to automatically advance to future phases without asking?" Then:
|
|
89140
|
+
- On YES: call \`swarm_command({ command: "auto-proceed", args: ["on"] })\` — this sets both override and nudge-done
|
|
89141
|
+
- On NO: call \`swarm_command({ command: "auto-proceed", args: ["off"] })\` — this sets override=false and nudge-done=true
|
|
89142
|
+
- If auto-proceed is OFF AND nudge flag is true: just ask "Ready for Phase [N+1]?" as before.
|
|
89143
|
+
- SC-001: auto-proceed only skips the phase-transition confirmation. The architect MUST still stop for blocked tasks, user questions, clarification needs, and any decision requiring human input. This behavior is NOT affected by the auto_proceed setting.
|
|
89144
|
+
- Full-auto mode (critic oversight) is independent — its existing "Do NOT ask Ready for Phase N+1?" override continues to work. auto_proceed has no additional effect under full-auto.
|
|
89052
89145
|
|
|
89053
89146
|
> **NOTE**: The \`critic_oversight\` agent (\`AUTONOMOUS_OVERSIGHT_PROMPT\`) is dispatched only via full-auto mode (\`src/full-auto/oversight.ts\`). It has no architect MODE dispatch path — it is **NOT** reachable from \`MODE: CRITIC-GATE\`, \`MODE: EXECUTE\`, or \`MODE: PHASE-WRAP\`. This is intentional: it serves as the sole quality gate in autonomous oversight mode.
|
|
89054
89147
|
|
|
@@ -97920,7 +98013,7 @@ var init_design_doc_drift = __esm(() => {
|
|
|
97920
98013
|
var exports_project_context = {};
|
|
97921
98014
|
__export(exports_project_context, {
|
|
97922
98015
|
buildProjectContext: () => buildProjectContext,
|
|
97923
|
-
_internals: () =>
|
|
98016
|
+
_internals: () => _internals91,
|
|
97924
98017
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
97925
98018
|
});
|
|
97926
98019
|
import * as fs135 from "node:fs";
|
|
@@ -98004,7 +98097,7 @@ function selectLintCommand(backend, directory) {
|
|
|
98004
98097
|
return null;
|
|
98005
98098
|
}
|
|
98006
98099
|
async function buildProjectContext(directory) {
|
|
98007
|
-
const backend = await
|
|
98100
|
+
const backend = await _internals91.pickBackend(directory);
|
|
98008
98101
|
if (!backend)
|
|
98009
98102
|
return null;
|
|
98010
98103
|
const ctx = emptyProjectContext();
|
|
@@ -98043,17 +98136,17 @@ async function buildProjectContext(directory) {
|
|
|
98043
98136
|
if (backend.prompts.reviewerChecklist.length > 0) {
|
|
98044
98137
|
ctx.REVIEWER_CHECKLIST = bulletList(backend.prompts.reviewerChecklist);
|
|
98045
98138
|
}
|
|
98046
|
-
const profiles =
|
|
98139
|
+
const profiles = _internals91.pickedProfiles(directory);
|
|
98047
98140
|
if (profiles.length > 1) {
|
|
98048
98141
|
ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES = profiles.slice(1).map((p) => p.id).join(", ");
|
|
98049
98142
|
}
|
|
98050
98143
|
return ctx;
|
|
98051
98144
|
}
|
|
98052
|
-
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300,
|
|
98145
|
+
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals91;
|
|
98053
98146
|
var init_project_context = __esm(() => {
|
|
98054
98147
|
init_dispatch();
|
|
98055
98148
|
init_framework_detector();
|
|
98056
|
-
|
|
98149
|
+
_internals91 = {
|
|
98057
98150
|
pickBackend,
|
|
98058
98151
|
pickedProfiles
|
|
98059
98152
|
};
|
|
@@ -103238,6 +103331,7 @@ init_schema();
|
|
|
103238
103331
|
init_manager2();
|
|
103239
103332
|
init_detector();
|
|
103240
103333
|
init_manager();
|
|
103334
|
+
init_state();
|
|
103241
103335
|
import * as fs71 from "node:fs";
|
|
103242
103336
|
import * as path114 from "node:path";
|
|
103243
103337
|
|
|
@@ -103531,7 +103625,6 @@ init_preflight_service();
|
|
|
103531
103625
|
init_status_service();
|
|
103532
103626
|
|
|
103533
103627
|
// src/hooks/system-enhancer.ts
|
|
103534
|
-
init_state();
|
|
103535
103628
|
init_telemetry();
|
|
103536
103629
|
init_utils();
|
|
103537
103630
|
|
|
@@ -106637,6 +106730,20 @@ ${lines.join(`
|
|
|
106637
106730
|
tryInject(LEAN_TURBO_BANNER);
|
|
106638
106731
|
}
|
|
106639
106732
|
}
|
|
106733
|
+
const sessionIdAutoProceed = _input.sessionID;
|
|
106734
|
+
if (sessionIdAutoProceed) {
|
|
106735
|
+
const sessionAutoProceed = getAgentSession(sessionIdAutoProceed);
|
|
106736
|
+
if (sessionAutoProceed && stripKnownSwarmPrefix(sessionAutoProceed.agentName) === "architect") {
|
|
106737
|
+
const resolvedAutoProceed = getResolvedAutoProceed(sessionAutoProceed, plan2?.execution_profile?.auto_proceed);
|
|
106738
|
+
const source = sessionAutoProceed.autoProceedOverride !== undefined ? "session" : "plan-or-default";
|
|
106739
|
+
const banner = `${AUTO_PROCEED_BANNER}
|
|
106740
|
+
## ⏭️ AUTO_PROCEED STATUS:
|
|
106741
|
+
- auto-proceed: ${resolvedAutoProceed ? "on" : "off"}
|
|
106742
|
+
- source: ${source}
|
|
106743
|
+
- nudge: ${sessionAutoProceed.autoProceedNudgeDone ? "true" : "false"}`;
|
|
106744
|
+
tryInject(banner);
|
|
106745
|
+
}
|
|
106746
|
+
}
|
|
106640
106747
|
try {
|
|
106641
106748
|
const currentPhaseNum = plan2?.current_phase ?? 1;
|
|
106642
106749
|
const retroText = await buildRetroInjection(directory, currentPhaseNum, plan2?.title ?? undefined);
|
|
@@ -112462,7 +112569,9 @@ var TRANSIENT_SESSION_FIELDS = [
|
|
|
112462
112569
|
{ name: "model_fallback_index", resetValue: 0 },
|
|
112463
112570
|
{ name: "modelFallbackExhausted", resetValue: false },
|
|
112464
112571
|
{ name: "scopeViolationDetected", resetValue: false },
|
|
112465
|
-
{ name: "delegationActive", resetValue: false }
|
|
112572
|
+
{ name: "delegationActive", resetValue: false },
|
|
112573
|
+
{ name: "autoProceedOverride", resetValue: undefined },
|
|
112574
|
+
{ name: "autoProceedNudgeDone", resetValue: undefined }
|
|
112466
112575
|
];
|
|
112467
112576
|
var VALID_TASK_WORKFLOW_STATES = [
|
|
112468
112577
|
"idle",
|
|
@@ -112563,6 +112672,8 @@ function deserializeAgentSession(s) {
|
|
|
112563
112672
|
fullAutoDeadlockCount: s.fullAutoDeadlockCount ?? 0,
|
|
112564
112673
|
fullAutoLastQuestionHash: s.fullAutoLastQuestionHash ?? null,
|
|
112565
112674
|
maxConcurrencyOverride: typeof s.maxConcurrencyOverride === "number" ? Math.min(64, Math.max(1, s.maxConcurrencyOverride)) : undefined,
|
|
112675
|
+
autoProceedOverride: s.autoProceedOverride,
|
|
112676
|
+
autoProceedNudgeDone: s.autoProceedNudgeDone,
|
|
112566
112677
|
prmPatternCounts: new Map,
|
|
112567
112678
|
prmEscalationLevel: 0,
|
|
112568
112679
|
prmLastPatternDetected: null,
|
|
@@ -131215,7 +131326,7 @@ init_effective_spec();
|
|
|
131215
131326
|
init_state();
|
|
131216
131327
|
init_create_tool();
|
|
131217
131328
|
function executionProfilesEqual(a, b) {
|
|
131218
|
-
return a.parallelization_enabled === b.parallelization_enabled && a.max_concurrent_tasks === b.max_concurrent_tasks && a.council_parallel === b.council_parallel && a.locked === b.locked;
|
|
131329
|
+
return a.parallelization_enabled === b.parallelization_enabled && a.max_concurrent_tasks === b.max_concurrent_tasks && a.council_parallel === b.council_parallel && a.locked === b.locked && a.auto_proceed === b.auto_proceed;
|
|
131219
131330
|
}
|
|
131220
131331
|
function detectPlaceholderContent(args2) {
|
|
131221
131332
|
const issues = [];
|
|
@@ -131409,7 +131520,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
131409
131520
|
success: false,
|
|
131410
131521
|
message: "Invalid execution_profile: schema validation failed",
|
|
131411
131522
|
errors: requestedProfile.error.issues.map((i2) => `${i2.path.join(".")}: ${i2.message}`),
|
|
131412
|
-
recovery_guidance: "Check execution_profile fields: parallelization_enabled (boolean), " + "max_concurrent_tasks (integer 1-64), council_parallel (boolean), locked (boolean)."
|
|
131523
|
+
recovery_guidance: "Check execution_profile fields: parallelization_enabled (boolean), " + "max_concurrent_tasks (integer 1-64), council_parallel (boolean), locked (boolean), auto_proceed (boolean)."
|
|
131413
131524
|
};
|
|
131414
131525
|
}
|
|
131415
131526
|
if (executionProfilesEqual(existing.execution_profile, requestedProfile.data)) {
|
|
@@ -131699,7 +131810,8 @@ var save_plan = createSwarmTool({
|
|
|
131699
131810
|
parallelization_enabled: exports_external.boolean().optional().describe("When true, enables parallel task dispatch for this plan. Default false (serial)."),
|
|
131700
131811
|
max_concurrent_tasks: exports_external.number().int().min(1).max(64).optional().describe("Maximum tasks that may run concurrently when parallelization is enabled. Default 1."),
|
|
131701
131812
|
council_parallel: exports_external.boolean().optional().describe("When true, council review phases may run in parallel. Default false."),
|
|
131702
|
-
locked: exports_external.boolean().optional().describe("When true, locks the profile — future save_plan calls that include " + "execution_profile will be rejected (fail-closed). " + "Unlock by resetting the plan (reset_statuses: true).")
|
|
131813
|
+
locked: exports_external.boolean().optional().describe("When true, locks the profile — future save_plan calls that include " + "execution_profile will be rejected (fail-closed). " + "Unlock by resetting the plan (reset_statuses: true)."),
|
|
131814
|
+
auto_proceed: exports_external.boolean().optional().describe("When true, the architect advances to the next phase automatically without asking for confirmation. Default false.")
|
|
131703
131815
|
}).optional().describe("Architect-facing concurrency controls. Once locked, cannot be changed without resetting. " + "Omit to preserve the existing profile.")
|
|
131704
131816
|
},
|
|
131705
131817
|
execute: async (args2, _directory) => {
|
|
@@ -135859,6 +135971,11 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
135859
135971
|
init_task_id();
|
|
135860
135972
|
init_create_tool();
|
|
135861
135973
|
init_resolve_working_directory();
|
|
135974
|
+
var _internals89 = {
|
|
135975
|
+
tryAcquireLock,
|
|
135976
|
+
updateTaskStatus,
|
|
135977
|
+
resolveWorkingDirectory
|
|
135978
|
+
};
|
|
135862
135979
|
var VALID_STATUSES2 = [
|
|
135863
135980
|
"pending",
|
|
135864
135981
|
"in_progress",
|
|
@@ -135951,7 +136068,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
135951
136068
|
}
|
|
135952
136069
|
let resolvedDir;
|
|
135953
136070
|
if (fallbackDir) {
|
|
135954
|
-
const resolveResult = resolveWorkingDirectory(workingDirectory, fallbackDir);
|
|
136071
|
+
const resolveResult = _internals89.resolveWorkingDirectory(workingDirectory, fallbackDir);
|
|
135955
136072
|
if (resolveResult.success) {
|
|
135956
136073
|
resolvedDir = resolveResult.directory;
|
|
135957
136074
|
} else {
|
|
@@ -136298,14 +136415,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
136298
136415
|
}
|
|
136299
136416
|
}
|
|
136300
136417
|
let directory;
|
|
136301
|
-
|
|
136302
|
-
return {
|
|
136303
|
-
success: false,
|
|
136304
|
-
message: "No working_directory provided and fallbackDir is undefined",
|
|
136305
|
-
errors: ["Cannot resolve directory for task status update"]
|
|
136306
|
-
};
|
|
136307
|
-
}
|
|
136308
|
-
const resolveResult = resolveWorkingDirectory(args2.working_directory ?? fallbackDir, fallbackDir);
|
|
136418
|
+
const resolveResult = _internals89.resolveWorkingDirectory(args2.working_directory, fallbackDir);
|
|
136309
136419
|
if (!resolveResult.success) {
|
|
136310
136420
|
return {
|
|
136311
136421
|
success: false,
|
|
@@ -136398,7 +136508,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
136398
136508
|
}
|
|
136399
136509
|
let lockResult;
|
|
136400
136510
|
try {
|
|
136401
|
-
lockResult = await tryAcquireLock(directory, planFilePath, agentName, lockTaskId);
|
|
136511
|
+
lockResult = await _internals89.tryAcquireLock(directory, planFilePath, agentName, lockTaskId);
|
|
136402
136512
|
} catch (error93) {
|
|
136403
136513
|
return {
|
|
136404
136514
|
success: false,
|
|
@@ -136417,7 +136527,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
136417
136527
|
};
|
|
136418
136528
|
}
|
|
136419
136529
|
try {
|
|
136420
|
-
const updatedPlan = await updateTaskStatus(directory, args2.task_id, args2.status);
|
|
136530
|
+
const updatedPlan = await _internals89.updateTaskStatus(directory, args2.task_id, args2.status);
|
|
136421
136531
|
if (args2.status === "completed") {
|
|
136422
136532
|
for (const [_sessionId, session] of swarmState.agentSessions) {
|
|
136423
136533
|
if (!(session.taskWorkflowStates instanceof Map)) {
|
|
@@ -136841,7 +136951,7 @@ var web_search = createSwarmTool({
|
|
|
136841
136951
|
});
|
|
136842
136952
|
async function captureSearchEvidence(directory, query, results) {
|
|
136843
136953
|
try {
|
|
136844
|
-
const written = await
|
|
136954
|
+
const written = await _internals90.writeEvidenceDocuments(directory, results.map((result) => ({
|
|
136845
136955
|
sourceType: "web_search",
|
|
136846
136956
|
query,
|
|
136847
136957
|
title: result.title,
|
|
@@ -136869,7 +136979,7 @@ async function captureSearchEvidence(directory, query, results) {
|
|
|
136869
136979
|
};
|
|
136870
136980
|
}
|
|
136871
136981
|
}
|
|
136872
|
-
var
|
|
136982
|
+
var _internals90 = {
|
|
136873
136983
|
writeEvidenceDocuments
|
|
136874
136984
|
};
|
|
136875
136985
|
|
|
@@ -138379,6 +138489,10 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
138379
138489
|
template: "/swarm full-auto $ARGUMENTS",
|
|
138380
138490
|
description: "Toggle Full-Auto Mode for the active session [on|off]"
|
|
138381
138491
|
},
|
|
138492
|
+
"swarm-auto-proceed": {
|
|
138493
|
+
template: "/swarm auto-proceed $ARGUMENTS",
|
|
138494
|
+
description: "Toggle auto-proceed mode for automatic phase advancement"
|
|
138495
|
+
},
|
|
138382
138496
|
"swarm-write-retro": {
|
|
138383
138497
|
template: "/swarm write-retro $ARGUMENTS",
|
|
138384
138498
|
description: "Use /swarm write-retro to manually write a phase retrospective"
|
|
@@ -63,6 +63,10 @@ export interface SerializedAgentSession {
|
|
|
63
63
|
stageBCompletion?: Record<string, string[]>;
|
|
64
64
|
/** Session-scoped concurrency override for max_concurrent_tasks (Issue #761) */
|
|
65
65
|
maxConcurrencyOverride?: number;
|
|
66
|
+
/** Session-level auto-proceed override (Phase 1) */
|
|
67
|
+
autoProceedOverride?: boolean;
|
|
68
|
+
/** Flag tracking whether the auto-proceed nudge has been shown (Phase 1) */
|
|
69
|
+
autoProceedNudgeDone?: boolean;
|
|
66
70
|
}
|
|
67
71
|
/**
|
|
68
72
|
* Minimal interface for serialized InvocationWindow
|
package/dist/state.d.ts
CHANGED
|
@@ -175,6 +175,12 @@ export interface AgentSessionState {
|
|
|
175
175
|
* When set, overrides the plan's execution_profile.max_concurrent_tasks
|
|
176
176
|
* for delegation-gate guidance. Cleared on session reset. */
|
|
177
177
|
maxConcurrencyOverride?: number;
|
|
178
|
+
/** Session-scoped override for execution_profile.auto_proceed.
|
|
179
|
+
* When set, overrides the plan's auto_proceed for this session.
|
|
180
|
+
* true = auto-advance, false = do not auto-advance. Cleared on session reset. */
|
|
181
|
+
autoProceedOverride?: boolean;
|
|
182
|
+
/** Tracks whether the FR-004 nudge ("would you like to auto-advance?") has already been shown this session. */
|
|
183
|
+
autoProceedNudgeDone?: boolean;
|
|
178
184
|
/** Session-level QA gate overrides layered on top of the spec-level profile.
|
|
179
185
|
* Overrides can only enable gates (true); false values are ignored by
|
|
180
186
|
* getEffectiveGates. Cleared on session reset. Optional for backwards
|
|
@@ -594,6 +600,13 @@ export declare function hasActiveFullAuto(sessionID?: string): boolean;
|
|
|
594
600
|
* or if any session has that combination when no sessionID provided.
|
|
595
601
|
*/
|
|
596
602
|
export declare function hasActiveLeanTurbo(sessionID?: string): boolean;
|
|
603
|
+
/**
|
|
604
|
+
* Resolves the effective auto_proceed value for a session.
|
|
605
|
+
* Session override (autoProceedOverride) takes precedence over the plan default.
|
|
606
|
+
* Accepts `boolean | undefined` for the plan default so callers can pass
|
|
607
|
+
* `plan?.execution_profile?.auto_proceed` directly without a falsy fallback.
|
|
608
|
+
*/
|
|
609
|
+
export declare function getResolvedAutoProceed(session: AgentSessionState, planAutoProceed: boolean | undefined): boolean;
|
|
597
610
|
export declare function setSessionEnvironment(sessionId: string, profile: EnvironmentProfile): void;
|
|
598
611
|
export declare function getSessionEnvironment(sessionId: string): EnvironmentProfile | undefined;
|
|
599
612
|
export declare function ensureSessionEnvironment(sessionId: string): EnvironmentProfile;
|
|
@@ -39,4 +39,4 @@ export interface ResolveError {
|
|
|
39
39
|
* @param workingDirectory - Explicit working_directory from tool args (caller-controlled)
|
|
40
40
|
* @param fallbackDirectory - Injected directory from createSwarmTool (ctx.directory ?? process.cwd())
|
|
41
41
|
*/
|
|
42
|
-
export declare function resolveWorkingDirectory(workingDirectory: string | undefined | null, fallbackDirectory
|
|
42
|
+
export declare function resolveWorkingDirectory(workingDirectory: string | undefined | null, fallbackDirectory?: string | null): ResolveResult | ResolveError;
|
|
@@ -75,6 +75,7 @@ export interface SavePlanArgs {
|
|
|
75
75
|
max_concurrent_tasks?: number;
|
|
76
76
|
council_parallel?: boolean;
|
|
77
77
|
locked?: boolean;
|
|
78
|
+
auto_proceed?: boolean;
|
|
78
79
|
};
|
|
79
80
|
}
|
|
80
81
|
/**
|
|
@@ -95,6 +96,7 @@ export interface SavePlanResult {
|
|
|
95
96
|
max_concurrent_tasks: number;
|
|
96
97
|
council_parallel: boolean;
|
|
97
98
|
locked: boolean;
|
|
99
|
+
auto_proceed?: boolean;
|
|
98
100
|
};
|
|
99
101
|
}
|
|
100
102
|
/**
|
|
@@ -3,6 +3,19 @@
|
|
|
3
3
|
* Allows agents to mark tasks as pending, in_progress, completed, or blocked.
|
|
4
4
|
*/
|
|
5
5
|
import type { ToolContext, ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
6
|
+
import { tryAcquireLock } from '../parallel/file-locks.js';
|
|
7
|
+
import { updateTaskStatus } from '../plan/manager';
|
|
8
|
+
import { resolveWorkingDirectory } from './resolve-working-directory';
|
|
9
|
+
/**
|
|
10
|
+
* Internal seams for test injection.
|
|
11
|
+
* Tests should save/restore these in beforeEach/afterEach rather than using
|
|
12
|
+
* module-scope vi.mock, which leaks across files in Bun's shared test runner.
|
|
13
|
+
*/
|
|
14
|
+
export declare const _internals: {
|
|
15
|
+
readonly tryAcquireLock: typeof tryAcquireLock;
|
|
16
|
+
readonly updateTaskStatus: typeof updateTaskStatus;
|
|
17
|
+
readonly resolveWorkingDirectory: typeof resolveWorkingDirectory;
|
|
18
|
+
};
|
|
6
19
|
/**
|
|
7
20
|
* Arguments for the update_task_status tool
|
|
8
21
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.66.1",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|