opencode-swarm 7.13.2 → 7.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/cli/index.js +950 -269
- package/dist/commands/deep-dive.d.ts +5 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/registry.d.ts +14 -0
- package/dist/commands/turbo.d.ts +4 -4
- package/dist/config/constants.d.ts +12 -1
- package/dist/config/index.d.ts +2 -2
- package/dist/config/schema.d.ts +116 -0
- package/dist/index.js +4504 -1266
- package/dist/parallel/file-locks.d.ts +50 -2
- package/dist/services/status-service.d.ts +29 -0
- package/dist/state.d.ts +17 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/lean-turbo-acquire-locks.d.ts +36 -0
- package/dist/tools/lean-turbo-plan-lanes.d.ts +35 -0
- package/dist/tools/lean-turbo-review.d.ts +34 -0
- package/dist/tools/lean-turbo-run-phase.d.ts +44 -0
- package/dist/tools/lean-turbo-runner-status.d.ts +36 -0
- package/dist/tools/lean-turbo-status.d.ts +44 -0
- package/dist/tools/tool-names.d.ts +1 -1
- package/dist/tools/update-task-status.d.ts +7 -4
- package/dist/turbo/lean/conflicts.d.ts +100 -0
- package/dist/turbo/lean/evidence.d.ts +91 -0
- package/dist/turbo/lean/index.d.ts +27 -0
- package/dist/turbo/lean/integration.d.ts +137 -0
- package/dist/turbo/lean/phase-ready.d.ts +105 -0
- package/dist/turbo/lean/planner.d.ts +115 -0
- package/dist/turbo/lean/reviewer.d.ts +124 -0
- package/dist/turbo/lean/risk.d.ts +47 -0
- package/dist/turbo/lean/runner.d.ts +322 -0
- package/dist/turbo/lean/state.d.ts +61 -0
- package/dist/turbo/lean/task-completion.d.ts +53 -0
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
1
2
|
/**
|
|
2
3
|
* Test-only dependency-injection seam. Tests replace the function on this
|
|
3
4
|
* object so they can inject mock behaviour without touching the real
|
|
@@ -12,13 +13,27 @@
|
|
|
12
13
|
*/
|
|
13
14
|
export declare const _internals: {
|
|
14
15
|
tryAcquireLock: typeof tryAcquireLock;
|
|
16
|
+
writeFile: typeof fs.promises.writeFile;
|
|
15
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Sidecar metadata written alongside each lock sentinel file.
|
|
20
|
+
*/
|
|
21
|
+
export interface LockMetadata {
|
|
22
|
+
originalPath: string;
|
|
23
|
+
laneId: string;
|
|
24
|
+
taskId: string;
|
|
25
|
+
agent: string;
|
|
26
|
+
sessionID: string;
|
|
27
|
+
acquiredAt: string;
|
|
28
|
+
expiresAt: number;
|
|
29
|
+
}
|
|
16
30
|
export interface FileLock {
|
|
17
31
|
filePath: string;
|
|
18
32
|
agent: string;
|
|
19
33
|
taskId: string;
|
|
20
34
|
timestamp: string;
|
|
21
35
|
expiresAt: number;
|
|
36
|
+
laneId?: string;
|
|
22
37
|
_release?: () => Promise<void>;
|
|
23
38
|
}
|
|
24
39
|
/**
|
|
@@ -46,10 +61,43 @@ export declare function releaseLock(_directory: string, _filePath: string, _task
|
|
|
46
61
|
*/
|
|
47
62
|
export declare function isLocked(directory: string, filePath: string): FileLock | null;
|
|
48
63
|
/**
|
|
49
|
-
* Clean up expired locks
|
|
64
|
+
* Clean up expired locks and their sidecar metadata files.
|
|
50
65
|
*/
|
|
51
66
|
export declare function cleanupExpiredLocks(directory: string): number;
|
|
52
67
|
/**
|
|
53
|
-
* List all active locks
|
|
68
|
+
* List all active locks, reading metadata from sidecar files when available.
|
|
69
|
+
* Filters out expired locks.
|
|
54
70
|
*/
|
|
55
71
|
export declare function listActiveLocks(directory: string): FileLock[];
|
|
72
|
+
/**
|
|
73
|
+
* Acquire locks for all files in a lane (all-or-nothing).
|
|
74
|
+
*
|
|
75
|
+
* If ANY file is already locked, releases ALL previously acquired locks
|
|
76
|
+
* in this lane and returns `{ acquired: false, conflicts }`.
|
|
77
|
+
*
|
|
78
|
+
* @param directory - Project root directory
|
|
79
|
+
* @param laneId - Unique lane identifier
|
|
80
|
+
* @param files - Array of file paths to lock
|
|
81
|
+
* @param agent - Agent name
|
|
82
|
+
* @param taskId - Task ID
|
|
83
|
+
* @param sessionID - Session ID
|
|
84
|
+
* @returns Success with array of FileLock objects, or failure with conflict list
|
|
85
|
+
*/
|
|
86
|
+
export declare function acquireLaneLocks(directory: string, laneId: string, files: string[], agent: string, taskId: string, sessionID: string): Promise<{
|
|
87
|
+
acquired: true;
|
|
88
|
+
locks: FileLock[];
|
|
89
|
+
} | {
|
|
90
|
+
acquired: false;
|
|
91
|
+
conflicts: string[];
|
|
92
|
+
}>;
|
|
93
|
+
/**
|
|
94
|
+
* Release all locks for a given lane.
|
|
95
|
+
*
|
|
96
|
+
* Reads all `.meta` files in `.swarm/locks/`, finds entries matching `laneId`,
|
|
97
|
+
* and releases + deletes corresponding lock files.
|
|
98
|
+
*
|
|
99
|
+
* @param directory - Project root directory
|
|
100
|
+
* @param laneId - Lane ID to release
|
|
101
|
+
* @returns Number of locks released
|
|
102
|
+
*/
|
|
103
|
+
export declare function releaseLaneLocks(directory: string, laneId: string): Promise<number>;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import type { AgentDefinition } from '../agents';
|
|
2
|
+
import { hasActiveFullAuto, hasActiveLeanTurbo } from '../state';
|
|
3
|
+
import { loadLeanTurboRunState } from '../turbo/lean/state';
|
|
4
|
+
/**
|
|
5
|
+
* Dependency-injection seam for status-service.
|
|
6
|
+
* Allows tests to intercept Lean Turbo state queries without mock.module leakage.
|
|
7
|
+
*/
|
|
8
|
+
export declare const _internals: {
|
|
9
|
+
loadLeanTurboRunState: typeof loadLeanTurboRunState;
|
|
10
|
+
hasActiveLeanTurbo: typeof hasActiveLeanTurbo;
|
|
11
|
+
hasActiveFullAuto: typeof hasActiveFullAuto;
|
|
12
|
+
};
|
|
2
13
|
/**
|
|
3
14
|
* Structured status data returned by the status service.
|
|
4
15
|
* This can be used by GUI, background flows, or command adapters.
|
|
@@ -11,6 +22,24 @@ export interface StatusData {
|
|
|
11
22
|
agentCount: number;
|
|
12
23
|
isLegacy: boolean;
|
|
13
24
|
turboMode: boolean;
|
|
25
|
+
/** Lean Turbo strategy: 'lean', 'standard', or 'off' */
|
|
26
|
+
turboStrategy?: 'standard' | 'lean' | 'off';
|
|
27
|
+
/** Lean Turbo phase number, if Lean Turbo is active */
|
|
28
|
+
leanTurboPhase?: number;
|
|
29
|
+
/** Number of lanes currently in 'running' status */
|
|
30
|
+
leanActiveLaneCount?: number;
|
|
31
|
+
/** Max parallel coders configured for Lean Turbo */
|
|
32
|
+
leanMaxParallelCoders?: number;
|
|
33
|
+
/** Number of lanes completed */
|
|
34
|
+
leanCompletedLanes?: number;
|
|
35
|
+
/** Number of tasks marked as degraded */
|
|
36
|
+
leanDegradedTasks?: number;
|
|
37
|
+
/** Human-readable degradation summary */
|
|
38
|
+
leanDegradationSummary?: string;
|
|
39
|
+
/** Whether Full-Auto mode is currently active */
|
|
40
|
+
fullAutoActive?: boolean;
|
|
41
|
+
/** Reason for pause if Lean Turbo is paused */
|
|
42
|
+
leanPauseReason?: string;
|
|
14
43
|
/** Last known context budget percentage (0-100), or null if not yet measured */
|
|
15
44
|
contextBudgetPct: number | null;
|
|
16
45
|
/** Number of context compaction events triggered this session */
|
package/dist/state.d.ts
CHANGED
|
@@ -157,6 +157,14 @@ export interface AgentSessionState {
|
|
|
157
157
|
modelFallbackExhausted: boolean;
|
|
158
158
|
/** Session-scoped Turbo Mode flag for controlling LLM inference speed */
|
|
159
159
|
turboMode: boolean;
|
|
160
|
+
/** Session-scoped turbo strategy selection — standard or lean. When undefined,
|
|
161
|
+
* falls back to standard (current behavior). */
|
|
162
|
+
turboStrategy?: 'standard' | 'lean';
|
|
163
|
+
/** Whether Lean Turbo is actively running in this session. Requires
|
|
164
|
+
* turboStrategy === 'lean'. */
|
|
165
|
+
leanTurboActive?: boolean;
|
|
166
|
+
/** Current phase number when Lean Turbo is active (for durable state sync). */
|
|
167
|
+
leanTurboCurrentPhase?: number;
|
|
160
168
|
/** Session-level QA gate overrides layered on top of the spec-level profile.
|
|
161
169
|
* Overrides can only enable gates (true); false values are ignored by
|
|
162
170
|
* getEffectiveGates. Cleared on session reset. Optional for backwards
|
|
@@ -533,6 +541,14 @@ export declare function hasActiveTurboMode(sessionID?: string): boolean;
|
|
|
533
541
|
* @returns true if the specified session has fullAutoMode: true (model validation is advisory-only).
|
|
534
542
|
*/
|
|
535
543
|
export declare function hasActiveFullAuto(sessionID?: string): boolean;
|
|
544
|
+
/**
|
|
545
|
+
* Check if Lean Turbo Mode is active for a specific session or ANY session.
|
|
546
|
+
* @param sessionID - Optional session ID to check. If provided, checks only that session.
|
|
547
|
+
* If omitted, checks all sessions.
|
|
548
|
+
* @returns true if the specified session has turboStrategy: 'lean' AND leanTurboActive: true,
|
|
549
|
+
* or if any session has that combination when no sessionID provided.
|
|
550
|
+
*/
|
|
551
|
+
export declare function hasActiveLeanTurbo(sessionID?: string): boolean;
|
|
536
552
|
export declare function setSessionEnvironment(sessionId: string, profile: EnvironmentProfile): void;
|
|
537
553
|
export declare function getSessionEnvironment(sessionId: string): EnvironmentProfile | undefined;
|
|
538
554
|
export declare function ensureSessionEnvironment(sessionId: string): EnvironmentProfile;
|
|
@@ -574,6 +590,7 @@ export declare const _internals: {
|
|
|
574
590
|
getTaskState: typeof getTaskState;
|
|
575
591
|
hasActiveFullAuto: typeof hasActiveFullAuto;
|
|
576
592
|
hasActiveTurboMode: typeof hasActiveTurboMode;
|
|
593
|
+
hasActiveLeanTurbo: typeof hasActiveLeanTurbo;
|
|
577
594
|
buildRehydrationCache: typeof buildRehydrationCache;
|
|
578
595
|
applyRehydrationCache: typeof applyRehydrationCache;
|
|
579
596
|
rehydrateSessionFromDisk: typeof rehydrateSessionFromDisk;
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -59,6 +59,12 @@ export { classifyAndCluster, classifyFailure, clusterFailures, } from '../test-i
|
|
|
59
59
|
export type { FlakyTestEntry } from '../test-impact/flaky-detector.js';
|
|
60
60
|
export { computeFlakyScore, detectFlakyTests, isTestQuarantined, } from '../test-impact/flaky-detector.js';
|
|
61
61
|
export { generate_mutants } from './generate-mutants';
|
|
62
|
+
export { lean_turbo_acquire_locks } from './lean-turbo-acquire-locks';
|
|
63
|
+
export { lean_turbo_plan_lanes } from './lean-turbo-plan-lanes';
|
|
64
|
+
export { lean_turbo_review } from './lean-turbo-review';
|
|
65
|
+
export { lean_turbo_run_phase } from './lean-turbo-run-phase';
|
|
66
|
+
export { lean_turbo_runner_status } from './lean-turbo-runner-status';
|
|
67
|
+
export { lean_turbo_status } from './lean-turbo-status';
|
|
62
68
|
export { lint_spec } from './lint-spec';
|
|
63
69
|
export { mutation_test } from './mutation-test';
|
|
64
70
|
export { symbols } from './symbols';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lean Turbo Acquire Locks Tool.
|
|
3
|
+
* Wraps acquireLaneLocks from src/parallel/file-locks.
|
|
4
|
+
* Acquires file locks for all files in a lane (all-or-nothing).
|
|
5
|
+
*/
|
|
6
|
+
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
7
|
+
import { type FileLock } from '../parallel/file-locks';
|
|
8
|
+
/**
|
|
9
|
+
* Arguments for the lean_turbo_acquire_locks tool
|
|
10
|
+
*/
|
|
11
|
+
export interface LeanTurboAcquireLocksArgs {
|
|
12
|
+
directory: string;
|
|
13
|
+
laneId: string;
|
|
14
|
+
files: string[];
|
|
15
|
+
agent: string;
|
|
16
|
+
taskId: string;
|
|
17
|
+
sessionID: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Result from executing lean_turbo_acquire_locks
|
|
21
|
+
*/
|
|
22
|
+
export interface LeanTurboAcquireLocksResult {
|
|
23
|
+
success: boolean;
|
|
24
|
+
locks?: FileLock[];
|
|
25
|
+
conflicts?: string[];
|
|
26
|
+
errors?: string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Execute the lean_turbo_acquire_locks tool.
|
|
30
|
+
* Acquires locks for all files in a lane (all-or-nothing).
|
|
31
|
+
*/
|
|
32
|
+
export declare function executeLeanTurboAcquireLocks(args: LeanTurboAcquireLocksArgs): Promise<LeanTurboAcquireLocksResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Tool definition for lean_turbo_acquire_locks
|
|
35
|
+
*/
|
|
36
|
+
export declare const lean_turbo_acquire_locks: ToolDefinition;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lean Turbo Plan Lanes Tool.
|
|
3
|
+
* Wraps planLeanTurboLanes from src/turbo/lean/planner.
|
|
4
|
+
* Partitions phase tasks into parallel lanes based on file-scope conflicts.
|
|
5
|
+
*/
|
|
6
|
+
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
7
|
+
import type { LeanTurboLanePlan } from '../turbo/lean/planner';
|
|
8
|
+
/**
|
|
9
|
+
* Arguments for the lean_turbo_plan_lanes tool
|
|
10
|
+
*/
|
|
11
|
+
export interface LeanTurboPlanLanesArgs {
|
|
12
|
+
directory: string;
|
|
13
|
+
phase: number;
|
|
14
|
+
scopes?: Record<string, string[]>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Result from executing lean_turbo_plan_lanes
|
|
18
|
+
*/
|
|
19
|
+
export interface LeanTurboPlanLanesResult {
|
|
20
|
+
success: boolean;
|
|
21
|
+
plan?: LeanTurboLanePlan;
|
|
22
|
+
lanes?: LeanTurboLanePlan['lanes'];
|
|
23
|
+
degradedTasks?: LeanTurboLanePlan['degradedTasks'];
|
|
24
|
+
serializedTasks?: LeanTurboLanePlan['serializedTasks'];
|
|
25
|
+
errors?: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Execute the lean_turbo_plan_lanes tool.
|
|
29
|
+
* Partitions phase tasks into parallel lanes based on file-scope conflicts.
|
|
30
|
+
*/
|
|
31
|
+
export declare function executeLeanTurboPlanLanes(args: LeanTurboPlanLanesArgs): Promise<LeanTurboPlanLanesResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Tool definition for lean_turbo_plan_lanes
|
|
34
|
+
*/
|
|
35
|
+
export declare const lean_turbo_plan_lanes: ToolDefinition;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lean Turbo Review Tool.
|
|
3
|
+
* Wraps dispatchPhaseReviewer from src/turbo/lean/reviewer.
|
|
4
|
+
* Dispatches a read-only reviewer agent to evaluate a completed Lean Turbo phase.
|
|
5
|
+
*/
|
|
6
|
+
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
7
|
+
import { type PhaseReviewerResult } from '../turbo/lean/reviewer';
|
|
8
|
+
/**
|
|
9
|
+
* Arguments for the lean_turbo_review tool
|
|
10
|
+
*/
|
|
11
|
+
export interface LeanTurboReviewArgs {
|
|
12
|
+
directory: string;
|
|
13
|
+
phase: number;
|
|
14
|
+
sessionID: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Result from executing lean_turbo_review
|
|
18
|
+
*/
|
|
19
|
+
export interface LeanTurboReviewResult {
|
|
20
|
+
success: boolean;
|
|
21
|
+
verdict?: PhaseReviewerResult['verdict'];
|
|
22
|
+
reason?: string;
|
|
23
|
+
evidencePath?: string;
|
|
24
|
+
errors?: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Execute the lean_turbo_review tool.
|
|
28
|
+
* Dispatches a read-only reviewer agent to evaluate a completed Lean Turbo phase.
|
|
29
|
+
*/
|
|
30
|
+
export declare function executeLeanTurboReview(args: LeanTurboReviewArgs): Promise<LeanTurboReviewResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Tool definition for lean_turbo_review
|
|
33
|
+
*/
|
|
34
|
+
export declare const lean_turbo_review: ToolDefinition;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lean Turbo Run Phase Tool.
|
|
3
|
+
* Wraps LeanTurboRunner to execute a phase using Lean Turbo parallel lane execution.
|
|
4
|
+
*/
|
|
5
|
+
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
6
|
+
import { loadPluginConfigWithMeta as loadPluginConfigWithMeta_import } from '../config';
|
|
7
|
+
import type { LaneResult } from '../turbo/lean/runner';
|
|
8
|
+
import { LeanTurboRunner as LeanTurboRunner_import } from '../turbo/lean/runner';
|
|
9
|
+
/**
|
|
10
|
+
* Arguments for the lean_turbo_run_phase tool
|
|
11
|
+
*/
|
|
12
|
+
export interface LeanTurboRunPhaseArgs {
|
|
13
|
+
directory: string;
|
|
14
|
+
phase: number;
|
|
15
|
+
sessionID: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Result from executing lean_turbo_run_phase
|
|
19
|
+
*/
|
|
20
|
+
export interface LeanTurboRunPhaseResult {
|
|
21
|
+
success: boolean;
|
|
22
|
+
lanes?: LaneResult[];
|
|
23
|
+
degradedTasks?: string[];
|
|
24
|
+
serializedTasks?: string[];
|
|
25
|
+
reason?: string;
|
|
26
|
+
errors?: string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Test-only dependency-injection seam.
|
|
30
|
+
* Allows tests to inject mocks without mock.module leakage.
|
|
31
|
+
*/
|
|
32
|
+
export declare const _internals: {
|
|
33
|
+
LeanTurboRunner: typeof LeanTurboRunner_import;
|
|
34
|
+
loadPluginConfigWithMeta: typeof loadPluginConfigWithMeta_import;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Execute the lean_turbo_run_phase tool.
|
|
38
|
+
* Creates a LeanTurboRunner and executes the specified phase.
|
|
39
|
+
*/
|
|
40
|
+
export declare function executeLeanTurboRunPhase(args: LeanTurboRunPhaseArgs): Promise<LeanTurboRunPhaseResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Tool definition for lean_turbo_run_phase
|
|
43
|
+
*/
|
|
44
|
+
export declare const lean_turbo_run_phase: ToolDefinition;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lean Turbo Runner Status Tool.
|
|
3
|
+
* Reads Lean Turbo run state from .swarm/turbo-state.json.
|
|
4
|
+
*/
|
|
5
|
+
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
6
|
+
import { type LeanTurboRunState } from '../turbo/lean/state';
|
|
7
|
+
/**
|
|
8
|
+
* Arguments for the lean_turbo_runner_status tool
|
|
9
|
+
*/
|
|
10
|
+
export interface LeanTurboRunnerStatusArgs {
|
|
11
|
+
directory: string;
|
|
12
|
+
sessionID: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Result from executing lean_turbo_runner_status
|
|
16
|
+
*/
|
|
17
|
+
export interface LeanTurboRunnerStatusResult {
|
|
18
|
+
success: boolean;
|
|
19
|
+
status?: LeanTurboRunState['status'];
|
|
20
|
+
phase?: number;
|
|
21
|
+
lanes?: LeanTurboRunState['lanes'];
|
|
22
|
+
degradedTasks?: LeanTurboRunState['degradedTasks'];
|
|
23
|
+
maxParallelCoders?: number;
|
|
24
|
+
sessionID?: string;
|
|
25
|
+
strategy?: 'lean';
|
|
26
|
+
errors?: string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Execute the lean_turbo_runner_status tool.
|
|
30
|
+
* Reads Lean Turbo run state from .swarm/turbo-state.json.
|
|
31
|
+
*/
|
|
32
|
+
export declare function executeLeanTurboRunnerStatus(args: LeanTurboRunnerStatusArgs): Promise<LeanTurboRunnerStatusResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Tool definition for lean_turbo_runner_status
|
|
35
|
+
*/
|
|
36
|
+
export declare const lean_turbo_runner_status: ToolDefinition;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lean Turbo Status Tool.
|
|
3
|
+
* Returns Lean Turbo configuration and active status for the current session.
|
|
4
|
+
*/
|
|
5
|
+
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
6
|
+
/**
|
|
7
|
+
* Arguments for the lean_turbo_status tool
|
|
8
|
+
*/
|
|
9
|
+
export interface LeanTurboStatusArgs {
|
|
10
|
+
directory: string;
|
|
11
|
+
sessionID: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Lean Turbo configuration that would be active
|
|
15
|
+
*/
|
|
16
|
+
export interface LeanTurboStatusConfig {
|
|
17
|
+
max_parallel_coders: number;
|
|
18
|
+
require_declared_scope: boolean;
|
|
19
|
+
degrade_on_risk: boolean;
|
|
20
|
+
conflict_policy: 'degrade' | 'serialize';
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result from executing lean_turbo_status
|
|
24
|
+
*/
|
|
25
|
+
export interface LeanTurboStatusResult {
|
|
26
|
+
success: boolean;
|
|
27
|
+
strategy?: 'lean';
|
|
28
|
+
leanActive?: boolean;
|
|
29
|
+
config?: LeanTurboStatusConfig;
|
|
30
|
+
status?: string;
|
|
31
|
+
phase?: number;
|
|
32
|
+
lanes?: number;
|
|
33
|
+
degradedTasks?: number;
|
|
34
|
+
errors?: string[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Execute the lean_turbo_status tool.
|
|
38
|
+
* Returns Lean Turbo configuration and active status.
|
|
39
|
+
*/
|
|
40
|
+
export declare function executeLeanTurboStatus(args: LeanTurboStatusArgs): Promise<LeanTurboStatusResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Tool definition for lean_turbo_status
|
|
43
|
+
*/
|
|
44
|
+
export declare const lean_turbo_status: ToolDefinition;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Used for constants and agent setup references.
|
|
4
4
|
*/
|
|
5
5
|
/** Union type of all valid tool names */
|
|
6
|
-
export type ToolName = 'diff' | 'diff_summary' | 'syntax_check' | 'placeholder_scan' | 'imports' | 'lint' | 'secretscan' | 'sast_scan' | 'build_check' | 'pre_check_batch' | 'quality_budget' | 'symbols' | 'complexity_hotspots' | 'schema_drift' | 'todo_extract' | 'evidence_check' | 'check_gate_status' | 'completion_verify' | 'submit_council_verdicts' | 'submit_phase_council_verdicts' | 'declare_council_criteria' | 'sbom_generate' | 'checkpoint' | 'pkg_audit' | 'test_runner' | 'test_impact' | 'mutation_test' | 'generate_mutants' | 'detect_domains' | 'gitingest' | 'retrieve_summary' | 'extract_code_blocks' | 'phase_complete' | 'save_plan' | 'update_task_status' | 'lint_spec' | 'write_retro' | 'write_drift_evidence' | 'write_hallucination_evidence' | 'write_mutation_evidence' | 'declare_scope' | 'knowledge_query' | 'doc_scan' | 'doc_extract' | 'curator_analyze' | 'knowledge_add' | 'knowledge_recall' | 'knowledge_remove' | 'co_change_analyzer' | 'search' | 'batch_symbols' | 'suggest_patch' | 'req_coverage' | 'get_approved_plan' | 'repo_map' | 'get_qa_gate_profile' | 'set_qa_gates' | 'web_search' | 'convene_general_council' | 'write_final_council_evidence' | 'skill_generate' | 'skill_list' | 'skill_apply' | 'skill_inspect' | 'skill_improve' | 'spec_write' | 'knowledge_ack';
|
|
6
|
+
export type ToolName = 'diff' | 'diff_summary' | 'syntax_check' | 'placeholder_scan' | 'imports' | 'lint' | 'secretscan' | 'sast_scan' | 'build_check' | 'pre_check_batch' | 'quality_budget' | 'symbols' | 'complexity_hotspots' | 'schema_drift' | 'todo_extract' | 'evidence_check' | 'check_gate_status' | 'completion_verify' | 'submit_council_verdicts' | 'submit_phase_council_verdicts' | 'declare_council_criteria' | 'sbom_generate' | 'checkpoint' | 'pkg_audit' | 'test_runner' | 'test_impact' | 'mutation_test' | 'generate_mutants' | 'detect_domains' | 'gitingest' | 'retrieve_summary' | 'extract_code_blocks' | 'phase_complete' | 'save_plan' | 'update_task_status' | 'lint_spec' | 'write_retro' | 'write_drift_evidence' | 'write_hallucination_evidence' | 'write_mutation_evidence' | 'declare_scope' | 'knowledge_query' | 'doc_scan' | 'doc_extract' | 'curator_analyze' | 'knowledge_add' | 'knowledge_recall' | 'knowledge_remove' | 'co_change_analyzer' | 'search' | 'batch_symbols' | 'suggest_patch' | 'req_coverage' | 'get_approved_plan' | 'repo_map' | 'get_qa_gate_profile' | 'set_qa_gates' | 'web_search' | 'convene_general_council' | 'write_final_council_evidence' | 'skill_generate' | 'skill_list' | 'skill_apply' | 'skill_inspect' | 'skill_improve' | 'spec_write' | 'knowledge_ack' | 'lean_turbo_plan_lanes' | 'lean_turbo_acquire_locks' | 'lean_turbo_runner_status' | 'lean_turbo_review' | 'lean_turbo_run_phase' | 'lean_turbo_status';
|
|
7
7
|
/** Readonly array of all tool names */
|
|
8
8
|
export declare const TOOL_NAMES: readonly ToolName[];
|
|
9
9
|
/** Set for O(1) tool name validation */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Update task status tool for changing the status of individual tasks in a plan.
|
|
3
3
|
* Allows agents to mark tasks as pending, in_progress, completed, or blocked.
|
|
4
4
|
*/
|
|
5
|
-
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
5
|
+
import type { ToolContext, ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
6
6
|
/**
|
|
7
7
|
* Arguments for the update_task_status tool
|
|
8
8
|
*/
|
|
@@ -50,18 +50,20 @@ export interface ReviewerGateResult {
|
|
|
50
50
|
* @param taskId - The task ID to check gate state for
|
|
51
51
|
* @param workingDirectory - Optional working directory for plan.json fallback
|
|
52
52
|
* @param stageBParallelEnabled - When true, also accept both-markers-present as passing (PR 2 barrier)
|
|
53
|
+
* @param sessionID - Optional session ID to scope Lean Turbo bypass to the current tool-execution context
|
|
53
54
|
* @returns ReviewerGateResult indicating whether the gate is blocked
|
|
54
55
|
*/
|
|
55
|
-
export declare function checkReviewerGate(taskId: string, workingDirectory?: string, stageBParallelEnabled?: boolean): ReviewerGateResult;
|
|
56
|
+
export declare function checkReviewerGate(taskId: string, workingDirectory?: string, stageBParallelEnabled?: boolean, sessionID?: string): ReviewerGateResult;
|
|
56
57
|
/**
|
|
57
58
|
* Wrapper around checkReviewerGate that appends a diff-scope advisory warning.
|
|
58
59
|
* Keeps checkReviewerGate synchronous for backward compatibility.
|
|
59
60
|
* Stage B parallel is hardcoded (not config-driven).
|
|
60
61
|
* @param taskId - The task ID to check gate state for
|
|
61
62
|
* @param workingDirectory - Optional working directory for plan.json fallback
|
|
63
|
+
* @param sessionID - Optional session ID to scope Lean Turbo bypass to the current tool-execution context
|
|
62
64
|
* @returns ReviewerGateResult with optional scope warning appended to reason
|
|
63
65
|
*/
|
|
64
|
-
export declare function checkReviewerGateWithScope(taskId: string, workingDirectory?: string): Promise<ReviewerGateResult>;
|
|
66
|
+
export declare function checkReviewerGateWithScope(taskId: string, workingDirectory?: string, sessionID?: string): Promise<ReviewerGateResult>;
|
|
65
67
|
/**
|
|
66
68
|
* Recovery mechanism: reconcile task state with delegation history.
|
|
67
69
|
* When reviewer/test_engineer delegations occurred but the state machine
|
|
@@ -105,9 +107,10 @@ export declare function checkCouncilGate(workingDirectory: string, taskId: strin
|
|
|
105
107
|
* Only one concurrent call wins the lock; others return success: false with recovery_guidance: "retry".
|
|
106
108
|
* @param args - The update task status arguments
|
|
107
109
|
* @param fallbackDir - Fallback working directory if args.working_directory is not provided
|
|
110
|
+
* @param ctx - Optional ToolContext providing sessionID for Lean Turbo cross-session bypass prevention
|
|
108
111
|
* @returns UpdateTaskStatusResult with success status and details
|
|
109
112
|
*/
|
|
110
|
-
export declare function executeUpdateTaskStatus(args: UpdateTaskStatusArgs, fallbackDir?: string): Promise<UpdateTaskStatusResult>;
|
|
113
|
+
export declare function executeUpdateTaskStatus(args: UpdateTaskStatusArgs, fallbackDir?: string, ctx?: ToolContext): Promise<UpdateTaskStatusResult>;
|
|
111
114
|
/**
|
|
112
115
|
* Tool definition for update_task_status
|
|
113
116
|
*/
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Scope Conflict Detection for Lean Turbo.
|
|
3
|
+
*
|
|
4
|
+
* This module provides conflict detection utilities for determining whether
|
|
5
|
+
* tasks can be executed in parallel based on their file scopes.
|
|
6
|
+
*
|
|
7
|
+
* ## Conflict Detection Rules
|
|
8
|
+
*
|
|
9
|
+
* Two tasks conflict if:
|
|
10
|
+
* - They touch the **same file**
|
|
11
|
+
* - One task touches a **parent directory** of a file the other task touches
|
|
12
|
+
* (e.g., `src/auth/` vs `src/auth/login.ts`)
|
|
13
|
+
* - A task touches a **global file** (affects all coders)
|
|
14
|
+
* - A task touches a **protected path** (security-sensitive areas)
|
|
15
|
+
*
|
|
16
|
+
* ## Path Normalization
|
|
17
|
+
*
|
|
18
|
+
* All paths are normalized to POSIX-style (forward slashes, no trailing slash)
|
|
19
|
+
* before conflict detection. This ensures consistent behavior across platforms.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* A scope file persisted by the `declare_scope` tool.
|
|
23
|
+
* Stored at `.swarm/scopes/scope-{taskId}.json`.
|
|
24
|
+
*/
|
|
25
|
+
export interface ScopeFile {
|
|
26
|
+
taskId: string;
|
|
27
|
+
files: string[];
|
|
28
|
+
declaredAt: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Barrel file patterns that indicate generated/index files.
|
|
32
|
+
* These are treated as global because other tasks may import from them.
|
|
33
|
+
*/
|
|
34
|
+
export declare const BARREL_FILE_PATTERNS: readonly RegExp[];
|
|
35
|
+
/**
|
|
36
|
+
* Normalize a file path to POSIX-style for consistent cross-platform comparison.
|
|
37
|
+
*
|
|
38
|
+
* - Converts backslashes to forward slashes
|
|
39
|
+
* - Removes trailing slashes
|
|
40
|
+
* - Collapses multiple consecutive slashes
|
|
41
|
+
* - Resolves `.` path segments (current directory references)
|
|
42
|
+
* - Does NOT resolve `..` segments or symlinks
|
|
43
|
+
*
|
|
44
|
+
* @param filePath - The path to normalize
|
|
45
|
+
* @returns POSIX-normalized path
|
|
46
|
+
*/
|
|
47
|
+
export declare function normalizePath(filePath: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Check if a path contains directory traversal components.
|
|
50
|
+
* Rejects paths with `..` segments that could escape the project root.
|
|
51
|
+
*
|
|
52
|
+
* @param filePath - The path to validate
|
|
53
|
+
* @returns true if the path is safe (no traversal)
|
|
54
|
+
*/
|
|
55
|
+
export declare function isPathSafe(filePath: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Check if two normalized paths conflict.
|
|
58
|
+
*
|
|
59
|
+
* Conflicts occur when:
|
|
60
|
+
* - The paths are identical (same file)
|
|
61
|
+
* - One path is a parent directory of the other
|
|
62
|
+
*
|
|
63
|
+
* IMPORTANT: Parent/child detection is path-segment aware.
|
|
64
|
+
* `src/auth/` contains `src/auth/login.ts` but NOT `src/authentication.ts`.
|
|
65
|
+
*
|
|
66
|
+
* @param path1 - First normalized path
|
|
67
|
+
* @param path2 - Second normalized path
|
|
68
|
+
* @returns true if the paths conflict
|
|
69
|
+
*/
|
|
70
|
+
export declare function pathsConflict(path1: string, path2: string): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Check if a normalized path is a global file.
|
|
73
|
+
* Global files affect all coders and cannot be parallelized safely.
|
|
74
|
+
*
|
|
75
|
+
* @param normalizedPath - POSIX-normalized path
|
|
76
|
+
* @returns true if the file is global
|
|
77
|
+
*/
|
|
78
|
+
export declare function isGlobalFile(normalizedPath: string): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Check if a normalized path matches a protected path pattern.
|
|
81
|
+
* Protected paths are security-sensitive areas that require special handling.
|
|
82
|
+
*
|
|
83
|
+
* @param normalizedPath - POSIX-normalized path to check
|
|
84
|
+
* @returns true if the path is protected
|
|
85
|
+
*/
|
|
86
|
+
export declare function isProtectedPath(normalizedPath: string): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Read task scope from the scope file for a given task.
|
|
89
|
+
*
|
|
90
|
+
* Scope files are stored at `.swarm/scopes/scope-{taskId}.json`.
|
|
91
|
+
*
|
|
92
|
+
* @param directory - The project root directory
|
|
93
|
+
* @param taskId - The task ID (e.g., "4.1")
|
|
94
|
+
* @returns Array of file paths, or null if scope file doesn't exist
|
|
95
|
+
*/
|
|
96
|
+
export declare function readTaskScopes(directory: string, taskId: string): string[] | null;
|
|
97
|
+
/** Exported for unit testing */
|
|
98
|
+
export declare const GLOBAL_FILES_LIST: readonly string[];
|
|
99
|
+
/** Exported for unit testing */
|
|
100
|
+
export declare const PROTECTED_PATTERNS_LIST: readonly string[];
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence record for a single lane.
|
|
3
|
+
*/
|
|
4
|
+
export interface LaneEvidence {
|
|
5
|
+
laneId: string;
|
|
6
|
+
taskIds: string[];
|
|
7
|
+
files: string[];
|
|
8
|
+
status: 'pending' | 'running' | 'completed' | 'failed' | 'blocked';
|
|
9
|
+
startedAt?: string;
|
|
10
|
+
completedAt?: string;
|
|
11
|
+
error?: string;
|
|
12
|
+
agent?: string;
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
}
|
|
15
|
+
import type { LeanTurboConfig } from '../../config/schema';
|
|
16
|
+
/**
|
|
17
|
+
* Aggregated evidence for an entire Lean Turbo phase.
|
|
18
|
+
*/
|
|
19
|
+
export interface PhaseEvidence {
|
|
20
|
+
phase: number;
|
|
21
|
+
planId: string;
|
|
22
|
+
lanes: LaneEvidence[];
|
|
23
|
+
degradedTasks: {
|
|
24
|
+
taskId: string;
|
|
25
|
+
reason: string;
|
|
26
|
+
}[];
|
|
27
|
+
startedAt: string;
|
|
28
|
+
completedAt?: string;
|
|
29
|
+
status: 'running' | 'completed' | 'failed';
|
|
30
|
+
/** Paths to lane evidence files (e.g., `.swarm/evidence/{phase}/lean-turbo/{laneId}.json`) */
|
|
31
|
+
evidencePaths?: string[];
|
|
32
|
+
/** Summary of integrated diff across all lanes */
|
|
33
|
+
integratedDiffSummary?: string;
|
|
34
|
+
/** Integrated reviewer verdict */
|
|
35
|
+
reviewerVerdict?: 'APPROVED' | 'NEEDS_REVISION' | 'REJECTED';
|
|
36
|
+
/** Critic verdict */
|
|
37
|
+
criticVerdict?: 'APPROVED' | 'NEEDS_REVISION' | 'REJECTED' | 'ESCALATE_TO_HUMAN';
|
|
38
|
+
/** Snapshot of lean turbo config used for this phase */
|
|
39
|
+
configSnapshot?: LeanTurboConfig;
|
|
40
|
+
/** ISO timestamp when phase evidence was written (distinct from startedAt/completedAt) */
|
|
41
|
+
timestamp?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Writes a single lane's evidence to disk.
|
|
45
|
+
*
|
|
46
|
+
* Uses atomic write (temp file + rename) so readers never see a partial file.
|
|
47
|
+
*
|
|
48
|
+
* @param directory - Project root directory
|
|
49
|
+
* @param phase - Phase number
|
|
50
|
+
* @param evidence - Lane evidence to persist
|
|
51
|
+
* @throws Error if laneId fails validation
|
|
52
|
+
*/
|
|
53
|
+
export declare function writeLaneEvidence(directory: string, phase: number, evidence: LaneEvidence): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Reads a single lane's evidence from disk.
|
|
56
|
+
*
|
|
57
|
+
* @param directory - Project root directory
|
|
58
|
+
* @param phase - Phase number
|
|
59
|
+
* @param laneId - Lane identifier
|
|
60
|
+
* @returns Parsed LaneEvidence, or null if file does not exist or is invalid
|
|
61
|
+
* @throws Error if laneId fails validation
|
|
62
|
+
*/
|
|
63
|
+
export declare function readLaneEvidence(directory: string, phase: number, laneId: string): Promise<LaneEvidence | null>;
|
|
64
|
+
/**
|
|
65
|
+
* Writes phase-level aggregated evidence to disk.
|
|
66
|
+
*
|
|
67
|
+
* Uses atomic write (temp file + rename).
|
|
68
|
+
*
|
|
69
|
+
* @param directory - Project root directory
|
|
70
|
+
* @param evidence - Phase evidence to persist
|
|
71
|
+
*/
|
|
72
|
+
export declare function writePhaseEvidence(directory: string, evidence: PhaseEvidence): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Reads phase-level aggregated evidence from disk.
|
|
75
|
+
*
|
|
76
|
+
* @param directory - Project root directory
|
|
77
|
+
* @param phase - Phase number
|
|
78
|
+
* @returns Parsed PhaseEvidence, or null if file does not exist or is invalid
|
|
79
|
+
*/
|
|
80
|
+
export declare function readPhaseEvidence(directory: string, phase: number): Promise<PhaseEvidence | null>;
|
|
81
|
+
/**
|
|
82
|
+
* Lists all lane evidence files for a given phase.
|
|
83
|
+
*
|
|
84
|
+
* Reads every `.json` file in the lean-turbo evidence directory and returns
|
|
85
|
+
* parsed LaneEvidence objects. Files that cannot be read or parsed are skipped.
|
|
86
|
+
*
|
|
87
|
+
* @param directory - Project root directory
|
|
88
|
+
* @param phase - Phase number
|
|
89
|
+
* @returns Array of LaneEvidence, skipping any invalid files
|
|
90
|
+
*/
|
|
91
|
+
export declare function listLaneEvidence(directory: string, phase: number): Promise<LaneEvidence[]>;
|