opencode-swarm 7.81.1 → 7.81.3

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.
@@ -1,4 +1,13 @@
1
+ import { loadPluginConfigWithMeta } from '../config';
2
+ import { type KnowledgeConfig, type PluginConfig } from '../config/schema';
3
+ import { archiveEvidence } from '../evidence/manager';
1
4
  import { getGitRepositoryStatus, resetToMainAfterMerge, resetToRemoteBranch } from '../git/branch';
5
+ import { createCuratorLLMDelegate } from '../hooks/curator-llm-factory';
6
+ import { runCuratorPostMortem } from '../hooks/curator-postmortem';
7
+ import { checkHivePromotions } from '../hooks/hive-promoter';
8
+ import { curateAndStoreSwarm } from '../hooks/knowledge-curator';
9
+ import { closePlanTerminalState } from '../plan/manager';
10
+ import { resetSwarmStatePreservingSingletons } from '../state';
2
11
  interface PlanPhase {
3
12
  id: number;
4
13
  name: string;
@@ -17,9 +26,63 @@ interface CloseCommandOptions {
17
26
  sessionID?: string;
18
27
  skillReviewTimeoutMs?: number;
19
28
  }
29
+ interface CurationCounts {
30
+ stored: number;
31
+ skipped: number;
32
+ rejected: number;
33
+ quarantined: number;
34
+ }
20
35
  interface CloseKnowledgeEntry {
21
36
  created_at?: string;
22
37
  }
38
+ export interface ArchiveStageContext {
39
+ directory: string;
40
+ swarmDir: string;
41
+ config: PluginConfig;
42
+ warnings: string[];
43
+ }
44
+ export interface CloseStageContext {
45
+ directory: string;
46
+ swarmDir: string;
47
+ planData: PlanData;
48
+ planExists: boolean;
49
+ planAlreadyDone: boolean;
50
+ config: KnowledgeConfig;
51
+ projectName: string;
52
+ warnings: string[];
53
+ closedPhases: number[];
54
+ closedTasks: string[];
55
+ sessionStart: string | undefined;
56
+ isForced: boolean;
57
+ runSkillReview: boolean;
58
+ options: CloseCommandOptions;
59
+ phases: PlanPhase[];
60
+ inProgressPhases: PlanPhase[];
61
+ curationSucceeded: boolean;
62
+ curationResult: CurationCounts | undefined;
63
+ allLessons: string[];
64
+ explicitLessons: string[];
65
+ retroLessons: string[];
66
+ knowledgeSkillHint: string;
67
+ skillReviewSummary: string;
68
+ postMortemSummary: string;
69
+ hivePromoted: number;
70
+ sessionKnowledgeCreated: number;
71
+ fallbackKnowledgeCreated: number;
72
+ originalStatuses: Map<string, string>;
73
+ guaranteeResult: {
74
+ closedPhaseIds: number[];
75
+ closedTaskIds: string[];
76
+ };
77
+ archiveResult: string;
78
+ archivedFileCount: number;
79
+ archivedActiveStateFiles: Set<string>;
80
+ archivedActiveStateDirs: Set<string>;
81
+ timestamp: string;
82
+ archiveDir: string;
83
+ archiveSuffix: string;
84
+ args: string[];
85
+ }
23
86
  declare function countSessionKnowledgeEntries(entries: CloseKnowledgeEntry[], sessionStart: string | undefined, fallbackCount: number): number;
24
87
  declare function copyDirRecursive(src: string, dest: string): Promise<number>;
25
88
  /**
@@ -31,6 +94,58 @@ declare function guaranteeAllPlansComplete(planData: PlanData): {
31
94
  closedPhaseIds: number[];
32
95
  closedTaskIds: string[];
33
96
  };
97
+ export interface GitAlignResult {
98
+ gitAlignResult: string;
99
+ prunedBranches: string[];
100
+ }
101
+ export interface CleanStageResult {
102
+ cleanedFiles: string[];
103
+ configBackupsRemoved: number;
104
+ swarmPlanFilesRemoved: number;
105
+ tmpFilesRemoved: number;
106
+ }
107
+ /**
108
+ * STAGE 1: FINALIZE
109
+ *
110
+ * Writes retrospectives for in-progress phases (or a session-level retro for
111
+ * plan-free closes), curates lessons, promotes to hive, runs skill review,
112
+ * persists terminal plan state, and runs post-mortem. All state mutations are
113
+ * written back to ctx so the caller can build the close summary.
114
+ */
115
+ export declare function runFinalizeStage(ctx: CloseStageContext): Promise<void>;
116
+ /**
117
+ * STAGE 2: ARCHIVE
118
+ *
119
+ * Creates a timestamped archive bundle under .swarm/archive/, copies flat-file
120
+ * artifacts and active-state directories, then runs the evidence retention
121
+ * policy. All state mutations (archive path, counts, success sets) are written
122
+ * back to ctx so the caller can build the close summary.
123
+ */
124
+ export declare function runArchiveStage(ctx: CloseStageContext): Promise<void>;
125
+ /**
126
+ * Runs the evidence-retention sub-logic of STAGE 2 (ARCHIVE).
127
+ * Reads max_age_days / max_bundles from config.evidence (FR-016) and
128
+ * calls archiveEvidence. Fail-open: pushes a warning on error but never throws.
129
+ */
130
+ export declare function runArchiveEvidenceRetention(ctx: ArchiveStageContext): Promise<void>;
131
+ /**
132
+ * STAGE 3: CLEAN
133
+ *
134
+ * Removes active-state files and directories that were successfully archived
135
+ * (archive-first guard), plus stale config-backup/ledger-sibling/SWARM_PLAN/.tmp
136
+ * artifacts. Resets context.md for the next session. All state mutations are
137
+ * written back to ctx so the caller can build the close summary.
138
+ */
139
+ export declare function runCleanStage(ctx: CloseStageContext): Promise<CleanStageResult>;
140
+ /**
141
+ * STAGE 4: ALIGN
142
+ *
143
+ * Performs safe git alignment to main (resetToMainAfterMerge / resetToRemoteBranch
144
+ * via _internals), handling post-merge scenarios and non-git directories.
145
+ * Returns { gitAlignResult, prunedBranches } so the orchestrator can build
146
+ * the close summary. All warnings are pushed into ctx.warnings.
147
+ */
148
+ export declare function runAlignStage(ctx: CloseStageContext): Promise<GitAlignResult>;
34
149
  /**
35
150
  * Handles /swarm close command - performs full terminal session finalization:
36
151
  * 0. Guarantee: mark all incomplete phases/tasks as closed
@@ -42,7 +157,16 @@ declare function guaranteeAllPlansComplete(planData: PlanData): {
42
157
  * Must be idempotent - safe to run multiple times.
43
158
  */
44
159
  export declare function handleCloseCommand(directory: string, args: string[], options?: CloseCommandOptions): Promise<string>;
160
+ /**
161
+ * Acquire the finalize lock for the close command (FR-012).
162
+ * Wraps tryAcquireLock with a directory-only API.
163
+ */
164
+ declare function acquireFinalizeLock(directory: string): Promise<{
165
+ acquired: boolean;
166
+ release?: () => Promise<void>;
167
+ }>;
45
168
  export declare const _internals: {
169
+ ACTIVE_STATE_DIRS_TO_CLEAN: string[];
46
170
  countSessionKnowledgeEntries: typeof countSessionKnowledgeEntries;
47
171
  CLOSE_SKILL_REVIEW_TIMEOUT_MS: number;
48
172
  guaranteeAllPlansComplete: typeof guaranteeAllPlansComplete;
@@ -50,5 +174,19 @@ export declare const _internals: {
50
174
  resetToMainAfterMerge: typeof resetToMainAfterMerge;
51
175
  resetToRemoteBranch: typeof resetToRemoteBranch;
52
176
  copyDirRecursive: typeof copyDirRecursive;
177
+ loadPluginConfigWithMeta: typeof loadPluginConfigWithMeta;
178
+ curateAndStoreSwarm: typeof curateAndStoreSwarm;
179
+ checkHivePromotions: typeof checkHivePromotions;
180
+ runCuratorPostMortem: typeof runCuratorPostMortem;
181
+ createCuratorLLMDelegate: typeof createCuratorLLMDelegate;
182
+ resetSwarmStatePreservingSingletons: typeof resetSwarmStatePreservingSingletons;
183
+ runFinalizeStage: typeof runFinalizeStage;
184
+ acquireFinalizeLock: typeof acquireFinalizeLock;
185
+ runArchiveStage: typeof runArchiveStage;
186
+ runArchiveEvidenceRetention: typeof runArchiveEvidenceRetention;
187
+ runCleanStage: typeof runCleanStage;
188
+ runAlignStage: typeof runAlignStage;
189
+ archiveEvidence: typeof archiveEvidence;
190
+ closePlanTerminalState: typeof closePlanTerminalState;
53
191
  };
54
192
  export {};
@@ -1,3 +1,9 @@
1
+ import { createCuratorLLMDelegate } from '../hooks/curator-llm-factory.js';
2
+ import { runCuratorPostMortem } from '../hooks/curator-postmortem.js';
3
+ export declare const _internals: {
4
+ createCuratorLLMDelegate: typeof createCuratorLLMDelegate;
5
+ runCuratorPostMortem: typeof runCuratorPostMortem;
6
+ };
1
7
  export declare function handlePostMortemCommand(directory: string, args: string[], options?: {
2
8
  sessionID?: string;
3
9
  }): Promise<string>;
@@ -312,7 +312,7 @@ export declare const COMMAND_REGISTRY: {
312
312
  readonly finalize: {
313
313
  readonly handler: (ctx: CommandContext) => Promise<string>;
314
314
  readonly description: "Use /swarm finalize to finalize the swarm project and archive evidence";
315
- readonly details: "Idempotent 4-stage terminal finalization: (1) finalize writes retrospectives for in-progress phases, (2) archive creates timestamped bundle of swarm artifacts and evidence, (3) clean removes active-state files for a clean slate, (4) align performs aggressive git reset --hard to the default remote branch, discarding uncommitted changes and untracked files; falls back to a cautious reset that preserves uncommitted changes when the aggressive path cannot proceed. WARNING: alignment discards local changes and untracked files. Resets agent sessions and delegation chains. Reads .swarm/close-lessons.md for explicit lessons and runs curation. Use --skill-review to run the quota-bounded skill_improver in proposal mode.";
315
+ readonly details: "Idempotent 4-stage terminal finalization: (1) finalize writes retrospectives for in-progress phases, (2) archive creates timestamped bundle of swarm artifacts and evidence, (3) clean removes active-state files for a clean slate, (4) align performs aggressive git reset --hard to the default remote branch, discarding uncommitted changes and gitignored build artifacts (user-created untracked files are preserved); falls back to a cautious reset that preserves uncommitted changes when the aggressive path cannot proceed. WARNING: alignment discards local changes and gitignored files. Resets agent sessions and delegation chains. Reads .swarm/close-lessons.md for explicit lessons and runs curation. Use --skill-review to run the quota-bounded skill_improver in proposal mode.";
316
316
  readonly args: "--prune-branches, --skill-review";
317
317
  readonly category: "core";
318
318
  readonly toolPolicy: "none";
@@ -83,7 +83,7 @@ declare function detectDefaultRemoteBranch(cwd: string): string | null;
83
83
  */
84
84
  export declare function resetToRemoteBranch(cwd: string, options?: {
85
85
  pruneBranches?: boolean;
86
- }): ResetToRemoteBranchResult;
86
+ }): Promise<ResetToRemoteBranchResult>;
87
87
  export interface ResetToMainAfterMergeResult {
88
88
  success: boolean;
89
89
  targetBranch: string;
@@ -101,7 +101,7 @@ export interface ResetToMainAfterMergeResult {
101
101
  */
102
102
  export declare function resetToMainAfterMerge(cwd: string, options?: {
103
103
  pruneBranches?: boolean;
104
- }): ResetToMainAfterMergeResult;
104
+ }): Promise<ResetToMainAfterMergeResult>;
105
105
  /**
106
106
  * DI seam for testability. Contains all test-mocked exports.
107
107
  * Internal calls should use _internals.fn() instead of fn() directly.
@@ -33,13 +33,18 @@ interface KnowledgeEventSummary {
33
33
  status: string;
34
34
  }
35
35
  declare function collectKnowledgeSummary(directory: string): Promise<KnowledgeEventSummary[]>;
36
- declare function readJsonlFile(filePath: string): unknown[];
36
+ declare function readJsonlFile(filePath: string, maxLines?: number): unknown[];
37
37
  declare function collectRetrospectives(directory: string): string[];
38
38
  declare function collectDriftReports(directory: string): string[];
39
39
  declare function collectPendingProposals(directory: string): Array<{
40
40
  source: string;
41
41
  content: string;
42
42
  }>;
43
+ declare function isReportValid(reportPath: string): boolean;
44
+ declare function acquirePostMortemLock(directory: string, planId: string): Promise<{
45
+ acquired: boolean;
46
+ release?: () => Promise<void>;
47
+ }>;
43
48
  declare function buildDataOnlyReport(planId: string, planSummary: string, knowledgeSummary: KnowledgeEventSummary[], curatorDigest: string | null, proposals: Array<{
44
49
  source: string;
45
50
  content: string;
@@ -50,6 +55,7 @@ declare function assembleLLMInput(planId: string, planSummary: string, knowledge
50
55
  }>, unactionable: unknown[], retrospectives: string[], driftReports: string[]): string;
51
56
  export declare function runCuratorPostMortem(directory: string, options?: PostMortemOptions): Promise<PostMortemResult>;
52
57
  export declare const _internals: {
58
+ acquirePostMortemLock: typeof acquirePostMortemLock;
53
59
  collectKnowledgeSummary: typeof collectKnowledgeSummary;
54
60
  collectRetrospectives: typeof collectRetrospectives;
55
61
  collectDriftReports: typeof collectDriftReports;
@@ -57,5 +63,6 @@ export declare const _internals: {
57
63
  readJsonlFile: typeof readJsonlFile;
58
64
  buildDataOnlyReport: typeof buildDataOnlyReport;
59
65
  assembleLLMInput: typeof assembleLLMInput;
66
+ isReportValid: typeof isReportValid;
60
67
  };
61
68
  export {};
@@ -186,8 +186,11 @@ export declare function recordHiveKnowledgeEvent(event: KnowledgeEventInput): Pr
186
186
  * Read all events from the log. Skips corrupted JSONL lines (logging a warning
187
187
  * for each) and returns an empty array when the file does not exist — mirrors
188
188
  * `readKnowledge` in knowledge-store.ts.
189
+ *
190
+ * Optional maxEvents cap: when provided as a positive finite number, stops
191
+ * after that many events are parsed, preventing unbounded memory growth.
189
192
  */
190
- export declare function readKnowledgeEvents(directory: string): Promise<KnowledgeEvent[]>;
193
+ export declare function readKnowledgeEvents(directory: string, maxEvents?: number): Promise<KnowledgeEvent[]>;
191
194
  /**
192
195
  * Read all events from the shared, cross-project hive events log. Skips
193
196
  * corrupted JSONL lines and returns an empty array when the file does not exist.
@@ -7,7 +7,8 @@ export declare function resolveSwarmRetractionsPath(directory: string): string;
7
7
  export declare function resolveHiveKnowledgePath(): string;
8
8
  export declare function resolveHiveRejectedPath(): string;
9
9
  export declare function resolveHiveEventsPath(): string;
10
- export declare function readKnowledge<T>(filePath: string): Promise<T[]>;
10
+ declare function parseKnowledgeContent<T>(content: string, max: number): T[];
11
+ export declare function readKnowledge<T>(filePath: string, maxEntries?: number): Promise<T[]>;
11
12
  export declare function normalizeEntry<T>(raw: T): T;
12
13
  export declare function readRejectedLessons(directory: string): Promise<RejectedLesson[]>;
13
14
  export interface KnowledgeRetractionRecord {
@@ -76,6 +77,7 @@ export declare const _internals: {
76
77
  resolveHiveRejectedPath: typeof resolveHiveRejectedPath;
77
78
  resolveHiveEventsPath: typeof resolveHiveEventsPath;
78
79
  readKnowledge: typeof readKnowledge;
80
+ parseKnowledgeContent: typeof parseKnowledgeContent;
79
81
  readRejectedLessons: typeof readRejectedLessons;
80
82
  appendKnowledge: typeof appendKnowledge;
81
83
  rewriteKnowledge: typeof rewriteKnowledge;