opencode-hive 1.3.4 → 1.3.5

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 CHANGED
@@ -108,6 +108,32 @@ When using Dynamic Context Pruning (DCP), use a Hive-safe config in `~/.config/o
108
108
 
109
109
  For local plugin testing, keep OpenCode plugin entry as `"opencode-hive"` (not `"opencode-hive@latest"`).
110
110
 
111
+ #### Compaction recovery and session re-anchoring
112
+
113
+ OpenCode can compact long sessions. When that happens mid-orchestration or mid-task, Hive needs the session to recover its role and task boundaries without re-reading the whole repository.
114
+
115
+ The plugin now persists durable session metadata and uses it during `experimental.session.compacting` to rebuild a compact re-anchor prompt.
116
+
117
+ Where:
118
+
119
+ - Global session state is written to `.hive/sessions.json`.
120
+ - Feature-local mirrors are written to `.hive/features/<feature>/sessions.json`.
121
+ - Session classification distinguishes `primary`, `subagent`, `task-worker`, and `unknown`.
122
+ - Primary and subagent recovery can replay the stored user directive once after compaction.
123
+ - For task workers, the re-anchor context can include `.hive/features/<feature>/tasks/<task>/worker-prompt.md`.
124
+
125
+ Task-worker recovery is intentionally strict:
126
+
127
+ - keep the same role
128
+ - do not delegate
129
+ - do not re-read the full codebase
130
+ - re-read `worker-prompt.md`
131
+ - continue from the last known point
132
+
133
+ This split is deliberate: post-compaction replay is for primary/subagent intent, while task-worker recovery comes from durable worktree context plus `worker-prompt.md` so implementation sessions stay attached to the exact task contract.
134
+
135
+ This matters most for `forager-worker` and forager-derived custom agents, because they are the sessions most likely to be compacted mid-implementation.
136
+
111
137
  ## Prompt Budgeting & Observability
112
138
 
113
139
  Hive automatically bounds worker prompt sizes to prevent context overflow and tool output truncation.
@@ -136,6 +162,8 @@ When limits are exceeded, content is truncated with `...[truncated]` markers and
136
162
 
137
163
  Large prompts are written to `.hive/features/<feature>/tasks/<task>/worker-prompt.md` and passed by file reference (`workerPromptPath`) rather than inlined in tool output. This prevents truncation of large prompts.
138
164
 
165
+ That same `worker-prompt.md` path is also reused during compaction recovery so task workers can re-anchor to the exact task assignment after a compacted session resumes.
166
+
139
167
  ## Plan Format
140
168
 
141
169
  ```markdown
@@ -359,6 +387,13 @@ ID guardrails:
359
387
  - plugin-reserved aliases are blocked (`hive`, `architect`, `swarm`, `scout`, `forager`, `hygienic`, `receiver`)
360
388
  - operational IDs are blocked (`build`, `plan`, `code`)
361
389
 
390
+ Compaction classification follows the base agent:
391
+
392
+ - `forager-worker` derivatives are treated as `task-worker`
393
+ - `hygienic-reviewer` derivatives are treated as `subagent`
394
+
395
+ This ensures custom workers recover with the same execution constraints as their base role.
396
+
362
397
  ### Custom Models
363
398
 
364
399
  Override models for specific agents:
@@ -1,10 +1,17 @@
1
- import { SessionInfo } from '../types.js';
1
+ import type { SessionInfo } from '../types.js';
2
2
  export declare class SessionService {
3
3
  private projectRoot;
4
4
  constructor(projectRoot: string);
5
+ private applySessionPatch;
5
6
  private getSessionsPath;
6
7
  private getSessions;
7
8
  private saveSessions;
9
+ private getGlobalSessions;
10
+ private saveGlobalSessions;
11
+ private updateGlobalSessions;
12
+ trackGlobal(sessionId: string, patch?: Partial<SessionInfo>): SessionInfo;
13
+ bindFeature(sessionId: string, featureName: string, patch?: Partial<SessionInfo>): SessionInfo;
14
+ getGlobal(sessionId: string): SessionInfo | undefined;
8
15
  track(featureName: string, sessionId: string, taskFolder?: string): SessionInfo;
9
16
  setMaster(featureName: string, sessionId: string): void;
10
17
  getMaster(featureName: string): string | undefined;
@@ -120,9 +120,17 @@ export interface ContextFile {
120
120
  content: string;
121
121
  updatedAt: string;
122
122
  }
123
+ export type SessionKind = 'primary' | 'subagent' | 'task-worker' | 'unknown';
123
124
  export interface SessionInfo {
124
125
  sessionId: string;
126
+ featureName?: string;
125
127
  taskFolder?: string;
128
+ agent?: string;
129
+ baseAgent?: string;
130
+ sessionKind?: SessionKind;
131
+ workerPromptPath?: string;
132
+ directivePrompt?: string;
133
+ replayDirectivePending?: boolean;
126
134
  startedAt: string;
127
135
  lastActiveAt: string;
128
136
  messageCount?: number;
@@ -3,6 +3,7 @@ export declare function normalizePath(filePath: string): string;
3
3
  export declare function getHivePath(projectRoot: string): string;
4
4
  export declare function getFeaturesPath(projectRoot: string): string;
5
5
  export declare function getActiveFeaturePath(projectRoot: string): string;
6
+ export declare function getGlobalSessionsPath(projectRoot: string): string;
6
7
  export declare function listFeatureDirectories(projectRoot: string): FeatureDirectoryInfo[];
7
8
  export declare function resolveFeatureDirectoryName(projectRoot: string, featureName: string): string;
8
9
  export declare function getNextIndexedFeatureDirectoryName(projectRoot: string, featureName: string): string;