opencode-swarm 7.19.0 → 7.19.2

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.
@@ -6,13 +6,18 @@
6
6
  */
7
7
  import { type Plan } from '../config/plan-schema';
8
8
  /**
9
- * Ledger schema version
9
+ * Ledger schema version.
10
+ *
11
+ * v7.19.0: bumped from 1.0.0 → 1.1.0 with the addition of `task_removed`.
12
+ * Older plugin readers throw on unknown event types (applyEventToPlan default
13
+ * branch); restart any running OpenCode session after upgrade so the new
14
+ * reader is loaded in-process.
10
15
  */
11
- export declare const LEDGER_SCHEMA_VERSION = "1.0.0";
16
+ export declare const LEDGER_SCHEMA_VERSION = "1.1.0";
12
17
  /**
13
18
  * Valid ledger event types
14
19
  */
15
- export declare const LEDGER_EVENT_TYPES: readonly ["plan_created", "task_added", "task_updated", "task_status_changed", "task_reordered", "phase_completed", "plan_rebuilt", "plan_exported", "plan_reset", "snapshot", "execution_profile_set", "execution_profile_locked"];
20
+ export declare const LEDGER_EVENT_TYPES: readonly ["plan_created", "task_added", "task_removed", "task_updated", "task_status_changed", "task_reordered", "phase_completed", "plan_rebuilt", "plan_exported", "plan_reset", "snapshot", "execution_profile_set", "execution_profile_locked"];
16
21
  export type LedgerEventType = (typeof LEDGER_EVENT_TYPES)[number];
17
22
  /**
18
23
  * A ledger event representing a plan mutation.
@@ -6,6 +6,38 @@
6
6
  export declare class PlanConcurrentModificationError extends Error {
7
7
  constructor(message: string);
8
8
  }
9
+ /**
10
+ * Thrown when savePlan detects that the incoming plan would silently drop one
11
+ * or more tasks from the prior plan without the caller acknowledging the
12
+ * removal (issue #853).
13
+ *
14
+ * Callers must pass `options.acknowledged_removals.ids` covering every missing
15
+ * task id together with a non-empty reason to proceed.
16
+ */
17
+ export declare class PlanTaskRemovalNotAcknowledgedError extends Error {
18
+ readonly missingTasks: Array<{
19
+ id: string;
20
+ phase: number;
21
+ status: TaskStatus;
22
+ }>;
23
+ constructor(missingTasks: Array<{
24
+ id: string;
25
+ phase: number;
26
+ status: TaskStatus;
27
+ }>);
28
+ }
29
+ /**
30
+ * Caller-supplied acknowledgement that a save_plan operation is intentionally
31
+ * removing tasks from the prior plan (issue #853). Passed to savePlan via the
32
+ * `acknowledged_removals` option; `ids` must list every task id missing from
33
+ * the incoming plan; `reason` must be non-empty; `source` identifies the
34
+ * caller (e.g. 'save_plan_tool', 'phase_complete_rebuild_from_ledger').
35
+ */
36
+ export interface AcknowledgedRemovals {
37
+ ids: string[];
38
+ reason: string;
39
+ source: string;
40
+ }
9
41
  import { type Plan, type RuntimePlan, type TaskStatus } from '../config/plan-schema';
10
42
  import { type LedgerEvent, type LedgerEventInput } from './ledger';
11
43
  /** Reset the startup ledger check flag. For testing only. */
@@ -63,12 +95,32 @@ export declare function regeneratePlanMarkdown(directory: string, plan: Plan): P
63
95
  * 4. Neither exists -> return null
64
96
  */
65
97
  export declare function loadPlan(directory: string): Promise<RuntimePlan | null>;
98
+ /**
99
+ * Recovery-path helper for callers that legitimately need to replace the
100
+ * plan task set without explicit per-id acknowledgement (e.g. rebuilding
101
+ * from the ledger after replay, importing an external checkpoint, or
102
+ * recovering from a critic-approved snapshot).
103
+ *
104
+ * Diffs the on-disk plan against the incoming plan, auto-populates
105
+ * `acknowledged_removals` with every missing id, and delegates to savePlan.
106
+ * The architect-facing save_plan tool MUST NOT use this — it should fail
107
+ * closed and require the caller to enumerate removals explicitly.
108
+ *
109
+ * Returns the count of auto-acknowledged removals so the caller can attach
110
+ * `_midLoadRemovals` to the RuntimePlan for Layer A disclosure.
111
+ */
112
+ export declare function savePlanWithAutoAcknowledgedRemovals(directory: string, plan: Plan, source: string, reason: string, options?: {
113
+ preserveCompletedStatuses?: boolean;
114
+ }): Promise<{
115
+ removedCount: number;
116
+ }>;
66
117
  /**
67
118
  * Validate against PlanSchema (throw on invalid), write to .swarm/plan.json via atomic temp+rename pattern,
68
119
  * then derive and write .swarm/plan.md
69
120
  */
70
121
  export declare function savePlan(directory: string, plan: Plan, options?: {
71
122
  preserveCompletedStatuses?: boolean;
123
+ acknowledged_removals?: AcknowledgedRemovals;
72
124
  }): Promise<void>;
73
125
  /**
74
126
  * Rebuild plan from ledger events.
@@ -46,6 +46,14 @@ export interface StatusData {
46
46
  compactionCount: number;
47
47
  /** ISO timestamp of last compaction snapshot, or null if none */
48
48
  lastSnapshotAt: string | null;
49
+ /** Issue #853 Layer C: true if spec drift was detected for this plan */
50
+ specStale?: boolean;
51
+ /** Reason text from .swarm/spec-staleness.json (or RuntimePlan._specStaleReason) */
52
+ specStaleReason?: string;
53
+ /** Stored spec hash from when the plan was last saved */
54
+ specStaleStoredHash?: string;
55
+ /** Current spec.md hash on disk (null when spec.md is missing) */
56
+ specStaleCurrentHash?: string | null;
49
57
  }
50
58
  /**
51
59
  * Get status data from the swarm directory.
@@ -33,6 +33,25 @@ export interface SavePlanArgs {
33
33
  * after a failed phase). Defaults to false (existing statuses preserved).
34
34
  */
35
35
  reset_statuses?: boolean;
36
+ /**
37
+ * Issue #853: tasks that are present in the prior plan but intentionally
38
+ * being removed by this save. Every task missing from `phases` must be
39
+ * enumerated here, otherwise save_plan rejects with
40
+ * `PLAN_TASK_REMOVAL_NOT_ACKNOWLEDGED`.
41
+ */
42
+ removed_task_ids?: string[];
43
+ /**
44
+ * Human-readable reason for the removals listed in `removed_task_ids`.
45
+ * Must be non-empty when `removed_task_ids` is non-empty. Recorded on
46
+ * each `task_removed` ledger event for audit.
47
+ */
48
+ removal_reason?: string;
49
+ /**
50
+ * Required when both `reset_statuses` is true AND at least one task is
51
+ * missing from the new plan. Without this flag set, save_plan rejects to
52
+ * prevent a destructive reset from silently dropping unfinished work.
53
+ */
54
+ confirm_destructive_reset?: boolean;
36
55
  /**
37
56
  * Architect-facing concurrency controls for this plan.
38
57
  * When execution_profile.locked is true the profile is immutable — subsequent
@@ -4,6 +4,7 @@ export declare const MAX_COMMAND_LENGTH = 500;
4
4
  export declare const DEFAULT_TIMEOUT_MS = 60000;
5
5
  export declare const MAX_TIMEOUT_MS = 300000;
6
6
  export declare const MAX_SAFE_TEST_FILES = 50;
7
+ export declare const MAX_SAFE_SOURCE_FILES = 1;
7
8
  export declare const SUPPORTED_FRAMEWORKS: readonly ["bun", "vitest", "jest", "mocha", "pytest", "cargo", "pester", "go-test", "maven", "gradle", "dotnet-test", "ctest", "swift-test", "dart-test", "rspec", "minitest"];
8
9
  export type TestFramework = (typeof SUPPORTED_FRAMEWORKS)[number] | 'none';
9
10
  export interface TestRunnerArgs {
@@ -90,6 +90,26 @@ export interface SpecDriftAcknowledgedEvent {
90
90
  previousHash: string;
91
91
  newHash: string | null;
92
92
  }
93
+ /**
94
+ * Emitted whenever savePlan removes one or more tasks from the prior plan
95
+ * (issue #853). Functional during replayFromLedger (post-merge fix) — the
96
+ * ledger commit precedes the plan.json rename, so rebuild must drop the
97
+ * task to maintain crash consistency. The `source` identifies the caller
98
+ * (e.g. 'save_plan_tool', 'phase_complete_rebuild_from_ledger'); the
99
+ * removal reason rides on the `payload` envelope to match LedgerEvent.
100
+ */
101
+ export interface TaskRemovedEvent {
102
+ type: 'task_removed';
103
+ timestamp: string;
104
+ task_id: string;
105
+ phase_id: number;
106
+ from_status: string;
107
+ source: string;
108
+ payload?: {
109
+ reason?: string;
110
+ source?: string;
111
+ };
112
+ }
93
113
  export interface PrmPatternDetectedEvent {
94
114
  type: 'prm_pattern_detected';
95
115
  timestamp: string;
@@ -122,4 +142,4 @@ export interface PrmHardStopEvent {
122
142
  level: number;
123
143
  occurrenceCount: number;
124
144
  }
125
- export type V619Event = SoundingBoardConsultedEvent | ArchitectLoopDetectedEvent | PrecedentManipulationDetectedEvent | CoderSelfAuditEvent | CoderRetryCircuitBreakerEvent | AgentConflictDetectedEvent | AuthorityHandoffResolvedEvent | SpecStaleDetectedEvent | SpecDriftAcknowledgedEvent | PrmPatternDetectedEvent | PrmCourseCorrectionInjectedEvent | PrmEscalationTriggeredEvent | PrmHardStopEvent;
145
+ export type V619Event = SoundingBoardConsultedEvent | ArchitectLoopDetectedEvent | PrecedentManipulationDetectedEvent | CoderSelfAuditEvent | CoderRetryCircuitBreakerEvent | AgentConflictDetectedEvent | AuthorityHandoffResolvedEvent | SpecStaleDetectedEvent | SpecDriftAcknowledgedEvent | TaskRemovedEvent | PrmPatternDetectedEvent | PrmCourseCorrectionInjectedEvent | PrmEscalationTriggeredEvent | PrmHardStopEvent;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.19.0",
3
+ "version": "7.19.2",
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",