opencode-swarm 6.57.0 → 6.59.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/dist/__tests__/acknowledge-spec-drift.test.d.ts +1 -0
- package/dist/__tests__/critic_drift_verifier-whitelist.test.d.ts +1 -0
- package/dist/__tests__/lint-spec.test.d.ts +1 -0
- package/dist/__tests__/preflight-phase.test.d.ts +1 -0
- package/dist/__tests__/req-coverage.test.d.ts +1 -0
- package/dist/__tests__/spec-hash.test.d.ts +1 -0
- package/dist/__tests__/spec-schema.test.d.ts +1 -0
- package/dist/__tests__/write-drift-evidence-requirement-coverage.test.d.ts +4 -0
- package/dist/agents/critic.d.ts +4 -4
- package/dist/agents/explorer-consumer-contract.test.d.ts +1 -0
- package/dist/agents/explorer-role-boundary.test.d.ts +1 -0
- package/dist/agents/explorer.d.ts +3 -3
- package/dist/cli/index.js +3627 -3183
- package/dist/commands/acknowledge-spec-drift.d.ts +5 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/registry.d.ts +4 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/plan-schema.d.ts +10 -0
- package/dist/config/spec-schema.d.ts +113 -0
- package/dist/evidence/manager.d.ts +8 -0
- package/dist/hooks/curator.d.ts +21 -2
- package/dist/index.js +12674 -11481
- package/dist/plan/ledger.d.ts +91 -1
- package/dist/plan/manager.d.ts +2 -2
- package/dist/services/preflight-service.d.ts +1 -1
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/lint-spec.d.ts +2 -0
- package/dist/tools/req-coverage.d.ts +47 -0
- package/dist/tools/tool-names.d.ts +1 -1
- package/dist/tools/write-drift-evidence.d.ts +2 -0
- package/dist/types/events.d.ts +19 -1
- package/dist/utils/spec-hash.d.ts +15 -0
- package/package.json +1 -1
package/dist/plan/ledger.d.ts
CHANGED
|
@@ -123,17 +123,67 @@ export declare function appendLedgerEvent(directory: string, eventInput: LedgerE
|
|
|
123
123
|
expectedHash?: string;
|
|
124
124
|
planHashAfter?: string;
|
|
125
125
|
}): Promise<LedgerEvent>;
|
|
126
|
+
/**
|
|
127
|
+
* Append a ledger event with optimistic retry on stale-writer conflicts.
|
|
128
|
+
*
|
|
129
|
+
* When another writer advances the ledger between the caller's read and
|
|
130
|
+
* their append, `appendLedgerEvent` throws `LedgerStaleWriterError`. This
|
|
131
|
+
* helper wraps that call in a bounded retry loop, refreshing the
|
|
132
|
+
* `expectedHash` concurrency token against the current plan.json before
|
|
133
|
+
* each retry.
|
|
134
|
+
*
|
|
135
|
+
* IMPORTANT: refreshing the hash is only safe when the event input is
|
|
136
|
+
* *still semantically valid* after the intervening write. For audit
|
|
137
|
+
* events computed from an in-memory plan the caller is about to persist,
|
|
138
|
+
* it is always valid. For `task_status_changed` events, pass a
|
|
139
|
+
* `verifyValid` callback that returns false when the transition no
|
|
140
|
+
* longer applies (e.g. the task's on-disk status already matches the
|
|
141
|
+
* `to_status`, or has moved past it). When `verifyValid` returns false,
|
|
142
|
+
* the retry loop exits and the helper returns `null` to signal that the
|
|
143
|
+
* event was skipped — it is not an error.
|
|
144
|
+
*
|
|
145
|
+
* @param directory - Working directory containing `.swarm/plan-ledger.jsonl`
|
|
146
|
+
* @param eventInput - Event to append (required fields minus auto-generated)
|
|
147
|
+
* @param options - Concurrency and retry configuration:
|
|
148
|
+
* - expectedHash: the hash of plan.json the caller observed (REQUIRED)
|
|
149
|
+
* - planHashAfter: precomputed hash of the mutated plan
|
|
150
|
+
* - maxRetries: max stale-writer retries (default: 3)
|
|
151
|
+
* - backoffMs: base delay in milliseconds (default: 10; exponential)
|
|
152
|
+
* - verifyValid: callback invoked before each retry to confirm the
|
|
153
|
+
* event input is still meaningful. Returning false aborts and
|
|
154
|
+
* resolves the helper to `null`.
|
|
155
|
+
* @returns The written LedgerEvent, or `null` if verifyValid aborted.
|
|
156
|
+
* @throws LedgerStaleWriterError if retries are exhausted.
|
|
157
|
+
*/
|
|
158
|
+
export declare function appendLedgerEventWithRetry(directory: string, eventInput: LedgerEventInput, options: {
|
|
159
|
+
expectedHash: string;
|
|
160
|
+
planHashAfter?: string;
|
|
161
|
+
maxRetries?: number;
|
|
162
|
+
backoffMs?: number;
|
|
163
|
+
verifyValid?: () => Promise<boolean> | boolean;
|
|
164
|
+
}): Promise<LedgerEvent | null>;
|
|
126
165
|
/**
|
|
127
166
|
* Take a snapshot event and append it to the ledger.
|
|
128
167
|
* The snapshot embeds the full Plan payload for ledger-only rebuild.
|
|
129
168
|
*
|
|
130
169
|
* @param directory - The working directory
|
|
131
170
|
* @param plan - The current plan state to snapshot
|
|
132
|
-
* @param options - Optional configuration
|
|
171
|
+
* @param options - Optional configuration:
|
|
172
|
+
* - planHashAfter: precomputed hash of the mutated plan (bypasses the
|
|
173
|
+
* on-disk plan.json read when available)
|
|
174
|
+
* - source: attribution string stored on the ledger event. Defaults to
|
|
175
|
+
* `'takeSnapshotEvent'`. Use `'critic_approved'` to mark a snapshot as
|
|
176
|
+
* the immutable phase-approved checkpoint readable by
|
|
177
|
+
* `loadLastApprovedPlan`.
|
|
178
|
+
* - approvalMetadata: optional free-form metadata embedded into the
|
|
179
|
+
* snapshot payload (e.g. phase number, verdict, summary) so that
|
|
180
|
+
* downstream readers can filter without decoding prompts.
|
|
133
181
|
* @returns The LedgerEvent that was written
|
|
134
182
|
*/
|
|
135
183
|
export declare function takeSnapshotEvent(directory: string, plan: Plan, options?: {
|
|
136
184
|
planHashAfter?: string;
|
|
185
|
+
source?: string;
|
|
186
|
+
approvalMetadata?: Record<string, unknown>;
|
|
137
187
|
}): Promise<LedgerEvent>;
|
|
138
188
|
/**
|
|
139
189
|
* Options for replayFromLedger
|
|
@@ -193,4 +243,44 @@ export declare function quarantineLedgerSuffix(directory: string, badSuffix: str
|
|
|
193
243
|
* @returns Reconstructed Plan from ledger events, or null if replay fails
|
|
194
244
|
*/
|
|
195
245
|
export declare function replayWithIntegrity(directory: string): Promise<Plan | null>;
|
|
246
|
+
/**
|
|
247
|
+
* Metadata describing an approved snapshot recovered from the ledger.
|
|
248
|
+
*/
|
|
249
|
+
export interface ApprovedSnapshotInfo {
|
|
250
|
+
/** The immutable plan payload captured at critic approval time */
|
|
251
|
+
plan: Plan;
|
|
252
|
+
/** The ledger sequence number of the snapshot event */
|
|
253
|
+
seq: number;
|
|
254
|
+
/** ISO 8601 timestamp of the snapshot event */
|
|
255
|
+
timestamp: string;
|
|
256
|
+
/** Arbitrary metadata the caller attached (phase, verdict, summary, ...) */
|
|
257
|
+
approval?: Record<string, unknown>;
|
|
258
|
+
/** Hash of the plan payload at snapshot time */
|
|
259
|
+
payloadHash: string;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Find the most recent critic-approved immutable plan snapshot in the ledger.
|
|
263
|
+
*
|
|
264
|
+
* Snapshots are tagged at write time with a distinguishing `source` string
|
|
265
|
+
* (see `takeSnapshotEvent`). The `critic_approved` marker identifies snapshots
|
|
266
|
+
* persisted by the orchestrator after a phase Critic returns APPROVED. This
|
|
267
|
+
* function scans the ledger in reverse order and returns the first matching
|
|
268
|
+
* snapshot, including its embedded plan payload and approval metadata.
|
|
269
|
+
*
|
|
270
|
+
* Intended for use as a fallback when plan.json is lost, overwritten, or
|
|
271
|
+
* suspected of drift: the Architect can fall back to the last approved plan
|
|
272
|
+
* and the Critic can drift-check against it.
|
|
273
|
+
*
|
|
274
|
+
* SAFETY: when `expectedPlanId` is supplied, only snapshots whose event
|
|
275
|
+
* `plan_id` matches are considered. Callers MUST pass an expected identity
|
|
276
|
+
* whenever they have one (e.g. from the ledger's first `plan_created` anchor)
|
|
277
|
+
* to prevent cross-identity contamination: a stale `critic_approved` snapshot
|
|
278
|
+
* left in a reused directory could otherwise be resurrected as the active plan.
|
|
279
|
+
*
|
|
280
|
+
* @param directory - Working directory containing `.swarm/plan-ledger.jsonl`
|
|
281
|
+
* @param expectedPlanId - Optional plan identity filter. When provided, only
|
|
282
|
+
* snapshots whose ledger event `plan_id` matches are considered.
|
|
283
|
+
* @returns The most recent approved snapshot info, or null if none exists
|
|
284
|
+
*/
|
|
285
|
+
export declare function loadLastApprovedPlan(directory: string, expectedPlanId?: string): Promise<ApprovedSnapshotInfo | null>;
|
|
196
286
|
export {};
|
package/dist/plan/manager.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Plan, type TaskStatus } from '../config/plan-schema';
|
|
1
|
+
import { type Plan, type RuntimePlan, type TaskStatus } from '../config/plan-schema';
|
|
2
2
|
/** Reset the startup ledger check flag. For testing only. */
|
|
3
3
|
export declare function resetStartupLedgerCheck(): void;
|
|
4
4
|
/**
|
|
@@ -24,7 +24,7 @@ export declare function regeneratePlanMarkdown(directory: string, plan: Plan): P
|
|
|
24
24
|
* 3. .swarm/plan.md exists only -> migrate from plan.md, save both files, return Plan
|
|
25
25
|
* 4. Neither exists -> return null
|
|
26
26
|
*/
|
|
27
|
-
export declare function loadPlan(directory: string): Promise<
|
|
27
|
+
export declare function loadPlan(directory: string): Promise<RuntimePlan | null>;
|
|
28
28
|
/**
|
|
29
29
|
* Validate against PlanSchema (throw on invalid), write to .swarm/plan.json via atomic temp+rename pattern,
|
|
30
30
|
* then derive and write .swarm/plan.md
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Callable by background flow (from preflight.requested events).
|
|
13
13
|
*/
|
|
14
14
|
/** Preflight check types */
|
|
15
|
-
export type PreflightCheckType = 'lint' | 'tests' | 'secrets' | 'evidence' | 'version';
|
|
15
|
+
export type PreflightCheckType = 'lint' | 'tests' | 'secrets' | 'evidence' | 'version' | 'req_coverage';
|
|
16
16
|
/** Individual check status */
|
|
17
17
|
export interface PreflightCheckResult {
|
|
18
18
|
type: PreflightCheckType;
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export { pkg_audit } from './pkg-audit';
|
|
|
24
24
|
export { type PlaceholderFinding, type PlaceholderScanInput, type PlaceholderScanResult, placeholder_scan, placeholderScan, } from './placeholder-scan';
|
|
25
25
|
export { type PreCheckBatchInput, type PreCheckBatchResult, pre_check_batch, runPreCheckBatch, type ToolResult, } from './pre-check-batch';
|
|
26
26
|
export { type QualityBudgetInput, type QualityBudgetResult, quality_budget, qualityBudget, } from './quality-budget';
|
|
27
|
+
export { req_coverage } from './req-coverage';
|
|
27
28
|
export { retrieve_summary } from './retrieve-summary';
|
|
28
29
|
export { type SastScanFinding, type SastScanInput, type SastScanResult, sast_scan, sastScan, } from './sast-scan';
|
|
29
30
|
export type { SavePlanArgs, SavePlanResult } from './save-plan';
|
|
@@ -36,6 +37,7 @@ import { suggestPatch } from './suggest-patch';
|
|
|
36
37
|
export { suggestPatch };
|
|
37
38
|
export type { SuggestPatchArgs } from './suggest-patch';
|
|
38
39
|
export declare const suggest_patch: typeof suggestPatch;
|
|
40
|
+
export { lint_spec } from './lint-spec';
|
|
39
41
|
export { symbols } from './symbols';
|
|
40
42
|
export { type SyntaxCheckFileResult, type SyntaxCheckInput, type SyntaxCheckResult, syntax_check, syntaxCheck, } from './syntax-check';
|
|
41
43
|
export { test_runner } from './test-runner';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Requirement coverage tool for analyzing FR requirements against touched files.
|
|
3
|
+
* Reads .swarm/spec.md for FR-### requirements and checks coverage against
|
|
4
|
+
* files touched during a phase via evidence files.
|
|
5
|
+
*/
|
|
6
|
+
import { tool } from '@opencode-ai/plugin';
|
|
7
|
+
declare const OBLIGATION_KEYWORDS: readonly ["MUST", "SHOULD", "SHALL"];
|
|
8
|
+
type ObligationLevel = (typeof OBLIGATION_KEYWORDS)[number];
|
|
9
|
+
interface Requirement {
|
|
10
|
+
id: string;
|
|
11
|
+
obligation: ObligationLevel | null;
|
|
12
|
+
text: string;
|
|
13
|
+
status: 'covered' | 'missing';
|
|
14
|
+
filesSearched: string[];
|
|
15
|
+
}
|
|
16
|
+
interface RequirementMatch {
|
|
17
|
+
id: string;
|
|
18
|
+
obligation: ObligationLevel | null;
|
|
19
|
+
text: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Extract all FR-### requirements from spec content.
|
|
23
|
+
* For each requirement, identifies obligation level (MUST/SHOULD/SHALL) and text.
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractRequirements(specContent: string): RequirementMatch[];
|
|
26
|
+
/**
|
|
27
|
+
* Extract obligation level (MUST/SHOULD/SHALL) and requirement text from a line.
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractObligationAndText(id: string, lineText: string): RequirementMatch | null;
|
|
30
|
+
/**
|
|
31
|
+
* Read evidence files from .swarm/evidence/{taskId}/ directory structure.
|
|
32
|
+
* Returns list of source files that were touched during the specified phase.
|
|
33
|
+
* Evidence is stored at .swarm/evidence/<taskId>/evidence.json (e.g., 1.1, 2.3.1).
|
|
34
|
+
* Only directories with numeric task IDs matching the phase prefix are processed.
|
|
35
|
+
*/
|
|
36
|
+
export declare function readTouchedFiles(evidenceDir: string, phase: number, cwd: string): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Search a file for keywords from a requirement.
|
|
39
|
+
* Returns true if any keyword is found.
|
|
40
|
+
*/
|
|
41
|
+
export declare function searchFileForKeywords(filePath: string, keywords: string[], cwd: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Analyze coverage for a requirement against touched files.
|
|
44
|
+
*/
|
|
45
|
+
export declare function analyzeRequirementCoverage(requirement: RequirementMatch, touchedFiles: string[], cwd: string): Requirement;
|
|
46
|
+
export declare const req_coverage: ReturnType<typeof tool>;
|
|
47
|
+
export {};
|
|
@@ -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' | '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' | 'sbom_generate' | 'checkpoint' | 'pkg_audit' | 'test_runner' | 'detect_domains' | 'gitingest' | 'retrieve_summary' | 'extract_code_blocks' | 'phase_complete' | 'save_plan' | 'update_task_status' | 'write_retro' | 'write_drift_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';
|
|
6
|
+
export type ToolName = 'diff' | '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' | 'sbom_generate' | 'checkpoint' | 'pkg_audit' | 'test_runner' | 'detect_domains' | 'gitingest' | 'retrieve_summary' | 'extract_code_blocks' | 'phase_complete' | 'save_plan' | 'update_task_status' | 'lint_spec' | 'write_retro' | 'write_drift_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';
|
|
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 */
|
|
@@ -14,6 +14,8 @@ export interface WriteDriftEvidenceArgs {
|
|
|
14
14
|
verdict: 'APPROVED' | 'NEEDS_REVISION';
|
|
15
15
|
/** Human-readable summary of the drift verification */
|
|
16
16
|
summary: string;
|
|
17
|
+
/** Requirement coverage report from req_coverage tool */
|
|
18
|
+
requirementCoverage?: string;
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
19
21
|
* Execute the write_drift_evidence tool.
|
package/dist/types/events.d.ts
CHANGED
|
@@ -72,4 +72,22 @@ export interface AuthorityHandoffResolvedEvent {
|
|
|
72
72
|
newAgent: string;
|
|
73
73
|
reason: 'task_complete' | 'stale_delegation' | 'conflict_escalation' | 'manual_reset';
|
|
74
74
|
}
|
|
75
|
-
export
|
|
75
|
+
export interface SpecStaleDetectedEvent {
|
|
76
|
+
type: 'spec_stale_detected';
|
|
77
|
+
timestamp: string;
|
|
78
|
+
phase: number;
|
|
79
|
+
specHash_plan: string;
|
|
80
|
+
specHash_current: string | null;
|
|
81
|
+
reason: string;
|
|
82
|
+
planTitle: string;
|
|
83
|
+
}
|
|
84
|
+
export interface SpecDriftAcknowledgedEvent {
|
|
85
|
+
type: 'spec_drift_acknowledged';
|
|
86
|
+
timestamp: string;
|
|
87
|
+
phase: number;
|
|
88
|
+
planTitle: string;
|
|
89
|
+
acknowledgedBy: string;
|
|
90
|
+
previousHash: string;
|
|
91
|
+
newHash: string | null;
|
|
92
|
+
}
|
|
93
|
+
export type V619Event = SoundingBoardConsultedEvent | ArchitectLoopDetectedEvent | PrecedentManipulationDetectedEvent | CoderSelfAuditEvent | CoderRetryCircuitBreakerEvent | AgentConflictDetectedEvent | AuthorityHandoffResolvedEvent | SpecStaleDetectedEvent | SpecDriftAcknowledgedEvent;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Plan } from '../config/plan-schema';
|
|
2
|
+
/**
|
|
3
|
+
* Computes SHA-256 hex hash of `.swarm/spec.md` content in the given directory.
|
|
4
|
+
* Returns null if the file does not exist (does NOT throw).
|
|
5
|
+
*/
|
|
6
|
+
export declare function computeSpecHash(directory: string): Promise<string | null>;
|
|
7
|
+
/**
|
|
8
|
+
* Determines if the spec file has changed since the plan was saved.
|
|
9
|
+
* Plans created before this feature (no specHash) are exempt from staleness checks.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isSpecStale(directory: string, plan: Plan): Promise<{
|
|
12
|
+
stale: boolean;
|
|
13
|
+
reason?: string;
|
|
14
|
+
currentHash?: string | null;
|
|
15
|
+
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.59.0",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|