opencode-swarm 6.21.3 → 6.22.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/README.md +56 -4
- package/dist/agents/critic.d.ts +1 -0
- package/dist/agents/explorer.d.ts +1 -0
- package/dist/background/event-bus.d.ts +1 -1
- package/dist/cli/index.js +18 -6
- package/dist/config/schema.d.ts +21 -0
- package/dist/hooks/curator-drift.d.ts +30 -0
- package/dist/hooks/curator-types.d.ts +99 -0
- package/dist/hooks/curator.d.ts +70 -0
- package/dist/index.js +950 -279
- package/dist/session/snapshot-reader.d.ts +8 -0
- package/dist/session/snapshot-writer.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ This checks that everything is wired up correctly.
|
|
|
78
78
|
|
|
79
79
|
### Configure Models (Optional)
|
|
80
80
|
|
|
81
|
-
By default, Swarm v6.14+ uses free OpenCode Zen models (no API key required). You can override any agent's model by creating `.opencode/swarm.json` in your project. See the [LLM Provider Guide](#llm-provider-guide) for all options.
|
|
81
|
+
By default, Swarm v6.14+ uses free OpenCode Zen models (no API key required). You can override any agent's model by creating `.opencode/opencode-swarm.json` in your project. See the [LLM Provider Guide](#llm-provider-guide) for all options.
|
|
82
82
|
|
|
83
83
|
```json
|
|
84
84
|
{
|
|
@@ -152,7 +152,7 @@ OpenCode Zen provides free models via the `opencode/` provider prefix. These are
|
|
|
152
152
|
}
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
-
> Save this configuration to `.opencode/swarm.json` in your project root (or `~/.config/opencode/opencode-swarm.json` for global config).
|
|
155
|
+
> Save this configuration to `.opencode/opencode-swarm.json` in your project root (or `~/.config/opencode/opencode-swarm.json` for global config).
|
|
156
156
|
|
|
157
157
|
> **Note:** The `architect` key is intentionally omitted — it inherits whatever model you have selected in the OpenCode UI for maximum reasoning quality.
|
|
158
158
|
|
|
@@ -552,7 +552,7 @@ Optional enhancement: Semgrep (if on PATH).
|
|
|
552
552
|
<details>
|
|
553
553
|
<summary><strong>Full Configuration Reference</strong></summary>
|
|
554
554
|
|
|
555
|
-
Config file location: `~/.config/opencode/opencode-swarm.json` (global) or `.opencode/swarm.json` (project). Project config merges over global.
|
|
555
|
+
Config file location: `~/.config/opencode/opencode-swarm.json` (global) or `.opencode/opencode-swarm.json` (project). Project config merges over global.
|
|
556
556
|
|
|
557
557
|
```json
|
|
558
558
|
{
|
|
@@ -1019,9 +1019,61 @@ OpenCode Swarm v6.16+ ships with language profiles for 11 languages across three
|
|
|
1019
1019
|
|
|
1020
1020
|
## Roadmap
|
|
1021
1021
|
|
|
1022
|
+
## Curator
|
|
1023
|
+
|
|
1024
|
+
The Curator is an optional background analysis system that runs after each phase. It is **disabled by default** (`curator.enabled = false`) and never blocks execution — all Curator operations are wrapped in try/catch.
|
|
1025
|
+
|
|
1026
|
+
### What the Curator Does
|
|
1027
|
+
|
|
1028
|
+
- **Init** (`phase-monitor.ts`): On the first phase, initializes a curator summary file at `.swarm/curator-summary.json`.
|
|
1029
|
+
- **Phase analysis** (`phase-complete.ts`): After each phase completes, collects phase events, checks compliance, and optionally invokes the curator explorer to summarize findings.
|
|
1030
|
+
- **Knowledge updates** (`phase-complete.ts`): Merges curator findings into the knowledge base up to the configured `max_summary_tokens` cap.
|
|
1031
|
+
- **Drift injection** (`knowledge-injector.ts`): Prepends the latest drift report summary to the architect's knowledge context at phase start, up to `drift_inject_max_chars` characters.
|
|
1032
|
+
|
|
1033
|
+
### Configuration
|
|
1034
|
+
|
|
1035
|
+
Add a `curator` block to `.opencode/opencode-swarm.json`:
|
|
1036
|
+
|
|
1037
|
+
```json
|
|
1038
|
+
{
|
|
1039
|
+
"curator": {
|
|
1040
|
+
"enabled": false,
|
|
1041
|
+
"init_enabled": true,
|
|
1042
|
+
"phase_enabled": true,
|
|
1043
|
+
"max_summary_tokens": 2000,
|
|
1044
|
+
"min_knowledge_confidence": 0.7,
|
|
1045
|
+
"compliance_report": true,
|
|
1046
|
+
"suppress_warnings": true,
|
|
1047
|
+
"drift_inject_max_chars": 500
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
| Field | Default | Description |
|
|
1053
|
+
|-------|---------|-------------|
|
|
1054
|
+
| `enabled` | `false` | Master switch. Set to `true` to activate the Curator pipeline. |
|
|
1055
|
+
| `init_enabled` | `true` | Initialize curator summary on first phase (requires `enabled: true`). |
|
|
1056
|
+
| `phase_enabled` | `true` | Run phase analysis and knowledge updates after each phase. |
|
|
1057
|
+
| `max_summary_tokens` | `2000` | Maximum token budget for curator knowledge summaries. |
|
|
1058
|
+
| `min_knowledge_confidence` | `0.7` | Minimum confidence threshold for curator knowledge entries. |
|
|
1059
|
+
| `compliance_report` | `true` | Include phase compliance check results in curator summary. |
|
|
1060
|
+
| `suppress_warnings` | `true` | Suppress non-critical curator warnings from the architect context. |
|
|
1061
|
+
| `drift_inject_max_chars` | `500` | Maximum characters of drift report text injected into each phase context. |
|
|
1062
|
+
|
|
1063
|
+
### Drift Reports
|
|
1064
|
+
|
|
1065
|
+
Drift reports are written to `.swarm/drift-report-phase-N.json` after each phase. The `knowledge-injector.ts` hook reads the latest report and prepends a summary to the architect's knowledge context for the next phase, helping the architect stay aware of plan vs. reality divergence.
|
|
1066
|
+
|
|
1067
|
+
### Issue #81 Hotfix — taskWorkflowStates Persistence
|
|
1068
|
+
|
|
1069
|
+
v6.21 includes a fix for session snapshot persistence of per-task workflow states:
|
|
1070
|
+
|
|
1071
|
+
- **`SerializedAgentSession.taskWorkflowStates`**: Task workflow states are now serialized as `Record<string, string>` in session snapshots and deserialized back to a `Map` on load. Invalid state values are filtered out and default to `idle`.
|
|
1072
|
+
- **`reconcileTaskStatesFromPlan`**: On snapshot load, task states are reconciled against the current plan — tasks marked `completed` in the plan are seeded to `tests_run` state, and `in_progress` tasks are seeded to `coder_delegated` if currently `idle`. This is best-effort and never throws.
|
|
1073
|
+
|
|
1022
1074
|
See [CHANGELOG.md](CHANGELOG.md) for shipped features.
|
|
1023
1075
|
|
|
1024
|
-
Upcoming: v6.
|
|
1076
|
+
Upcoming: v6.22 focuses on further context optimization and agent coordination improvements.
|
|
1025
1077
|
|
|
1026
1078
|
---
|
|
1027
1079
|
|
package/dist/agents/critic.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { AgentDefinition } from './architect';
|
|
2
2
|
export declare function createCriticAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
3
|
+
export declare function createCriticDriftAgent(model: string, customAppendPrompt?: string): AgentDefinition;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { AgentDefinition } from './architect';
|
|
2
2
|
export declare function createExplorerAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
3
|
+
export declare function createExplorerCuratorAgent(model: string, mode: 'CURATOR_INIT' | 'CURATOR_PHASE', customAppendPrompt?: string): AgentDefinition;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Events flow through the system without external dependencies.
|
|
6
6
|
*/
|
|
7
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';
|
|
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' | 'curator.init.completed' | 'curator.phase.completed' | 'curator.drift.completed' | 'curator.error';
|
|
9
9
|
/** Base automation event */
|
|
10
10
|
export interface AutomationEvent<T = unknown> {
|
|
11
11
|
type: AutomationEventType;
|
package/dist/cli/index.js
CHANGED
|
@@ -14382,7 +14382,7 @@ async function loadEvidence(directory, taskId) {
|
|
|
14382
14382
|
return { status: "found", bundle: validated };
|
|
14383
14383
|
} catch (error49) {
|
|
14384
14384
|
warn(`Wrapped flat retrospective failed validation for task ${sanitizedTaskId}: ${error49 instanceof Error ? error49.message : String(error49)}`);
|
|
14385
|
-
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => e.path.join(".")
|
|
14385
|
+
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [String(error49)];
|
|
14386
14386
|
return { status: "invalid_schema", errors: errors3 };
|
|
14387
14387
|
}
|
|
14388
14388
|
}
|
|
@@ -14391,7 +14391,7 @@ async function loadEvidence(directory, taskId) {
|
|
|
14391
14391
|
return { status: "found", bundle: validated };
|
|
14392
14392
|
} catch (error49) {
|
|
14393
14393
|
warn(`Evidence bundle validation failed for task ${sanitizedTaskId}: ${error49 instanceof Error ? error49.message : String(error49)}`);
|
|
14394
|
-
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => e.path.join(".")
|
|
14394
|
+
const errors3 = error49 instanceof ZodError ? error49.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [String(error49)];
|
|
14395
14395
|
return { status: "invalid_schema", errors: errors3 };
|
|
14396
14396
|
}
|
|
14397
14397
|
}
|
|
@@ -17121,6 +17121,16 @@ var KnowledgeConfigSchema = exports_external.object({
|
|
|
17121
17121
|
min_retrievals_for_utility: exports_external.number().min(1).max(100).default(3),
|
|
17122
17122
|
schema_version: exports_external.number().int().min(1).default(1)
|
|
17123
17123
|
});
|
|
17124
|
+
var CuratorConfigSchema = exports_external.object({
|
|
17125
|
+
enabled: exports_external.boolean().default(false),
|
|
17126
|
+
init_enabled: exports_external.boolean().default(true),
|
|
17127
|
+
phase_enabled: exports_external.boolean().default(true),
|
|
17128
|
+
max_summary_tokens: exports_external.number().min(500).max(8000).default(2000),
|
|
17129
|
+
min_knowledge_confidence: exports_external.number().min(0).max(1).default(0.7),
|
|
17130
|
+
compliance_report: exports_external.boolean().default(true),
|
|
17131
|
+
suppress_warnings: exports_external.boolean().default(true),
|
|
17132
|
+
drift_inject_max_chars: exports_external.number().min(100).max(2000).default(500)
|
|
17133
|
+
});
|
|
17124
17134
|
var PluginConfigSchema = exports_external.object({
|
|
17125
17135
|
agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional(),
|
|
17126
17136
|
swarms: exports_external.record(exports_external.string(), SwarmConfigSchema).optional(),
|
|
@@ -17148,6 +17158,7 @@ var PluginConfigSchema = exports_external.object({
|
|
|
17148
17158
|
checkpoint: CheckpointConfigSchema.optional(),
|
|
17149
17159
|
automation: AutomationConfigSchema.optional(),
|
|
17150
17160
|
knowledge: KnowledgeConfigSchema.optional(),
|
|
17161
|
+
curator: CuratorConfigSchema.optional(),
|
|
17151
17162
|
tool_output: exports_external.object({
|
|
17152
17163
|
truncation_enabled: exports_external.boolean().default(true),
|
|
17153
17164
|
max_lines: exports_external.number().min(10).max(500).default(150),
|
|
@@ -17371,7 +17382,7 @@ async function readKnowledge(filePath) {
|
|
|
17371
17382
|
}
|
|
17372
17383
|
async function appendKnowledge(filePath, entry) {
|
|
17373
17384
|
await mkdir(path4.dirname(filePath), { recursive: true });
|
|
17374
|
-
await appendFile(filePath, JSON.stringify(entry)
|
|
17385
|
+
await appendFile(filePath, `${JSON.stringify(entry)}
|
|
17375
17386
|
`, "utf-8");
|
|
17376
17387
|
}
|
|
17377
17388
|
async function rewriteKnowledge(filePath, entries) {
|
|
@@ -30109,7 +30120,7 @@ function sanitizeString(str, maxLength) {
|
|
|
30109
30120
|
return "";
|
|
30110
30121
|
const sanitized = String(str).replace(RTL_OVERRIDE_PATTERN, "");
|
|
30111
30122
|
if (sanitized.length > maxLength) {
|
|
30112
|
-
return sanitized.substring(0, maxLength - 3)
|
|
30123
|
+
return `${sanitized.substring(0, maxLength - 3)}...`;
|
|
30113
30124
|
}
|
|
30114
30125
|
return sanitized;
|
|
30115
30126
|
}
|
|
@@ -30280,7 +30291,7 @@ async function getHandoffData(directory) {
|
|
|
30280
30291
|
const phaseMatch = planMdContent.match(/^## Phase (\d+):?\s*(.+)?$/m);
|
|
30281
30292
|
const taskMatch = planMdContent.match(/^- \[ \] (\d+\.\d+)/g);
|
|
30282
30293
|
if (phaseMatch) {
|
|
30283
|
-
planInfo.currentPhase = sanitizeString(`Phase ${phaseMatch[1]}${phaseMatch[2] ?
|
|
30294
|
+
planInfo.currentPhase = sanitizeString(`Phase ${phaseMatch[1]}${phaseMatch[2] ? `: ${phaseMatch[2]}` : ""}`, MAX_TASK_ID_LENGTH);
|
|
30284
30295
|
}
|
|
30285
30296
|
if (taskMatch) {
|
|
30286
30297
|
const rawTasks = taskMatch.map((t) => t.replace("- [ ] ", ""));
|
|
@@ -30447,7 +30458,8 @@ function serializeAgentSession(s) {
|
|
|
30447
30458
|
lastPhaseCompletePhase: s.lastPhaseCompletePhase ?? 0,
|
|
30448
30459
|
phaseAgentsDispatched,
|
|
30449
30460
|
qaSkipCount: s.qaSkipCount ?? 0,
|
|
30450
|
-
qaSkipTaskIds: s.qaSkipTaskIds ?? []
|
|
30461
|
+
qaSkipTaskIds: s.qaSkipTaskIds ?? [],
|
|
30462
|
+
taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map)
|
|
30451
30463
|
};
|
|
30452
30464
|
}
|
|
30453
30465
|
async function writeSnapshot(directory, state) {
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -399,6 +399,17 @@ export declare const KnowledgeConfigSchema: z.ZodObject<{
|
|
|
399
399
|
schema_version: z.ZodDefault<z.ZodNumber>;
|
|
400
400
|
}, z.core.$strip>;
|
|
401
401
|
export type KnowledgeConfig = z.infer<typeof KnowledgeConfigSchema>;
|
|
402
|
+
export declare const CuratorConfigSchema: z.ZodObject<{
|
|
403
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
404
|
+
init_enabled: z.ZodDefault<z.ZodBoolean>;
|
|
405
|
+
phase_enabled: z.ZodDefault<z.ZodBoolean>;
|
|
406
|
+
max_summary_tokens: z.ZodDefault<z.ZodNumber>;
|
|
407
|
+
min_knowledge_confidence: z.ZodDefault<z.ZodNumber>;
|
|
408
|
+
compliance_report: z.ZodDefault<z.ZodBoolean>;
|
|
409
|
+
suppress_warnings: z.ZodDefault<z.ZodBoolean>;
|
|
410
|
+
drift_inject_max_chars: z.ZodDefault<z.ZodNumber>;
|
|
411
|
+
}, z.core.$strip>;
|
|
412
|
+
export type CuratorConfig = z.infer<typeof CuratorConfigSchema>;
|
|
402
413
|
export declare const PluginConfigSchema: z.ZodObject<{
|
|
403
414
|
agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
404
415
|
model: z.ZodOptional<z.ZodString>;
|
|
@@ -643,6 +654,16 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
643
654
|
min_retrievals_for_utility: z.ZodDefault<z.ZodNumber>;
|
|
644
655
|
schema_version: z.ZodDefault<z.ZodNumber>;
|
|
645
656
|
}, z.core.$strip>>;
|
|
657
|
+
curator: z.ZodOptional<z.ZodObject<{
|
|
658
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
659
|
+
init_enabled: z.ZodDefault<z.ZodBoolean>;
|
|
660
|
+
phase_enabled: z.ZodDefault<z.ZodBoolean>;
|
|
661
|
+
max_summary_tokens: z.ZodDefault<z.ZodNumber>;
|
|
662
|
+
min_knowledge_confidence: z.ZodDefault<z.ZodNumber>;
|
|
663
|
+
compliance_report: z.ZodDefault<z.ZodBoolean>;
|
|
664
|
+
suppress_warnings: z.ZodDefault<z.ZodBoolean>;
|
|
665
|
+
drift_inject_max_chars: z.ZodDefault<z.ZodNumber>;
|
|
666
|
+
}, z.core.$strip>>;
|
|
646
667
|
tool_output: z.ZodOptional<z.ZodObject<{
|
|
647
668
|
truncation_enabled: z.ZodDefault<z.ZodBoolean>;
|
|
648
669
|
max_lines: z.ZodDefault<z.ZodNumber>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CriticDriftResult, CuratorConfig, CuratorPhaseResult, DriftReport } from './curator-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read all prior drift reports from .swarm/drift-report-phase-*.json files.
|
|
4
|
+
* Returns reports sorted ascending by phase number.
|
|
5
|
+
* Skips corrupt/unreadable files with a console.warn.
|
|
6
|
+
*/
|
|
7
|
+
export declare function readPriorDriftReports(directory: string): Promise<DriftReport[]>;
|
|
8
|
+
/**
|
|
9
|
+
* Write a drift report to .swarm/drift-report-phase-{N}.json.
|
|
10
|
+
* Creates .swarm/ if it doesn't exist.
|
|
11
|
+
* Returns the absolute path of the written file.
|
|
12
|
+
*/
|
|
13
|
+
export declare function writeDriftReport(directory: string, report: DriftReport): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Run the critic drift check for the given phase.
|
|
16
|
+
* Builds a structured DriftReport from curator data, plan, spec, and prior reports.
|
|
17
|
+
* Writes the report to .swarm/drift-report-phase-N.json.
|
|
18
|
+
* Emits 'curator.drift.completed' event on success.
|
|
19
|
+
* On any error: emits 'curator.error' event and returns a safe default result.
|
|
20
|
+
* NEVER throws — drift failures must not block phase_complete.
|
|
21
|
+
*/
|
|
22
|
+
export declare function runCriticDriftCheck(directory: string, phase: number, curatorResult: CuratorPhaseResult, config: CuratorConfig): Promise<CriticDriftResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Build a truncated summary suitable for architect context injection.
|
|
25
|
+
* Format: "<drift_report>Phase N: {alignment} ({drift_score}) — {key finding}. {correction if any}.</drift_report>"
|
|
26
|
+
* Truncate to maxChars (simple slice). Tags may be broken when truncation occurs mid-tag.
|
|
27
|
+
* If ALIGNED with drift_score < 0.1: minimal output "Phase N: ALIGNED, all requirements on track."
|
|
28
|
+
* If MINOR_DRIFT or worse: include first_deviation and top correction.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildDriftInjectionText(report: DriftReport, maxChars: number): string;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Curator types — phase context consolidation and drift detection.
|
|
3
|
+
* No runtime logic. Types only.
|
|
4
|
+
*/
|
|
5
|
+
/** Curator summary — anchored iterative format. Persisted to .swarm/curator-summary.json */
|
|
6
|
+
export interface CuratorSummary {
|
|
7
|
+
schema_version: 1;
|
|
8
|
+
session_id: string;
|
|
9
|
+
last_updated: string;
|
|
10
|
+
last_phase_covered: number;
|
|
11
|
+
/** Running digest — extended each phase, never regenerated */
|
|
12
|
+
digest: string;
|
|
13
|
+
/** Phase-level digests for lookup */
|
|
14
|
+
phase_digests: PhaseDigestEntry[];
|
|
15
|
+
/** Accumulated compliance observations */
|
|
16
|
+
compliance_observations: ComplianceObservation[];
|
|
17
|
+
/** Knowledge update recommendations from the last curator run */
|
|
18
|
+
knowledge_recommendations: KnowledgeRecommendation[];
|
|
19
|
+
}
|
|
20
|
+
export interface PhaseDigestEntry {
|
|
21
|
+
phase: number;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
summary: string;
|
|
24
|
+
agents_used: string[];
|
|
25
|
+
tasks_completed: number;
|
|
26
|
+
tasks_total: number;
|
|
27
|
+
key_decisions: string[];
|
|
28
|
+
blockers_resolved: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface ComplianceObservation {
|
|
31
|
+
phase: number;
|
|
32
|
+
timestamp: string;
|
|
33
|
+
type: 'missing_reviewer' | 'missing_retro' | 'missing_sme' | 'skipped_test' | 'workflow_deviation';
|
|
34
|
+
description: string;
|
|
35
|
+
severity: 'info' | 'warning';
|
|
36
|
+
}
|
|
37
|
+
export interface KnowledgeRecommendation {
|
|
38
|
+
action: 'promote' | 'archive' | 'flag_contradiction';
|
|
39
|
+
entry_id?: string;
|
|
40
|
+
lesson: string;
|
|
41
|
+
reason: string;
|
|
42
|
+
}
|
|
43
|
+
/** Drift report — produced by critic after curator phase run */
|
|
44
|
+
export interface DriftReport {
|
|
45
|
+
schema_version: 1;
|
|
46
|
+
phase: number;
|
|
47
|
+
timestamp: string;
|
|
48
|
+
/** Overall alignment verdict */
|
|
49
|
+
alignment: 'ALIGNED' | 'MINOR_DRIFT' | 'MAJOR_DRIFT' | 'OFF_SPEC';
|
|
50
|
+
/** Severity score 0.0-1.0 (0 = perfectly aligned, 1 = completely off-spec) */
|
|
51
|
+
drift_score: number;
|
|
52
|
+
/** First deviation point if drift detected */
|
|
53
|
+
first_deviation: {
|
|
54
|
+
phase: number;
|
|
55
|
+
task: string;
|
|
56
|
+
description: string;
|
|
57
|
+
} | null;
|
|
58
|
+
/** Compounding effects across phases */
|
|
59
|
+
compounding_effects: string[];
|
|
60
|
+
/** Recommended course corrections */
|
|
61
|
+
corrections: string[];
|
|
62
|
+
/** Spec requirements checked */
|
|
63
|
+
requirements_checked: number;
|
|
64
|
+
/** Spec requirements satisfied */
|
|
65
|
+
requirements_satisfied: number;
|
|
66
|
+
/** Scope additions not in original plan */
|
|
67
|
+
scope_additions: string[];
|
|
68
|
+
/** Truncated summary for architect context injection */
|
|
69
|
+
injection_summary: string;
|
|
70
|
+
}
|
|
71
|
+
export interface CuratorConfig {
|
|
72
|
+
enabled: boolean;
|
|
73
|
+
init_enabled: boolean;
|
|
74
|
+
phase_enabled: boolean;
|
|
75
|
+
max_summary_tokens: number;
|
|
76
|
+
min_knowledge_confidence: number;
|
|
77
|
+
compliance_report: boolean;
|
|
78
|
+
suppress_warnings: boolean;
|
|
79
|
+
drift_inject_max_chars: number;
|
|
80
|
+
}
|
|
81
|
+
export interface CuratorInitResult {
|
|
82
|
+
briefing: string;
|
|
83
|
+
contradictions: string[];
|
|
84
|
+
knowledge_entries_reviewed: number;
|
|
85
|
+
prior_phases_covered: number;
|
|
86
|
+
}
|
|
87
|
+
export interface CuratorPhaseResult {
|
|
88
|
+
phase: number;
|
|
89
|
+
digest: PhaseDigestEntry;
|
|
90
|
+
compliance: ComplianceObservation[];
|
|
91
|
+
knowledge_recommendations: KnowledgeRecommendation[];
|
|
92
|
+
summary_updated: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface CriticDriftResult {
|
|
95
|
+
phase: number;
|
|
96
|
+
report: DriftReport;
|
|
97
|
+
report_path: string;
|
|
98
|
+
injection_text: string;
|
|
99
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Curator core — file I/O for curator summary persistence.
|
|
3
|
+
* Extended incrementally: filterPhaseEvents, checkPhaseCompliance,
|
|
4
|
+
* runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates added in subsequent tasks.
|
|
5
|
+
*/
|
|
6
|
+
import type { ComplianceObservation, CuratorConfig, CuratorInitResult, CuratorPhaseResult, CuratorSummary, KnowledgeRecommendation } from './curator-types.js';
|
|
7
|
+
import type { KnowledgeConfig } from './knowledge-types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Read curator summary from .swarm/curator-summary.json
|
|
10
|
+
* @param directory - The workspace directory
|
|
11
|
+
* @returns CuratorSummary if valid, null if missing or invalid
|
|
12
|
+
*/
|
|
13
|
+
export declare function readCuratorSummary(directory: string): Promise<CuratorSummary | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Write curator summary to .swarm/curator-summary.json
|
|
16
|
+
* @param directory - The workspace directory
|
|
17
|
+
* @param summary - The curator summary to write
|
|
18
|
+
*/
|
|
19
|
+
export declare function writeCuratorSummary(directory: string, summary: CuratorSummary): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Filter events from JSONL by phase or timestamp.
|
|
22
|
+
* @param eventsJsonl - Raw JSONL string of events
|
|
23
|
+
* @param phase - Phase number to filter by
|
|
24
|
+
* @param sinceTimestamp - Optional ISO 8601 timestamp to filter events after
|
|
25
|
+
* @returns Array of parsed event objects
|
|
26
|
+
*/
|
|
27
|
+
export declare function filterPhaseEvents(eventsJsonl: string, phase: number, sinceTimestamp?: string): object[];
|
|
28
|
+
/**
|
|
29
|
+
* Check compliance for a phase based on events and dispatched agents.
|
|
30
|
+
* @param phaseEvents - Array of events for the phase
|
|
31
|
+
* @param agentsDispatched - List of agent names that were dispatched
|
|
32
|
+
* @param requiredAgents - List of required agent names for this phase
|
|
33
|
+
* @param phase - Phase number
|
|
34
|
+
* @returns Array of compliance observations
|
|
35
|
+
*/
|
|
36
|
+
export declare function checkPhaseCompliance(phaseEvents: object[], agentsDispatched: string[], requiredAgents: string[], phase: number): ComplianceObservation[];
|
|
37
|
+
/**
|
|
38
|
+
* Prepare curator init data: reads prior summary, knowledge entries, and context.md.
|
|
39
|
+
* Returns a structured briefing result. Does NOT make LLM calls.
|
|
40
|
+
* The caller (phase-monitor integration) is responsible for the actual agent delegation.
|
|
41
|
+
* @param directory - The workspace directory
|
|
42
|
+
* @param config - Curator configuration
|
|
43
|
+
* @returns CuratorInitResult with briefing text, contradictions, and stats
|
|
44
|
+
*/
|
|
45
|
+
export declare function runCuratorInit(directory: string, config: CuratorConfig): Promise<CuratorInitResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Run curator phase analysis: reads events, runs compliance, updates and writes summary.
|
|
48
|
+
* Does NOT make LLM calls. The caller is responsible for agent delegation.
|
|
49
|
+
* @param directory - The workspace directory
|
|
50
|
+
* @param phase - The phase number that just completed
|
|
51
|
+
* @param agentsDispatched - List of agent names dispatched in this phase
|
|
52
|
+
* @param config - Curator configuration
|
|
53
|
+
* @param knowledgeConfig - Knowledge configuration (used for knowledge path resolution)
|
|
54
|
+
* @returns CuratorPhaseResult with digest, compliance, and recommendations
|
|
55
|
+
*/
|
|
56
|
+
export declare function runCuratorPhase(directory: string, phase: number, agentsDispatched: string[], _config: CuratorConfig, _knowledgeConfig: {
|
|
57
|
+
directory?: string;
|
|
58
|
+
}): Promise<CuratorPhaseResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Apply curator knowledge recommendations: promote, archive, or flag contradictions.
|
|
61
|
+
* Uses readKnowledge + rewriteKnowledge pattern for atomic updates.
|
|
62
|
+
* @param directory - The workspace directory
|
|
63
|
+
* @param recommendations - Array of knowledge recommendations to apply
|
|
64
|
+
* @param knowledgeConfig - Knowledge configuration (for path resolution)
|
|
65
|
+
* @returns Counts of applied and skipped recommendations
|
|
66
|
+
*/
|
|
67
|
+
export declare function applyCuratorKnowledgeUpdates(directory: string, recommendations: KnowledgeRecommendation[], _knowledgeConfig: KnowledgeConfig): Promise<{
|
|
68
|
+
applied: number;
|
|
69
|
+
skipped: number;
|
|
70
|
+
}>;
|