opencode-swarm 6.5.0 → 6.8.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 +52 -6
- package/dist/__tests__/security-adversarial.test.d.ts +1 -0
- package/dist/background/circuit-breaker.d.ts +149 -0
- package/dist/background/event-bus.d.ts +60 -0
- package/dist/background/evidence-summary-integration.d.ts +73 -0
- package/dist/background/index.d.ts +22 -0
- package/dist/background/manager.d.ts +122 -0
- package/dist/background/plan-sync-worker.d.ts +117 -0
- package/dist/background/queue.d.ts +116 -0
- package/dist/background/status-artifact.d.ts +115 -0
- package/dist/background/trigger.d.ts +175 -0
- package/dist/background/trigger.vulnerability.test.d.ts +1 -0
- package/dist/background/worker.d.ts +92 -0
- package/dist/commands/command-adapters.security.test.d.ts +14 -0
- package/dist/commands/commands.test.d.ts +1 -0
- package/dist/commands/diagnose.d.ts +1 -5
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/evidence.d.ts +1 -5
- package/dist/commands/export.d.ts +1 -5
- package/dist/commands/history.d.ts +1 -5
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/plan.d.ts +1 -1
- package/dist/commands/preflight.d.ts +1 -0
- package/dist/commands/status.d.ts +1 -2
- package/dist/commands/sync-plan.d.ts +8 -0
- package/dist/config/index.d.ts +2 -2
- package/dist/config/plan-schema.d.ts +4 -4
- package/dist/config/schema.d.ts +53 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/phase-monitor.d.ts +16 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +27786 -22900
- package/dist/plan/manager.d.ts +13 -6
- package/dist/services/config-doctor.d.ts +125 -0
- package/dist/services/config-doctor.security.test.d.ts +1 -0
- package/dist/services/config-doctor.test.d.ts +1 -0
- package/dist/services/decision-drift-analyzer.d.ts +96 -0
- package/dist/services/diagnose-service.d.ts +31 -0
- package/dist/services/evidence-service.d.ts +65 -0
- package/dist/services/evidence-summary-service.d.ts +75 -0
- package/dist/services/export-service.d.ts +23 -0
- package/dist/services/history-service.d.ts +35 -0
- package/dist/services/index.d.ts +11 -0
- package/dist/services/plan-service.d.ts +25 -0
- package/dist/services/preflight-integration.d.ts +38 -0
- package/dist/services/preflight-service.d.ts +62 -0
- package/dist/services/status-service.d.ts +28 -0
- package/dist/tools/secretscan.d.ts +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://img.shields.io/badge/version-6.
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<img src="https://img.shields.io/badge/version-6.8.0-blue" alt="Version">
|
|
3
|
+
<img src="https://img.shields.io/badge/license-MIT-green" alt="License">
|
|
4
|
+
<img src="https://img.shields.io/badge/opencode-plugin-purple" alt="OpenCode Plugin">
|
|
5
|
+
<img src="https://img.shields.io/badge/agents-9-orange" alt="Agents">
|
|
6
|
+
<img src="https://img.shields.io/badge/tests-4008-brightgreen" alt="Tests">
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
<h1 align="center">🐝 OpenCode Swarm</h1>
|
|
@@ -352,6 +352,9 @@ Per-agent profiles allow fine-grained overrides:
|
|
|
352
352
|
| `/swarm benchmark` | Performance benchmarks |
|
|
353
353
|
| `/swarm retrieve [id]` | Retrieve auto-summarized tool outputs |
|
|
354
354
|
| `/swarm reset --confirm` | Clear swarm state files |
|
|
355
|
+
| `/swarm preflight` | Run phase preflight checks (v6.7) |
|
|
356
|
+
| `/swarm config doctor [--fix] [--restore <id>]` | Config validation with optional auto-fix (v6.7) |
|
|
357
|
+
| `/swarm sync-plan` | Force plan.md regeneration from plan.json (v6.7) |
|
|
355
358
|
|
|
356
359
|
---
|
|
357
360
|
|
|
@@ -380,12 +383,53 @@ Per-agent profiles allow fine-grained overrides:
|
|
|
380
383
|
"review_passes": {
|
|
381
384
|
"always_security_review": false,
|
|
382
385
|
"security_globs": ["**/*auth*", "**/*crypto*", "**/*session*", "**/*token*"]
|
|
386
|
+
},
|
|
387
|
+
"automation": {
|
|
388
|
+
"mode": "manual",
|
|
389
|
+
"capabilities": {
|
|
390
|
+
"plan_sync": false,
|
|
391
|
+
"phase_preflight": false,
|
|
392
|
+
"config_doctor_on_startup": false,
|
|
393
|
+
"config_doctor_autofix": false,
|
|
394
|
+
"evidence_auto_summaries": false,
|
|
395
|
+
"decision_drift_detection": false
|
|
396
|
+
}
|
|
383
397
|
}
|
|
384
398
|
}
|
|
385
399
|
```
|
|
386
400
|
|
|
387
401
|
Save to `~/.config/opencode/opencode-swarm.json` or `.opencode/swarm.json` in your project root. Project config merges over global config via deep merge — partial overrides do not clobber unspecified fields.
|
|
388
402
|
|
|
403
|
+
### Automation (v6.7)
|
|
404
|
+
|
|
405
|
+
**Default mode: `manual`** (no background automation). Enable automation features via `automation` config:
|
|
406
|
+
|
|
407
|
+
```json
|
|
408
|
+
{
|
|
409
|
+
"automation": {
|
|
410
|
+
"mode": "hybrid",
|
|
411
|
+
"capabilities": {
|
|
412
|
+
"plan_sync": true,
|
|
413
|
+
"config_doctor_on_startup": true,
|
|
414
|
+
"evidence_auto_summaries": true
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Automation modes:**
|
|
421
|
+
- `manual` - No background automation (default)
|
|
422
|
+
- `hybrid` - Background automation for safe ops, manual for sensitive ones
|
|
423
|
+
- `auto` - Full background automation (target state)
|
|
424
|
+
|
|
425
|
+
**Per-feature flags (all default `false`):**
|
|
426
|
+
- `plan_sync` - Auto-regenerate plan.md from plan.json when out of sync
|
|
427
|
+
- `phase_preflight` - Phase-boundary validation before agent execution
|
|
428
|
+
- `config_doctor_on_startup` - Config validation on plugin initialization
|
|
429
|
+
- `config_doctor_autofix` - Auto-fix mode for Config Doctor (requires explicit opt-in)
|
|
430
|
+
- `evidence_auto_summaries` - Auto-generate evidence summaries
|
|
431
|
+
- `decision_drift_detection` - Detect drift between planned and actual decisions
|
|
432
|
+
|
|
389
433
|
### Disabling Agents
|
|
390
434
|
|
|
391
435
|
```json
|
|
@@ -423,7 +467,7 @@ The installer auto-configures `opencode.json` to include the plugin. Manual conf
|
|
|
423
467
|
|
|
424
468
|
## Testing
|
|
425
469
|
|
|
426
|
-
|
|
470
|
+
4008 tests across 136 files. Unit, integration, adversarial, and smoke. Covers config schemas, all agent prompts, all hooks, all tools, all commands, guardrail circuit breaker, race conditions, invocation window isolation, multi-invocation state, security category classification, evidence validation, background workers, phase-monitor hooks, and evidence-summary automation.
|
|
427
471
|
|
|
428
472
|
```bash
|
|
429
473
|
bun test
|
|
@@ -483,6 +527,8 @@ Five tools that improve planning quality and post-phase validation:
|
|
|
483
527
|
- [Architecture Deep Dive](docs/architecture.md)
|
|
484
528
|
- [Design Rationale](docs/design-rationale.md)
|
|
485
529
|
- [Installation Guide](docs/installation.md)
|
|
530
|
+
- [Linux + Native Windows + Docker Desktop Install Guide](docs/installation-linux-docker.md)
|
|
531
|
+
- [LLM Operator Install Guide](docs/installation-llm-operator.md)
|
|
486
532
|
|
|
487
533
|
---
|
|
488
534
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circuit Breaker + Loop Protection Primitives
|
|
3
|
+
*
|
|
4
|
+
* Provides fault tolerance and infinite loop prevention for background automation.
|
|
5
|
+
*/
|
|
6
|
+
/** Circuit breaker states */
|
|
7
|
+
export type CircuitBreakerState = 'closed' | 'open' | 'half-open';
|
|
8
|
+
/** Circuit breaker configuration */
|
|
9
|
+
export interface CircuitBreakerConfig {
|
|
10
|
+
/** Number of failures before opening circuit */
|
|
11
|
+
failureThreshold: number;
|
|
12
|
+
/** Time in ms to wait before attempting reset */
|
|
13
|
+
resetTimeoutMs: number;
|
|
14
|
+
/** Number of success calls needed to close from half-open */
|
|
15
|
+
successThreshold: number;
|
|
16
|
+
/** Timeout for individual calls (0 = no timeout) */
|
|
17
|
+
callTimeoutMs: number;
|
|
18
|
+
}
|
|
19
|
+
/** Circuit breaker events */
|
|
20
|
+
export interface CircuitBreakerEvents {
|
|
21
|
+
opened: {
|
|
22
|
+
timestamp: number;
|
|
23
|
+
failureCount: number;
|
|
24
|
+
};
|
|
25
|
+
closed: {
|
|
26
|
+
timestamp: number;
|
|
27
|
+
successCount: number;
|
|
28
|
+
};
|
|
29
|
+
'half-open': {
|
|
30
|
+
timestamp: number;
|
|
31
|
+
};
|
|
32
|
+
callSuccess: {
|
|
33
|
+
duration: number;
|
|
34
|
+
};
|
|
35
|
+
callFailure: {
|
|
36
|
+
error: unknown;
|
|
37
|
+
duration: number;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export type CircuitBreakerEventType = keyof CircuitBreakerEvents;
|
|
41
|
+
/**
|
|
42
|
+
* Circuit Breaker Implementation
|
|
43
|
+
*
|
|
44
|
+
* Prevents cascading failures by stopping requests when the circuit is open.
|
|
45
|
+
* States:
|
|
46
|
+
* - closed: Normal operation, requests pass through
|
|
47
|
+
* - open: Circuit is open, requests fail fast
|
|
48
|
+
* - half-open: Testing if service recovered
|
|
49
|
+
*/
|
|
50
|
+
export declare class CircuitBreaker {
|
|
51
|
+
private state;
|
|
52
|
+
private failureCount;
|
|
53
|
+
private successCount;
|
|
54
|
+
private lastFailureTime?;
|
|
55
|
+
private readonly config;
|
|
56
|
+
private readonly name;
|
|
57
|
+
private readonly onStateChange?;
|
|
58
|
+
constructor(name: string, config?: Partial<CircuitBreakerConfig>, onStateChange?: (eventType: string, event: unknown) => void);
|
|
59
|
+
/**
|
|
60
|
+
* Get current circuit state
|
|
61
|
+
*/
|
|
62
|
+
getState(): CircuitBreakerState;
|
|
63
|
+
/**
|
|
64
|
+
* Execute a function with circuit breaker protection
|
|
65
|
+
*/
|
|
66
|
+
execute<T>(fn: () => Promise<T>): Promise<T>;
|
|
67
|
+
/**
|
|
68
|
+
* Execute with timeout
|
|
69
|
+
*/
|
|
70
|
+
private executeWithTimeout;
|
|
71
|
+
/**
|
|
72
|
+
* Record a successful call
|
|
73
|
+
*/
|
|
74
|
+
private recordSuccess;
|
|
75
|
+
/**
|
|
76
|
+
* Record a failed call
|
|
77
|
+
*/
|
|
78
|
+
private recordFailure;
|
|
79
|
+
/**
|
|
80
|
+
* Transition to a new state
|
|
81
|
+
*/
|
|
82
|
+
private transitionTo;
|
|
83
|
+
/**
|
|
84
|
+
* Manually reset the circuit breaker
|
|
85
|
+
*/
|
|
86
|
+
reset(): void;
|
|
87
|
+
/**
|
|
88
|
+
* Get circuit breaker statistics
|
|
89
|
+
*/
|
|
90
|
+
getStats(): {
|
|
91
|
+
state: CircuitBreakerState;
|
|
92
|
+
failureCount: number;
|
|
93
|
+
successCount: number;
|
|
94
|
+
lastFailureTime?: number;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Loop Protection for preventing infinite automation loops
|
|
99
|
+
*
|
|
100
|
+
* Tracks operation history and detects potential infinite loops.
|
|
101
|
+
*/
|
|
102
|
+
export interface LoopProtectionConfig {
|
|
103
|
+
/** Maximum times an operation can be attempted */
|
|
104
|
+
maxIterations: number;
|
|
105
|
+
/** Time window in ms to track iterations */
|
|
106
|
+
timeWindowMs: number;
|
|
107
|
+
/** Unique key for the operation being protected */
|
|
108
|
+
operationKey: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Loop Protection Implementation
|
|
112
|
+
*
|
|
113
|
+
* Prevents infinite loops by tracking operation frequency.
|
|
114
|
+
*/
|
|
115
|
+
export declare class LoopProtection {
|
|
116
|
+
private records;
|
|
117
|
+
private readonly config;
|
|
118
|
+
private readonly onLoopDetected?;
|
|
119
|
+
constructor(config: LoopProtectionConfig, onLoopDetected?: (key: string, count: number) => void);
|
|
120
|
+
/**
|
|
121
|
+
* Record an iteration attempt
|
|
122
|
+
* Returns false if max iterations exceeded
|
|
123
|
+
*/
|
|
124
|
+
recordAttempt(key?: string): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Check if operation is allowed without recording
|
|
127
|
+
*/
|
|
128
|
+
canProceed(key?: string): boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Get remaining iterations allowed
|
|
131
|
+
*/
|
|
132
|
+
getRemainingIterations(key?: string): number;
|
|
133
|
+
/**
|
|
134
|
+
* Reset tracking for an operation
|
|
135
|
+
*/
|
|
136
|
+
reset(key?: string): void;
|
|
137
|
+
/**
|
|
138
|
+
* Reset all tracking
|
|
139
|
+
*/
|
|
140
|
+
resetAll(): void;
|
|
141
|
+
/**
|
|
142
|
+
* Get current iteration count
|
|
143
|
+
*/
|
|
144
|
+
getIterationCount(key?: string): number;
|
|
145
|
+
/**
|
|
146
|
+
* Get all operation keys being tracked
|
|
147
|
+
*/
|
|
148
|
+
getTrackedOperations(): string[];
|
|
149
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed Event Bus for Internal Automation Events
|
|
3
|
+
*
|
|
4
|
+
* Provides a type-safe event system for background automation.
|
|
5
|
+
* Events flow through the system without external dependencies.
|
|
6
|
+
*/
|
|
7
|
+
/** Automation event types */
|
|
8
|
+
export type AutomationEventType = 'queue.item.enqueued' | 'queue.item.dequeued' | 'queue.item.completed' | 'queue.item.failed' | 'queue.item.retry scheduled' | 'worker.started' | 'worker.stopped' | 'worker.error' | 'circuit.breaker.opened' | 'circuit.breaker.half-open' | 'circuit.breaker.closed' | 'loop.protection.triggered' | 'automation.started' | 'automation.stopped' | 'preflight.requested' | 'preflight.triggered' | 'preflight.skipped' | 'preflight.completed' | 'phase.boundary.detected' | 'phase.status.checked' | 'task.completed' | 'evidence.summary.generated' | 'evidence.summary.error';
|
|
9
|
+
/** Base automation event */
|
|
10
|
+
export interface AutomationEvent<T = unknown> {
|
|
11
|
+
type: AutomationEventType;
|
|
12
|
+
timestamp: number;
|
|
13
|
+
payload: T;
|
|
14
|
+
source?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Event listener type */
|
|
17
|
+
export type EventListener<T = unknown> = (event: AutomationEvent<T>) => void | Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Type-safe event bus for automation events
|
|
20
|
+
*/
|
|
21
|
+
export declare class AutomationEventBus {
|
|
22
|
+
private listeners;
|
|
23
|
+
private eventHistory;
|
|
24
|
+
private readonly maxHistorySize;
|
|
25
|
+
constructor(options?: {
|
|
26
|
+
maxHistorySize?: number;
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Subscribe to an event type
|
|
30
|
+
*/
|
|
31
|
+
subscribe<T>(type: AutomationEventType, listener: EventListener<T>): () => void;
|
|
32
|
+
/**
|
|
33
|
+
* Publish an event to all subscribers
|
|
34
|
+
*/
|
|
35
|
+
publish<T>(type: AutomationEventType, payload: T, source?: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Get recent event history
|
|
38
|
+
*/
|
|
39
|
+
getHistory(types?: AutomationEventType[]): AutomationEvent[];
|
|
40
|
+
/**
|
|
41
|
+
* Clear event history
|
|
42
|
+
*/
|
|
43
|
+
clearHistory(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get listener count for an event type
|
|
46
|
+
*/
|
|
47
|
+
getListenerCount(type: AutomationEventType): number;
|
|
48
|
+
/**
|
|
49
|
+
* Check if any listeners exist for a type
|
|
50
|
+
*/
|
|
51
|
+
hasListeners(type: AutomationEventType): boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get or create the global event bus instance
|
|
55
|
+
*/
|
|
56
|
+
export declare function getGlobalEventBus(): AutomationEventBus;
|
|
57
|
+
/**
|
|
58
|
+
* Reset the global event bus (for testing)
|
|
59
|
+
*/
|
|
60
|
+
export declare function resetGlobalEventBus(): void;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence Summary Background Integration
|
|
3
|
+
*
|
|
4
|
+
* Wires the evidence summary service to background automation:
|
|
5
|
+
* - Subscribes to preflight and phase boundary events
|
|
6
|
+
* - Generates evidence summaries automatically
|
|
7
|
+
* - Persists artifacts under .swarm/ for GUI consumption
|
|
8
|
+
* - Respects feature flags (evidence_auto_summaries) with default-off safety
|
|
9
|
+
*/
|
|
10
|
+
import type { AutomationConfig } from '../config/schema';
|
|
11
|
+
import { type EvidenceSummaryArtifact } from '../services/evidence-summary-service';
|
|
12
|
+
/** Evidence summary integration configuration */
|
|
13
|
+
export interface EvidenceSummaryIntegrationConfig {
|
|
14
|
+
/** Automation configuration for feature flag gating */
|
|
15
|
+
automationConfig: AutomationConfig;
|
|
16
|
+
/** Directory to run evidence analysis in */
|
|
17
|
+
directory: string;
|
|
18
|
+
/** Swarm directory for persisting summary artifacts */
|
|
19
|
+
swarmDir: string;
|
|
20
|
+
/** Filename for the summary artifact (default: evidence-summary.json) */
|
|
21
|
+
summaryFilename?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Event types that can trigger evidence summary generation */
|
|
24
|
+
export type EvidenceSummaryTriggerEvent = 'preflight.completed' | 'phase.boundary.detected' | 'phase.status.checked' | 'task.completed';
|
|
25
|
+
/** Payload for evidence summary trigger events */
|
|
26
|
+
export interface EvidenceSummaryTriggerPayload {
|
|
27
|
+
trigger: EvidenceSummaryTriggerEvent;
|
|
28
|
+
phase: number;
|
|
29
|
+
reason: string;
|
|
30
|
+
metadata?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Evidence Summary Integration
|
|
34
|
+
*
|
|
35
|
+
* Automatically generates and persists evidence summaries on relevant events.
|
|
36
|
+
*/
|
|
37
|
+
export declare class EvidenceSummaryIntegration {
|
|
38
|
+
private readonly config;
|
|
39
|
+
private readonly eventBus;
|
|
40
|
+
private unsubscribes;
|
|
41
|
+
constructor(config: EvidenceSummaryIntegrationConfig);
|
|
42
|
+
/**
|
|
43
|
+
* Check if auto-summaries are enabled
|
|
44
|
+
*/
|
|
45
|
+
isEnabled(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Initialize the integration by subscribing to trigger events
|
|
48
|
+
* Only subscribes if enabled via feature flags
|
|
49
|
+
*/
|
|
50
|
+
initialize(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Subscribe to an event type
|
|
53
|
+
*/
|
|
54
|
+
private subscribeToEvent;
|
|
55
|
+
/**
|
|
56
|
+
* Generate and persist evidence summary
|
|
57
|
+
*/
|
|
58
|
+
generateSummary(phase: number, trigger: EvidenceSummaryTriggerEvent): Promise<EvidenceSummaryArtifact | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Manually trigger summary generation (for CLI or testing)
|
|
61
|
+
*/
|
|
62
|
+
triggerManual(phase?: number): Promise<EvidenceSummaryArtifact | null>;
|
|
63
|
+
/**
|
|
64
|
+
* Cleanup subscriptions
|
|
65
|
+
*/
|
|
66
|
+
cleanup(): void;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create evidence summary integration
|
|
70
|
+
*
|
|
71
|
+
* Factory function that creates and optionally initializes the integration.
|
|
72
|
+
*/
|
|
73
|
+
export declare function createEvidenceSummaryIntegration(config: EvidenceSummaryIntegrationConfig, autoInitialize?: boolean): EvidenceSummaryIntegration;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Automation Framework
|
|
3
|
+
*
|
|
4
|
+
* Provides infrastructure for v6.7 background-first automation:
|
|
5
|
+
* - Typed event bus for internal automation events
|
|
6
|
+
* - Lightweight in-process queue with priorities and retry metadata
|
|
7
|
+
* - Worker lifecycle manager (start/stop/register handlers)
|
|
8
|
+
* - Circuit breaker + loop protection primitives
|
|
9
|
+
* - Phase-boundary trigger detection and preflight request plumbing
|
|
10
|
+
* - Passive status artifact writer for GUI visibility
|
|
11
|
+
*
|
|
12
|
+
* Gated behind Task 5.2 automation feature flags and default-off behavior.
|
|
13
|
+
*/
|
|
14
|
+
export { CircuitBreaker, type CircuitBreakerConfig, type CircuitBreakerState, LoopProtection, } from './circuit-breaker';
|
|
15
|
+
export { type AutomationEvent, AutomationEventBus, type AutomationEventType, } from './event-bus';
|
|
16
|
+
export { createEvidenceSummaryIntegration, type EvidenceSummaryIntegrationConfig, type EvidenceSummaryTriggerEvent, type EvidenceSummaryTriggerPayload, } from './evidence-summary-integration';
|
|
17
|
+
export { type AutomationFrameworkConfig, BackgroundAutomationManager, createAutomationManager, } from './manager';
|
|
18
|
+
export { PlanSyncWorker, type PlanSyncWorkerOptions, type PlanSyncWorkerStatus, } from './plan-sync-worker';
|
|
19
|
+
export { AutomationQueue, type QueueItem, type QueuePriority, type RetryMetadata, } from './queue';
|
|
20
|
+
export { AutomationStatusArtifact, type AutomationStatusSnapshot, } from './status-artifact';
|
|
21
|
+
export { type PhaseBoundaryResult, PhaseBoundaryTrigger, type PreflightHandler, type PreflightRequest, type PreflightRequestPayload, type PreflightTriggerConfig, type PreflightTriggerEventType, PreflightTriggerManager, } from './trigger';
|
|
22
|
+
export { type WorkerHandler, WorkerManager, type WorkerRegistration, } from './worker';
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Automation Manager
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for the background automation framework.
|
|
5
|
+
* Handles feature flag gating and orchestrates all components.
|
|
6
|
+
*/
|
|
7
|
+
import type { AutomationConfig } from '../config/schema';
|
|
8
|
+
import { CircuitBreaker, type CircuitBreakerConfig, LoopProtection, type LoopProtectionConfig } from './circuit-breaker';
|
|
9
|
+
import { type AutomationEvent, type AutomationEventType } from './event-bus';
|
|
10
|
+
import { AutomationQueue } from './queue';
|
|
11
|
+
import { WorkerManager, type WorkerRegistration } from './worker';
|
|
12
|
+
/** Framework configuration */
|
|
13
|
+
export interface AutomationFrameworkConfig {
|
|
14
|
+
/** Enable/disable the entire framework */
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
/** Max queue size */
|
|
17
|
+
maxQueueSize?: number;
|
|
18
|
+
/** Max retries for failed items */
|
|
19
|
+
maxRetries?: number;
|
|
20
|
+
/** Circuit breaker config */
|
|
21
|
+
circuitBreaker?: Partial<CircuitBreakerConfig>;
|
|
22
|
+
/** Loop protection config */
|
|
23
|
+
loopProtection?: Partial<LoopProtectionConfig>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Background Automation Manager
|
|
27
|
+
*
|
|
28
|
+
* Provides a unified interface for background automation with feature flag gating.
|
|
29
|
+
* All components are optional and only activated when enabled.
|
|
30
|
+
*/
|
|
31
|
+
export declare class BackgroundAutomationManager {
|
|
32
|
+
private readonly config;
|
|
33
|
+
private readonly eventBus;
|
|
34
|
+
private readonly workerManager;
|
|
35
|
+
private readonly queues;
|
|
36
|
+
private readonly circuitBreakers;
|
|
37
|
+
private readonly loopProtections;
|
|
38
|
+
private isInitialized;
|
|
39
|
+
private isRunning;
|
|
40
|
+
constructor(config: AutomationFrameworkConfig);
|
|
41
|
+
/**
|
|
42
|
+
* Initialize the automation framework
|
|
43
|
+
* Only performs work if enabled
|
|
44
|
+
*/
|
|
45
|
+
initialize(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Start the automation framework
|
|
48
|
+
*/
|
|
49
|
+
start(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Stop the automation framework
|
|
52
|
+
*/
|
|
53
|
+
stop(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Check if framework is enabled
|
|
56
|
+
*/
|
|
57
|
+
isEnabled(): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Check if framework is running
|
|
60
|
+
*/
|
|
61
|
+
isActive(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Create or get a named queue
|
|
64
|
+
*/
|
|
65
|
+
getOrCreateQueue<T>(name: string): AutomationQueue<T>;
|
|
66
|
+
/**
|
|
67
|
+
* Register a worker with the framework
|
|
68
|
+
*/
|
|
69
|
+
registerWorker(registration: WorkerRegistration): void;
|
|
70
|
+
/**
|
|
71
|
+
* Start a specific worker
|
|
72
|
+
*/
|
|
73
|
+
startWorker(name: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Stop a specific worker
|
|
76
|
+
*/
|
|
77
|
+
stopWorker(name: string): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Get or create a circuit breaker
|
|
80
|
+
*/
|
|
81
|
+
getOrCreateCircuitBreaker(name: string): CircuitBreaker;
|
|
82
|
+
/**
|
|
83
|
+
* Get or create loop protection
|
|
84
|
+
*/
|
|
85
|
+
getOrCreateLoopProtection(operationKey: string): LoopProtection;
|
|
86
|
+
/**
|
|
87
|
+
* Subscribe to automation events
|
|
88
|
+
*/
|
|
89
|
+
subscribe<T>(type: AutomationEventType, listener: (event: AutomationEvent<T>) => void | Promise<void>): () => void;
|
|
90
|
+
/**
|
|
91
|
+
* Publish an event to the automation event bus
|
|
92
|
+
*/
|
|
93
|
+
publish<T>(type: AutomationEventType, payload: T, source?: string): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Get framework statistics
|
|
96
|
+
*/
|
|
97
|
+
getStats(): {
|
|
98
|
+
enabled: boolean;
|
|
99
|
+
initialized: boolean;
|
|
100
|
+
running: boolean;
|
|
101
|
+
queues: Record<string, ReturnType<AutomationQueue['getStats']>>;
|
|
102
|
+
workers: Record<string, ReturnType<WorkerManager['getStats']>>;
|
|
103
|
+
circuitBreakers: Record<string, ReturnType<CircuitBreaker['getStats']>>;
|
|
104
|
+
loopProtections: string[];
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Reset the framework (for testing)
|
|
108
|
+
*/
|
|
109
|
+
reset(): void;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get or create the global automation manager
|
|
113
|
+
*/
|
|
114
|
+
export declare function getAutomationManager(config?: AutomationFrameworkConfig): BackgroundAutomationManager;
|
|
115
|
+
/**
|
|
116
|
+
* Initialize automation manager from plugin config
|
|
117
|
+
*/
|
|
118
|
+
export declare function createAutomationManager(automationConfig: AutomationConfig | undefined): BackgroundAutomationManager;
|
|
119
|
+
/**
|
|
120
|
+
* Reset the global manager (for testing)
|
|
121
|
+
*/
|
|
122
|
+
export declare function resetAutomationManager(): void;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Sync Worker
|
|
3
|
+
*
|
|
4
|
+
* Watches .swarm/plan.json for changes and syncs plan.md accordingly.
|
|
5
|
+
* Uses fs.watch with polling fallback for cross-platform reliability.
|
|
6
|
+
*/
|
|
7
|
+
/** Configuration options for PlanSyncWorker */
|
|
8
|
+
export interface PlanSyncWorkerOptions {
|
|
9
|
+
/** Directory containing .swarm folder (defaults to cwd) */
|
|
10
|
+
directory?: string;
|
|
11
|
+
/** Debounce delay in ms (default: 300ms) */
|
|
12
|
+
debounceMs?: number;
|
|
13
|
+
/** Polling interval in ms when fs.watch fails (default: 2000ms) */
|
|
14
|
+
pollIntervalMs?: number;
|
|
15
|
+
/** Sync operation timeout in ms (default: 30000ms) - prevents runaway hangs */
|
|
16
|
+
syncTimeoutMs?: number;
|
|
17
|
+
/** Called on sync completion (success or failure) */
|
|
18
|
+
onSyncComplete?: (success: boolean, error?: Error) => void;
|
|
19
|
+
}
|
|
20
|
+
/** Worker status */
|
|
21
|
+
export type PlanSyncWorkerStatus = 'stopped' | 'starting' | 'running' | 'stopping';
|
|
22
|
+
/**
|
|
23
|
+
* Plan Sync Worker
|
|
24
|
+
*
|
|
25
|
+
* Standalone class that watches plan.json and triggers plan.md regeneration.
|
|
26
|
+
* Handles cross-platform fs.watch reliability issues with polling fallback.
|
|
27
|
+
*/
|
|
28
|
+
export declare class PlanSyncWorker {
|
|
29
|
+
private readonly directory;
|
|
30
|
+
private readonly debounceMs;
|
|
31
|
+
private readonly pollIntervalMs;
|
|
32
|
+
private readonly syncTimeoutMs;
|
|
33
|
+
private readonly onSyncComplete?;
|
|
34
|
+
private status;
|
|
35
|
+
private watcher;
|
|
36
|
+
private pollTimer;
|
|
37
|
+
private debounceTimer;
|
|
38
|
+
/** In-flight sync lock */
|
|
39
|
+
private syncing;
|
|
40
|
+
/** Pending sync requested while in-flight */
|
|
41
|
+
private pendingSync;
|
|
42
|
+
/** Last known plan.json stat to detect changes */
|
|
43
|
+
private lastStat;
|
|
44
|
+
/** Track if we've been disposed */
|
|
45
|
+
private disposed;
|
|
46
|
+
constructor(options?: PlanSyncWorkerOptions);
|
|
47
|
+
/**
|
|
48
|
+
* Get the swarm directory path
|
|
49
|
+
*/
|
|
50
|
+
private getSwarmDir;
|
|
51
|
+
/**
|
|
52
|
+
* Get the plan.json file path
|
|
53
|
+
*/
|
|
54
|
+
private getPlanJsonPath;
|
|
55
|
+
/**
|
|
56
|
+
* Start watching for plan.json changes
|
|
57
|
+
*/
|
|
58
|
+
start(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Stop watching and clean up resources
|
|
61
|
+
*/
|
|
62
|
+
stop(): void;
|
|
63
|
+
/**
|
|
64
|
+
* Dispose of the worker - stop and prevent further use
|
|
65
|
+
*/
|
|
66
|
+
dispose(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Get current status
|
|
69
|
+
*/
|
|
70
|
+
getStatus(): PlanSyncWorkerStatus;
|
|
71
|
+
/**
|
|
72
|
+
* Check if worker is running
|
|
73
|
+
*/
|
|
74
|
+
isRunning(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Initialize the stat tracking for change detection
|
|
77
|
+
*/
|
|
78
|
+
private initializeStat;
|
|
79
|
+
/**
|
|
80
|
+
* Set up native fs.watch on the swarm directory
|
|
81
|
+
* Returns true if successful, false if unavailable
|
|
82
|
+
*/
|
|
83
|
+
private setupNativeWatcher;
|
|
84
|
+
/**
|
|
85
|
+
* Set up polling fallback
|
|
86
|
+
*/
|
|
87
|
+
private setupPolling;
|
|
88
|
+
/**
|
|
89
|
+
* Check for changes via polling
|
|
90
|
+
*/
|
|
91
|
+
private pollCheck;
|
|
92
|
+
/**
|
|
93
|
+
* Debounced sync - prevents rapid successive syncs
|
|
94
|
+
*/
|
|
95
|
+
private debouncedSync;
|
|
96
|
+
/**
|
|
97
|
+
* Clear debounce timer
|
|
98
|
+
*/
|
|
99
|
+
private clearDebounce;
|
|
100
|
+
/**
|
|
101
|
+
* Trigger a sync operation with overlap protection
|
|
102
|
+
*/
|
|
103
|
+
private triggerSync;
|
|
104
|
+
/**
|
|
105
|
+
* Execute the sync operation with timeout protection
|
|
106
|
+
*/
|
|
107
|
+
private executeSync;
|
|
108
|
+
/**
|
|
109
|
+
* Safely invoke onSyncComplete callback, catching any exceptions
|
|
110
|
+
* to prevent callback errors from affecting worker stability
|
|
111
|
+
*/
|
|
112
|
+
private safeCallback;
|
|
113
|
+
/**
|
|
114
|
+
* Wrap a promise with a timeout
|
|
115
|
+
*/
|
|
116
|
+
private withTimeout;
|
|
117
|
+
}
|