opencode-swarm 6.22.19 → 6.22.21
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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -13,8 +13,10 @@ export type CuratorInitRunner = (directory: string, config: CuratorConfig) => Pr
|
|
|
13
13
|
* Creates a hook that monitors plan phase transitions and triggers preflight.
|
|
14
14
|
*
|
|
15
15
|
* @param directory - Project directory (where .swarm/ lives)
|
|
16
|
-
* @param preflightManager -
|
|
16
|
+
* @param preflightManager - Optional PreflightTriggerManager to call on phase change.
|
|
17
|
+
* When undefined, preflight checks are skipped but curator initialization still runs
|
|
18
|
+
* at session start (useful when knowledge.enabled but phase_preflight is disabled).
|
|
17
19
|
* @param curatorRunner - Optional curator init runner (defaults to runCuratorInit; injectable for tests)
|
|
18
20
|
* @returns A safeHook-wrapped system.transform handler
|
|
19
21
|
*/
|
|
20
|
-
export declare function createPhaseMonitorHook(directory: string, preflightManager
|
|
22
|
+
export declare function createPhaseMonitorHook(directory: string, preflightManager?: PreflightTriggerManager, curatorRunner?: CuratorInitRunner): (input: unknown, output: unknown) => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -15792,6 +15792,18 @@ async function updateTaskStatus(directory, taskId, status) {
|
|
|
15792
15792
|
throw new Error(`Plan not found in directory: ${directory}`);
|
|
15793
15793
|
}
|
|
15794
15794
|
let taskFound = false;
|
|
15795
|
+
const derivePhaseStatusFromTasks = (tasks) => {
|
|
15796
|
+
if (tasks.length > 0 && tasks.every((task) => task.status === "completed")) {
|
|
15797
|
+
return "complete";
|
|
15798
|
+
}
|
|
15799
|
+
if (tasks.some((task) => task.status === "in_progress")) {
|
|
15800
|
+
return "in_progress";
|
|
15801
|
+
}
|
|
15802
|
+
if (tasks.some((task) => task.status === "blocked")) {
|
|
15803
|
+
return "blocked";
|
|
15804
|
+
}
|
|
15805
|
+
return "pending";
|
|
15806
|
+
};
|
|
15795
15807
|
const updatedPhases = plan.phases.map((phase) => {
|
|
15796
15808
|
const updatedTasks = phase.tasks.map((task) => {
|
|
15797
15809
|
if (task.id === taskId) {
|
|
@@ -15800,7 +15812,11 @@ async function updateTaskStatus(directory, taskId, status) {
|
|
|
15800
15812
|
}
|
|
15801
15813
|
return task;
|
|
15802
15814
|
});
|
|
15803
|
-
return {
|
|
15815
|
+
return {
|
|
15816
|
+
...phase,
|
|
15817
|
+
status: derivePhaseStatusFromTasks(updatedTasks),
|
|
15818
|
+
tasks: updatedTasks
|
|
15819
|
+
};
|
|
15804
15820
|
});
|
|
15805
15821
|
if (!taskFound) {
|
|
15806
15822
|
throw new Error(`Task not found: ${taskId}`);
|
|
@@ -39880,8 +39896,8 @@ When writing output consumed by other agents, prefix with:
|
|
|
39880
39896
|
[FOR: agent1, agent2] \u2014 relevant to specific agents
|
|
39881
39897
|
[FOR: ALL] \u2014 relevant to all agents
|
|
39882
39898
|
Examples:
|
|
39883
|
-
[FOR:
|
|
39884
|
-
[FOR:
|
|
39899
|
+
[FOR: reviewer, test_engineer] "Added validation \u2014 needs safety check"
|
|
39900
|
+
[FOR: architect] "Research: Tree-sitter supports TypeScript AST"
|
|
39885
39901
|
[FOR: ALL] "Breaking change: StateManager renamed"
|
|
39886
39902
|
This tag is informational in v6.19; v6.20 will use for context filtering.
|
|
39887
39903
|
`;
|
|
@@ -48612,6 +48628,9 @@ function extractPlanTaskId(text) {
|
|
|
48612
48628
|
}
|
|
48613
48629
|
return null;
|
|
48614
48630
|
}
|
|
48631
|
+
function getSeedTaskId(session) {
|
|
48632
|
+
return session.currentTaskId ?? session.lastCoderDelegationTaskId;
|
|
48633
|
+
}
|
|
48615
48634
|
function createDelegationGateHook(config3) {
|
|
48616
48635
|
const enabled = config3.hooks?.delegation_gate !== false;
|
|
48617
48636
|
const delegationMaxChars = config3.hooks?.delegation_max_chars ?? 4000;
|
|
@@ -48669,6 +48688,10 @@ function createDelegationGateHook(config3) {
|
|
|
48669
48688
|
if (!otherSession.taskWorkflowStates)
|
|
48670
48689
|
continue;
|
|
48671
48690
|
if (targetAgent === "reviewer") {
|
|
48691
|
+
const seedTaskId = getSeedTaskId(session);
|
|
48692
|
+
if (seedTaskId && !otherSession.taskWorkflowStates.has(seedTaskId)) {
|
|
48693
|
+
otherSession.taskWorkflowStates.set(seedTaskId, "coder_delegated");
|
|
48694
|
+
}
|
|
48672
48695
|
for (const [taskId, state] of otherSession.taskWorkflowStates) {
|
|
48673
48696
|
if (state === "coder_delegated" || state === "pre_check_passed") {
|
|
48674
48697
|
try {
|
|
@@ -48680,6 +48703,10 @@ function createDelegationGateHook(config3) {
|
|
|
48680
48703
|
}
|
|
48681
48704
|
}
|
|
48682
48705
|
if (targetAgent === "test_engineer") {
|
|
48706
|
+
const seedTaskId = getSeedTaskId(session);
|
|
48707
|
+
if (seedTaskId && !otherSession.taskWorkflowStates.has(seedTaskId)) {
|
|
48708
|
+
otherSession.taskWorkflowStates.set(seedTaskId, "reviewer_run");
|
|
48709
|
+
}
|
|
48683
48710
|
for (const [taskId, state] of otherSession.taskWorkflowStates) {
|
|
48684
48711
|
if (state === "reviewer_run") {
|
|
48685
48712
|
try {
|
|
@@ -48750,6 +48777,10 @@ function createDelegationGateHook(config3) {
|
|
|
48750
48777
|
continue;
|
|
48751
48778
|
if (!otherSession.taskWorkflowStates)
|
|
48752
48779
|
continue;
|
|
48780
|
+
const seedTaskId = getSeedTaskId(session);
|
|
48781
|
+
if (seedTaskId && !otherSession.taskWorkflowStates.has(seedTaskId)) {
|
|
48782
|
+
otherSession.taskWorkflowStates.set(seedTaskId, "coder_delegated");
|
|
48783
|
+
}
|
|
48753
48784
|
for (const [taskId, state] of otherSession.taskWorkflowStates) {
|
|
48754
48785
|
if (state === "coder_delegated" || state === "pre_check_passed") {
|
|
48755
48786
|
try {
|
|
@@ -48767,6 +48798,10 @@ function createDelegationGateHook(config3) {
|
|
|
48767
48798
|
continue;
|
|
48768
48799
|
if (!otherSession.taskWorkflowStates)
|
|
48769
48800
|
continue;
|
|
48801
|
+
const seedTaskId = getSeedTaskId(session);
|
|
48802
|
+
if (seedTaskId && !otherSession.taskWorkflowStates.has(seedTaskId)) {
|
|
48803
|
+
otherSession.taskWorkflowStates.set(seedTaskId, "reviewer_run");
|
|
48804
|
+
}
|
|
48770
48805
|
for (const [taskId, state] of otherSession.taskWorkflowStates) {
|
|
48771
48806
|
if (state === "reviewer_run") {
|
|
48772
48807
|
try {
|
|
@@ -49221,7 +49256,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner = run
|
|
|
49221
49256
|
const phase = plan.phases.find((p) => p.id === previousPhase);
|
|
49222
49257
|
const completedTasks = phase?.tasks.filter((t) => t.status === "completed").length ?? 0;
|
|
49223
49258
|
const totalTasks = phase?.tasks.length ?? 0;
|
|
49224
|
-
|
|
49259
|
+
if (preflightManager) {
|
|
49260
|
+
await preflightManager.checkAndTrigger(currentPhase, completedTasks, totalTasks);
|
|
49261
|
+
}
|
|
49225
49262
|
}
|
|
49226
49263
|
};
|
|
49227
49264
|
return safeHook(handler);
|
|
@@ -60913,7 +60950,9 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
60913
60950
|
stateEntries.push(`${sessionId}: ${state}`);
|
|
60914
60951
|
}
|
|
60915
60952
|
const allIdle = stateEntries.length > 0 && stateEntries.every((e) => e.endsWith(": idle"));
|
|
60916
|
-
if (allIdle) {
|
|
60953
|
+
if (allIdle) {
|
|
60954
|
+
return { blocked: false, reason: "" };
|
|
60955
|
+
}
|
|
60917
60956
|
try {
|
|
60918
60957
|
const resolvedDir = workingDirectory ?? process.cwd();
|
|
60919
60958
|
const planPath = path47.join(resolvedDir, ".swarm", "plan.json");
|
|
@@ -60930,7 +60969,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
60930
60969
|
const currentStateStr = stateEntries.length > 0 ? stateEntries.join(", ") : "no active sessions";
|
|
60931
60970
|
return {
|
|
60932
60971
|
blocked: true,
|
|
60933
|
-
reason: `Task ${taskId} has not passed QA gates. Current state: [${currentStateStr}].
|
|
60972
|
+
reason: `Task ${taskId} has not passed QA gates. Current state by session: [${currentStateStr}]. Missing required state: tests_run or complete in at least one valid session. Do not write directly to plan files \u2014 use update_task_status after running the reviewer and test_engineer agents.`
|
|
60934
60973
|
};
|
|
60935
60974
|
} catch {
|
|
60936
60975
|
return { blocked: false, reason: "" };
|
|
@@ -61030,6 +61069,19 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
61030
61069
|
}
|
|
61031
61070
|
try {
|
|
61032
61071
|
const updatedPlan = await updateTaskStatus(directory, args2.task_id, args2.status);
|
|
61072
|
+
if (args2.status === "completed") {
|
|
61073
|
+
for (const [_sessionId, session] of swarmState.agentSessions) {
|
|
61074
|
+
if (!(session.taskWorkflowStates instanceof Map)) {
|
|
61075
|
+
continue;
|
|
61076
|
+
}
|
|
61077
|
+
const currentState = getTaskState(session, args2.task_id);
|
|
61078
|
+
if (currentState === "tests_run") {
|
|
61079
|
+
try {
|
|
61080
|
+
advanceTaskState(session, args2.task_id, "complete");
|
|
61081
|
+
} catch {}
|
|
61082
|
+
}
|
|
61083
|
+
}
|
|
61084
|
+
}
|
|
61033
61085
|
return {
|
|
61034
61086
|
success: true,
|
|
61035
61087
|
message: "Task status updated successfully",
|
|
@@ -61098,7 +61150,7 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
61098
61150
|
const activityHooks = createAgentActivityHooks(config3, ctx.directory);
|
|
61099
61151
|
const delegationGateHooks = createDelegationGateHook(config3);
|
|
61100
61152
|
const delegationSanitizerHook = createDelegationSanitizerHook(ctx.directory);
|
|
61101
|
-
const guardrailsFallback = config3.guardrails?.enabled === false ? { ...config3.guardrails, enabled: false } :
|
|
61153
|
+
const guardrailsFallback = config3.guardrails?.enabled === false ? { ...config3.guardrails, enabled: false } : config3.guardrails ?? {};
|
|
61102
61154
|
const guardrailsConfig = GuardrailsConfigSchema.parse(guardrailsFallback);
|
|
61103
61155
|
if (loadedFromFile && guardrailsConfig.enabled === false) {
|
|
61104
61156
|
console.warn("");
|
|
@@ -61379,7 +61431,7 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
61379
61431
|
].filter((fn) => Boolean(fn))),
|
|
61380
61432
|
"experimental.chat.system.transform": composeHandlers(...[
|
|
61381
61433
|
systemEnhancerHook["experimental.chat.system.transform"],
|
|
61382
|
-
automationConfig.capabilities?.phase_preflight === true && preflightTriggerManager ? createPhaseMonitorHook(ctx.directory, preflightTriggerManager) : undefined
|
|
61434
|
+
automationConfig.capabilities?.phase_preflight === true && preflightTriggerManager ? createPhaseMonitorHook(ctx.directory, preflightTriggerManager) : knowledgeConfig.enabled ? createPhaseMonitorHook(ctx.directory) : undefined
|
|
61383
61435
|
].filter(Boolean)),
|
|
61384
61436
|
"experimental.session.compacting": compactionHook["experimental.session.compacting"],
|
|
61385
61437
|
"command.execute.before": safeHook(commandHandler),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "6.22.
|
|
3
|
+
"version": "6.22.21",
|
|
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",
|