opencode-hive 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +634 -139
- package/dist/skills/builtin.d.ts +6 -5
- package/dist/skills/registry.generated.d.ts +14 -0
- package/dist/utils/agent-selector.d.ts +9 -1
- package/package.json +3 -2
- package/skills/hive-execution/SKILL.md +37 -270
package/dist/index.js
CHANGED
|
@@ -14,7 +14,6 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
14
14
|
// src/index.ts
|
|
15
15
|
import * as path5 from "path";
|
|
16
16
|
import * as fs6 from "fs";
|
|
17
|
-
import { fileURLToPath } from "url";
|
|
18
17
|
|
|
19
18
|
// ../../node_modules/.bun/zod@4.1.8/node_modules/zod/v4/classic/external.js
|
|
20
19
|
var exports_external = {};
|
|
@@ -12336,6 +12335,337 @@ function tool(input) {
|
|
|
12336
12335
|
return input;
|
|
12337
12336
|
}
|
|
12338
12337
|
tool.schema = exports_external;
|
|
12338
|
+
// src/skills/registry.generated.ts
|
|
12339
|
+
var BUILTIN_SKILL_NAMES = ["hive", "hive-execution"];
|
|
12340
|
+
var BUILTIN_SKILLS = [
|
|
12341
|
+
{
|
|
12342
|
+
name: "hive",
|
|
12343
|
+
description: "Plan-first AI development with isolated git worktrees and human review. Use for any feature development.",
|
|
12344
|
+
template: `# Hive Workflow
|
|
12345
|
+
|
|
12346
|
+
You are working in a Hive-enabled repository. Follow this plan-first workflow.
|
|
12347
|
+
|
|
12348
|
+
## Lifecycle
|
|
12349
|
+
|
|
12350
|
+
\`\`\`
|
|
12351
|
+
Feature -> Plan -> Review -> Approve -> Execute -> Merge -> Complete
|
|
12352
|
+
\`\`\`
|
|
12353
|
+
|
|
12354
|
+
---
|
|
12355
|
+
|
|
12356
|
+
## Phase 1: Planning
|
|
12357
|
+
|
|
12358
|
+
### Start Feature
|
|
12359
|
+
|
|
12360
|
+
\`\`\`
|
|
12361
|
+
hive_feature_create({ name: "feature-name" })
|
|
12362
|
+
\`\`\`
|
|
12363
|
+
|
|
12364
|
+
### Discovery Phase (Required)
|
|
12365
|
+
|
|
12366
|
+
BEFORE writing a plan, you MUST:
|
|
12367
|
+
1. Ask clarifying questions about the feature
|
|
12368
|
+
2. Document Q&A in plan.md with a \`## Discovery\` section
|
|
12369
|
+
3. Research the codebase (grep, read existing code)
|
|
12370
|
+
4. Save findings with hive_context_write
|
|
12371
|
+
|
|
12372
|
+
Your plan MUST include a \`## Discovery\` section or hive_plan_write will be BLOCKED.
|
|
12373
|
+
|
|
12374
|
+
Example discovery section:
|
|
12375
|
+
\`\`\`markdown
|
|
12376
|
+
## Discovery
|
|
12377
|
+
|
|
12378
|
+
**Q: What authentication system do we use?**
|
|
12379
|
+
A: JWT with refresh tokens, see src/auth/
|
|
12380
|
+
|
|
12381
|
+
**Q: Should this work offline?**
|
|
12382
|
+
A: No, online-only is fine
|
|
12383
|
+
|
|
12384
|
+
**Research:**
|
|
12385
|
+
- Found existing theme system in src/theme/
|
|
12386
|
+
- Uses CSS variables pattern
|
|
12387
|
+
\`\`\`
|
|
12388
|
+
|
|
12389
|
+
### Research First
|
|
12390
|
+
|
|
12391
|
+
Before writing anything:
|
|
12392
|
+
1. Search for relevant files (grep, explore)
|
|
12393
|
+
2. Read existing implementations
|
|
12394
|
+
3. Identify patterns and conventions
|
|
12395
|
+
|
|
12396
|
+
Save all findings:
|
|
12397
|
+
\`\`\`
|
|
12398
|
+
hive_context_write({
|
|
12399
|
+
name: "research",
|
|
12400
|
+
content: \`# Research Findings
|
|
12401
|
+
|
|
12402
|
+
## Existing Patterns
|
|
12403
|
+
- Theme system uses CSS variables in src/theme/
|
|
12404
|
+
- Components follow atomic design
|
|
12405
|
+
|
|
12406
|
+
## Files to Modify
|
|
12407
|
+
- src/theme/colors.ts
|
|
12408
|
+
- src/components/ThemeProvider.tsx
|
|
12409
|
+
\`
|
|
12410
|
+
})
|
|
12411
|
+
\`\`\`
|
|
12412
|
+
|
|
12413
|
+
### Write the Plan
|
|
12414
|
+
|
|
12415
|
+
Your plan should include these sections:
|
|
12416
|
+
|
|
12417
|
+
| Section | Required | Purpose |
|
|
12418
|
+
|---------|----------|---------|
|
|
12419
|
+
| \`## Discovery\` | Yes (gate enforced) | Q&A and research before planning |
|
|
12420
|
+
| \`## Problem\` | Yes | What we're solving |
|
|
12421
|
+
| \`## Non-Goals\` | Recommended | What we're NOT building (scope boundaries) |
|
|
12422
|
+
| \`## Tasks\` | Yes | Implementation steps with \`### N. Task Name\` format |
|
|
12423
|
+
| \`## Ghost Diffs\` | Recommended | Rejected alternatives (prevents re-proposing) |
|
|
12424
|
+
| \`## Success Criteria\` | Optional | How we know we're done |
|
|
12425
|
+
|
|
12426
|
+
Format for task parsing:
|
|
12427
|
+
|
|
12428
|
+
\`\`\`markdown
|
|
12429
|
+
# Feature Name
|
|
12430
|
+
|
|
12431
|
+
## Overview
|
|
12432
|
+
One paragraph explaining what and why.
|
|
12433
|
+
|
|
12434
|
+
## Tasks
|
|
12435
|
+
|
|
12436
|
+
### 1. Task Name
|
|
12437
|
+
Description of what this task accomplishes.
|
|
12438
|
+
- Specific files to modify
|
|
12439
|
+
- Expected outcome
|
|
12440
|
+
|
|
12441
|
+
### 2. Another Task
|
|
12442
|
+
Description...
|
|
12443
|
+
|
|
12444
|
+
### 3. Final Task
|
|
12445
|
+
Description...
|
|
12446
|
+
\`\`\`
|
|
12447
|
+
|
|
12448
|
+
Write with:
|
|
12449
|
+
\`\`\`
|
|
12450
|
+
hive_plan_write({ content: \`...\` })
|
|
12451
|
+
\`\`\`
|
|
12452
|
+
|
|
12453
|
+
**STOP** and tell user: "Plan written. Please review."
|
|
12454
|
+
|
|
12455
|
+
---
|
|
12456
|
+
|
|
12457
|
+
## Phase 2: Review (Human)
|
|
12458
|
+
|
|
12459
|
+
- User reviews plan.md in VS Code sidebar
|
|
12460
|
+
- User can add comments
|
|
12461
|
+
- Use \`hive_plan_read()\` to see user comments
|
|
12462
|
+
- Revise plan based on feedback
|
|
12463
|
+
- User clicks "Approve" or runs \`hive_plan_approve()\`
|
|
12464
|
+
|
|
12465
|
+
---
|
|
12466
|
+
|
|
12467
|
+
## Phase 3: Execution
|
|
12468
|
+
|
|
12469
|
+
### Generate Tasks
|
|
12470
|
+
|
|
12471
|
+
\`\`\`
|
|
12472
|
+
hive_tasks_sync()
|
|
12473
|
+
\`\`\`
|
|
12474
|
+
|
|
12475
|
+
Parses \`### N. Task Name\` headers into task folders.
|
|
12476
|
+
|
|
12477
|
+
### Execute Each Task
|
|
12478
|
+
|
|
12479
|
+
For each task in order:
|
|
12480
|
+
|
|
12481
|
+
#### 1. Start (creates worktree)
|
|
12482
|
+
\`\`\`
|
|
12483
|
+
hive_exec_start({ task: "01-task-name" })
|
|
12484
|
+
\`\`\`
|
|
12485
|
+
|
|
12486
|
+
#### 2. Implement
|
|
12487
|
+
Work in the isolated worktree path. Read \`spec.md\` for context.
|
|
12488
|
+
|
|
12489
|
+
#### 3. Complete (commits to branch)
|
|
12490
|
+
\`\`\`
|
|
12491
|
+
hive_exec_complete({ task: "01-task-name", summary: "What was done. Tests pass." })
|
|
12492
|
+
\`\`\`
|
|
12493
|
+
|
|
12494
|
+
**Note**: Summary must mention verification (tests/build) or completion will be BLOCKED.
|
|
12495
|
+
|
|
12496
|
+
#### 4. Merge (integrates to main)
|
|
12497
|
+
\`\`\`
|
|
12498
|
+
hive_merge({ task: "01-task-name", strategy: "squash" })
|
|
12499
|
+
\`\`\`
|
|
12500
|
+
|
|
12501
|
+
---
|
|
12502
|
+
|
|
12503
|
+
## Phase 4: Completion
|
|
12504
|
+
|
|
12505
|
+
After all tasks merged:
|
|
12506
|
+
\`\`\`
|
|
12507
|
+
hive_feature_complete({ name: "feature-name" })
|
|
12508
|
+
\`\`\`
|
|
12509
|
+
|
|
12510
|
+
---
|
|
12511
|
+
|
|
12512
|
+
## Tool Quick Reference
|
|
12513
|
+
|
|
12514
|
+
| Phase | Tool | Purpose |
|
|
12515
|
+
|-------|------|---------|
|
|
12516
|
+
| Plan | \`hive_feature_create\` | Start new feature |
|
|
12517
|
+
| Plan | \`hive_context_write\` | Save research findings |
|
|
12518
|
+
| Plan | \`hive_plan_write\` | Write the plan |
|
|
12519
|
+
| Plan | \`hive_plan_read\` | Check for user comments |
|
|
12520
|
+
| Plan | \`hive_plan_approve\` | Approve plan |
|
|
12521
|
+
| Execute | \`hive_tasks_sync\` | Generate tasks from plan |
|
|
12522
|
+
| Execute | \`hive_exec_start\` | Start task (creates worktree) |
|
|
12523
|
+
| Execute | \`hive_exec_complete\` | Finish task (commits changes) |
|
|
12524
|
+
| Execute | \`hive_merge\` | Integrate task to main |
|
|
12525
|
+
| Complete | \`hive_feature_complete\` | Mark feature done |
|
|
12526
|
+
|
|
12527
|
+
---
|
|
12528
|
+
|
|
12529
|
+
## Task Design Guidelines
|
|
12530
|
+
|
|
12531
|
+
### Good Tasks
|
|
12532
|
+
|
|
12533
|
+
| Characteristic | Example |
|
|
12534
|
+
|---------------|---------|
|
|
12535
|
+
| **Atomic** | "Add ThemeContext provider" not "Add theming" |
|
|
12536
|
+
| **Testable** | "Toggle switches between light/dark" |
|
|
12537
|
+
| **Independent** | Can be completed without other tasks (where possible) |
|
|
12538
|
+
| **Ordered** | Dependencies come first |
|
|
12539
|
+
|
|
12540
|
+
### Task Sizing
|
|
12541
|
+
|
|
12542
|
+
- **Too small**: "Add import statement" - combine with related work
|
|
12543
|
+
- **Too large**: "Implement entire feature" - break into logical units
|
|
12544
|
+
- **Just right**: "Create theme context with light/dark values"
|
|
12545
|
+
|
|
12546
|
+
---
|
|
12547
|
+
|
|
12548
|
+
## Rules
|
|
12549
|
+
|
|
12550
|
+
1. **Never skip planning** - Always write plan first
|
|
12551
|
+
2. **Context is critical** - Save all research with \`hive_context_write\`
|
|
12552
|
+
3. **Wait for approval** - Don't execute until user approves
|
|
12553
|
+
4. **One task at a time** - Complete and merge before starting next
|
|
12554
|
+
5. **Squash merges** - Keep history clean with single commit per task
|
|
12555
|
+
|
|
12556
|
+
---
|
|
12557
|
+
|
|
12558
|
+
## Error Recovery
|
|
12559
|
+
|
|
12560
|
+
### Task Failed
|
|
12561
|
+
\`\`\`
|
|
12562
|
+
hive_exec_abort(task="<task>") # Discards changes
|
|
12563
|
+
hive_exec_start(task="<task>") # Fresh start
|
|
12564
|
+
\`\`\`
|
|
12565
|
+
|
|
12566
|
+
### Merge Conflicts
|
|
12567
|
+
1. Resolve conflicts in the worktree
|
|
12568
|
+
2. Commit the resolution
|
|
12569
|
+
3. Run \`hive_merge\` again
|
|
12570
|
+
|
|
12571
|
+
---
|
|
12572
|
+
|
|
12573
|
+
## Example
|
|
12574
|
+
|
|
12575
|
+
User: "Add dark mode support"
|
|
12576
|
+
|
|
12577
|
+
\`\`\`
|
|
12578
|
+
1. hive_feature_create({ name: "dark-mode" })
|
|
12579
|
+
2. Research: grep for theme, colors, CSS variables
|
|
12580
|
+
3. hive_context_write({ name: "research", content: "Found theme in src/theme/..." })
|
|
12581
|
+
4. hive_plan_write({ content: "# Dark Mode\\n\\n## Tasks\\n\\n### 1. Add theme context..." })
|
|
12582
|
+
5. Tell user: "Plan ready for review"
|
|
12583
|
+
6. [User reviews and approves]
|
|
12584
|
+
7. hive_tasks_sync()
|
|
12585
|
+
8. For each task: exec_start -> implement -> exec_complete -> merge
|
|
12586
|
+
9. hive_feature_complete({ name: "dark-mode" })
|
|
12587
|
+
\`\`\``
|
|
12588
|
+
},
|
|
12589
|
+
{
|
|
12590
|
+
name: "hive-execution",
|
|
12591
|
+
description: "Execute Hive feature tasks with worktree isolation, parallel orchestration, and clean git history. Use when running synced Hive tasks.",
|
|
12592
|
+
template: `# Hive Execution
|
|
12593
|
+
|
|
12594
|
+
Quick reference for executing Hive tasks.
|
|
12595
|
+
|
|
12596
|
+
## Workflow Summary
|
|
12597
|
+
|
|
12598
|
+
1. **Feature create** → Discovery guide injected
|
|
12599
|
+
2. **Discovery** → Q&A documented in plan.md
|
|
12600
|
+
3. **Plan write** → GATE: requires ## Discovery section
|
|
12601
|
+
4. **Approval** → User reviews in VS Code
|
|
12602
|
+
5. **Exec start** → Delegation guide (Master), TDD+debugging (Worker)
|
|
12603
|
+
6. **Complete** → GATE: requires verification mention
|
|
12604
|
+
7. **Merge** → Squash into feature branch
|
|
12605
|
+
|
|
12606
|
+
## Gates
|
|
12607
|
+
|
|
12608
|
+
| Tool | Gate | Error |
|
|
12609
|
+
|------|------|-------|
|
|
12610
|
+
| hive_plan_write | ## Discovery section | "BLOCKED: Discovery required" |
|
|
12611
|
+
| hive_exec_complete | Verification in summary | "BLOCKED: No verification" |
|
|
12612
|
+
|
|
12613
|
+
## Task Lifecycle
|
|
12614
|
+
|
|
12615
|
+
\`\`\`
|
|
12616
|
+
hive_exec_start(task) # Creates worktree
|
|
12617
|
+
↓
|
|
12618
|
+
[implement in worktree]
|
|
12619
|
+
↓
|
|
12620
|
+
hive_exec_complete(task, summary) # Commits to branch
|
|
12621
|
+
↓
|
|
12622
|
+
hive_merge(task, strategy: "squash") # Integrates to main
|
|
12623
|
+
\`\`\`
|
|
12624
|
+
|
|
12625
|
+
## Quick Reference
|
|
12626
|
+
|
|
12627
|
+
| Tool | Purpose |
|
|
12628
|
+
|------|---------|
|
|
12629
|
+
| hive_status | Check overall progress |
|
|
12630
|
+
| hive_worker_status | Check delegated workers |
|
|
12631
|
+
| hive_exec_abort | Discard changes, restart |
|
|
12632
|
+
| hive_merge | Integrate completed task |
|
|
12633
|
+
| hive_worktree_list | See active worktrees |
|
|
12634
|
+
|
|
12635
|
+
## Error Recovery
|
|
12636
|
+
|
|
12637
|
+
### Task Failed
|
|
12638
|
+
\`\`\`
|
|
12639
|
+
hive_exec_abort(task) # Discards changes
|
|
12640
|
+
hive_exec_start(task) # Fresh start
|
|
12641
|
+
\`\`\`
|
|
12642
|
+
|
|
12643
|
+
### Merge Conflicts
|
|
12644
|
+
1. Resolve conflicts in worktree
|
|
12645
|
+
2. Commit resolution
|
|
12646
|
+
3. Run hive_merge again`
|
|
12647
|
+
}
|
|
12648
|
+
];
|
|
12649
|
+
|
|
12650
|
+
// src/skills/builtin.ts
|
|
12651
|
+
function loadBuiltinSkill(name) {
|
|
12652
|
+
const skill = BUILTIN_SKILLS.find((s) => s.name === name);
|
|
12653
|
+
if (!skill) {
|
|
12654
|
+
return {
|
|
12655
|
+
found: false,
|
|
12656
|
+
error: `Unknown builtin skill: ${name}. Available: ${BUILTIN_SKILL_NAMES.join(", ")}`
|
|
12657
|
+
};
|
|
12658
|
+
}
|
|
12659
|
+
return {
|
|
12660
|
+
found: true,
|
|
12661
|
+
skill,
|
|
12662
|
+
source: "builtin"
|
|
12663
|
+
};
|
|
12664
|
+
}
|
|
12665
|
+
function getBuiltinSkills() {
|
|
12666
|
+
return BUILTIN_SKILLS;
|
|
12667
|
+
}
|
|
12668
|
+
|
|
12339
12669
|
// ../hive-core/dist/index.js
|
|
12340
12670
|
import { createRequire as createRequire2 } from "node:module";
|
|
12341
12671
|
import * as path from "path";
|
|
@@ -12353,6 +12683,8 @@ import { normalize } from "node:path";
|
|
|
12353
12683
|
import { EventEmitter } from "node:events";
|
|
12354
12684
|
import * as fs8 from "fs";
|
|
12355
12685
|
import * as path4 from "path";
|
|
12686
|
+
import * as fs10 from "fs";
|
|
12687
|
+
import * as path6 from "path";
|
|
12356
12688
|
var __create = Object.create;
|
|
12357
12689
|
var __getProtoOf = Object.getPrototypeOf;
|
|
12358
12690
|
var __defProp2 = Object.defineProperty;
|
|
@@ -13176,6 +13508,17 @@ var require_dist2 = __commonJS((exports) => {
|
|
|
13176
13508
|
exports.createDeferred = deferred;
|
|
13177
13509
|
exports.default = deferred;
|
|
13178
13510
|
});
|
|
13511
|
+
var DEFAULT_HIVE_CONFIG = {
|
|
13512
|
+
enableToolsFor: [],
|
|
13513
|
+
agents: {
|
|
13514
|
+
worker: {
|
|
13515
|
+
visible: true
|
|
13516
|
+
}
|
|
13517
|
+
},
|
|
13518
|
+
omoSlim: {
|
|
13519
|
+
enabled: false
|
|
13520
|
+
}
|
|
13521
|
+
};
|
|
13179
13522
|
var HIVE_DIR = ".hive";
|
|
13180
13523
|
var FEATURES_DIR = "features";
|
|
13181
13524
|
var TASKS_DIR = "tasks";
|
|
@@ -13186,9 +13529,13 @@ var FEATURE_FILE = "feature.json";
|
|
|
13186
13529
|
var STATUS_FILE = "status.json";
|
|
13187
13530
|
var REPORT_FILE = "report.md";
|
|
13188
13531
|
var APPROVED_FILE = "APPROVED";
|
|
13532
|
+
var JOURNAL_FILE = "journal.md";
|
|
13189
13533
|
function getHivePath(projectRoot) {
|
|
13190
13534
|
return path.join(projectRoot, HIVE_DIR);
|
|
13191
13535
|
}
|
|
13536
|
+
function getJournalPath(projectRoot) {
|
|
13537
|
+
return path.join(getHivePath(projectRoot), JOURNAL_FILE);
|
|
13538
|
+
}
|
|
13192
13539
|
function getFeaturesPath(projectRoot) {
|
|
13193
13540
|
return path.join(getHivePath(projectRoot), FEATURES_DIR);
|
|
13194
13541
|
}
|
|
@@ -13318,6 +13665,22 @@ function listFeatures(projectRoot) {
|
|
|
13318
13665
|
return [];
|
|
13319
13666
|
return fs2.readdirSync(featuresPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
13320
13667
|
}
|
|
13668
|
+
var JOURNAL_TEMPLATE = `# Hive Journal
|
|
13669
|
+
|
|
13670
|
+
Audit trail of project learnings. Updated when trouble is resolved.
|
|
13671
|
+
|
|
13672
|
+
---
|
|
13673
|
+
|
|
13674
|
+
<!-- Entry template:
|
|
13675
|
+
### YYYY-MM-DD: feature-name
|
|
13676
|
+
|
|
13677
|
+
**Trouble**: What went wrong
|
|
13678
|
+
**Resolution**: How it was fixed
|
|
13679
|
+
**Constraint**: Never/Always rule derived (add to Iron Laws if recurring)
|
|
13680
|
+
**See**: .hive/features/feature-name/plan.md
|
|
13681
|
+
-->
|
|
13682
|
+
`;
|
|
13683
|
+
|
|
13321
13684
|
class FeatureService {
|
|
13322
13685
|
projectRoot;
|
|
13323
13686
|
constructor(projectRoot) {
|
|
@@ -13331,6 +13694,10 @@ class FeatureService {
|
|
|
13331
13694
|
ensureDir(featurePath);
|
|
13332
13695
|
ensureDir(getContextPath(this.projectRoot, name));
|
|
13333
13696
|
ensureDir(getTasksPath(this.projectRoot, name));
|
|
13697
|
+
const journalPath = getJournalPath(this.projectRoot);
|
|
13698
|
+
if (!fileExists(journalPath)) {
|
|
13699
|
+
fs3.writeFileSync(journalPath, JOURNAL_TEMPLATE);
|
|
13700
|
+
}
|
|
13334
13701
|
const feature = {
|
|
13335
13702
|
name,
|
|
13336
13703
|
status: "planning",
|
|
@@ -18384,16 +18751,83 @@ ${f.content}`);
|
|
|
18384
18751
|
return `${normalized}.md`;
|
|
18385
18752
|
}
|
|
18386
18753
|
}
|
|
18754
|
+
class ConfigService {
|
|
18755
|
+
configPath;
|
|
18756
|
+
constructor() {
|
|
18757
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
18758
|
+
const configDir = path6.join(homeDir, ".config", "opencode");
|
|
18759
|
+
this.configPath = path6.join(configDir, "agent_hive.json");
|
|
18760
|
+
}
|
|
18761
|
+
getPath() {
|
|
18762
|
+
return this.configPath;
|
|
18763
|
+
}
|
|
18764
|
+
get() {
|
|
18765
|
+
try {
|
|
18766
|
+
if (!fs10.existsSync(this.configPath)) {
|
|
18767
|
+
return { ...DEFAULT_HIVE_CONFIG };
|
|
18768
|
+
}
|
|
18769
|
+
const raw = fs10.readFileSync(this.configPath, "utf-8");
|
|
18770
|
+
const stored = JSON.parse(raw);
|
|
18771
|
+
return {
|
|
18772
|
+
...DEFAULT_HIVE_CONFIG,
|
|
18773
|
+
...stored,
|
|
18774
|
+
agents: {
|
|
18775
|
+
...DEFAULT_HIVE_CONFIG.agents,
|
|
18776
|
+
...stored.agents
|
|
18777
|
+
},
|
|
18778
|
+
omoSlim: {
|
|
18779
|
+
...DEFAULT_HIVE_CONFIG.omoSlim,
|
|
18780
|
+
...stored.omoSlim
|
|
18781
|
+
}
|
|
18782
|
+
};
|
|
18783
|
+
} catch {
|
|
18784
|
+
return { ...DEFAULT_HIVE_CONFIG };
|
|
18785
|
+
}
|
|
18786
|
+
}
|
|
18787
|
+
set(updates) {
|
|
18788
|
+
const current = this.get();
|
|
18789
|
+
const merged = {
|
|
18790
|
+
...current,
|
|
18791
|
+
...updates,
|
|
18792
|
+
agents: updates.agents ? {
|
|
18793
|
+
...current.agents,
|
|
18794
|
+
...updates.agents
|
|
18795
|
+
} : current.agents,
|
|
18796
|
+
omoSlim: updates.omoSlim ? {
|
|
18797
|
+
...current.omoSlim,
|
|
18798
|
+
...updates.omoSlim
|
|
18799
|
+
} : current.omoSlim
|
|
18800
|
+
};
|
|
18801
|
+
const configDir = path6.dirname(this.configPath);
|
|
18802
|
+
if (!fs10.existsSync(configDir)) {
|
|
18803
|
+
fs10.mkdirSync(configDir, { recursive: true });
|
|
18804
|
+
}
|
|
18805
|
+
fs10.writeFileSync(this.configPath, JSON.stringify(merged, null, 2));
|
|
18806
|
+
return merged;
|
|
18807
|
+
}
|
|
18808
|
+
exists() {
|
|
18809
|
+
return fs10.existsSync(this.configPath);
|
|
18810
|
+
}
|
|
18811
|
+
init() {
|
|
18812
|
+
if (!this.exists()) {
|
|
18813
|
+
return this.set(DEFAULT_HIVE_CONFIG);
|
|
18814
|
+
}
|
|
18815
|
+
return this.get();
|
|
18816
|
+
}
|
|
18817
|
+
isOmoSlimEnabled() {
|
|
18818
|
+
return this.get().omoSlim?.enabled ?? false;
|
|
18819
|
+
}
|
|
18820
|
+
setOmoSlim(enabled) {
|
|
18821
|
+
return this.set({ omoSlim: { enabled } });
|
|
18822
|
+
}
|
|
18823
|
+
}
|
|
18387
18824
|
|
|
18388
18825
|
// src/utils/agent-selector.ts
|
|
18389
18826
|
var AGENT_PATTERNS = [
|
|
18390
|
-
{ pattern: /\b(find|search|locate|where|grep|explore|scan)\b/i, agent: "
|
|
18391
|
-
{ pattern: /\b(research|investigate|learn|
|
|
18392
|
-
{ pattern: /\b(ui|ux|component|frontend|react|vue|svelte|css|style|layout|design|button|form|modal)\b/i, agent: "
|
|
18393
|
-
{ pattern: /\b(
|
|
18394
|
-
{ pattern: /\b(readme|document|explain|write.*doc|comment|jsdoc|tsdoc)\b/i, agent: "document-writer" },
|
|
18395
|
-
{ pattern: /\b(image|screenshot|visual|diagram|mockup|pdf|picture|photo)\b/i, agent: "multimodal-looker" },
|
|
18396
|
-
{ pattern: /\b(architect|design.*decision|tradeoff|approach|strategy|choose|decide|compare)\b/i, agent: "oracle" }
|
|
18827
|
+
{ pattern: /\b(find|search|locate|where|grep|explore|scan|codebase)\b/i, agent: "explorer" },
|
|
18828
|
+
{ pattern: /\b(research|investigate|learn|docs?|documentation|library|api|external|github)\b/i, agent: "librarian" },
|
|
18829
|
+
{ pattern: /\b(ui|ux|component|frontend|react|vue|svelte|css|style|layout|design|button|form|modal|visual|responsive)\b/i, agent: "designer" },
|
|
18830
|
+
{ pattern: /\b(architect|decision|tradeoff|approach|strategy|choose|decide|compare|review|debug|complex)\b/i, agent: "oracle" }
|
|
18397
18831
|
];
|
|
18398
18832
|
function selectAgent(taskName, spec) {
|
|
18399
18833
|
const content = `${taskName} ${spec}`.toLowerCase();
|
|
@@ -18402,7 +18836,7 @@ function selectAgent(taskName, spec) {
|
|
|
18402
18836
|
return agent;
|
|
18403
18837
|
}
|
|
18404
18838
|
}
|
|
18405
|
-
return "
|
|
18839
|
+
return "fixer";
|
|
18406
18840
|
}
|
|
18407
18841
|
|
|
18408
18842
|
// src/utils/worker-prompt.ts
|
|
@@ -18493,6 +18927,7 @@ Instead, escalate via the blocker protocol:
|
|
|
18493
18927
|
\`\`\`
|
|
18494
18928
|
hive_exec_complete({
|
|
18495
18929
|
task: "${task}",
|
|
18930
|
+
feature: "${feature}",
|
|
18496
18931
|
status: "blocked",
|
|
18497
18932
|
summary: "What you accomplished so far",
|
|
18498
18933
|
blocker: {
|
|
@@ -18504,6 +18939,8 @@ hive_exec_complete({
|
|
|
18504
18939
|
})
|
|
18505
18940
|
\`\`\`
|
|
18506
18941
|
|
|
18942
|
+
**After calling hive_exec_complete with blocked status, STOP IMMEDIATELY.**
|
|
18943
|
+
|
|
18507
18944
|
The Hive Master will:
|
|
18508
18945
|
1. Receive your blocker info
|
|
18509
18946
|
2. Ask the user via question()
|
|
@@ -18520,16 +18957,22 @@ When your task is **fully complete**:
|
|
|
18520
18957
|
\`\`\`
|
|
18521
18958
|
hive_exec_complete({
|
|
18522
18959
|
task: "${task}",
|
|
18960
|
+
feature: "${feature}",
|
|
18523
18961
|
status: "completed",
|
|
18524
18962
|
summary: "Concise summary of what you accomplished"
|
|
18525
18963
|
})
|
|
18526
18964
|
\`\`\`
|
|
18527
18965
|
|
|
18966
|
+
**CRITICAL: After calling hive_exec_complete, you MUST STOP IMMEDIATELY.**
|
|
18967
|
+
Do NOT continue working. Do NOT respond further. Your session is DONE.
|
|
18968
|
+
The Hive Master will take over from here.
|
|
18969
|
+
|
|
18528
18970
|
If you encounter an **unrecoverable error**:
|
|
18529
18971
|
|
|
18530
18972
|
\`\`\`
|
|
18531
18973
|
hive_exec_complete({
|
|
18532
18974
|
task: "${task}",
|
|
18975
|
+
feature: "${feature}",
|
|
18533
18976
|
status: "failed",
|
|
18534
18977
|
summary: "What went wrong and what was attempted"
|
|
18535
18978
|
})
|
|
@@ -18540,6 +18983,7 @@ If you made **partial progress** but can't continue:
|
|
|
18540
18983
|
\`\`\`
|
|
18541
18984
|
hive_exec_complete({
|
|
18542
18985
|
task: "${task}",
|
|
18986
|
+
feature: "${feature}",
|
|
18543
18987
|
status: "partial",
|
|
18544
18988
|
summary: "What was completed and what remains"
|
|
18545
18989
|
})
|
|
@@ -18547,6 +18991,26 @@ hive_exec_complete({
|
|
|
18547
18991
|
|
|
18548
18992
|
---
|
|
18549
18993
|
|
|
18994
|
+
## TDD Protocol (Required)
|
|
18995
|
+
|
|
18996
|
+
1. **Red**: Write failing test first
|
|
18997
|
+
2. **Green**: Minimal code to pass
|
|
18998
|
+
3. **Refactor**: Clean up, keep tests green
|
|
18999
|
+
|
|
19000
|
+
Never write implementation before test exists.
|
|
19001
|
+
Exception: Pure refactoring of existing tested code.
|
|
19002
|
+
|
|
19003
|
+
## Debugging Protocol (When stuck)
|
|
19004
|
+
|
|
19005
|
+
1. **Reproduce**: Get consistent failure
|
|
19006
|
+
2. **Isolate**: Binary search to find cause
|
|
19007
|
+
3. **Hypothesize**: Form theory, test it
|
|
19008
|
+
4. **Fix**: Minimal change that resolves
|
|
19009
|
+
|
|
19010
|
+
After 3 failed attempts at same fix: STOP and report blocker.
|
|
19011
|
+
|
|
19012
|
+
---
|
|
19013
|
+
|
|
18550
19014
|
## Tool Access
|
|
18551
19015
|
|
|
18552
19016
|
**You have access to:**
|
|
@@ -18656,6 +19120,22 @@ When a worker returns status: 'blocked':
|
|
|
18656
19120
|
|
|
18657
19121
|
This keeps the user focused on ONE conversation (you) instead of multiple worker panes.
|
|
18658
19122
|
|
|
19123
|
+
## Iron Laws
|
|
19124
|
+
|
|
19125
|
+
### Never
|
|
19126
|
+
- Plan without asking questions first (discovery required)
|
|
19127
|
+
- Code without failing test first
|
|
19128
|
+
- Complete without running verification
|
|
19129
|
+
- Assume when uncertain - ASK
|
|
19130
|
+
- Put raw data in Master context - DELEGATE
|
|
19131
|
+
- Attempt same fix more than 3 times
|
|
19132
|
+
|
|
19133
|
+
### Always
|
|
19134
|
+
- One question at a time (discovery)
|
|
19135
|
+
- Test -> Code -> Verify (TDD)
|
|
19136
|
+
- Delegate data queries to subagents
|
|
19137
|
+
- Stop and ask when blocked
|
|
19138
|
+
|
|
18659
19139
|
## Communication Style
|
|
18660
19140
|
|
|
18661
19141
|
- Be concise, no preamble
|
|
@@ -18683,7 +19163,7 @@ Workers spawn in tmux panes with specialized agents:
|
|
|
18683
19163
|
- **librarian** - External docs and library research
|
|
18684
19164
|
- **oracle** - Architecture decisions and guidance
|
|
18685
19165
|
- **designer** - UI/UX implementation
|
|
18686
|
-
- **
|
|
19166
|
+
- **fixer** - Default implementation (code changes)
|
|
18687
19167
|
|
|
18688
19168
|
Agent is auto-selected based on task content.
|
|
18689
19169
|
Watch workers in tmux panes for real-time progress.
|
|
@@ -18700,57 +19180,8 @@ function buildHiveAgentPrompt(featureContext, omoSlimDetected) {
|
|
|
18700
19180
|
}
|
|
18701
19181
|
|
|
18702
19182
|
// src/index.ts
|
|
18703
|
-
function
|
|
18704
|
-
const
|
|
18705
|
-
if (!match) {
|
|
18706
|
-
return { meta: {}, body: content.trim() };
|
|
18707
|
-
}
|
|
18708
|
-
const meta = {};
|
|
18709
|
-
const frontmatter = match[1];
|
|
18710
|
-
const body = match[2];
|
|
18711
|
-
for (const line of frontmatter.split(`
|
|
18712
|
-
`)) {
|
|
18713
|
-
const colonIdx = line.indexOf(":");
|
|
18714
|
-
if (colonIdx > 0) {
|
|
18715
|
-
const key = line.slice(0, colonIdx).trim();
|
|
18716
|
-
const value = line.slice(colonIdx + 1).trim();
|
|
18717
|
-
meta[key] = value;
|
|
18718
|
-
}
|
|
18719
|
-
}
|
|
18720
|
-
return { meta, body: body.trim() };
|
|
18721
|
-
}
|
|
18722
|
-
function getSkillsDir() {
|
|
18723
|
-
const filename = fileURLToPath(import.meta.url);
|
|
18724
|
-
const dirname5 = path5.dirname(filename);
|
|
18725
|
-
return path5.join(dirname5, "..", "skills");
|
|
18726
|
-
}
|
|
18727
|
-
function discoverHiveSkills() {
|
|
18728
|
-
const skillsDir = getSkillsDir();
|
|
18729
|
-
const skills = [];
|
|
18730
|
-
if (!fs6.existsSync(skillsDir)) {
|
|
18731
|
-
return skills;
|
|
18732
|
-
}
|
|
18733
|
-
const entries = fs6.readdirSync(skillsDir, { withFileTypes: true });
|
|
18734
|
-
for (const entry of entries) {
|
|
18735
|
-
if (!entry.isDirectory())
|
|
18736
|
-
continue;
|
|
18737
|
-
const skillPath = path5.join(skillsDir, entry.name, "SKILL.md");
|
|
18738
|
-
if (!fs6.existsSync(skillPath))
|
|
18739
|
-
continue;
|
|
18740
|
-
try {
|
|
18741
|
-
const content = fs6.readFileSync(skillPath, "utf-8");
|
|
18742
|
-
const { meta, body } = parseFrontmatter(content);
|
|
18743
|
-
skills.push({
|
|
18744
|
-
name: meta.name || entry.name,
|
|
18745
|
-
description: meta.description || "",
|
|
18746
|
-
path: skillPath,
|
|
18747
|
-
body
|
|
18748
|
-
});
|
|
18749
|
-
} catch {}
|
|
18750
|
-
}
|
|
18751
|
-
return skills;
|
|
18752
|
-
}
|
|
18753
|
-
function formatSkillsXml(skills) {
|
|
19183
|
+
function formatSkillsXml() {
|
|
19184
|
+
const skills = getBuiltinSkills();
|
|
18754
19185
|
if (skills.length === 0)
|
|
18755
19186
|
return "";
|
|
18756
19187
|
const skillsXml = skills.map((skill) => {
|
|
@@ -18770,49 +19201,29 @@ ${skillsXml}
|
|
|
18770
19201
|
</available_skills>`;
|
|
18771
19202
|
}
|
|
18772
19203
|
function createHiveSkillTool() {
|
|
18773
|
-
|
|
18774
|
-
|
|
18775
|
-
const
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
cachedSkills = discoverHiveSkills();
|
|
18779
|
-
return cachedSkills;
|
|
18780
|
-
};
|
|
18781
|
-
const getDescription = () => {
|
|
18782
|
-
if (cachedDescription)
|
|
18783
|
-
return cachedDescription;
|
|
18784
|
-
const skills = getSkills();
|
|
18785
|
-
const base = "Load a Hive skill to get detailed instructions for a specific workflow.";
|
|
18786
|
-
if (skills.length === 0) {
|
|
18787
|
-
cachedDescription = base + `
|
|
18788
|
-
|
|
18789
|
-
No Hive skills available.`;
|
|
18790
|
-
} else {
|
|
18791
|
-
cachedDescription = base + formatSkillsXml(skills);
|
|
18792
|
-
}
|
|
18793
|
-
return cachedDescription;
|
|
18794
|
-
};
|
|
18795
|
-
getDescription();
|
|
19204
|
+
const base = "Load a Hive skill to get detailed instructions for a specific workflow.";
|
|
19205
|
+
const skills = getBuiltinSkills();
|
|
19206
|
+
const description = skills.length === 0 ? base + `
|
|
19207
|
+
|
|
19208
|
+
No Hive skills available.` : base + formatSkillsXml();
|
|
18796
19209
|
return tool({
|
|
18797
|
-
|
|
18798
|
-
return cachedDescription ?? "Load a Hive skill to get detailed instructions for a specific workflow.";
|
|
18799
|
-
},
|
|
19210
|
+
description,
|
|
18800
19211
|
args: {
|
|
18801
19212
|
name: tool.schema.string().describe("The skill name from available_skills")
|
|
18802
19213
|
},
|
|
18803
19214
|
async execute({ name }) {
|
|
18804
|
-
const
|
|
18805
|
-
|
|
18806
|
-
if (!skill) {
|
|
19215
|
+
const result = loadBuiltinSkill(name);
|
|
19216
|
+
if (!result.found || !result.skill) {
|
|
18807
19217
|
const available = skills.map((s) => s.name).join(", ");
|
|
18808
19218
|
throw new Error(`Skill "${name}" not found. Available Hive skills: ${available || "none"}`);
|
|
18809
19219
|
}
|
|
19220
|
+
const skill = result.skill;
|
|
18810
19221
|
return [
|
|
18811
19222
|
`## Hive Skill: ${skill.name}`,
|
|
18812
19223
|
"",
|
|
18813
19224
|
`**Description**: ${skill.description}`,
|
|
18814
19225
|
"",
|
|
18815
|
-
skill.
|
|
19226
|
+
skill.template
|
|
18816
19227
|
].join(`
|
|
18817
19228
|
`);
|
|
18818
19229
|
}
|
|
@@ -18897,29 +19308,18 @@ During execution, call \`hive_status\` periodically to:
|
|
|
18897
19308
|
- Get reminded of next actions
|
|
18898
19309
|
`;
|
|
18899
19310
|
var plugin = async (ctx) => {
|
|
18900
|
-
const { directory } = ctx;
|
|
19311
|
+
const { directory, client } = ctx;
|
|
18901
19312
|
const featureService = new FeatureService(directory);
|
|
18902
19313
|
const planService = new PlanService(directory);
|
|
18903
19314
|
const taskService = new TaskService(directory);
|
|
18904
19315
|
const contextService = new ContextService(directory);
|
|
19316
|
+
const configService = new ConfigService;
|
|
18905
19317
|
const worktreeService = new WorktreeService({
|
|
18906
19318
|
baseDir: directory,
|
|
18907
19319
|
hiveDir: path5.join(directory, ".hive")
|
|
18908
19320
|
});
|
|
18909
|
-
|
|
18910
|
-
|
|
18911
|
-
const detectOmoSlim = (toolContext) => {
|
|
18912
|
-
if (detectionDone)
|
|
18913
|
-
return omoSlimDetected;
|
|
18914
|
-
const ctx2 = toolContext;
|
|
18915
|
-
if (ctx2?.tools?.includes?.("background_task") || ctx2?.background_task || typeof ctx2?.callTool === "function") {
|
|
18916
|
-
omoSlimDetected = true;
|
|
18917
|
-
}
|
|
18918
|
-
detectionDone = true;
|
|
18919
|
-
if (omoSlimDetected) {
|
|
18920
|
-
console.log("[Hive] OMO-Slim detected: delegated execution with tmux panes enabled");
|
|
18921
|
-
}
|
|
18922
|
-
return omoSlimDetected;
|
|
19321
|
+
const isOmoSlimEnabled = () => {
|
|
19322
|
+
return configService.isOmoSlimEnabled();
|
|
18923
19323
|
};
|
|
18924
19324
|
const resolveFeature = (explicit) => {
|
|
18925
19325
|
if (explicit)
|
|
@@ -18987,7 +19387,40 @@ To unblock: Remove .hive/features/${feature}/BLOCKED`;
|
|
|
18987
19387
|
},
|
|
18988
19388
|
async execute({ name, ticket }) {
|
|
18989
19389
|
const feature = featureService.create(name, ticket);
|
|
18990
|
-
return `Feature "${name}" created.
|
|
19390
|
+
return `Feature "${name}" created.
|
|
19391
|
+
|
|
19392
|
+
## Discovery Phase Required
|
|
19393
|
+
|
|
19394
|
+
Before writing a plan, you MUST:
|
|
19395
|
+
1. Ask clarifying questions about the feature
|
|
19396
|
+
2. Document Q&A in plan.md with a \`## Discovery\` section
|
|
19397
|
+
3. Research the codebase (grep, read existing code)
|
|
19398
|
+
4. Save findings with hive_context_write
|
|
19399
|
+
|
|
19400
|
+
Example discovery section:
|
|
19401
|
+
\`\`\`markdown
|
|
19402
|
+
## Discovery
|
|
19403
|
+
|
|
19404
|
+
**Q: What authentication system do we use?**
|
|
19405
|
+
A: JWT with refresh tokens, see src/auth/
|
|
19406
|
+
|
|
19407
|
+
**Q: Should this work offline?**
|
|
19408
|
+
A: No, online-only is fine
|
|
19409
|
+
|
|
19410
|
+
**Research:**
|
|
19411
|
+
- Found existing theme system in src/theme/
|
|
19412
|
+
- Uses CSS variables pattern
|
|
19413
|
+
\`\`\`
|
|
19414
|
+
|
|
19415
|
+
## Planning Guidelines
|
|
19416
|
+
|
|
19417
|
+
When writing your plan, include:
|
|
19418
|
+
- \`## Non-Goals\` - What we're explicitly NOT building (scope boundaries)
|
|
19419
|
+
- \`## Ghost Diffs\` - Alternatives you considered but rejected
|
|
19420
|
+
|
|
19421
|
+
These prevent scope creep and re-proposing rejected solutions.
|
|
19422
|
+
|
|
19423
|
+
NEXT: Ask your first clarifying question about this feature.`;
|
|
18991
19424
|
}
|
|
18992
19425
|
}),
|
|
18993
19426
|
hive_feature_list: tool({
|
|
@@ -19017,6 +19450,34 @@ To unblock: Remove .hive/features/${feature}/BLOCKED`;
|
|
|
19017
19450
|
return `Feature "${feature}" marked as completed`;
|
|
19018
19451
|
}
|
|
19019
19452
|
}),
|
|
19453
|
+
hive_journal_append: tool({
|
|
19454
|
+
description: "Append entry to .hive/journal.md for audit trail",
|
|
19455
|
+
args: {
|
|
19456
|
+
feature: tool.schema.string().describe("Feature name for context"),
|
|
19457
|
+
trouble: tool.schema.string().describe("What went wrong"),
|
|
19458
|
+
resolution: tool.schema.string().describe("How it was fixed"),
|
|
19459
|
+
constraint: tool.schema.string().optional().describe("Never/Always rule derived")
|
|
19460
|
+
},
|
|
19461
|
+
async execute({ feature, trouble, resolution, constraint }) {
|
|
19462
|
+
const journalPath = path5.join(directory, ".hive", "journal.md");
|
|
19463
|
+
if (!fs6.existsSync(journalPath)) {
|
|
19464
|
+
return `Error: journal.md not found. Create a feature first to initialize the journal.`;
|
|
19465
|
+
}
|
|
19466
|
+
const date5 = new Date().toISOString().split("T")[0];
|
|
19467
|
+
const entry = `
|
|
19468
|
+
### ${date5}: ${feature}
|
|
19469
|
+
|
|
19470
|
+
**Trouble**: ${trouble}
|
|
19471
|
+
**Resolution**: ${resolution}
|
|
19472
|
+
${constraint ? `**Constraint**: ${constraint}` : ""}
|
|
19473
|
+
**See**: .hive/features/${feature}/plan.md
|
|
19474
|
+
|
|
19475
|
+
---
|
|
19476
|
+
`;
|
|
19477
|
+
fs6.appendFileSync(journalPath, entry);
|
|
19478
|
+
return `Journal entry added for ${feature}. ${constraint ? `Constraint: "${constraint}"` : ""}`;
|
|
19479
|
+
}
|
|
19480
|
+
}),
|
|
19020
19481
|
hive_plan_write: tool({
|
|
19021
19482
|
description: "Write plan.md (clears existing comments)",
|
|
19022
19483
|
args: {
|
|
@@ -19027,6 +19488,17 @@ To unblock: Remove .hive/features/${feature}/BLOCKED`;
|
|
|
19027
19488
|
const feature = resolveFeature(explicitFeature);
|
|
19028
19489
|
if (!feature)
|
|
19029
19490
|
return "Error: No feature specified. Create a feature or provide feature param.";
|
|
19491
|
+
const hasDiscovery = content.toLowerCase().includes("## discovery");
|
|
19492
|
+
if (!hasDiscovery) {
|
|
19493
|
+
return `BLOCKED: Discovery section required before planning.
|
|
19494
|
+
|
|
19495
|
+
Your plan must include a \`## Discovery\` section documenting:
|
|
19496
|
+
- Questions you asked and answers received
|
|
19497
|
+
- Research findings from codebase exploration
|
|
19498
|
+
- Key decisions made
|
|
19499
|
+
|
|
19500
|
+
Add this section to your plan content and try again.`;
|
|
19501
|
+
}
|
|
19030
19502
|
captureSession(feature, toolContext);
|
|
19031
19503
|
const planPath = planService.write(feature, content);
|
|
19032
19504
|
return `Plan written to ${planPath}. Comments cleared for fresh review.`;
|
|
@@ -19192,8 +19664,7 @@ ${priorTasks.join(`
|
|
|
19192
19664
|
`;
|
|
19193
19665
|
}
|
|
19194
19666
|
taskService.writeSpec(feature, task, specContent);
|
|
19195
|
-
|
|
19196
|
-
if (omoSlimDetected) {
|
|
19667
|
+
if (isOmoSlimEnabled()) {
|
|
19197
19668
|
const contextFiles = [];
|
|
19198
19669
|
const contextDir = path5.join(directory, ".hive", "features", feature, "context");
|
|
19199
19670
|
if (fs6.existsSync(contextDir)) {
|
|
@@ -19221,33 +19692,39 @@ ${priorTasks.join(`
|
|
|
19221
19692
|
} : undefined
|
|
19222
19693
|
});
|
|
19223
19694
|
const agent = selectAgent(taskInfo.name, specContent);
|
|
19224
|
-
|
|
19225
|
-
|
|
19226
|
-
|
|
19227
|
-
|
|
19228
|
-
|
|
19229
|
-
|
|
19230
|
-
|
|
19231
|
-
|
|
19232
|
-
|
|
19233
|
-
|
|
19234
|
-
|
|
19235
|
-
|
|
19236
|
-
|
|
19237
|
-
|
|
19238
|
-
|
|
19239
|
-
|
|
19240
|
-
|
|
19241
|
-
|
|
19242
|
-
|
|
19243
|
-
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
|
|
19249
|
-
|
|
19250
|
-
|
|
19695
|
+
return JSON.stringify({
|
|
19696
|
+
worktreePath: worktree.path,
|
|
19697
|
+
branch: worktree.branch,
|
|
19698
|
+
mode: "delegate",
|
|
19699
|
+
agent,
|
|
19700
|
+
delegationRequired: true,
|
|
19701
|
+
backgroundTaskCall: {
|
|
19702
|
+
agent,
|
|
19703
|
+
prompt: workerPrompt,
|
|
19704
|
+
description: `Hive: ${task}`,
|
|
19705
|
+
sync: false
|
|
19706
|
+
},
|
|
19707
|
+
instructions: `## Delegation Required
|
|
19708
|
+
|
|
19709
|
+
You MUST now call background_task to spawn a worker:
|
|
19710
|
+
|
|
19711
|
+
\`\`\`
|
|
19712
|
+
background_task({
|
|
19713
|
+
agent: "${agent}",
|
|
19714
|
+
prompt: <the workerPrompt below>,
|
|
19715
|
+
description: "Hive: ${task}",
|
|
19716
|
+
sync: false
|
|
19717
|
+
})
|
|
19718
|
+
\`\`\`
|
|
19719
|
+
|
|
19720
|
+
After spawning:
|
|
19721
|
+
- Monitor with hive_worker_status
|
|
19722
|
+
- Handle blockers when worker exits
|
|
19723
|
+
- Merge completed work with hive_merge
|
|
19724
|
+
|
|
19725
|
+
DO NOT do the work yourself. Delegate it.`,
|
|
19726
|
+
workerPrompt
|
|
19727
|
+
}, null, 2);
|
|
19251
19728
|
}
|
|
19252
19729
|
return `Worktree created at ${worktree.path}
|
|
19253
19730
|
Branch: ${worktree.branch}
|
|
@@ -19279,6 +19756,23 @@ Reminder: do all work inside this worktree and ensure any subagents do the same.
|
|
|
19279
19756
|
return `Error: Task "${task}" not found`;
|
|
19280
19757
|
if (taskInfo.status !== "in_progress" && taskInfo.status !== "blocked")
|
|
19281
19758
|
return "Error: Task not in progress";
|
|
19759
|
+
if (status === "completed") {
|
|
19760
|
+
const verificationKeywords = ["test", "build", "lint", "vitest", "jest", "npm run", "pnpm", "cargo", "pytest", "verified", "passes", "succeeds"];
|
|
19761
|
+
const summaryLower = summary.toLowerCase();
|
|
19762
|
+
const hasVerificationMention = verificationKeywords.some((kw) => summaryLower.includes(kw));
|
|
19763
|
+
if (!hasVerificationMention) {
|
|
19764
|
+
return `BLOCKED: No verification detected in summary.
|
|
19765
|
+
|
|
19766
|
+
Before claiming completion, you must:
|
|
19767
|
+
1. Run tests (vitest, jest, pytest, etc.)
|
|
19768
|
+
2. Run build (npm run build, cargo build, etc.)
|
|
19769
|
+
3. Include verification results in summary
|
|
19770
|
+
|
|
19771
|
+
Example summary: "Implemented auth flow. Tests pass (vitest). Build succeeds."
|
|
19772
|
+
|
|
19773
|
+
Re-run with updated summary showing verification results.`;
|
|
19774
|
+
}
|
|
19775
|
+
}
|
|
19282
19776
|
if (status === "blocked") {
|
|
19283
19777
|
taskService.update(feature, task, {
|
|
19284
19778
|
status: "blocked",
|
|
@@ -19385,9 +19879,10 @@ Use hive_merge to integrate changes. Worktree preserved at ${worktree?.path || "
|
|
|
19385
19879
|
summary: t.summary || null
|
|
19386
19880
|
};
|
|
19387
19881
|
}));
|
|
19882
|
+
const omoSlimEnabled = isOmoSlimEnabled();
|
|
19388
19883
|
return JSON.stringify({
|
|
19389
19884
|
feature,
|
|
19390
|
-
|
|
19885
|
+
omoSlimEnabled,
|
|
19391
19886
|
workers,
|
|
19392
19887
|
hint: workers.some((w) => w.status === "blocked") ? 'Use hive_exec_start(task, continueFrom: "blocked", decision: answer) to resume blocked workers' : workers.some((w) => w.maybeStuck) ? "Some workers may be stuck. Check tmux panes or abort with hive_exec_abort." : "Workers in progress. Watch tmux panes for live updates."
|
|
19393
19888
|
}, null, 2);
|
|
@@ -19673,8 +20168,8 @@ Make the requested changes, then call hive_request_review again.`;
|
|
|
19673
20168
|
break;
|
|
19674
20169
|
}
|
|
19675
20170
|
}
|
|
19676
|
-
if (featureContext ||
|
|
19677
|
-
return buildHiveAgentPrompt(featureContext,
|
|
20171
|
+
if (featureContext || isOmoSlimEnabled()) {
|
|
20172
|
+
return buildHiveAgentPrompt(featureContext, isOmoSlimEnabled());
|
|
19678
20173
|
}
|
|
19679
20174
|
return existingPrompt;
|
|
19680
20175
|
},
|