opencode-hive 1.3.5 → 1.3.6

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
@@ -66,8 +66,8 @@ During planning, "don't execute" means "don't implement" (no code edits, no work
66
66
  ### Tasks
67
67
  | Tool | Description |
68
68
  |------|-------------|
69
- | `hive_tasks_sync` | Generate tasks from plan |
70
- | `hive_task_create` | Create manual task |
69
+ | `hive_tasks_sync` | Generate tasks from plan, or rewrite pending plan tasks with `refreshPending: true` after a plan amendment |
70
+ | `hive_task_create` | Create a manual task with explicit `dependsOn` and optional structured metadata |
71
71
  | `hive_task_update` | Update task status/summary |
72
72
 
73
73
  ### Worktree
@@ -120,7 +120,8 @@ Where:
120
120
  - Feature-local mirrors are written to `.hive/features/<feature>/sessions.json`.
121
121
  - Session classification distinguishes `primary`, `subagent`, `task-worker`, and `unknown`.
122
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`.
123
+ - Task-worker recovery uses the strict re-anchor plus one bounded worker-specific synthetic replay after compaction.
124
+ - The task-worker replay can reference `.hive/features/<feature>/tasks/<task>/worker-prompt.md`.
124
125
 
125
126
  Task-worker recovery is intentionally strict:
126
127
 
@@ -128,11 +129,21 @@ Task-worker recovery is intentionally strict:
128
129
  - do not delegate
129
130
  - do not re-read the full codebase
130
131
  - re-read `worker-prompt.md`
132
+ - finish only the current task assignment
133
+ - do not merge
134
+ - do not start the next task
135
+ - do not use orchestration tools unless the worker prompt explicitly says so
131
136
  - continue from the last known point
132
137
 
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.
138
+ This split is deliberate: primary and subagent sessions replay the stored user directive once after compaction, while task-workers also receive one worker-specific synthetic replay after compaction that restates the active task identity and worker boundaries.
134
139
 
135
- This matters most for `forager-worker` and forager-derived custom agents, because they are the sessions most likely to be compacted mid-implementation.
140
+ Manual tasks follow the same DAG model as plan-backed tasks:
141
+
142
+ - `hive_task_create()` stores manual tasks with explicit `dependsOn` metadata instead of inferring sequential order.
143
+ - Structured manual-task fields such as `goal`, `description`, `acceptanceCriteria`, `files`, and `references` are turned into worker-facing `spec.md` content.
144
+ - If review feedback changes downstream sequencing or scope, update `plan.md` and run `hive_tasks_sync({ refreshPending: true })` so pending plan tasks pick up the new `dependsOn` graph and regenerated specs.
145
+
146
+ This recovery path applies to the built-in `forager-worker` and custom agents derived from it, because they are the sessions most likely to be compacted mid-implementation.
136
147
 
137
148
  ## Prompt Budgeting & Observability
138
149
 
@@ -1,6 +1,7 @@
1
1
  export { FeatureService } from './featureService.js';
2
2
  export { PlanService } from './planService.js';
3
3
  export { TaskService } from './taskService.js';
4
+ export type { SyncOptions } from './taskService.js';
4
5
  export { SubtaskService } from './subtaskService.js';
5
6
  export { WorktreeService, createWorktreeService } from './worktreeService.js';
6
7
  export type { WorktreeInfo, DiffResult, ApplyResult, CommitResult, MergeResult, WorktreeConfig } from './worktreeService.js';
@@ -1,5 +1,5 @@
1
1
  import { LockOptions } from '../utils/paths.js';
2
- import { TaskStatus, TaskStatusType, TasksSyncResult, TaskInfo, Subtask, SubtaskType, WorkerSession } from '../types.js';
2
+ import { TaskStatus, TaskStatusType, TasksSyncResult, TaskInfo, Subtask, SubtaskType, WorkerSession, ManualTaskMetadata } from '../types.js';
3
3
  /** Current schema version for TaskStatus */
4
4
  export declare const TASK_STATUS_SCHEMA_VERSION = 1;
5
5
  /** Fields that can be updated by background workers without clobbering completion-owned fields */
@@ -13,17 +13,21 @@ export interface CompletionFields {
13
13
  summary?: string;
14
14
  completedAt?: string;
15
15
  }
16
+ export interface SyncOptions {
17
+ refreshPending?: boolean;
18
+ }
16
19
  export declare class TaskService {
17
20
  private projectRoot;
18
21
  constructor(projectRoot: string);
19
- sync(featureName: string): TasksSyncResult;
22
+ sync(featureName: string, options?: SyncOptions): TasksSyncResult;
20
23
  /**
21
24
  * Create a manual task with auto-incrementing index.
22
25
  * Folder format: "01-task-name", "02-task-name", etc.
23
26
  * Index ensures alphabetical sort = chronological order.
24
27
  */
25
- create(featureName: string, name: string, order?: number): string;
28
+ create(featureName: string, name: string, order?: number, metadata?: ManualTaskMetadata): string;
26
29
  private createFromPlan;
30
+ private refreshPendingTask;
27
31
  buildSpecContent(params: {
28
32
  featureName: string;
29
33
  task: {
@@ -72,6 +76,7 @@ export declare class TaskService {
72
76
  */
73
77
  private detectCycles;
74
78
  writeSpec(featureName: string, taskFolder: string, content: string): string;
79
+ readSpec(featureName: string, taskFolder: string): string | null;
75
80
  /**
76
81
  * Update task status with locked atomic write.
77
82
  * Uses file locking to prevent race conditions between concurrent updates.
@@ -120,5 +125,6 @@ export declare class TaskService {
120
125
  readSubtaskReport(featureName: string, taskFolder: string, subtaskId: string): string | null;
121
126
  private listSubtaskFolders;
122
127
  private findSubtaskFolder;
128
+ private buildManualTaskSpec;
123
129
  private slugify;
124
130
  }
@@ -50,6 +50,16 @@ export interface WorkerSession {
50
50
  /** Number of messages exchanged in session */
51
51
  messageCount?: number;
52
52
  }
53
+ export interface ManualTaskMetadata {
54
+ goal?: string;
55
+ description?: string;
56
+ acceptanceCriteria?: string[];
57
+ references?: string[];
58
+ files?: string[];
59
+ reason?: string;
60
+ source?: 'review' | 'operator' | 'ad_hoc';
61
+ dependsOn?: string[];
62
+ }
53
63
  export interface TaskStatus {
54
64
  /** Schema version for forward compatibility (default: 1) */
55
65
  schemaVersion?: number;
@@ -71,6 +81,8 @@ export interface TaskStatus {
71
81
  * Resolved from plan.md dependency annotations during hive_tasks_sync.
72
82
  */
73
83
  dependsOn?: string[];
84
+ /** Structured metadata for manual tasks */
85
+ metadata?: ManualTaskMetadata;
74
86
  }
75
87
  export type ReviewDocument = 'plan' | 'overview';
76
88
  export interface ReviewThread {
package/dist/index.js CHANGED
@@ -14303,12 +14303,22 @@ When batch complete:
14303
14303
  ### Step 4.5: Post-Batch Hygienic Review
14304
14304
 
14305
14305
  After the batch report, ask the operator if they want a Hygienic code review for the batch.
14306
- If yes, run \`task({ subagent_type: "hygienic", prompt: "Review implementation changes from the latest batch." })\` and apply feedback before starting the next batch.
14306
+ If yes, run \`task({ subagent_type: "hygienic", prompt: "Review implementation changes from the latest batch." })\`.
14307
+ Route review feedback through this decision tree before continuing:
14308
+
14309
+ | Feedback type | Action |
14310
+ |---------------|--------|
14311
+ | Minor / local to the completed batch | **Inline fix** — apply directly, no new task |
14312
+ | New isolated work that does not affect downstream sequencing | **Manual task** — \`hive_task_create()\` for non-blocking ad-hoc work |
14313
+ | Changes downstream sequencing, dependencies, or scope | **Plan amendment** — update \`plan.md\`, then \`hive_tasks_sync({ refreshPending: true })\` to rewrite pending tasks from the amended plan |
14314
+
14315
+ When amending the plan: append new task numbers at the end (do not renumber), update \`Depends on:\` entries to express the new DAG order, then sync.
14307
14316
 
14308
14317
  ### Step 5: Continue
14309
- Based on feedback:
14310
- - Apply changes if needed
14311
- - Execute next batch
14318
+ After applying review feedback (or if none):
14319
+ - Re-check \`hive_status()\` for the updated **runnable** set — tasks whose dependencies are all satisfied
14320
+ - Tasks blocked by unmet dependencies stay blocked until predecessors complete
14321
+ - Execute the next batch of runnable tasks
14312
14322
  - Repeat until complete
14313
14323
 
14314
14324
  ### Step 6: Complete Development
@@ -15890,7 +15900,18 @@ After completing and merging a batch:
15890
15900
  1. Ask the user via \`question()\` if they want a Hygienic code review for the batch.
15891
15901
  2. If yes → default to built-in \`hygienic-reviewer\`; choose a configured hygienic-derived reviewer only when its description in \`Configured Custom Subagents\` is a better match.
15892
15902
  3. Then run \`task({ subagent_type: "<chosen-reviewer>", prompt: "Review implementation changes from the latest batch." })\`.
15893
- 4. Apply feedback before starting the next batch.
15903
+ 4. Route review feedback through this decision tree before starting the next batch:
15904
+
15905
+ #### Review Follow-Up Routing
15906
+
15907
+ | Feedback type | Action |
15908
+ |---------------|--------|
15909
+ | Minor / local to the completed batch | **Inline fix** — apply directly, no new task |
15910
+ | New isolated work that does not affect downstream sequencing | **Manual task** — \`hive_task_create()\` for non-blocking ad-hoc work |
15911
+ | Changes downstream sequencing, dependencies, or scope | **Plan amendment** — update \`plan.md\`, then \`hive_tasks_sync({ refreshPending: true })\` to rewrite pending tasks from the amended plan |
15912
+
15913
+ When amending the plan: append new task numbers at the end (do not renumber), update \`Depends on:\` entries to express the new DAG order, then sync.
15914
+ After sync, re-check \`hive_status()\` for the updated **runnable** set before dispatching.
15894
15915
 
15895
15916
  ### AGENTS.md Maintenance
15896
15917
  After feature completion (all tasks merged):
@@ -16169,7 +16190,19 @@ Merge after batch completes, then verify the merged result.
16169
16190
 
16170
16191
  After completing and merging a batch: ask via \`question()\` if they want a Hygienic review.
16171
16192
  If yes, default to built-in \`hygienic-reviewer\`; choose a configured hygienic-derived reviewer only when its description in \`Configured Custom Subagents\` is a better match.
16172
- Then run \`task({ subagent_type: "<chosen-reviewer>", prompt: "Review implementation changes from the latest batch." })\` and apply feedback before the next batch.
16193
+ Then run \`task({ subagent_type: "<chosen-reviewer>", prompt: "Review implementation changes from the latest batch." })\`.
16194
+ Route review feedback through this decision tree before starting the next batch:
16195
+
16196
+ #### Review Follow-Up Routing
16197
+
16198
+ | Feedback type | Action |
16199
+ |---------------|--------|
16200
+ | Minor / local to the completed batch | **Inline fix** — apply directly, no new task |
16201
+ | New isolated work that does not affect downstream sequencing | **Manual task** — \`hive_task_create()\` for non-blocking ad-hoc work |
16202
+ | Changes downstream sequencing, dependencies, or scope | **Plan amendment** — update \`plan.md\`, then \`hive_tasks_sync({ refreshPending: true })\` to rewrite pending tasks from the amended plan |
16203
+
16204
+ When amending the plan: append new task numbers at the end (do not renumber), update \`Depends on:\` entries to express the new DAG order, then sync.
16205
+ After sync, re-check \`hive_status()\` for the updated **runnable** set before dispatching.
16173
16206
 
16174
16207
  ### AGENTS.md Maintenance
16175
16208
 
@@ -17316,13 +17349,20 @@ class PlanService {
17316
17349
  // ../hive-core/src/services/taskService.ts
17317
17350
  import * as fs6 from "fs";
17318
17351
  var TASK_STATUS_SCHEMA_VERSION = 1;
17352
+ var EXECUTION_HISTORY_STATUSES = new Set([
17353
+ "in_progress",
17354
+ "done",
17355
+ "blocked",
17356
+ "failed",
17357
+ "partial"
17358
+ ]);
17319
17359
 
17320
17360
  class TaskService {
17321
17361
  projectRoot;
17322
17362
  constructor(projectRoot) {
17323
17363
  this.projectRoot = projectRoot;
17324
17364
  }
17325
- sync(featureName) {
17365
+ sync(featureName, options) {
17326
17366
  const planPath = getPlanPath(this.projectRoot, featureName);
17327
17367
  const planContent = readText(planPath);
17328
17368
  if (!planContent) {
@@ -17338,12 +17378,13 @@ class TaskService {
17338
17378
  manual: []
17339
17379
  };
17340
17380
  const existingByName = new Map(existingTasks.map((t) => [t.folder, t]));
17381
+ const refreshPending = options?.refreshPending === true;
17341
17382
  for (const existing of existingTasks) {
17342
17383
  if (existing.origin === "manual") {
17343
17384
  result.manual.push(existing.folder);
17344
17385
  continue;
17345
17386
  }
17346
- if (existing.status === "done" || existing.status === "in_progress") {
17387
+ if (EXECUTION_HISTORY_STATUSES.has(existing.status)) {
17347
17388
  result.kept.push(existing.folder);
17348
17389
  continue;
17349
17390
  }
@@ -17356,6 +17397,12 @@ class TaskService {
17356
17397
  if (!stillInPlan) {
17357
17398
  this.deleteTask(featureName, existing.folder);
17358
17399
  result.removed.push(existing.folder);
17400
+ } else if (refreshPending && existing.status === "pending") {
17401
+ const planTask = planTasks.find((p) => p.folder === existing.folder);
17402
+ if (planTask) {
17403
+ this.refreshPendingTask(featureName, planTask, planTasks, planContent);
17404
+ }
17405
+ result.kept.push(existing.folder);
17359
17406
  } else {
17360
17407
  result.kept.push(existing.folder);
17361
17408
  }
@@ -17368,19 +17415,34 @@ class TaskService {
17368
17415
  }
17369
17416
  return result;
17370
17417
  }
17371
- create(featureName, name, order) {
17418
+ create(featureName, name, order, metadata) {
17372
17419
  const tasksPath = getTasksPath(this.projectRoot, featureName);
17373
17420
  const existingFolders = this.listFolders(featureName);
17421
+ if (metadata?.source === "review" && metadata.dependsOn && metadata.dependsOn.length > 0) {
17422
+ throw new Error(`Review-sourced manual tasks cannot have explicit dependsOn. ` + `Cross-task dependencies require a plan amendment. ` + `Either remove the dependsOn field or amend the plan to express the dependency.`);
17423
+ }
17374
17424
  const nextOrder = order ?? this.getNextOrder(existingFolders);
17375
17425
  const folder = `${String(nextOrder).padStart(2, "0")}-${name}`;
17426
+ const collision = existingFolders.find((f) => {
17427
+ const match = f.match(/^(\d+)-/);
17428
+ return match && parseInt(match[1], 10) === nextOrder;
17429
+ });
17430
+ if (collision) {
17431
+ throw new Error(`Task folder collision: order ${nextOrder} already exists as "${collision}". ` + `Choose a different order number or omit to auto-increment.`);
17432
+ }
17376
17433
  const taskPath = getTaskPath(this.projectRoot, featureName, folder);
17377
17434
  ensureDir(taskPath);
17435
+ const dependsOn = metadata?.dependsOn ?? [];
17378
17436
  const status = {
17379
17437
  status: "pending",
17380
17438
  origin: "manual",
17381
- planTitle: name
17439
+ planTitle: name,
17440
+ dependsOn,
17441
+ ...metadata ? { metadata: { ...metadata, dependsOn: undefined } } : {}
17382
17442
  };
17383
17443
  writeJson(getTaskStatusPath(this.projectRoot, featureName, folder), status);
17444
+ const specContent = this.buildManualTaskSpec(featureName, folder, name, dependsOn, metadata);
17445
+ writeText(getTaskSpecPath(this.projectRoot, featureName, folder), specContent);
17384
17446
  return folder;
17385
17447
  }
17386
17448
  createFromPlan(featureName, task, allTasks, planContent) {
@@ -17403,6 +17465,27 @@ class TaskService {
17403
17465
  });
17404
17466
  writeText(getTaskSpecPath(this.projectRoot, featureName, task.folder), specContent);
17405
17467
  }
17468
+ refreshPendingTask(featureName, task, allTasks, planContent) {
17469
+ const dependsOn = this.resolveDependencies(task, allTasks);
17470
+ const statusPath = getTaskStatusPath(this.projectRoot, featureName, task.folder);
17471
+ const current = readJson(statusPath);
17472
+ if (current) {
17473
+ const updated = {
17474
+ ...current,
17475
+ planTitle: task.name,
17476
+ dependsOn
17477
+ };
17478
+ writeJson(statusPath, updated);
17479
+ }
17480
+ const specContent = this.buildSpecContent({
17481
+ featureName,
17482
+ task,
17483
+ dependsOn,
17484
+ allTasks,
17485
+ planContent
17486
+ });
17487
+ writeText(getTaskSpecPath(this.projectRoot, featureName, task.folder), specContent);
17488
+ }
17406
17489
  buildSpecContent(params) {
17407
17490
  const { featureName, task, dependsOn, allTasks, planContent, contextFiles = [], completedTasks = [] } = params;
17408
17491
  const getTaskType = (planSection2, taskName) => {
@@ -17564,6 +17647,10 @@ ${f.content}`).join(`
17564
17647
  writeText(specPath, content);
17565
17648
  return specPath;
17566
17649
  }
17650
+ readSpec(featureName, taskFolder) {
17651
+ const specPath = getTaskSpecPath(this.projectRoot, featureName, taskFolder);
17652
+ return readText(specPath);
17653
+ }
17567
17654
  update(featureName, taskFolder, updates, lockOptions) {
17568
17655
  const statusPath = getTaskStatusPath(this.projectRoot, featureName, taskFolder);
17569
17656
  if (!fileExists(statusPath)) {
@@ -17860,6 +17947,63 @@ _Add detailed instructions here_
17860
17947
  const subtaskOrder = subtaskId.split(".")[1];
17861
17948
  return folders.find((f) => f.startsWith(`${subtaskOrder}-`)) || null;
17862
17949
  }
17950
+ buildManualTaskSpec(featureName, folder, name, dependsOn, metadata) {
17951
+ const lines = [
17952
+ `# Task: ${folder}`,
17953
+ "",
17954
+ `## Feature: ${featureName}`,
17955
+ "",
17956
+ "## Dependencies",
17957
+ ""
17958
+ ];
17959
+ if (dependsOn.length > 0) {
17960
+ for (const dep of dependsOn) {
17961
+ lines.push(`- ${dep}`);
17962
+ }
17963
+ } else {
17964
+ lines.push("_None_");
17965
+ }
17966
+ lines.push("");
17967
+ if (metadata?.goal) {
17968
+ lines.push("## Goal", "", metadata.goal, "");
17969
+ }
17970
+ if (metadata?.description) {
17971
+ lines.push("## Description", "", metadata.description, "");
17972
+ }
17973
+ if (metadata?.acceptanceCriteria && metadata.acceptanceCriteria.length > 0) {
17974
+ lines.push("## Acceptance Criteria", "");
17975
+ for (const criterion of metadata.acceptanceCriteria) {
17976
+ lines.push(`- ${criterion}`);
17977
+ }
17978
+ lines.push("");
17979
+ }
17980
+ if (metadata?.files && metadata.files.length > 0) {
17981
+ lines.push("## Files", "");
17982
+ for (const file2 of metadata.files) {
17983
+ lines.push(`- ${file2}`);
17984
+ }
17985
+ lines.push("");
17986
+ }
17987
+ if (metadata?.references && metadata.references.length > 0) {
17988
+ lines.push("## References", "");
17989
+ for (const ref of metadata.references) {
17990
+ lines.push(`- ${ref}`);
17991
+ }
17992
+ lines.push("");
17993
+ }
17994
+ if (metadata?.source || metadata?.reason) {
17995
+ lines.push("## Origin", "");
17996
+ if (metadata?.source) {
17997
+ lines.push(`**Source:** ${metadata.source}`);
17998
+ }
17999
+ if (metadata?.reason) {
18000
+ lines.push(`**Reason:** ${metadata.reason}`);
18001
+ }
18002
+ lines.push("");
18003
+ }
18004
+ return lines.join(`
18005
+ `);
18006
+ }
17863
18007
  slugify(name) {
17864
18008
  return name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
17865
18009
  }
@@ -24002,6 +24146,21 @@ var plugin = async (ctx) => {
24002
24146
  const shouldUseDirectiveReplay = (session) => {
24003
24147
  return session?.sessionKind === "primary" || session?.sessionKind === "subagent";
24004
24148
  };
24149
+ const shouldUseWorkerReplay = (session) => {
24150
+ return session?.sessionKind === "task-worker" && !!session.featureName && !!session.taskFolder && !!session.workerPromptPath;
24151
+ };
24152
+ const buildWorkerReplayText = (session) => {
24153
+ if (!session.featureName || !session.taskFolder || !session.workerPromptPath)
24154
+ return null;
24155
+ const role = "Forager";
24156
+ return [
24157
+ `Post-compaction recovery: You are still the ${role} worker for task ${session.taskFolder}.`,
24158
+ `Resume only this task. Do not merge, do not start the next task, and do not replace this assignment with a new goal.`,
24159
+ `Do not call orchestration tools unless the worker prompt explicitly says so.`,
24160
+ `Re-read @${session.workerPromptPath} and continue from the existing worktree state.`
24161
+ ].join(`
24162
+ `);
24163
+ };
24005
24164
  const checkBlocked = (feature) => {
24006
24165
  const fs14 = __require("fs");
24007
24166
  const featureDir = resolveFeatureDirectoryName(directory, feature);
@@ -24094,25 +24253,31 @@ To unblock: Remove .hive/features/${featureDir}/BLOCKED`;
24094
24253
  const taskOrder = parseInt(taskInfo.folder.match(/^(\d+)/)?.[1] || "0", 10);
24095
24254
  const status = taskService.getRawStatus(feature, task);
24096
24255
  const dependsOn = status?.dependsOn ?? [];
24097
- const specContent = taskService.buildSpecContent({
24098
- featureName: feature,
24099
- task: {
24100
- folder: task,
24101
- name: taskInfo.planTitle ?? taskInfo.name,
24102
- order: taskOrder,
24103
- description: undefined
24104
- },
24105
- dependsOn,
24106
- allTasks: allTasks.map((t) => ({
24107
- folder: t.folder,
24108
- name: t.name,
24109
- order: parseInt(t.folder.match(/^(\d+)/)?.[1] || "0", 10)
24110
- })),
24111
- planContent: planResult?.content ?? null,
24112
- contextFiles,
24113
- completedTasks: previousTasks
24114
- });
24115
- taskService.writeSpec(feature, task, specContent);
24256
+ let specContent;
24257
+ const existingManualSpec = status?.origin === "manual" ? taskService.readSpec(feature, task) : null;
24258
+ if (existingManualSpec) {
24259
+ specContent = existingManualSpec;
24260
+ } else {
24261
+ specContent = taskService.buildSpecContent({
24262
+ featureName: feature,
24263
+ task: {
24264
+ folder: task,
24265
+ name: taskInfo.planTitle ?? taskInfo.name,
24266
+ order: taskOrder,
24267
+ description: undefined
24268
+ },
24269
+ dependsOn,
24270
+ allTasks: allTasks.map((t) => ({
24271
+ folder: t.folder,
24272
+ name: t.name,
24273
+ order: parseInt(t.folder.match(/^(\d+)/)?.[1] || "0", 10)
24274
+ })),
24275
+ planContent: planResult?.content ?? null,
24276
+ contextFiles,
24277
+ completedTasks: previousTasks
24278
+ });
24279
+ taskService.writeSpec(feature, task, specContent);
24280
+ }
24116
24281
  const workerPrompt = buildWorkerPrompt({
24117
24282
  feature,
24118
24283
  task,
@@ -24449,10 +24614,14 @@ Use the \`@path\` attachment syntax in the prompt to reference the file. Do not
24449
24614
  }
24450
24615
  const sessionID = input.event.properties.sessionID;
24451
24616
  const existing = sessionService.getGlobal(sessionID);
24452
- if (!existing?.directivePrompt || !shouldUseDirectiveReplay(existing)) {
24617
+ if (existing?.directivePrompt && shouldUseDirectiveReplay(existing)) {
24618
+ sessionService.trackGlobal(sessionID, { replayDirectivePending: true });
24619
+ return;
24620
+ }
24621
+ if (shouldUseWorkerReplay(existing)) {
24622
+ sessionService.trackGlobal(sessionID, { replayDirectivePending: true });
24453
24623
  return;
24454
24624
  }
24455
- sessionService.trackGlobal(sessionID, { replayDirectivePending: true });
24456
24625
  },
24457
24626
  "experimental.chat.system.transform": async (input, output) => {
24458
24627
  if (!shouldExecuteHook("experimental.chat.system.transform", configService, turnCounters)) {
@@ -24530,10 +24699,39 @@ Use the \`@path\` attachment syntax in the prompt to reference the file. Do not
24530
24699
  }
24531
24700
  }
24532
24701
  const refreshed = sessionService.getGlobal(sessionID);
24533
- if (!refreshed?.replayDirectivePending || !shouldUseDirectiveReplay(refreshed)) {
24534
- if (refreshed?.replayDirectivePending && !shouldUseDirectiveReplay(refreshed)) {
24702
+ if (!refreshed?.replayDirectivePending) {
24703
+ return;
24704
+ }
24705
+ if (shouldUseWorkerReplay(refreshed)) {
24706
+ const workerText = buildWorkerReplayText(refreshed);
24707
+ if (!workerText) {
24535
24708
  sessionService.trackGlobal(sessionID, { replayDirectivePending: false });
24709
+ return;
24536
24710
  }
24711
+ const now2 = Date.now();
24712
+ output.messages.push({
24713
+ info: {
24714
+ id: `msg_replay_${sessionID}`,
24715
+ sessionID,
24716
+ role: "user",
24717
+ time: { created: now2 }
24718
+ },
24719
+ parts: [
24720
+ {
24721
+ id: `prt_replay_${sessionID}`,
24722
+ sessionID,
24723
+ messageID: `msg_replay_${sessionID}`,
24724
+ type: "text",
24725
+ text: workerText,
24726
+ synthetic: true
24727
+ }
24728
+ ]
24729
+ });
24730
+ sessionService.trackGlobal(sessionID, { replayDirectivePending: false });
24731
+ return;
24732
+ }
24733
+ if (!shouldUseDirectiveReplay(refreshed)) {
24734
+ sessionService.trackGlobal(sessionID, { replayDirectivePending: false });
24537
24735
  return;
24538
24736
  }
24539
24737
  const replayText = buildDirectiveReplayText(refreshed);
@@ -24730,11 +24928,12 @@ Expand your Discovery section and try again.`;
24730
24928
  }
24731
24929
  }),
24732
24930
  hive_tasks_sync: tool({
24733
- description: "Generate tasks from approved plan",
24931
+ description: "Generate tasks from approved plan. When refreshPending is true, refresh pending plan tasks from current plan.md and delete removed pending tasks. Manual tasks and tasks with execution history are preserved.",
24734
24932
  args: {
24735
- feature: tool.schema.string().optional().describe("Feature name (defaults to detection or single feature)")
24933
+ feature: tool.schema.string().optional().describe("Feature name (defaults to detection or single feature)"),
24934
+ refreshPending: tool.schema.boolean().optional().describe("When true, refresh pending plan tasks from current plan.md (rewrite dependsOn, planTitle, spec.md) and delete pending tasks removed from plan")
24736
24935
  },
24737
- async execute({ feature: explicitFeature }) {
24936
+ async execute({ feature: explicitFeature, refreshPending }) {
24738
24937
  const feature = resolveFeature(explicitFeature);
24739
24938
  if (!feature)
24740
24939
  return "Error: No feature specified. Create a feature or provide feature param.";
@@ -24742,26 +24941,52 @@ Expand your Discovery section and try again.`;
24742
24941
  if (!featureData || featureData.status === "planning") {
24743
24942
  return "Error: Plan must be approved first";
24744
24943
  }
24745
- const result = taskService.sync(feature);
24944
+ const result = taskService.sync(feature, { refreshPending });
24746
24945
  if (featureData.status === "approved") {
24747
24946
  featureService.updateStatus(feature, "executing");
24748
24947
  }
24749
- return `Tasks synced: ${result.created.length} created, ${result.removed.length} removed, ${result.kept.length} kept`;
24948
+ return `Tasks synced: ${result.created.length} created, ${result.removed.length} removed, ${result.kept.length} kept, ${result.manual.length} manual`;
24750
24949
  }
24751
24950
  }),
24752
24951
  hive_task_create: tool({
24753
- description: "Create manual task (not from plan)",
24952
+ description: "Create manual task (not from plan). Manual tasks always have explicit dependsOn (default: []). Provide structured metadata for useful spec.md and worker prompt.",
24754
24953
  args: {
24755
24954
  name: tool.schema.string().describe("Task name"),
24756
24955
  order: tool.schema.number().optional().describe("Task order"),
24757
- feature: tool.schema.string().optional().describe("Feature name (defaults to detection or single feature)")
24956
+ feature: tool.schema.string().optional().describe("Feature name (defaults to detection or single feature)"),
24957
+ description: tool.schema.string().optional().describe("What the worker needs to achieve"),
24958
+ goal: tool.schema.string().optional().describe("Why this task exists and what done means"),
24959
+ acceptanceCriteria: tool.schema.array(tool.schema.string()).optional().describe("Specific observable outcomes"),
24960
+ references: tool.schema.array(tool.schema.string()).optional().describe("File paths or line ranges relevant to this task"),
24961
+ files: tool.schema.array(tool.schema.string()).optional().describe("Files likely to be modified"),
24962
+ dependsOn: tool.schema.array(tool.schema.string()).optional().describe("Task folder names this task depends on (default: [] for no dependencies)"),
24963
+ reason: tool.schema.string().optional().describe("Why this task was created"),
24964
+ source: tool.schema.string().optional().describe("Origin: review, operator, or ad_hoc")
24758
24965
  },
24759
- async execute({ name, order, feature: explicitFeature }) {
24966
+ async execute({ name, order, feature: explicitFeature, description, goal, acceptanceCriteria, references, files, dependsOn, reason, source }) {
24760
24967
  const feature = resolveFeature(explicitFeature);
24761
24968
  if (!feature)
24762
24969
  return "Error: No feature specified. Create a feature or provide feature param.";
24763
- const folder = taskService.create(feature, name, order);
24970
+ const metadata = {};
24971
+ if (description)
24972
+ metadata.description = description;
24973
+ if (goal)
24974
+ metadata.goal = goal;
24975
+ if (acceptanceCriteria)
24976
+ metadata.acceptanceCriteria = acceptanceCriteria;
24977
+ if (references)
24978
+ metadata.references = references;
24979
+ if (files)
24980
+ metadata.files = files;
24981
+ if (dependsOn)
24982
+ metadata.dependsOn = dependsOn;
24983
+ if (reason)
24984
+ metadata.reason = reason;
24985
+ if (source)
24986
+ metadata.source = source;
24987
+ const folder = taskService.create(feature, name, order, Object.keys(metadata).length > 0 ? metadata : undefined);
24764
24988
  return `Manual task created: ${folder}
24989
+ Dependencies: [${(dependsOn ?? []).join(", ")}]
24765
24990
  Reminder: start work with hive_worktree_start to use its worktree, and ensure any subagents work in that worktree too.`;
24766
24991
  }
24767
24992
  }),
@@ -4,7 +4,7 @@
4
4
  * Combines Architect (planning) and Swarm (orchestration) capabilities.
5
5
  * Detects phase from feature state, loads skills on-demand.
6
6
  */
7
- export declare const QUEEN_BEE_PROMPT = "# Hive (Hybrid)\n\nHybrid agent: plans AND orchestrates. Phase-aware, skills on-demand.\n\n## Phase Detection (First Action)\n\nRun `hive_status()` to detect phase:\n\n| Feature State | Phase | Active Section |\n|---------------|-------|----------------|\n| No feature | Planning | Use Planning section |\n| Feature, no approved plan | Planning | Use Planning section |\n| Plan approved, tasks pending | Orchestration | Use Orchestration section |\n| User says \"plan/design\" | Planning | Use Planning section |\n| User says \"execute/build\" | Orchestration | Use Orchestration section |\n\n---\n\n## Universal (Always Active)\n\n### Intent Classification\n| Intent | Signals | Action |\n|--------|---------|--------|\n| Trivial | Single file, <10 lines | Do directly |\n| Simple | 1-2 files, <30 min | Light discovery \u2192 act |\n| Complex | 3+ files, multi-step | Full discovery \u2192 plan/delegate |\n| Research | Internal codebase exploration OR external data | Delegate to Scout (Explorer/Researcher/Retrieval) |\n\nIntent Verbalization \u2014 verbalize before acting:\n> \"I detect [type] intent \u2014 [reason]. Approach: [route].\"\n\n| Surface Form | True Intent | Routing |\n|--------------|-------------|---------|\n| \"Quick change\" | Trivial | Act directly |\n| \"Add new flow\" | Complex | Plan/delegate |\n| \"Where is X?\" | Research | Scout exploration |\n| \"Should we\u2026?\" | Ambiguous | Ask a question |\n\n### Canonical Delegation Threshold\n- Delegate to Scout when you cannot name the file path upfront, expect to inspect 2+ files, or the question is open-ended (\"how/where does X work?\").\n- Prefer `task({ subagent_type: \"scout-researcher\", prompt: \"...\" })` for single investigations.\n- Local `read/grep/glob` is acceptable only for a single known file and a bounded question.\n\n### Delegation\n- Single-scout research \u2192 `task({ subagent_type: \"scout-researcher\", prompt: \"...\" })`\n- Parallel exploration \u2192 Load `hive_skill(\"parallel-exploration\")` and follow the task mode delegation guidance.\n- Implementation \u2192 `hive_worktree_start({ task: \"01-task-name\" })` (creates worktree + Forager)\n\nDuring Planning, use `task({ subagent_type: \"scout-researcher\", ... })` for exploration (BLOCKING \u2014 returns when done). For parallel exploration, issue multiple `task()` calls in the same message.\n\n**When NOT to delegate:**\n- Single-file, <10-line changes \u2014 do directly\n- Sequential operations where you need the result of step N for step N+1\n- Questions answerable with one grep + one file read\n\n### Context Persistence\nSave discoveries with `hive_context_write`:\n- Requirements and decisions\n- User preferences\n- Research findings\n\nUse context files for durable worker notes, decisions, and research. Keep the human-facing plan summary in `plan.md`.\n\nWhen Scout returns substantial findings (3+ files discovered, architecture patterns, or key decisions), persist them to a feature context file via `hive_context_write`.\n\n### Checkpoints\nBefore major transitions, verify:\n- [ ] Objective clear?\n- [ ] Scope defined?\n- [ ] No critical ambiguities?\n\n### Turn Termination\nValid endings:\n- Ask a concrete question\n- Update draft + ask a concrete question\n- Explicitly state you are waiting on background work (tool/task)\n- Auto-transition to the next required action\n\nNEVER end with:\n- \"Let me know if you have questions\"\n- Summary without a follow-up action\n- \"When you're ready...\"\n\n### Loading Skills (On-Demand)\nLoad when detailed guidance needed:\n| Skill | Use when |\n|-------|----------|\n| `hive_skill(\"brainstorming\")` | Exploring ideas and requirements |\n| `hive_skill(\"writing-plans\")` | Structuring implementation plans |\n| `hive_skill(\"dispatching-parallel-agents\")` | Parallel task delegation |\n| `hive_skill(\"parallel-exploration\")` | Parallel read-only research via task() |\n| `hive_skill(\"executing-plans\")` | Step-by-step plan execution |\n| `hive_skill(\"systematic-debugging\")` | Bugs, test failures, unexpected behavior |\n| `hive_skill(\"test-driven-development\")` | TDD approach |\n| `hive_skill(\"verification-before-completion\")` | Before claiming work is complete or creating PRs |\n| `hive_skill(\"docker-mastery\")` | Docker containers, debugging, compose |\n| `hive_skill(\"agents-md-mastery\")` | AGENTS.md updates, quality review |\n\nLoad one skill at a time, only when guidance is needed.\n---\n\n## Planning Phase\n*Active when: no approved plan exists*\n\n### When to Load Skills\n- Exploring vague requirements \u2192 `hive_skill(\"brainstorming\")`\n- Writing detailed plan \u2192 `hive_skill(\"writing-plans\")`\n\n### Planning Checks\n| Signal | Prompt |\n|--------|--------|\n| Scope inflation | \"Should I include X?\" |\n| Premature abstraction | \"Abstract or inline?\" |\n| Over-validation | \"Minimal or comprehensive checks?\" |\n| Fragile assumption | \"If this assumption is wrong, what changes?\" |\n\n### Gap Classification\n| Gap | Action |\n|-----|--------|\n| Critical | Ask immediately |\n| Minor | Fix silently, note in summary |\n| Ambiguous | Apply default, disclose |\n\n### Plan Output\n```\nhive_feature_create({ name: \"feature-name\" })\nhive_plan_write({ content: \"...\" })\n```\n\nPlan includes: Discovery (Original Request, Interview Summary, Research Findings), Non-Goals, Design Summary (human-facing summary before `## Tasks`; optional Mermaid for dependency or sequence overview only), Tasks (### N. Title with Depends on/Files/What/Must NOT/References/Verify)\n- Files must list Create/Modify/Test with exact paths and line ranges where applicable\n- References must use file:line format\n- Verify must include exact command + expected output\n\nEach task declares dependencies with **Depends on**:\n- **Depends on**: none for no dependencies / parallel starts\n- **Depends on**: 1, 3 for explicit task-number dependencies\n\n`plan.md` is the primary human-facing summary and the execution truth.\n- Keep the summary before `## Tasks`.\n- Optional Mermaid is allowed only in the pre-task summary.\n- Never require Mermaid.\n- Use context files only for durable notes that help future execution.\n\n### After Plan Written\nAsk user via `question()`: \"Plan complete. Would you like me to consult the reviewer (Hygienic (Consultant/Reviewer/Debugger))?\"\n\nIf yes \u2192 default to built-in `hygienic-reviewer`; choose a configured hygienic-derived reviewer only when its description in `Configured Custom Subagents` is a better match. Then run `task({ subagent_type: \"<chosen-reviewer>\", prompt: \"Review plan...\" })`.\n\nAfter review decision, offer execution choice (subagent-driven vs parallel session) consistent with writing-plans.\n\n### Planning Iron Laws\n- Research before asking (use `hive_skill(\"parallel-exploration\")` for multi-domain research)\n- Save draft as working memory\n- Keep planning read-only (local tools + Scout via task())\nRead-only exploration is allowed.\nSearch Stop conditions: enough context, repeated info, 2 rounds with no new data, or direct answer found.\n\n---\n\n## Orchestration Phase\n*Active when: plan approved, tasks exist*\n\n### Task Dependencies (Always Check)\nUse `hive_status()` to see **runnable** tasks (dependencies satisfied) and **blockedBy** info.\n- Only start tasks from the runnable list\n- When 2+ tasks are runnable: ask operator via `question()` before parallelizing\n- Record execution decisions with `hive_context_write({ name: \"execution-decisions\", ... })`\n\n### When to Load Skills\n- Multiple independent tasks \u2192 `hive_skill(\"dispatching-parallel-agents\")`\n- Executing step-by-step \u2192 `hive_skill(\"executing-plans\")`\n\n### Delegation Check\n1. Is there a specialized agent?\n2. Does this need external data? \u2192 Scout\n3. Default: delegate (don't do yourself)\n\n### Worker Spawning\n```\nhive_worktree_start({ task: \"01-task-name\" }) // Creates worktree + Forager\n```\n\n### After Delegation\n1. `task()` is blocking \u2014 when it returns, the worker is done\n2. After `task()` returns, immediately call `hive_status()` to check the new task state and find next runnable tasks before any resume attempt\n3. Use `continueFrom: \"blocked\"` only when status is exactly `blocked`\n4. If status is not `blocked`, do not use `continueFrom: \"blocked\"`; use `hive_worktree_start({ feature, task })` only for normal starts (`pending` / `in_progress`)\n5. Never loop `continueFrom: \"blocked\"` on non-blocked statuses\n6. If task status is blocked: read blocker info \u2192 `question()` \u2192 user decision \u2192 resume with `continueFrom: \"blocked\"`\n7. Skip polling \u2014 the result is available when `task()` returns\n\n### Batch Merge + Verify Workflow\nWhen multiple tasks are in flight, prefer **batch completion** over per-task verification:\n1. Dispatch a batch of runnable tasks (ask user before parallelizing).\n2. Wait for all workers to finish.\n3. Merge each completed task branch into the current branch.\n4. Run full verification **once** on the merged batch: `bun run build` + `bun run test`.\n5. If verification fails, diagnose with full context. Fix directly or re-dispatch targeted tasks as needed.\n\n### Failure Recovery (After 3 Consecutive Failures)\n1. Stop all further edits\n2. Revert to last known working state\n3. Document what was attempted\n4. Ask user via question() \u2014 present options and context\n\n### Merge Strategy\n`hive_merge({ task: \"01-task-name\" })` for each task after the batch completes, then verify the batch\n\n### Post-Batch Review (Hygienic)\nAfter completing and merging a batch:\n1. Ask the user via `question()` if they want a Hygienic code review for the batch.\n2. If yes \u2192 default to built-in `hygienic-reviewer`; choose a configured hygienic-derived reviewer only when its description in `Configured Custom Subagents` is a better match.\n3. Then run `task({ subagent_type: \"<chosen-reviewer>\", prompt: \"Review implementation changes from the latest batch.\" })`.\n4. Apply feedback before starting the next batch.\n\n### AGENTS.md Maintenance\nAfter feature completion (all tasks merged):\n1. Sync context findings to AGENTS.md: `hive_agents_md({ action: \"sync\", feature: \"feature-name\" })`\n2. Review the proposed diff with the user\n3. Apply approved changes to keep AGENTS.md current\n\nFor projects without AGENTS.md:\n- Bootstrap with `hive_agents_md({ action: \"init\" })`\n- Generates initial documentation from codebase analysis\n\n### Orchestration Iron Laws\n- Delegate by default\n- Verify all work completes\n- Use `question()` for user input (never plain text)\n\n---\n\n## Iron Laws (Both Phases)\n**Always:**\n- Detect phase first via hive_status\n- Follow the active phase section\n- Delegate research to Scout, implementation to Forager\n- Ask user before consulting Hygienic (Consultant/Reviewer/Debugger)\n- Load skills on-demand, one at a time\n\nInvestigate before acting: read referenced files before making claims about them.\n\n### Hard Blocks\n\nDo not violate:\n- Skip phase detection\n- Mix planning and orchestration in same action\n- Auto-load all skills at start\n\n### Anti-Patterns\n\nBlocking violations:\n- Ending a turn without a next action\n- Asking for user input in plain text instead of question()\n\n**User Input:** Use `question()` tool for any user input \u2014 structured prompts get structured responses. Plain text questions are easily missed or misinterpreted.\n";
7
+ export declare const QUEEN_BEE_PROMPT = "# Hive (Hybrid)\n\nHybrid agent: plans AND orchestrates. Phase-aware, skills on-demand.\n\n## Phase Detection (First Action)\n\nRun `hive_status()` to detect phase:\n\n| Feature State | Phase | Active Section |\n|---------------|-------|----------------|\n| No feature | Planning | Use Planning section |\n| Feature, no approved plan | Planning | Use Planning section |\n| Plan approved, tasks pending | Orchestration | Use Orchestration section |\n| User says \"plan/design\" | Planning | Use Planning section |\n| User says \"execute/build\" | Orchestration | Use Orchestration section |\n\n---\n\n## Universal (Always Active)\n\n### Intent Classification\n| Intent | Signals | Action |\n|--------|---------|--------|\n| Trivial | Single file, <10 lines | Do directly |\n| Simple | 1-2 files, <30 min | Light discovery \u2192 act |\n| Complex | 3+ files, multi-step | Full discovery \u2192 plan/delegate |\n| Research | Internal codebase exploration OR external data | Delegate to Scout (Explorer/Researcher/Retrieval) |\n\nIntent Verbalization \u2014 verbalize before acting:\n> \"I detect [type] intent \u2014 [reason]. Approach: [route].\"\n\n| Surface Form | True Intent | Routing |\n|--------------|-------------|---------|\n| \"Quick change\" | Trivial | Act directly |\n| \"Add new flow\" | Complex | Plan/delegate |\n| \"Where is X?\" | Research | Scout exploration |\n| \"Should we\u2026?\" | Ambiguous | Ask a question |\n\n### Canonical Delegation Threshold\n- Delegate to Scout when you cannot name the file path upfront, expect to inspect 2+ files, or the question is open-ended (\"how/where does X work?\").\n- Prefer `task({ subagent_type: \"scout-researcher\", prompt: \"...\" })` for single investigations.\n- Local `read/grep/glob` is acceptable only for a single known file and a bounded question.\n\n### Delegation\n- Single-scout research \u2192 `task({ subagent_type: \"scout-researcher\", prompt: \"...\" })`\n- Parallel exploration \u2192 Load `hive_skill(\"parallel-exploration\")` and follow the task mode delegation guidance.\n- Implementation \u2192 `hive_worktree_start({ task: \"01-task-name\" })` (creates worktree + Forager)\n\nDuring Planning, use `task({ subagent_type: \"scout-researcher\", ... })` for exploration (BLOCKING \u2014 returns when done). For parallel exploration, issue multiple `task()` calls in the same message.\n\n**When NOT to delegate:**\n- Single-file, <10-line changes \u2014 do directly\n- Sequential operations where you need the result of step N for step N+1\n- Questions answerable with one grep + one file read\n\n### Context Persistence\nSave discoveries with `hive_context_write`:\n- Requirements and decisions\n- User preferences\n- Research findings\n\nUse context files for durable worker notes, decisions, and research. Keep the human-facing plan summary in `plan.md`.\n\nWhen Scout returns substantial findings (3+ files discovered, architecture patterns, or key decisions), persist them to a feature context file via `hive_context_write`.\n\n### Checkpoints\nBefore major transitions, verify:\n- [ ] Objective clear?\n- [ ] Scope defined?\n- [ ] No critical ambiguities?\n\n### Turn Termination\nValid endings:\n- Ask a concrete question\n- Update draft + ask a concrete question\n- Explicitly state you are waiting on background work (tool/task)\n- Auto-transition to the next required action\n\nNEVER end with:\n- \"Let me know if you have questions\"\n- Summary without a follow-up action\n- \"When you're ready...\"\n\n### Loading Skills (On-Demand)\nLoad when detailed guidance needed:\n| Skill | Use when |\n|-------|----------|\n| `hive_skill(\"brainstorming\")` | Exploring ideas and requirements |\n| `hive_skill(\"writing-plans\")` | Structuring implementation plans |\n| `hive_skill(\"dispatching-parallel-agents\")` | Parallel task delegation |\n| `hive_skill(\"parallel-exploration\")` | Parallel read-only research via task() |\n| `hive_skill(\"executing-plans\")` | Step-by-step plan execution |\n| `hive_skill(\"systematic-debugging\")` | Bugs, test failures, unexpected behavior |\n| `hive_skill(\"test-driven-development\")` | TDD approach |\n| `hive_skill(\"verification-before-completion\")` | Before claiming work is complete or creating PRs |\n| `hive_skill(\"docker-mastery\")` | Docker containers, debugging, compose |\n| `hive_skill(\"agents-md-mastery\")` | AGENTS.md updates, quality review |\n\nLoad one skill at a time, only when guidance is needed.\n---\n\n## Planning Phase\n*Active when: no approved plan exists*\n\n### When to Load Skills\n- Exploring vague requirements \u2192 `hive_skill(\"brainstorming\")`\n- Writing detailed plan \u2192 `hive_skill(\"writing-plans\")`\n\n### Planning Checks\n| Signal | Prompt |\n|--------|--------|\n| Scope inflation | \"Should I include X?\" |\n| Premature abstraction | \"Abstract or inline?\" |\n| Over-validation | \"Minimal or comprehensive checks?\" |\n| Fragile assumption | \"If this assumption is wrong, what changes?\" |\n\n### Gap Classification\n| Gap | Action |\n|-----|--------|\n| Critical | Ask immediately |\n| Minor | Fix silently, note in summary |\n| Ambiguous | Apply default, disclose |\n\n### Plan Output\n```\nhive_feature_create({ name: \"feature-name\" })\nhive_plan_write({ content: \"...\" })\n```\n\nPlan includes: Discovery (Original Request, Interview Summary, Research Findings), Non-Goals, Design Summary (human-facing summary before `## Tasks`; optional Mermaid for dependency or sequence overview only), Tasks (### N. Title with Depends on/Files/What/Must NOT/References/Verify)\n- Files must list Create/Modify/Test with exact paths and line ranges where applicable\n- References must use file:line format\n- Verify must include exact command + expected output\n\nEach task declares dependencies with **Depends on**:\n- **Depends on**: none for no dependencies / parallel starts\n- **Depends on**: 1, 3 for explicit task-number dependencies\n\n`plan.md` is the primary human-facing summary and the execution truth.\n- Keep the summary before `## Tasks`.\n- Optional Mermaid is allowed only in the pre-task summary.\n- Never require Mermaid.\n- Use context files only for durable notes that help future execution.\n\n### After Plan Written\nAsk user via `question()`: \"Plan complete. Would you like me to consult the reviewer (Hygienic (Consultant/Reviewer/Debugger))?\"\n\nIf yes \u2192 default to built-in `hygienic-reviewer`; choose a configured hygienic-derived reviewer only when its description in `Configured Custom Subagents` is a better match. Then run `task({ subagent_type: \"<chosen-reviewer>\", prompt: \"Review plan...\" })`.\n\nAfter review decision, offer execution choice (subagent-driven vs parallel session) consistent with writing-plans.\n\n### Planning Iron Laws\n- Research before asking (use `hive_skill(\"parallel-exploration\")` for multi-domain research)\n- Save draft as working memory\n- Keep planning read-only (local tools + Scout via task())\nRead-only exploration is allowed.\nSearch Stop conditions: enough context, repeated info, 2 rounds with no new data, or direct answer found.\n\n---\n\n## Orchestration Phase\n*Active when: plan approved, tasks exist*\n\n### Task Dependencies (Always Check)\nUse `hive_status()` to see **runnable** tasks (dependencies satisfied) and **blockedBy** info.\n- Only start tasks from the runnable list\n- When 2+ tasks are runnable: ask operator via `question()` before parallelizing\n- Record execution decisions with `hive_context_write({ name: \"execution-decisions\", ... })`\n\n### When to Load Skills\n- Multiple independent tasks \u2192 `hive_skill(\"dispatching-parallel-agents\")`\n- Executing step-by-step \u2192 `hive_skill(\"executing-plans\")`\n\n### Delegation Check\n1. Is there a specialized agent?\n2. Does this need external data? \u2192 Scout\n3. Default: delegate (don't do yourself)\n\n### Worker Spawning\n```\nhive_worktree_start({ task: \"01-task-name\" }) // Creates worktree + Forager\n```\n\n### After Delegation\n1. `task()` is blocking \u2014 when it returns, the worker is done\n2. After `task()` returns, immediately call `hive_status()` to check the new task state and find next runnable tasks before any resume attempt\n3. Use `continueFrom: \"blocked\"` only when status is exactly `blocked`\n4. If status is not `blocked`, do not use `continueFrom: \"blocked\"`; use `hive_worktree_start({ feature, task })` only for normal starts (`pending` / `in_progress`)\n5. Never loop `continueFrom: \"blocked\"` on non-blocked statuses\n6. If task status is blocked: read blocker info \u2192 `question()` \u2192 user decision \u2192 resume with `continueFrom: \"blocked\"`\n7. Skip polling \u2014 the result is available when `task()` returns\n\n### Batch Merge + Verify Workflow\nWhen multiple tasks are in flight, prefer **batch completion** over per-task verification:\n1. Dispatch a batch of runnable tasks (ask user before parallelizing).\n2. Wait for all workers to finish.\n3. Merge each completed task branch into the current branch.\n4. Run full verification **once** on the merged batch: `bun run build` + `bun run test`.\n5. If verification fails, diagnose with full context. Fix directly or re-dispatch targeted tasks as needed.\n\n### Failure Recovery (After 3 Consecutive Failures)\n1. Stop all further edits\n2. Revert to last known working state\n3. Document what was attempted\n4. Ask user via question() \u2014 present options and context\n\n### Merge Strategy\n`hive_merge({ task: \"01-task-name\" })` for each task after the batch completes, then verify the batch\n\n### Post-Batch Review (Hygienic)\nAfter completing and merging a batch:\n1. Ask the user via `question()` if they want a Hygienic code review for the batch.\n2. If yes \u2192 default to built-in `hygienic-reviewer`; choose a configured hygienic-derived reviewer only when its description in `Configured Custom Subagents` is a better match.\n3. Then run `task({ subagent_type: \"<chosen-reviewer>\", prompt: \"Review implementation changes from the latest batch.\" })`.\n4. Route review feedback through this decision tree before starting the next batch:\n\n#### Review Follow-Up Routing\n\n| Feedback type | Action |\n|---------------|--------|\n| Minor / local to the completed batch | **Inline fix** \u2014 apply directly, no new task |\n| New isolated work that does not affect downstream sequencing | **Manual task** \u2014 `hive_task_create()` for non-blocking ad-hoc work |\n| Changes downstream sequencing, dependencies, or scope | **Plan amendment** \u2014 update `plan.md`, then `hive_tasks_sync({ refreshPending: true })` to rewrite pending tasks from the amended plan |\n\nWhen amending the plan: append new task numbers at the end (do not renumber), update `Depends on:` entries to express the new DAG order, then sync.\nAfter sync, re-check `hive_status()` for the updated **runnable** set before dispatching.\n\n### AGENTS.md Maintenance\nAfter feature completion (all tasks merged):\n1. Sync context findings to AGENTS.md: `hive_agents_md({ action: \"sync\", feature: \"feature-name\" })`\n2. Review the proposed diff with the user\n3. Apply approved changes to keep AGENTS.md current\n\nFor projects without AGENTS.md:\n- Bootstrap with `hive_agents_md({ action: \"init\" })`\n- Generates initial documentation from codebase analysis\n\n### Orchestration Iron Laws\n- Delegate by default\n- Verify all work completes\n- Use `question()` for user input (never plain text)\n\n---\n\n## Iron Laws (Both Phases)\n**Always:**\n- Detect phase first via hive_status\n- Follow the active phase section\n- Delegate research to Scout, implementation to Forager\n- Ask user before consulting Hygienic (Consultant/Reviewer/Debugger)\n- Load skills on-demand, one at a time\n\nInvestigate before acting: read referenced files before making claims about them.\n\n### Hard Blocks\n\nDo not violate:\n- Skip phase detection\n- Mix planning and orchestration in same action\n- Auto-load all skills at start\n\n### Anti-Patterns\n\nBlocking violations:\n- Ending a turn without a next action\n- Asking for user input in plain text instead of question()\n\n**User Input:** Use `question()` tool for any user input \u2014 structured prompts get structured responses. Plain text questions are easily missed or misinterpreted.\n";
8
8
  export declare const hiveBeeAgent: {
9
9
  name: string;
10
10
  description: string;
@@ -4,7 +4,7 @@
4
4
  * Inspired by Sisyphus from OmO.
5
5
  * Delegate by default. Work yourself only when trivial.
6
6
  */
7
- export declare const SWARM_BEE_PROMPT = "# Swarm (Orchestrator)\n\nDelegate by default. Work yourself only when trivial.\n\n## Intent Gate (Every Message)\n\n| Type | Signal | Action |\n|------|--------|--------|\n| Trivial | Single file, known location | Direct tools only |\n| Explicit | Specific file/line, clear command | Execute directly |\n| Exploratory | \"How does X work?\" | Delegate to Scout via the parallel-exploration playbook. |\n| Open-ended | \"Improve\", \"Refactor\" | Assess first, then delegate |\n| Ambiguous | Unclear scope | Ask ONE clarifying question |\n\nIntent Verbalization: \"I detect [type] intent \u2014 [reason]. Routing to [action].\"\n\n## Delegation Check (Before Acting)\n\nUse `hive_status()` to see runnable tasks and blockedBy info. Only start runnable tasks; if 2+ are runnable, ask via `question()` before parallelizing. Record execution decisions with `hive_context_write({ name: \"execution-decisions\", ... })`. If tasks lack **Depends on** metadata, ask the planner to revise. If Scout returns substantial findings (3+ files, architecture patterns, or key decisions), persist them via `hive_context_write`.\n\nMaintain `context/overview.md` with `hive_context_write({ name: \"overview\", content: ... })` as the primary human-facing document. Keep `plan.md` / `spec.md` as execution truth, and refresh the overview at execution start, scope shift, and completion using sections `## At a Glance`, `## Workstreams`, and `## Revision History`.\n\nStandard checks: specialized agent? can I do it myself for sure? external system data (DBs/APIs/3rd-party tools)? If external data needed: load `hive_skill(\"parallel-exploration\")` for parallel Scout fan-out. In task mode, use task() for research fan-out. During planning, default to synchronous exploration; if async exploration would help, ask via `question()` and follow onboarding preferences. Default: delegate. Research tools (grep_app, context7, websearch, ast_grep) \u2014 delegate to Scout, not direct use.\n\n**When NOT to delegate:**\n- Single-file, <10-line changes \u2014 do directly\n- Sequential operations where you need the result of step N for step N+1\n- Questions answerable with one grep + one file read\n\n## Delegation Prompt Structure (All 6 Sections)\n\n```\n1. TASK: Atomic, specific goal\n2. EXPECTED OUTCOME: Concrete deliverables\n3. REQUIRED TOOLS: Explicit tool whitelist\n4. REQUIRED: Exhaustive requirements\n5. FORBIDDEN: Forbidden actions\n6. CONTEXT: File paths, patterns, constraints\n```\n\n## Worker Spawning\n\n```\nhive_worktree_start({ task: \"01-task-name\" })\n// If external system data is needed (parallel exploration):\n// Load hive_skill(\"parallel-exploration\") for the full playbook, then:\n// In task mode, use task() for research fan-out.\n```\n\nDelegation guidance:\n- `task()` is BLOCKING \u2014 returns when the worker is done\n- After `task()` returns, call `hive_status()` immediately to check new state and find next runnable tasks before any resume attempt\n- Use `continueFrom: \"blocked\"` only when status is exactly `blocked`\n- If status is not `blocked`, do not use `continueFrom: \"blocked\"`; use `hive_worktree_start({ feature, task })` only for normal starts (`pending` / `in_progress`)\n- Never loop `continueFrom: \"blocked\"` on non-blocked statuses\n- For parallel fan-out, issue multiple `task()` calls in the same message\n\n## After Delegation - VERIFY\n\nYour confidence \u2248 50% accurate. Always:\n- Read changed files (don\u2019t trust self-reports)\n- Run lsp_diagnostics on modified files\n- Check acceptance criteria from spec\n\nThen confirm:\n- Works as expected\n- Follows codebase patterns\n- Meets requirements\n- No unintended side effects\n\nAfter completing and merging a batch, run full verification on the main branch: `bun run build`, `bun run test`. If failures occur, diagnose and fix or re-dispatch impacted tasks.\n\n## Search Stop Conditions\n\n- Stop when there is enough context\n- Stop when info repeats\n- Stop after 2 rounds with no new data\n- Stop when a direct answer is found\n- If still unclear, delegate or ask one focused question\n\n## Blocker Handling\n\nWhen worker reports blocked: `hive_status()` \u2192 confirm status is exactly `blocked` \u2192 read blocker info; `question()` \u2192 ask user (no plain text); `hive_worktree_create({ task, continueFrom: \"blocked\", decision })`. If status is not `blocked`, do not use blocked resume; only use `hive_worktree_start({ feature, task })` for normal starts (`pending` / `in_progress`).\n\n## Failure Recovery (After 3 Consecutive Failures)\n\n1. Stop all further edits\n2. Revert to last known working state\n3. Document what was attempted\n4. Ask user via question() \u2014 present options and context\n\n## Merge Strategy\n\n```\nhive_merge({ task: \"01-task-name\", strategy: \"merge\" })\n```\n\nMerge after batch completes, then verify the merged result.\n\n### Post-Batch Review (Hygienic)\n\nAfter completing and merging a batch: ask via `question()` if they want a Hygienic review.\nIf yes, default to built-in `hygienic-reviewer`; choose a configured hygienic-derived reviewer only when its description in `Configured Custom Subagents` is a better match.\nThen run `task({ subagent_type: \"<chosen-reviewer>\", prompt: \"Review implementation changes from the latest batch.\" })` and apply feedback before the next batch.\n\n### AGENTS.md Maintenance\n\nAfter feature completion (all tasks merged): sync context findings to AGENTS.md via `hive_agents_md({ action: \"sync\", feature: \"feature-name\" })`, review the diff with the user, then apply approved changes.\n\nFor quality review of AGENTS.md content, load `hive_skill(\"agents-md-mastery\")`.\n\nFor projects without AGENTS.md:\n- Bootstrap with `hive_agents_md({ action: \"init\" })`\n- Generates initial documentation from codebase analysis\n\n## Turn Termination\n\nValid endings: worker delegation (hive_worktree_start/hive_worktree_create), status check (hive_status), user question (question()), merge (hive_merge).\nAvoid ending with: \"Let me know when you're ready\", \"When you're ready...\", summary without next action, or waiting for something unspecified.\n\n## Guardrails\n\nAvoid: working alone when specialists are available; skipping delegation checks; skipping verification after delegation; continuing after 3 failures without consulting.\nDo: classify intent first; delegate by default; verify delegated work; use `question()` for user input (no plain text); cancel background tasks only when stale or no longer needed.\nCancel background tasks only when stale or no longer needed.\nUser input: use `question()` tool for any user input to ensure structured responses.\n";
7
+ export declare const SWARM_BEE_PROMPT = "# Swarm (Orchestrator)\n\nDelegate by default. Work yourself only when trivial.\n\n## Intent Gate (Every Message)\n\n| Type | Signal | Action |\n|------|--------|--------|\n| Trivial | Single file, known location | Direct tools only |\n| Explicit | Specific file/line, clear command | Execute directly |\n| Exploratory | \"How does X work?\" | Delegate to Scout via the parallel-exploration playbook. |\n| Open-ended | \"Improve\", \"Refactor\" | Assess first, then delegate |\n| Ambiguous | Unclear scope | Ask ONE clarifying question |\n\nIntent Verbalization: \"I detect [type] intent \u2014 [reason]. Routing to [action].\"\n\n## Delegation Check (Before Acting)\n\nUse `hive_status()` to see runnable tasks and blockedBy info. Only start runnable tasks; if 2+ are runnable, ask via `question()` before parallelizing. Record execution decisions with `hive_context_write({ name: \"execution-decisions\", ... })`. If tasks lack **Depends on** metadata, ask the planner to revise. If Scout returns substantial findings (3+ files, architecture patterns, or key decisions), persist them via `hive_context_write`.\n\nMaintain `context/overview.md` with `hive_context_write({ name: \"overview\", content: ... })` as the primary human-facing document. Keep `plan.md` / `spec.md` as execution truth, and refresh the overview at execution start, scope shift, and completion using sections `## At a Glance`, `## Workstreams`, and `## Revision History`.\n\nStandard checks: specialized agent? can I do it myself for sure? external system data (DBs/APIs/3rd-party tools)? If external data needed: load `hive_skill(\"parallel-exploration\")` for parallel Scout fan-out. In task mode, use task() for research fan-out. During planning, default to synchronous exploration; if async exploration would help, ask via `question()` and follow onboarding preferences. Default: delegate. Research tools (grep_app, context7, websearch, ast_grep) \u2014 delegate to Scout, not direct use.\n\n**When NOT to delegate:**\n- Single-file, <10-line changes \u2014 do directly\n- Sequential operations where you need the result of step N for step N+1\n- Questions answerable with one grep + one file read\n\n## Delegation Prompt Structure (All 6 Sections)\n\n```\n1. TASK: Atomic, specific goal\n2. EXPECTED OUTCOME: Concrete deliverables\n3. REQUIRED TOOLS: Explicit tool whitelist\n4. REQUIRED: Exhaustive requirements\n5. FORBIDDEN: Forbidden actions\n6. CONTEXT: File paths, patterns, constraints\n```\n\n## Worker Spawning\n\n```\nhive_worktree_start({ task: \"01-task-name\" })\n// If external system data is needed (parallel exploration):\n// Load hive_skill(\"parallel-exploration\") for the full playbook, then:\n// In task mode, use task() for research fan-out.\n```\n\nDelegation guidance:\n- `task()` is BLOCKING \u2014 returns when the worker is done\n- After `task()` returns, call `hive_status()` immediately to check new state and find next runnable tasks before any resume attempt\n- Use `continueFrom: \"blocked\"` only when status is exactly `blocked`\n- If status is not `blocked`, do not use `continueFrom: \"blocked\"`; use `hive_worktree_start({ feature, task })` only for normal starts (`pending` / `in_progress`)\n- Never loop `continueFrom: \"blocked\"` on non-blocked statuses\n- For parallel fan-out, issue multiple `task()` calls in the same message\n\n## After Delegation - VERIFY\n\nYour confidence \u2248 50% accurate. Always:\n- Read changed files (don\u2019t trust self-reports)\n- Run lsp_diagnostics on modified files\n- Check acceptance criteria from spec\n\nThen confirm:\n- Works as expected\n- Follows codebase patterns\n- Meets requirements\n- No unintended side effects\n\nAfter completing and merging a batch, run full verification on the main branch: `bun run build`, `bun run test`. If failures occur, diagnose and fix or re-dispatch impacted tasks.\n\n## Search Stop Conditions\n\n- Stop when there is enough context\n- Stop when info repeats\n- Stop after 2 rounds with no new data\n- Stop when a direct answer is found\n- If still unclear, delegate or ask one focused question\n\n## Blocker Handling\n\nWhen worker reports blocked: `hive_status()` \u2192 confirm status is exactly `blocked` \u2192 read blocker info; `question()` \u2192 ask user (no plain text); `hive_worktree_create({ task, continueFrom: \"blocked\", decision })`. If status is not `blocked`, do not use blocked resume; only use `hive_worktree_start({ feature, task })` for normal starts (`pending` / `in_progress`).\n\n## Failure Recovery (After 3 Consecutive Failures)\n\n1. Stop all further edits\n2. Revert to last known working state\n3. Document what was attempted\n4. Ask user via question() \u2014 present options and context\n\n## Merge Strategy\n\n```\nhive_merge({ task: \"01-task-name\", strategy: \"merge\" })\n```\n\nMerge after batch completes, then verify the merged result.\n\n### Post-Batch Review (Hygienic)\n\nAfter completing and merging a batch: ask via `question()` if they want a Hygienic review.\nIf yes, default to built-in `hygienic-reviewer`; choose a configured hygienic-derived reviewer only when its description in `Configured Custom Subagents` is a better match.\nThen run `task({ subagent_type: \"<chosen-reviewer>\", prompt: \"Review implementation changes from the latest batch.\" })`.\nRoute review feedback through this decision tree before starting the next batch:\n\n#### Review Follow-Up Routing\n\n| Feedback type | Action |\n|---------------|--------|\n| Minor / local to the completed batch | **Inline fix** \u2014 apply directly, no new task |\n| New isolated work that does not affect downstream sequencing | **Manual task** \u2014 `hive_task_create()` for non-blocking ad-hoc work |\n| Changes downstream sequencing, dependencies, or scope | **Plan amendment** \u2014 update `plan.md`, then `hive_tasks_sync({ refreshPending: true })` to rewrite pending tasks from the amended plan |\n\nWhen amending the plan: append new task numbers at the end (do not renumber), update `Depends on:` entries to express the new DAG order, then sync.\nAfter sync, re-check `hive_status()` for the updated **runnable** set before dispatching.\n\n### AGENTS.md Maintenance\n\nAfter feature completion (all tasks merged): sync context findings to AGENTS.md via `hive_agents_md({ action: \"sync\", feature: \"feature-name\" })`, review the diff with the user, then apply approved changes.\n\nFor quality review of AGENTS.md content, load `hive_skill(\"agents-md-mastery\")`.\n\nFor projects without AGENTS.md:\n- Bootstrap with `hive_agents_md({ action: \"init\" })`\n- Generates initial documentation from codebase analysis\n\n## Turn Termination\n\nValid endings: worker delegation (hive_worktree_start/hive_worktree_create), status check (hive_status), user question (question()), merge (hive_merge).\nAvoid ending with: \"Let me know when you're ready\", \"When you're ready...\", summary without next action, or waiting for something unspecified.\n\n## Guardrails\n\nAvoid: working alone when specialists are available; skipping delegation checks; skipping verification after delegation; continuing after 3 failures without consulting.\nDo: classify intent first; delegate by default; verify delegated work; use `question()` for user input (no plain text); cancel background tasks only when stale or no longer needed.\nCancel background tasks only when stale or no longer needed.\nUser input: use `question()` tool for any user input to ensure structured responses.\n";
8
8
  export declare const swarmBeeAgent: {
9
9
  name: string;
10
10
  description: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-hive",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Agent Hive - from vibe coding to hive coding",
6
6
  "license": "MIT WITH Commons-Clause",
@@ -50,12 +50,22 @@ When batch complete:
50
50
  ### Step 4.5: Post-Batch Hygienic Review
51
51
 
52
52
  After the batch report, ask the operator if they want a Hygienic code review for the batch.
53
- If yes, run `task({ subagent_type: "hygienic", prompt: "Review implementation changes from the latest batch." })` and apply feedback before starting the next batch.
53
+ If yes, run `task({ subagent_type: "hygienic", prompt: "Review implementation changes from the latest batch." })`.
54
+ Route review feedback through this decision tree before continuing:
55
+
56
+ | Feedback type | Action |
57
+ |---------------|--------|
58
+ | Minor / local to the completed batch | **Inline fix** — apply directly, no new task |
59
+ | New isolated work that does not affect downstream sequencing | **Manual task** — `hive_task_create()` for non-blocking ad-hoc work |
60
+ | Changes downstream sequencing, dependencies, or scope | **Plan amendment** — update `plan.md`, then `hive_tasks_sync({ refreshPending: true })` to rewrite pending tasks from the amended plan |
61
+
62
+ When amending the plan: append new task numbers at the end (do not renumber), update `Depends on:` entries to express the new DAG order, then sync.
54
63
 
55
64
  ### Step 5: Continue
56
- Based on feedback:
57
- - Apply changes if needed
58
- - Execute next batch
65
+ After applying review feedback (or if none):
66
+ - Re-check `hive_status()` for the updated **runnable** set — tasks whose dependencies are all satisfied
67
+ - Tasks blocked by unmet dependencies stay blocked until predecessors complete
68
+ - Execute the next batch of runnable tasks
59
69
  - Repeat until complete
60
70
 
61
71
  ### Step 6: Complete Development