opencode-hive 1.1.0 → 1.2.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 CHANGED
@@ -12,7 +12,7 @@ var __export = (target, all) => {
12
12
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
13
13
 
14
14
  // src/index.ts
15
- import * as path7 from "path";
15
+ import * as path8 from "path";
16
16
  import * as os from "os";
17
17
 
18
18
  // ../../node_modules/zod/v4/classic/external.js
@@ -12336,8 +12336,260 @@ function tool(input) {
12336
12336
  }
12337
12337
  tool.schema = exports_external;
12338
12338
  // src/skills/registry.generated.ts
12339
- var BUILTIN_SKILL_NAMES = ["brainstorming", "code-reviewer", "dispatching-parallel-agents", "executing-plans", "onboarding", "parallel-exploration", "systematic-debugging", "test-driven-development", "verification-before-completion", "writing-plans"];
12339
+ var BUILTIN_SKILL_NAMES = ["agents-md-mastery", "brainstorming", "code-reviewer", "dispatching-parallel-agents", "docker-mastery", "executing-plans", "parallel-exploration", "systematic-debugging", "test-driven-development", "verification-before-completion", "writing-plans"];
12340
12340
  var BUILTIN_SKILLS = [
12341
+ {
12342
+ name: "agents-md-mastery",
12343
+ description: "Use when bootstrapping, updating, or reviewing AGENTS.md — teaches what makes effective agent memory, how to structure sections, signal vs noise filtering, and when to prune stale entries",
12344
+ template: `# AGENTS.md Mastery
12345
+
12346
+ ## Overview
12347
+
12348
+ **AGENTS.md is pseudo-memory loaded at session start.** Every line shapes agent behavior for the entire session. Quality beats quantity. Write for agents, not humans.
12349
+
12350
+ Unlike code comments or READMEs, AGENTS.md entries persist across all agent sessions. A bad entry misleads agents hundreds of times. A missing entry causes the same mistake repeatedly.
12351
+
12352
+ **Core principle:** Optimize for agent comprehension and behavioral change, not human readability.
12353
+
12354
+ ## The Iron Law
12355
+
12356
+ \`\`\`
12357
+ EVERY ENTRY MUST CHANGE AGENT BEHAVIOR
12358
+ \`\`\`
12359
+
12360
+ If an entry doesn't:
12361
+ - Prevent a specific mistake
12362
+ - Enable a capability the agent would otherwise miss
12363
+ - Override a default assumption that breaks in this codebase
12364
+
12365
+ ...then it doesn't belong in AGENTS.md.
12366
+
12367
+ **Test:** Would a fresh agent session make a mistake without this entry? If no → noise.
12368
+
12369
+ ## When to Use
12370
+
12371
+ | Trigger | Action |
12372
+ |---------|--------|
12373
+ | New project bootstrap | Write initial AGENTS.md with build/test/style basics |
12374
+ | Feature completion | Sync new learnings via \`hive_agents_md\` tool |
12375
+ | Periodic review | Audit for stale/redundant entries (quarterly) |
12376
+ | Quality issues | Agent repeating mistakes? Check if AGENTS.md has the fix |
12377
+
12378
+ ## What Makes Good Agent Memory
12379
+
12380
+ ### Signal Entries (Keep)
12381
+
12382
+ ✅ **Project-specific conventions:**
12383
+ - "We use Zustand, not Redux — never add Redux"
12384
+ - "Auth lives in \`/lib/auth\` — never create auth elsewhere"
12385
+ - "Run \`bun test\` not \`npm test\` (we don't use npm)"
12386
+
12387
+ ✅ **Non-obvious patterns:**
12388
+ - "Use \`.js\` extension for local imports (ESM requirement)"
12389
+ - "Worktrees don't share \`node_modules\` — run \`bun install\` in each"
12390
+ - "SandboxConfig is in \`dockerSandboxService.ts\`, NOT \`types.ts\`"
12391
+
12392
+ ✅ **Gotchas that break builds:**
12393
+ - "Never use \`ensureDirSync\` — doesn't exist. Use \`ensureDir\` (sync despite name)"
12394
+ - "Import from \`../utils/paths.js\` not \`./paths\` (ESM strict)"
12395
+
12396
+ ### Noise Entries (Remove)
12397
+
12398
+ ❌ **Agent already knows:**
12399
+ - "This project uses TypeScript" (agent detects from files)
12400
+ - "We follow semantic versioning" (universal convention)
12401
+ - "Use descriptive variable names" (generic advice)
12402
+
12403
+ ❌ **Irrelevant metadata:**
12404
+ - "Created on January 2024"
12405
+ - "Originally written by X"
12406
+ - "License: MIT" (in LICENSE file already)
12407
+
12408
+ ❌ **Describes what code does:**
12409
+ - "FeatureService manages features" (agent can read code)
12410
+ - "The system uses git worktrees" (observable from commands)
12411
+
12412
+ ### Rule of Thumb
12413
+
12414
+ **Signal:** Changes how agent acts
12415
+ **Noise:** Documents what agent observes
12416
+
12417
+ ## Section Structure for Fast Comprehension
12418
+
12419
+ Agents read AGENTS.md top-to-bottom once at session start. Put high-value info first:
12420
+
12421
+ \`\`\`markdown
12422
+ # Project Name
12423
+
12424
+ ## Build & Test Commands
12425
+ # ← Agents need this IMMEDIATELY
12426
+ bun run build
12427
+ bun run test
12428
+ bun run release:check
12429
+
12430
+ ## Code Style
12431
+ # ← Prevents syntax/import errors
12432
+ - Semicolons: Yes
12433
+ - Quotes: Single
12434
+ - Imports: Use \`.js\` extension
12435
+
12436
+ ## Architecture
12437
+ # ← Key directories, where things live
12438
+ packages/
12439
+ ├── hive-core/ # Shared logic
12440
+ ├── opencode-hive/ # Plugin
12441
+ └── vscode-hive/ # Extension
12442
+
12443
+ ## Important Patterns
12444
+ # ← How to do common tasks correctly
12445
+ Use \`readText\` from paths.ts, not fs.readFileSync
12446
+
12447
+ ## Gotchas & Anti-Patterns
12448
+ # ← Things that break or mislead
12449
+ NEVER use \`ensureDirSync\` — doesn't exist
12450
+ \`\`\`
12451
+
12452
+ **Keep total under 500 lines.** Beyond that, agents lose focus and miss critical entries.
12453
+
12454
+ ## The Sync Workflow
12455
+
12456
+ After completing a feature, sync learnings to AGENTS.md:
12457
+
12458
+ 1. **Trigger sync:**
12459
+ \`\`\`typescript
12460
+ hive_agents_md({ action: 'sync', feature: 'feature-name' })
12461
+ \`\`\`
12462
+
12463
+ 2. **Review each proposal:**
12464
+ - Read the proposed change
12465
+ - Ask: "Does this change agent behavior?"
12466
+ - Check: Is this already obvious from code/files?
12467
+
12468
+ 3. **Accept signal, reject noise:**
12469
+ - ❌ "TypeScript is used" → Agent detects this
12470
+ - ✅ "Use \`.js\` extension for imports" → Prevents build failures
12471
+
12472
+ 4. **Apply approved changes:**
12473
+ \`\`\`typescript
12474
+ hive_agents_md({ action: 'apply' })
12475
+ \`\`\`
12476
+
12477
+ **Warning:** Don't auto-approve all proposals. One bad entry pollutes all future sessions.
12478
+
12479
+ ## When to Prune
12480
+
12481
+ Remove entries when they become:
12482
+
12483
+ **Outdated:**
12484
+ - "We use Redux" → Project migrated to Zustand
12485
+ - "Node 16 compatibility required" → Now on Node 22
12486
+
12487
+ **Redundant:**
12488
+ - "Use single quotes" + "Strings use single quotes" → Keep one
12489
+ - Near-duplicates in different sections
12490
+
12491
+ **Too generic:**
12492
+ - "Write clear code" → Applies to any project
12493
+ - "Test your changes" → Universal advice
12494
+
12495
+ **Describing code:**
12496
+ - "TaskService manages tasks" → Agent can read \`TaskService\` class
12497
+ - "Worktrees are in \`.hive/.worktrees/\`" → Observable from filesystem
12498
+
12499
+ **Proven unnecessary:**
12500
+ - Entry added 6 months ago, but agents haven't hit that issue since
12501
+
12502
+ ## Red Flags
12503
+
12504
+ | Warning Sign | Why It's Bad | Fix |
12505
+ |-------------|-------------|-----|
12506
+ | AGENTS.md > 800 lines | Agents lose focus, miss critical info | Prune aggressively |
12507
+ | Describes what code does | Agent can read code | Remove descriptions |
12508
+ | Missing build/test commands | First thing agents need | Add at top |
12509
+ | No gotchas section | Agents repeat past mistakes | Document failure modes |
12510
+ | Generic best practices | Doesn't change behavior | Remove or make specific |
12511
+ | Outdated patterns | Misleads agents | Prune during sync |
12512
+
12513
+ ## Anti-Patterns
12514
+
12515
+ | Anti-Pattern | Better Approach |
12516
+ |-------------|----------------|
12517
+ | "Document everything" | Document only what changes behavior |
12518
+ | "Keep for historical record" | Version control is history |
12519
+ | "Might be useful someday" | Add when proven necessary |
12520
+ | "Explains the system" | Agents read code for that |
12521
+ | "Comprehensive reference" | AGENTS.md is a filter, not docs |
12522
+
12523
+ ## Good Examples
12524
+
12525
+ **Build Commands (High value, agents need immediately):**
12526
+ \`\`\`markdown
12527
+ ## Build & Test Commands
12528
+ bun run build # Build all packages
12529
+ bun run test # Run all tests
12530
+ bun run release:check # Full CI check
12531
+ \`\`\`
12532
+
12533
+ **Project-Specific Convention (Prevents mistakes):**
12534
+ \`\`\`markdown
12535
+ ## Code Style
12536
+ - Imports: Use \`.js\` extension for local imports (ESM requirement)
12537
+ - Paths: Import from \`../utils/paths.js\` never \`./paths\`
12538
+ \`\`\`
12539
+
12540
+ **Non-Obvious Gotcha (Prevents build failure):**
12541
+ \`\`\`markdown
12542
+ ## Important Patterns
12543
+ Use \`ensureDir\` from paths.ts — sync despite name
12544
+ NEVER use \`ensureDirSync\` (doesn't exist)
12545
+ \`\`\`
12546
+
12547
+ ## Bad Examples
12548
+
12549
+ **Generic advice (agent already knows):**
12550
+ \`\`\`markdown
12551
+ ## Best Practices
12552
+ - Use meaningful variable names
12553
+ - Write unit tests
12554
+ - Follow DRY principle
12555
+ \`\`\`
12556
+
12557
+ **Describes code (agent can read it):**
12558
+ \`\`\`markdown
12559
+ ## Architecture
12560
+ The FeatureService class manages features. It has methods
12561
+ for create, read, update, and delete operations.
12562
+ \`\`\`
12563
+
12564
+ **Irrelevant metadata:**
12565
+ \`\`\`markdown
12566
+ ## Project History
12567
+ Created in January 2024 by the platform team.
12568
+ Originally built for internal use.
12569
+ \`\`\`
12570
+
12571
+ ## Verification
12572
+
12573
+ Before finalizing AGENTS.md updates:
12574
+
12575
+ - [ ] Every entry answers: "What mistake does this prevent?"
12576
+ - [ ] No generic advice that applies to all projects
12577
+ - [ ] Build/test commands are first
12578
+ - [ ] Gotchas section exists and is populated
12579
+ - [ ] Total length under 500 lines (800 absolute max)
12580
+ - [ ] No entries describing what code does
12581
+ - [ ] Fresh agent session would benefit from each entry
12582
+
12583
+ ## Summary
12584
+
12585
+ AGENTS.md is **behavioral memory**, not documentation:
12586
+ - Write for agents, optimize for behavior change
12587
+ - Signal = prevents mistakes, Noise = describes observables
12588
+ - Sync after features, prune quarterly
12589
+ - Test: Would agent make a mistake without this entry?
12590
+
12591
+ **Quality > quantity. Every line counts.**`
12592
+ },
12341
12593
  {
12342
12594
  name: "brainstorming",
12343
12595
  description: "Use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.",
@@ -12795,6 +13047,351 @@ From debugging session (2025-10-03):
12795
13047
  - All investigations completed concurrently
12796
13048
  - All fixes integrated successfully
12797
13049
  - Zero conflicts between agent changes`
13050
+ },
13051
+ {
13052
+ name: "docker-mastery",
13053
+ description: "Use when working with Docker containers — debugging container failures, writing Dockerfiles, docker-compose for integration tests, image optimization, or deploying containerized applications",
13054
+ template: `# Docker Mastery
13055
+
13056
+ ## Overview
13057
+
13058
+ Docker is a **platform for building, shipping, and running applications**, not just isolation.
13059
+
13060
+ Agents should think in containers: reproducible environments, declarative dependencies, isolated execution.
13061
+
13062
+ **Core principle:** Containers are not virtual machines. They share the kernel but isolate processes, filesystems, and networks.
13063
+
13064
+ **Violating the letter of these guidelines is violating the spirit of containerization.**
13065
+
13066
+ ## The Iron Law
13067
+
13068
+ \`\`\`
13069
+ UNDERSTAND THE CONTAINER BEFORE DEBUGGING INSIDE IT
13070
+ \`\`\`
13071
+
13072
+ Before exec'ing into a container or adding debug commands:
13073
+ 1. Check the image (what's installed?)
13074
+ 2. Check mounts (what host files are visible?)
13075
+ 3. Check environment variables (what config is passed?)
13076
+ 4. Check the Dockerfile (how was it built?)
13077
+
13078
+ Random debugging inside containers wastes time. Context first, then debug.
13079
+
13080
+ ## When to Use
13081
+
13082
+ Use this skill when working with:
13083
+ - **Container build failures** - Dockerfile errors, missing dependencies
13084
+ - **Test environment setup** - Reproducible test environments across machines
13085
+ - **Integration test orchestration** - Multi-service setups (DB + API + tests)
13086
+ - **Dockerfile authoring** - Writing efficient, maintainable Dockerfiles
13087
+ - **Image size optimization** - Reducing image size, layer caching
13088
+ - **Deployment** - Containerized application deployment
13089
+ - **Sandbox debugging** - Issues with Hive's Docker sandbox mode
13090
+
13091
+ **Use this ESPECIALLY when:**
13092
+ - Tests pass locally but fail in CI (environment mismatch)
13093
+ - "Works on my machine" problems
13094
+ - Need to test against specific dependency versions
13095
+ - Multiple services must coordinate (database + API)
13096
+ - Building for production deployment
13097
+
13098
+ ## Core Concepts
13099
+
13100
+ ### Images vs Containers
13101
+
13102
+ - **Image**: Read-only template (built from Dockerfile)
13103
+ - **Container**: Running instance of an image (ephemeral by default)
13104
+
13105
+ \`\`\`bash
13106
+ # Build once
13107
+ docker build -t myapp:latest .
13108
+
13109
+ # Run many times
13110
+ docker run --rm myapp:latest
13111
+ docker run --rm -e DEBUG=true myapp:latest
13112
+ \`\`\`
13113
+
13114
+ **Key insight:** Changes inside containers are lost unless committed or volumes are used.
13115
+
13116
+ ### Volumes & Mounts
13117
+
13118
+ Mount host directories into containers for persistence and code sharing:
13119
+
13120
+ \`\`\`bash
13121
+ # Mount current directory to /app in container
13122
+ docker run -v $(pwd):/app myapp:latest
13123
+
13124
+ # Hive worktrees are mounted automatically
13125
+ # Your code edits (via Read/Write/Edit tools) affect the host
13126
+ # Container sees the same files at runtime
13127
+ \`\`\`
13128
+
13129
+ **How Hive uses this:** Worktree is mounted into container, so file tools work on host, bash commands run in container.
13130
+
13131
+ ### Multi-Stage Builds
13132
+
13133
+ Minimize image size by using multiple FROM statements:
13134
+
13135
+ \`\`\`dockerfile
13136
+ # Build stage (large, has compilers)
13137
+ FROM node:22 AS builder
13138
+ WORKDIR /app
13139
+ COPY package.json bun.lockb ./
13140
+ RUN bun install
13141
+ COPY . .
13142
+ RUN bun run build
13143
+
13144
+ # Runtime stage (small, production only)
13145
+ FROM node:22-slim
13146
+ WORKDIR /app
13147
+ COPY --from=builder /app/dist ./dist
13148
+ COPY --from=builder /app/node_modules ./node_modules
13149
+ CMD ["node", "dist/index.js"]
13150
+ \`\`\`
13151
+
13152
+ **Result:** Builder tools (TypeScript, bundlers) not included in final image.
13153
+
13154
+ ### Docker Compose for Multi-Service Setups
13155
+
13156
+ Define multiple services in \`docker-compose.yml\`:
13157
+
13158
+ \`\`\`yaml
13159
+ version: '3.8'
13160
+ services:
13161
+ db:
13162
+ image: postgres:15
13163
+ environment:
13164
+ POSTGRES_PASSWORD: testpass
13165
+ ports:
13166
+ - "5432:5432"
13167
+
13168
+ api:
13169
+ build: .
13170
+ environment:
13171
+ DATABASE_URL: postgres://db:5432/testdb
13172
+ depends_on:
13173
+ - db
13174
+ ports:
13175
+ - "3000:3000"
13176
+ \`\`\`
13177
+
13178
+ Run with: \`docker-compose up -d\`
13179
+ Teardown with: \`docker-compose down\`
13180
+
13181
+ ### Network Modes
13182
+
13183
+ - **bridge** (default): Isolated network, containers can talk to each other by name
13184
+ - **host**: Container uses host's network directly (no isolation)
13185
+ - **none**: No network access
13186
+
13187
+ **When to use host mode:** Debugging network issues, accessing host services directly.
13188
+
13189
+ ## Common Patterns
13190
+
13191
+ ### Debug a Failing Container
13192
+
13193
+ **Problem:** Container exits immediately, logs unclear.
13194
+
13195
+ **Pattern:**
13196
+ 1. Run interactively with shell:
13197
+ \`\`\`bash
13198
+ docker run -it --entrypoint sh myapp:latest
13199
+ \`\`\`
13200
+ 2. Inspect filesystem, check if dependencies exist:
13201
+ \`\`\`bash
13202
+ ls /app
13203
+ which node
13204
+ cat /etc/os-release
13205
+ \`\`\`
13206
+ 3. Run command manually to see full error:
13207
+ \`\`\`bash
13208
+ node dist/index.js
13209
+ \`\`\`
13210
+
13211
+ ### Integration Tests with Docker Compose
13212
+
13213
+ **Pattern:**
13214
+ 1. Define services in \`docker-compose.test.yml\`
13215
+ 2. Add wait logic (wait for DB to be ready)
13216
+ 3. Run tests
13217
+ 4. Teardown
13218
+
13219
+ \`\`\`yaml
13220
+ # docker-compose.test.yml
13221
+ services:
13222
+ db:
13223
+ image: postgres:15
13224
+ environment:
13225
+ POSTGRES_PASSWORD: test
13226
+ test:
13227
+ build: .
13228
+ command: bun run test:integration
13229
+ depends_on:
13230
+ - db
13231
+ environment:
13232
+ DATABASE_URL: postgres://postgres:test@db:5432/testdb
13233
+ \`\`\`
13234
+
13235
+ \`\`\`bash
13236
+ docker-compose -f docker-compose.test.yml up --abort-on-container-exit
13237
+ docker-compose -f docker-compose.test.yml down
13238
+ \`\`\`
13239
+
13240
+ ### Optimize Dockerfile
13241
+
13242
+ **Anti-pattern:**
13243
+ \`\`\`dockerfile
13244
+ FROM node:22
13245
+ WORKDIR /app
13246
+ COPY . . # Copies everything (including node_modules, .git)
13247
+ RUN bun install # Invalidates cache on any file change
13248
+ CMD ["bun", "run", "start"]
13249
+ \`\`\`
13250
+
13251
+ **Optimized:**
13252
+ \`\`\`dockerfile
13253
+ FROM node:22-slim # Use slim variant
13254
+ WORKDIR /app
13255
+
13256
+ # Copy dependency files first (cache layer)
13257
+ COPY package.json bun.lockb ./
13258
+ RUN bun install --production
13259
+
13260
+ # Copy source code (changes frequently)
13261
+ COPY src ./src
13262
+ COPY tsconfig.json ./
13263
+
13264
+ CMD ["bun", "run", "start"]
13265
+ \`\`\`
13266
+
13267
+ **Add \`.dockerignore\`:**
13268
+ \`\`\`
13269
+ node_modules
13270
+ .git
13271
+ .env
13272
+ *.log
13273
+ dist
13274
+ .DS_Store
13275
+ \`\`\`
13276
+
13277
+ ### Handle Missing Dependencies
13278
+
13279
+ **Problem:** Command fails with "not found" in container.
13280
+
13281
+ **Pattern:**
13282
+ 1. Check if dependency is in image:
13283
+ \`\`\`bash
13284
+ docker run -it myapp:latest which git
13285
+ \`\`\`
13286
+ 2. If missing, add to Dockerfile:
13287
+ \`\`\`dockerfile
13288
+ RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
13289
+ \`\`\`
13290
+ 3. Or use a richer base image (e.g., \`node:22\` instead of \`node:22-slim\`).
13291
+
13292
+ ## Hive Sandbox Integration
13293
+
13294
+ ### How Hive Wraps Commands
13295
+
13296
+ When sandbox mode is active (\`sandbox: 'docker'\` in config):
13297
+ 1. Hive hook intercepts bash commands before execution
13298
+ 2. Wraps with \`docker run --rm -v <worktree>:/workspace -w /workspace <image> sh -c "<command>"\`
13299
+ 3. Command runs in container, but file edits (Read/Write/Edit) still affect host
13300
+
13301
+ **Workers are unaware** — they issue normal bash commands, Hive handles containerization.
13302
+
13303
+ ### When Host Access is Needed
13304
+
13305
+ Some operations MUST run on host:
13306
+ - **Git operations** (commit, push, branch) — repo state is on host
13307
+ - **Host-level tools** (Docker itself, system config)
13308
+ - **Cross-worktree operations** (accessing main repo from worktree)
13309
+
13310
+ **Pattern:** Use \`HOST:\` prefix to escape sandbox:
13311
+ \`\`\`bash
13312
+ HOST: git status
13313
+ HOST: docker ps
13314
+ \`\`\`
13315
+
13316
+ **If you need host access frequently:** Report as blocked and ask user if sandbox should be disabled for this task.
13317
+
13318
+ ### Persistent vs Ephemeral Containers
13319
+
13320
+ **Current (v1.2.0):** Each command runs \`docker run --rm\` (ephemeral). State does NOT persist.
13321
+
13322
+ Example: \`npm install lodash\` in one command → not available in next command.
13323
+
13324
+ **Workaround:** Install dependencies in Dockerfile, not at runtime.
13325
+
13326
+ **Future:** \`docker exec\` will reuse containers, persisting state across commands.
13327
+
13328
+ ### Auto-Detected Images
13329
+
13330
+ Hive detects runtime from project files:
13331
+ - \`package.json\` → \`node:22-slim\`
13332
+ - \`requirements.txt\` / \`pyproject.toml\` → \`python:3.12-slim\`
13333
+ - \`go.mod\` → \`golang:1.22-slim\`
13334
+ - \`Cargo.toml\` → \`rust:1.77-slim\`
13335
+ - \`Dockerfile\` → Builds from project Dockerfile
13336
+ - Fallback → \`ubuntu:24.04\`
13337
+
13338
+ **Override:** Set \`dockerImage\` in config (\`~/.config/opencode/agent_hive.json\`).
13339
+
13340
+ ## Red Flags - STOP
13341
+
13342
+ If you catch yourself:
13343
+ - Installing packages on host instead of in Dockerfile
13344
+ - Running \`docker build\` without \`.dockerignore\` (cache invalidation)
13345
+ - Using \`latest\` tag in production (non-reproducible)
13346
+ - Ignoring container exit codes (hides failures)
13347
+ - Assuming state persists between \`docker run --rm\` commands
13348
+ - Using absolute host paths in Dockerfile (not portable)
13349
+ - Copying secrets into image layers (leaks credentials)
13350
+
13351
+ **ALL of these mean: STOP. Review pattern.**
13352
+
13353
+ ## Anti-Patterns
13354
+
13355
+ | Excuse | Reality |
13356
+ |--------|---------|
13357
+ | "I'll just run it on host" | Container mismatch bugs are worse to debug later. Build happens in container anyway. |
13358
+ | "Works in my container, don't need CI" | CI uses different cache state. Always test in CI-like environment. |
13359
+ | "I'll optimize the Dockerfile later" | Later never comes. Large images slow down deployments now. |
13360
+ | "latest tag is fine for dev" | Dev should match prod. Pin versions or face surprises. |
13361
+ | "Don't need .dockerignore, COPY is fast" | Invalidates cache on every file change. Wastes minutes per build. |
13362
+ | "Install at runtime, not in image" | Ephemeral containers lose state. Slows down every command. |
13363
+ | "Skip depends_on, services start fast" | Race conditions in integration tests. Use wait-for-it or health checks. |
13364
+
13365
+ ## Verification Before Completion
13366
+
13367
+ Before marking Docker work complete:
13368
+
13369
+ - [ ] Container runs successfully: \`docker run --rm <image> <command>\` exits 0
13370
+ - [ ] Tests pass inside container (not just on host)
13371
+ - [ ] No host pollution (dependencies installed in container, not host)
13372
+ - [ ] \`.dockerignore\` exists if using \`COPY . .\`
13373
+ - [ ] Image tags are pinned (not \`latest\`) for production
13374
+ - [ ] Multi-stage build used if applicable (separate build/runtime)
13375
+ - [ ] Integration tests teardown properly (\`docker-compose down\`)
13376
+
13377
+ **If any fail:** Don't claim success. Fix or report blocker.
13378
+
13379
+ ## Quick Reference
13380
+
13381
+ | Task | Command Pattern |
13382
+ |------|----------------|
13383
+ | **Debug container** | \`docker run -it --entrypoint sh <image>\` |
13384
+ | **Run with mounts** | \`docker run -v $(pwd):/app <image>\` |
13385
+ | **Multi-service tests** | \`docker-compose up --abort-on-container-exit\` |
13386
+ | **Check image contents** | \`docker run --rm <image> ls /app\` |
13387
+ | **Optimize build** | Add \`.dockerignore\`, use multi-stage, pin versions |
13388
+ | **Escape Hive sandbox** | Prefix with \`HOST:\` (e.g., \`HOST: git status\`) |
13389
+
13390
+ ## Related Skills
13391
+
13392
+ - **hive_skill:systematic-debugging** - When container behavior is unexpected
13393
+ - **hive_skill:test-driven-development** - Write tests that run in containers
13394
+ - **hive_skill:verification-before-completion** - Verify tests pass in container before claiming done`
12798
13395
  },
12799
13396
  {
12800
13397
  name: "executing-plans",
@@ -12857,8 +13454,8 @@ Based on feedback:
12857
13454
  ### Step 6: Complete Development
12858
13455
 
12859
13456
  After all tasks complete and verified:
12860
- - Announce: "I'm using the finishing-a-development-branch skill to complete this work."
12861
- - **REQUIRED SUB-SKILL:** Use hive_skill:finishing-a-development-branch
13457
+ - Announce: "I'm using the verification-before-completion skill to complete this work."
13458
+ - **REQUIRED SUB-SKILL:** Use hive_skill:verification-before-completion
12862
13459
  - Follow that skill to verify tests, present options, execute choice
12863
13460
 
12864
13461
  ## When to Stop and Ask for Help
@@ -12886,66 +13483,6 @@ After all tasks complete and verified:
12886
13483
  - Reference skills when plan says to
12887
13484
  - Between batches: just report and wait
12888
13485
  - Stop when blocked, don't guess`
12889
- },
12890
- {
12891
- name: "onboarding",
12892
- description: "Ask about workflow preferences and store them in .hive/contexts/preferences.md before proceeding.",
12893
- template: `# Onboarding Preferences
12894
-
12895
- ## Overview
12896
-
12897
- Gather workflow preferences so the assistant can match the user's desired working style.
12898
-
12899
- ## When to Ask
12900
-
12901
- - **Immediately when the skill is loaded**, before any other work.
12902
- - If \`.hive/contexts/preferences.md\` does not exist, start onboarding.
12903
- - If later a decision is ambiguous and preferences are missing, ask again.
12904
-
12905
- ## Preference Storage
12906
-
12907
- Use \`hive_context_write\` to write \`.hive/contexts/preferences.md\` with this exact template:
12908
-
12909
- \`\`\`
12910
- # Preferences
12911
-
12912
- ## Exploration Style
12913
- sync
12914
-
12915
- ## Research Depth
12916
- medium
12917
-
12918
- ## Confirmation Level
12919
- standard
12920
-
12921
- ## Commit Behavior
12922
- ask-before-commit
12923
- \`\`\`
12924
-
12925
- ## If Preferences Already Exist
12926
-
12927
- Follow the same pattern used in \`packages/vscode-hive/src/tools/plan.ts\`:
12928
-
12929
- 1. Use \`contextService.list(feature)\` to detect existing contexts.
12930
- 2. Ask **"Preferences already exist. Keep or overwrite?"** using the \`question()\` tool.
12931
- 3. If keep → continue using existing preferences.
12932
- 4. If overwrite → collect new answers and write them with \`hive_context_write\`.
12933
-
12934
- ## Questions to Ask (Always use \`question()\`)
12935
-
12936
- Ask one at a time, with the provided options. Store the answers in \`.hive/contexts/preferences.md\`.
12937
-
12938
- 1. **Exploration Style:** sync | async
12939
- 2. **Research Depth:** shallow | medium | deep
12940
- 3. **Confirmation Level:** minimal | standard | high
12941
- 4. **Commit Behavior:** ask-before-commit | auto-commit | never-commit
12942
-
12943
- ## Requirements
12944
-
12945
- - Use the \`question()\` tool (no plain text questions).
12946
- - Ask immediately when the skill loads if preferences are missing.
12947
- - If later a decision is ambiguous and preferences are missing, ask again.
12948
- - Always store answers using \`hive_context_write\` with the template above.`
12949
13486
  },
12950
13487
  {
12951
13488
  name: "parallel-exploration",
@@ -13837,7 +14374,7 @@ Never fix bugs without a test.
13837
14374
 
13838
14375
  ## Testing Anti-Patterns
13839
14376
 
13840
- When adding mocks or test utilities, read @testing-anti-patterns.md to avoid common pitfalls:
14377
+ When adding mocks or test utilities, avoid common pitfalls:
13841
14378
  - Testing mock behavior instead of real behavior
13842
14379
  - Adding test-only methods to production classes
13843
14380
  - Mocking without understanding dependencies
@@ -14100,6 +14637,12 @@ Always include **Depends on** for each task. Use \`none\` to enable parallel sta
14100
14637
  **Verify**:
14101
14638
  - [ ] Run: \`{command}\` → {expected}
14102
14639
  - [ ] {Additional acceptance criteria}
14640
+
14641
+ All verification MUST be agent-executable (no human intervention):
14642
+ ✅ \`bun test\` → all pass
14643
+ ✅ \`curl -X POST /api/x\` → 201
14644
+ ❌ "User manually tests..."
14645
+ ❌ "Visually confirm..."
14103
14646
  \`\`\`\`
14104
14647
 
14105
14648
  ## Remember
@@ -14108,6 +14651,7 @@ Always include **Depends on** for each task. Use \`none\` to enable parallel sta
14108
14651
  - Exact commands with expected output
14109
14652
  - Reference relevant skills with @ syntax
14110
14653
  - DRY, YAGNI, TDD, frequent commits
14654
+ - All acceptance criteria must be agent-executable (zero human intervention)
14111
14655
 
14112
14656
  ## Execution Handoff
14113
14657
 
@@ -14317,6 +14861,19 @@ Before major transitions, verify:
14317
14861
  - [ ] Scope defined?
14318
14862
  - [ ] No critical ambiguities?
14319
14863
 
14864
+ ### Turn Termination
14865
+
14866
+ Valid endings:
14867
+ - Ask a concrete question
14868
+ - Update draft + ask a concrete question
14869
+ - Explicitly state you are waiting on background work (tool/task)
14870
+ - Auto-transition to the next required action
14871
+
14872
+ NEVER end with:
14873
+ - "Let me know if you have questions"
14874
+ - Summary without a follow-up action
14875
+ - "When you're ready..."
14876
+
14320
14877
  ### Loading Skills (On-Demand)
14321
14878
 
14322
14879
  Load when detailed guidance needed:
@@ -14325,6 +14882,11 @@ Load when detailed guidance needed:
14325
14882
  - \`hive_skill("dispatching-parallel-agents")\` - parallel task delegation
14326
14883
  - \`hive_skill("parallel-exploration")\` - parallel read-only research via task() (Scout fan-out)
14327
14884
  - \`hive_skill("executing-plans")\` - step-by-step plan execution
14885
+ - \`hive_skill("systematic-debugging")\` - encountering bugs, test failures, or unexpected behavior
14886
+ - \`hive_skill("test-driven-development")\` - implementing features with TDD approach
14887
+ - \`hive_skill("verification-before-completion")\` - before claiming work is complete or creating PRs
14888
+ - \`hive_skill("docker-mastery")\` - working with Docker containers, debugging, docker-compose
14889
+ - \`hive_skill("agents-md-mastery")\` - bootstrapping/updating AGENTS.md, quality review
14328
14890
 
14329
14891
  Load ONE skill at a time. Only when you need guidance beyond this prompt.
14330
14892
 
@@ -14445,6 +15007,17 @@ After completing and merging a batch:
14445
15007
  2. If yes, run \`task({ subagent_type: "hygienic", prompt: "Review implementation changes from the latest batch." })\`.
14446
15008
  3. Apply feedback before starting the next batch.
14447
15009
 
15010
+ ### AGENTS.md Maintenance
15011
+
15012
+ After feature completion (all tasks merged):
15013
+ 1. Sync context findings to AGENTS.md: \`hive_agents_md({ action: "sync", feature: "feature-name" })\`
15014
+ 2. Review the proposed diff with the user
15015
+ 3. Apply approved changes to keep AGENTS.md current
15016
+
15017
+ For projects without AGENTS.md:
15018
+ - Bootstrap with \`hive_agents_md({ action: "init" })\`
15019
+ - Generates initial documentation from codebase analysis
15020
+
14448
15021
  ### Orchestration Iron Laws
14449
15022
 
14450
15023
  - Delegate by default
@@ -14462,11 +15035,19 @@ After completing and merging a batch:
14462
15035
  - Ask user before consulting Hygienic (Consultant/Reviewer/Debugger)
14463
15036
  - Load skills on-demand, one at a time
14464
15037
 
14465
- **Never:**
15038
+ ### Hard Blocks
15039
+
15040
+ NEVER violate:
14466
15041
  - Skip phase detection
14467
15042
  - Mix planning and orchestration in same action
14468
15043
  - Auto-load all skills at start
14469
15044
 
15045
+ ### Anti-Patterns
15046
+
15047
+ BLOCKING violations:
15048
+ - Ending a turn without a next action
15049
+ - Asking for user input in plain text instead of question()
15050
+
14470
15051
  **User Input:** ALWAYS use \`question()\` tool for any user input - NEVER ask questions via plain text. This ensures structured responses.
14471
15052
  `;
14472
15053
 
@@ -14477,25 +15058,38 @@ PLANNER, NOT IMPLEMENTER. "Do X" means "create plan for X".
14477
15058
 
14478
15059
  ## Intent Classification (First)
14479
15060
 
14480
- | Intent | Signals | Action |
14481
- |--------|---------|--------|
14482
- | Trivial | Single file, <10 lines | Do directly. No plan needed. |
14483
- | Simple | 1-2 files, <30 min | Light interview → quick plan |
14484
- | Complex | 3+ files, review needed | Full discovery → detailed plan |
14485
- | Refactor | Existing code changes | Safety: tests, rollback, blast radius |
14486
- | Greenfield | New feature | Research patterns BEFORE asking. Delegate to Scout via \`task({ subagent_type: "scout-researcher", prompt: "..." })\` for single investigations. |
15061
+ | Intent | Signals | Strategy | Action |
15062
+ |--------|---------|----------|--------|
15063
+ | Trivial | Single file, <10 lines | N/A | Do directly. No plan needed. |
15064
+ | Simple | 1-2 files, <30 min | Quick assessment | Light interview → quick plan |
15065
+ | Complex | 3+ files, review needed | Full discovery | Full discovery → detailed plan |
15066
+ | Refactor | Existing code changes | Safety-first: behavior preservation | Tests → blast radius → plan |
15067
+ | Greenfield | New feature | Discovery-first: explore before asking | Research interview plan |
15068
+ | Architecture | Cross-cutting, multi-system | Strategic: consult Scout | Deep research → plan |
14487
15069
 
14488
15070
  During Planning, use \`task({ subagent_type: "scout-researcher", ... })\` for exploration (BLOCKING — returns when done). For parallel exploration, issue multiple \`task()\` calls in the same message.
14489
15071
 
14490
15072
  ## Self-Clearance Check (After Every Exchange)
14491
15073
 
14492
- □ Core objective clear?
14493
- □ Scope defined (IN/OUT)?
14494
- □ No critical ambiguities?
14495
- Approach decided?
15074
+ □ Core objective clearly defined?
15075
+ □ Scope boundaries established (IN/OUT)?
15076
+ □ No critical ambiguities remaining?
15077
+ Technical approach decided?
15078
+ □ Test strategy confirmed (TDD/tests-after/none)?
15079
+ □ No blocking questions outstanding?
15080
+
15081
+ ALL YES → Announce "Requirements clear. Generating plan." → Write plan
15082
+ ANY NO → Ask the specific unclear thing
15083
+
15084
+ ## Test Strategy (Ask Before Planning)
14496
15085
 
14497
- ALL YES Write plan
14498
- ANY NO Ask the unclear thing
15086
+ For Build and Refactor intents, ASK:
15087
+ "Should this include automated tests?"
15088
+ - TDD: Red-Green-Refactor per task
15089
+ - Tests after: Add test tasks after implementation
15090
+ - None: No unit/integration tests
15091
+
15092
+ Record decision in draft. Embed in plan tasks.
14499
15093
 
14500
15094
  ## AI-Slop Flags
14501
15095
 
@@ -14515,6 +15109,18 @@ ANY NO → Ask the unclear thing
14515
15109
  | MINOR | FIX silently, note in summary |
14516
15110
  | AMBIGUOUS | Apply default, DISCLOSE in summary |
14517
15111
 
15112
+ ## Turn Termination
15113
+
15114
+ Valid endings:
15115
+ - Question to user (via question() tool)
15116
+ - Draft update + next question
15117
+ - Auto-transition to plan generation
15118
+
15119
+ NEVER end with:
15120
+ - "Let me know if you have questions"
15121
+ - Summary without follow-up action
15122
+ - "When you're ready..."
15123
+
14518
15124
  ## Draft as Working Memory
14519
15125
 
14520
15126
  Create draft on first exchange. Update after EVERY user response:
@@ -14631,11 +15237,13 @@ hive_worktree_create({ task: "01-task-name" })
14631
15237
  - Call \`hive_status()\` immediately after to check new state and find next runnable tasks
14632
15238
  - For parallel fan-out, issue multiple \`task()\` calls in the same message
14633
15239
 
14634
- ## After Delegation - ALWAYS VERIFY
15240
+ ## After Delegation - VERIFY
14635
15241
 
15242
+ After every delegation, check:
14636
15243
  - Does it work as expected?
14637
- - Followed existing codebase pattern?
14638
- - Followed MUST DO and MUST NOT DO?
15244
+ - Followed existing codebase patterns?
15245
+ - Met MUST DO and MUST NOT DO requirements?
15246
+ - No unintended side effects?
14639
15247
 
14640
15248
  ## Blocker Handling
14641
15249
 
@@ -14649,8 +15257,7 @@ When worker reports blocked:
14649
15257
  1. STOP all further edits
14650
15258
  2. REVERT to last known working state
14651
15259
  3. DOCUMENT what was attempted
14652
- 4. Consult: \`task({ subagent_type: "oracle", prompt: "Analyze..." })\`
14653
- 5. If Oracle cannot resolve → ASK USER
15260
+ 4. ASK USER via question() present options and context
14654
15261
 
14655
15262
  ## Merge Strategy
14656
15263
 
@@ -14660,13 +15267,39 @@ hive_merge({ task: "01-task-name", strategy: "merge" })
14660
15267
 
14661
15268
  Merge only after verification passes.
14662
15269
 
14663
- ## Post-Batch Review (Hygienic)
15270
+ ### Post-Batch Review (Hygienic)
14664
15271
 
14665
15272
  After completing and merging a batch:
14666
15273
  1. Ask the user via \`question()\` if they want a Hygienic code review for the batch.
14667
15274
  2. If yes, run \`task({ subagent_type: "hygienic", prompt: "Review implementation changes from the latest batch." })\`.
14668
15275
  3. Apply feedback before starting the next batch.
14669
15276
 
15277
+ ### AGENTS.md Maintenance
15278
+
15279
+ After completing and merging a batch:
15280
+ 1. Sync context findings to AGENTS.md: \`hive_agents_md({ action: "sync", feature: "feature-name" })\`
15281
+ 2. Review the proposed diff with the user
15282
+ 3. Apply approved changes to keep AGENTS.md current
15283
+
15284
+ For quality review of AGENTS.md content, load \`hive_skill("agents-md-mastery")\`.
15285
+
15286
+ For projects without AGENTS.md:
15287
+ - Bootstrap with \`hive_agents_md({ action: "init" })\`
15288
+ - Generates initial documentation from codebase analysis
15289
+
15290
+ ## Turn Termination
15291
+
15292
+ Valid endings:
15293
+ - Worker delegation (hive_worktree_create)
15294
+ - Status check (hive_status)
15295
+ - User question (question())
15296
+ - Merge (hive_merge)
15297
+
15298
+ NEVER end with:
15299
+ - "Let me know when you're ready"
15300
+ - Summary without next action
15301
+ - Waiting for something unspecified
15302
+
14670
15303
  ## Iron Laws
14671
15304
 
14672
15305
  **Never:**
@@ -14778,84 +15411,12 @@ When asked to retrieve raw data from external systems (MongoDB/Stripe/etc.):
14778
15411
 
14779
15412
  ## Persistence
14780
15413
 
14781
- When operating within a feature context (background task with feature parameter):
14782
- - If findings are substantial (3+ files discovered, architecture patterns, or key decisions):
14783
- Use \`hive_context_write\` to persist findings:
15414
+ When operating within a feature context:
15415
+ - If findings are substantial (3+ files, architecture patterns, or key decisions):
14784
15416
  \`\`\`
14785
15417
  hive_context_write({
14786
- name: "research-{topic-slug}",
14787
- content: "## Research: {Topic}
14788
-
14789
- Date: {date}
14790
-
14791
- ## Context
14792
-
14793
- ## research-findings
14794
-
14795
- # Research Findings for Hive Improvements v2
14796
-
14797
- ## Worker Prompt Builder (\`worker-prompt.ts:48\`)
14798
- - \`buildWorkerPrompt(params: WorkerPromptParams): string\`
14799
- - Receives: feature, task, taskOrder, worktreePath, branch, plan, contextFiles, spec, previousTasks, continueFrom
14800
- - Only uses: feature, task, taskOrder, worktreePath, branch, spec, continueFrom
14801
- - plan/contextFiles/previousTasks passed but NOT used (already embedded in spec)
14802
- - 10 sections: Assignment, Continuation(optional), Mission(=spec), Blocker Protocol, Completion Protocol, TDD, Debugging, Tools, Guidelines, User Input
14803
- - **ZERO task-type awareness** — all workers get identical protocols
14804
- - Budget: 100KB soft limit (advisory, not enforced)
14805
-
14806
- ## Task Completion Flow (\`index.ts:974-1088\`)
14807
- - \`hive_exec_complete\` accepts: task, summary (string), status (completed|blocked|failed|partial), blocker (optional)
14808
- - Summary stored in: status.json, report.md, commit message (first 50 chars)
14809
- - **Summary is free-form string** — no structure enforced
14810
- - Completed summaries collected for next task: \`allTasks.filter(t => t.status === 'done' && t.summary)\`
14811
- - Injected into spec as \`## Completed Tasks\` → \`- taskName: summary\`
14812
-
14813
- ## TaskService (\`taskService.ts\`)
14814
- - \`buildSpecContent()\` (lines 168-225): builds spec with Dependencies, Plan Section, Context, Completed Tasks
14815
- - \`parseTasksFromPlan()\` (lines 532-602): regex \`/^###\\s+(\\d+)\\.\\s+(.+)$/\` for task headers
14816
- - \`resolveDependencies()\` (lines 248-268): explicit deps or implicit sequential (N depends on N-1)
14817
- - Types: TaskStatus has \`summary?: string\`, TaskInfo has \`summary?: string\`
14818
-
14819
- ## Forager Agent (\`forager.ts:8-117\`)
14820
- - Execution flow: Understand → Implement → Verify → Report
14821
- - **NO orient/pre-flight phase** — jumps straight to understanding task spec
14822
- - Can read codebase, use research tools (grep_app, context7, ast_grep)
14823
- - Cannot: delegate (task/hive_exec_start), modify plan, use hive_merge
14824
- - Notepads: \`.hive/features/{feature}/notepads/{learnings,issues,decisions}.md\` (append-only)
14825
-
14826
- ## Hygienic Agent (\`hygienic.ts:8-105\`)
14827
- - Reviews plan DOCUMENTATION quality, not design
14828
- - 4 criteria: Clarity, Verifiability, Completeness, Big Picture
14829
- - Verdict: OKAY or REJECT with 4-category assessment
14830
- - When asked to review implementation → loads \`hive_skill("code-reviewer")\`
14831
- - **Currently only invoked for plan review** (from Hive and Architect agents)
14832
- - Cannot delegate/spawn workers
14833
-
14834
- ## Scout Agent (\`scout.ts:8-112\`)
14835
- - Read-only research agent
14836
- - Classifies requests: CONCEPTUAL, IMPLEMENTATION, CODEBASE, COMPREHENSIVE
14837
- - Output format: \`<results><files>...<answer>...<next_steps>...</results>\`
14838
- - **Does NOT persist findings** — returns to orchestrator only
14839
- - Parallel execution by default (3+ tools simultaneously)
14840
-
14841
- ## Code-Reviewer Skill (\`skills/code-reviewer/SKILL.md\`)
14842
- - Loaded by Hygienic when reviewing implementation
14843
- - Output: APPROVE | REQUEST_CHANGES | NEEDS_DISCUSSION
14844
- - Reviews: plan adherence, correctness, simplicity/YAGNI, risk
14845
- - Already exists but underused (Hygienic only loads it when explicitly asked)
14846
-
14847
- ## Plan Format
14848
- - Headers: \`### N. Task Name\`
14849
- - Sections: Depends on, What to do, Must NOT do, References (file:lines), Acceptance Criteria
14850
- - Dependencies: \`none\` | \`1\` | \`1,3\` | implicit sequential
14851
-
14852
- ## Skills (10 total)
14853
- writing-plans, executing-plans, dispatching-parallel-agents, parallel-exploration, code-reviewer, onboarding, brainstorming, verification-before-completion, test-driven-development, systematic-debugging
14854
-
14855
- ## Notepad System
14856
- - Location: \`.hive/features/{feature}/notepads/{learnings,issues,decisions}.md\`
14857
- - Workers append-only
14858
- - **NOT automatically injected into next batch** — context injection only reads from \`contexts/\` directory"
15418
+ name: "research-{topic}",
15419
+ content: "## {Topic}\\n\\nDate: {YYYY-MM-DD}\\n\\n## Context\\n\\n## Findings"
14859
15420
  })
14860
15421
  \`\`\`
14861
15422
 
@@ -14895,6 +15456,20 @@ CAN use for quick lookups:
14895
15456
  - \`ast_grep_search\` — AST patterns
14896
15457
  - \`glob\`, \`grep\`, \`read\` — Codebase exploration
14897
15458
 
15459
+ ## Resolve Before Blocking
15460
+
15461
+ Default to exploration, questions are LAST resort:
15462
+ 1. Read the referenced files and surrounding code
15463
+ 2. Search for similar patterns in the codebase
15464
+ 3. Try a reasonable approach based on conventions
15465
+
15466
+ Only report as blocked when:
15467
+ - Multiple approaches failed (tried 3+)
15468
+ - Decision requires business logic you can't infer
15469
+ - External dependency is missing or broken
15470
+
15471
+ Context inference: Before asking "what does X do?", READ X first.
15472
+
14898
15473
  ## Plan = READ ONLY
14899
15474
 
14900
15475
  CRITICAL: NEVER MODIFY THE PLAN FILE
@@ -14919,8 +15494,11 @@ Read spec for:
14919
15494
  ### 2. Orient (Pre-flight Before Coding)
14920
15495
  Before writing code:
14921
15496
  - Confirm dependencies are satisfied and required context is present
15497
+ - Read the referenced files and surrounding code
15498
+ - Search for similar patterns in the codebase
14922
15499
  - Identify the exact files/sections to touch (from references)
14923
15500
  - Decide the first failing test you will write (TDD)
15501
+ - Identify the test command(s) and inputs you will run
14924
15502
  - Plan the minimum change to reach green
14925
15503
 
14926
15504
  ### 3. Implement
@@ -14966,6 +15544,16 @@ hive_worktree_commit({
14966
15544
  })
14967
15545
  \`\`\`
14968
15546
 
15547
+ ## Completion Checklist
15548
+
15549
+ Before calling hive_worktree_commit:
15550
+ - All tests in scope are run and passing (Record exact commands and results)
15551
+ - Build succeeds if required (Record exact command and result)
15552
+ - lsp_diagnostics clean on changed files (Record exact command and result)
15553
+ - Changes match the spec and references
15554
+ - No extra scope creep or unrelated edits
15555
+ - Summary includes what changed, why, and verification status
15556
+
14969
15557
  ## Failure Recovery
14970
15558
 
14971
15559
  After 3 consecutive failures:
@@ -14975,6 +15563,15 @@ After 3 consecutive failures:
14975
15563
 
14976
15564
  ## Iron Laws
14977
15565
 
15566
+ ### Docker Sandbox
15567
+
15568
+ When sandbox mode is active, ALL bash commands automatically run inside a Docker container.
15569
+ - Your commands are transparently wrapped — you don't need to do anything special
15570
+ - File edits (Read, Write, Edit tools) still work on the host filesystem (worktree is mounted)
15571
+ - If a command must run on the host (e.g., git operations), report as blocked and ask the user
15572
+ - If a command fails with "docker: command not found", report as blocked — the host needs Docker installed
15573
+ - For deeper Docker expertise, load \`hive_skill("docker-mastery")\`
15574
+
14978
15575
  **Never:**
14979
15576
  - Exceed task scope
14980
15577
  - Modify plan file
@@ -15017,7 +15614,10 @@ Self-check before every critique:
15017
15614
 
15018
15615
  ### 2. Verification & Acceptance Criteria
15019
15616
  - Are criteria measurable and concrete?
15020
- - Red flags: "should work", "looks good", "properly handles"
15617
+ - Are they agent-executable (tool-runnable) without human judgment?
15618
+ - Do they specify exact commands + expected signals (exit code, output text, counts)?
15619
+ - Red flags: "should work", "looks good", "properly handles", "verify manually"
15620
+ - If manual checks are required, the plan must explain why automation is impossible
15021
15621
 
15022
15622
  ### 3. Context Completeness (90% Confidence)
15023
15623
  - Could a capable worker execute with 90% confidence?
@@ -15149,6 +15749,11 @@ import * as fs8 from "fs";
15149
15749
  import * as path4 from "path";
15150
15750
  import * as fs10 from "fs";
15151
15751
  import * as path6 from "path";
15752
+ import * as fs11 from "fs";
15753
+ import * as path7 from "path";
15754
+ import { existsSync as existsSync5 } from "fs";
15755
+ import { join as join8, sep } from "path";
15756
+ import { execSync } from "child_process";
15152
15757
  var __create = Object.create;
15153
15758
  var __getProtoOf = Object.getPrototypeOf;
15154
15759
  var __defProp2 = Object.defineProperty;
@@ -15986,6 +16591,7 @@ var DEFAULT_HIVE_CONFIG = {
15986
16591
  disableSkills: [],
15987
16592
  disableMcps: [],
15988
16593
  agentMode: "unified",
16594
+ sandbox: "none",
15989
16595
  agents: {
15990
16596
  "hive-master": {
15991
16597
  model: DEFAULT_AGENT_MODELS["hive-master"],
@@ -21465,6 +22071,12 @@ class ContextService {
21465
22071
  ensureDir(contextPath);
21466
22072
  const filePath = path4.join(contextPath, this.normalizeFileName(fileName));
21467
22073
  writeText(filePath, content);
22074
+ const totalChars = this.list(featureName).reduce((sum, c) => sum + c.content.length, 0);
22075
+ if (totalChars > 20000) {
22076
+ return `${filePath}
22077
+
22078
+ ⚠️ Context total: ${totalChars} chars (exceeds 20,000). Consider archiving older contexts with contextService.archive().`;
22079
+ }
21468
22080
  return filePath;
21469
22081
  }
21470
22082
  read(featureName, fileName) {
@@ -21510,6 +22122,37 @@ ${f.content}`);
21510
22122
 
21511
22123
  `);
21512
22124
  }
22125
+ archive(featureName) {
22126
+ const contexts = this.list(featureName);
22127
+ if (contexts.length === 0)
22128
+ return { archived: [], archivePath: "" };
22129
+ const contextPath = getContextPath(this.projectRoot, featureName);
22130
+ const archiveDir = path4.join(contextPath, "..", "archive");
22131
+ ensureDir(archiveDir);
22132
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
22133
+ const archived = [];
22134
+ for (const ctx of contexts) {
22135
+ const archiveName = `${timestamp}_${ctx.name}.md`;
22136
+ const src = path4.join(contextPath, `${ctx.name}.md`);
22137
+ const dest = path4.join(archiveDir, archiveName);
22138
+ fs8.copyFileSync(src, dest);
22139
+ fs8.unlinkSync(src);
22140
+ archived.push(ctx.name);
22141
+ }
22142
+ return { archived, archivePath: archiveDir };
22143
+ }
22144
+ stats(featureName) {
22145
+ const contexts = this.list(featureName);
22146
+ if (contexts.length === 0)
22147
+ return { count: 0, totalChars: 0 };
22148
+ const sorted2 = [...contexts].sort((a, b) => new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime());
22149
+ return {
22150
+ count: contexts.length,
22151
+ totalChars: contexts.reduce((sum, c) => sum + c.content.length, 0),
22152
+ oldest: sorted2[0].name,
22153
+ newest: sorted2[sorted2.length - 1].name
22154
+ };
22155
+ }
21513
22156
  normalizeFileName(name) {
21514
22157
  const normalized = name.replace(/\.md$/, "");
21515
22158
  return `${normalized}.md`;
@@ -21623,6 +22266,304 @@ class ConfigService {
21623
22266
  const config2 = this.get();
21624
22267
  return config2.disableMcps ?? [];
21625
22268
  }
22269
+ getSandboxConfig() {
22270
+ const config2 = this.get();
22271
+ const mode = config2.sandbox ?? "none";
22272
+ const image = config2.dockerImage;
22273
+ const persistent = config2.persistentContainers ?? mode === "docker";
22274
+ return { mode, ...image && { image }, persistent };
22275
+ }
22276
+ }
22277
+
22278
+ class AgentsMdService {
22279
+ rootDir;
22280
+ contextService;
22281
+ constructor(rootDir, contextService) {
22282
+ this.rootDir = rootDir;
22283
+ this.contextService = contextService;
22284
+ }
22285
+ async init() {
22286
+ const agentsMdPath = path7.join(this.rootDir, "AGENTS.md");
22287
+ const existed = fileExists(agentsMdPath);
22288
+ if (existed) {
22289
+ const existing = readText(agentsMdPath);
22290
+ return { content: existing || "", existed: true };
22291
+ }
22292
+ const content = await this.scanAndGenerate();
22293
+ return { content, existed: false };
22294
+ }
22295
+ async sync(featureName) {
22296
+ const contexts = this.contextService.list(featureName);
22297
+ const agentsMdPath = path7.join(this.rootDir, "AGENTS.md");
22298
+ const current = await fs11.promises.readFile(agentsMdPath, "utf-8").catch(() => "");
22299
+ const findings = this.extractFindings(contexts);
22300
+ const proposals = this.generateProposals(findings, current);
22301
+ return { proposals, diff: this.formatDiff(current, proposals) };
22302
+ }
22303
+ apply(content) {
22304
+ const agentsMdPath = path7.join(this.rootDir, "AGENTS.md");
22305
+ const isNew = !fileExists(agentsMdPath);
22306
+ writeText(agentsMdPath, content);
22307
+ return { path: agentsMdPath, chars: content.length, isNew };
22308
+ }
22309
+ extractFindings(contexts) {
22310
+ const findings = [];
22311
+ const patterns = [
22312
+ /we\s+use\s+[^.\n]+/gi,
22313
+ /prefer\s+[^.\n]+\s+over\s+[^.\n]+/gi,
22314
+ /don't\s+use\s+[^.\n]+/gi,
22315
+ /do\s+not\s+use\s+[^.\n]+/gi,
22316
+ /(?:build|test|dev)\s+command:\s*[^.\n]+/gi,
22317
+ /[a-zA-Z]+\s+lives?\s+in\s+\/[^\s.\n]+/gi
22318
+ ];
22319
+ for (const context of contexts) {
22320
+ const lines = context.content.split(`
22321
+ `);
22322
+ for (const line of lines) {
22323
+ const trimmed2 = line.trim();
22324
+ if (!trimmed2 || trimmed2.startsWith("#"))
22325
+ continue;
22326
+ for (const pattern of patterns) {
22327
+ const matches = trimmed2.match(pattern);
22328
+ if (matches) {
22329
+ for (const match of matches) {
22330
+ const finding = match.trim();
22331
+ if (finding && !findings.includes(finding)) {
22332
+ findings.push(finding);
22333
+ }
22334
+ }
22335
+ }
22336
+ }
22337
+ }
22338
+ }
22339
+ return findings;
22340
+ }
22341
+ generateProposals(findings, current) {
22342
+ const proposals = [];
22343
+ const currentLower = current.toLowerCase();
22344
+ for (const finding of findings) {
22345
+ const findingLower = finding.toLowerCase();
22346
+ if (!currentLower.includes(findingLower)) {
22347
+ proposals.push(finding);
22348
+ }
22349
+ }
22350
+ return proposals;
22351
+ }
22352
+ formatDiff(current, proposals) {
22353
+ if (proposals.length === 0)
22354
+ return "";
22355
+ const lines = proposals.map((p) => `+ ${p}`);
22356
+ return lines.join(`
22357
+ `);
22358
+ }
22359
+ async scanAndGenerate() {
22360
+ const detections = await this.detectProjectInfo();
22361
+ return this.generateTemplate(detections);
22362
+ }
22363
+ async detectProjectInfo() {
22364
+ const packageJsonPath = path7.join(this.rootDir, "package.json");
22365
+ let packageJson = null;
22366
+ if (fileExists(packageJsonPath)) {
22367
+ try {
22368
+ const content = readText(packageJsonPath);
22369
+ packageJson = content ? JSON.parse(content) : null;
22370
+ } catch {}
22371
+ }
22372
+ const info = {
22373
+ packageManager: this.detectPackageManager(),
22374
+ language: this.detectLanguage(),
22375
+ testFramework: this.detectTestFramework(packageJson),
22376
+ buildCommand: packageJson?.scripts?.build || null,
22377
+ testCommand: packageJson?.scripts?.test || null,
22378
+ devCommand: packageJson?.scripts?.dev || null,
22379
+ isMonorepo: this.detectMonorepo(packageJson)
22380
+ };
22381
+ return info;
22382
+ }
22383
+ detectPackageManager() {
22384
+ if (fileExists(path7.join(this.rootDir, "bun.lockb")))
22385
+ return "bun";
22386
+ if (fileExists(path7.join(this.rootDir, "pnpm-lock.yaml")))
22387
+ return "pnpm";
22388
+ if (fileExists(path7.join(this.rootDir, "yarn.lock")))
22389
+ return "yarn";
22390
+ if (fileExists(path7.join(this.rootDir, "package-lock.json")))
22391
+ return "npm";
22392
+ return "npm";
22393
+ }
22394
+ detectLanguage() {
22395
+ if (fileExists(path7.join(this.rootDir, "tsconfig.json")))
22396
+ return "TypeScript";
22397
+ if (fileExists(path7.join(this.rootDir, "package.json")))
22398
+ return "JavaScript";
22399
+ if (fileExists(path7.join(this.rootDir, "requirements.txt")))
22400
+ return "Python";
22401
+ if (fileExists(path7.join(this.rootDir, "go.mod")))
22402
+ return "Go";
22403
+ if (fileExists(path7.join(this.rootDir, "Cargo.toml")))
22404
+ return "Rust";
22405
+ return "Unknown";
22406
+ }
22407
+ detectTestFramework(packageJson) {
22408
+ if (!packageJson)
22409
+ return null;
22410
+ const deps = {
22411
+ ...packageJson.dependencies,
22412
+ ...packageJson.devDependencies
22413
+ };
22414
+ if (deps?.vitest)
22415
+ return "vitest";
22416
+ if (deps?.jest)
22417
+ return "jest";
22418
+ if (this.detectPackageManager() === "bun")
22419
+ return "bun test";
22420
+ if (deps?.pytest)
22421
+ return "pytest";
22422
+ return null;
22423
+ }
22424
+ detectMonorepo(packageJson) {
22425
+ if (!packageJson)
22426
+ return false;
22427
+ return !!packageJson.workspaces;
22428
+ }
22429
+ generateTemplate(info) {
22430
+ const sections = [];
22431
+ sections.push(`# Agent Guidelines
22432
+ `);
22433
+ sections.push(`## Overview
22434
+ `);
22435
+ sections.push(`This project uses AI-assisted development. Follow these guidelines.
22436
+ `);
22437
+ sections.push(`## Build & Test Commands
22438
+ `);
22439
+ sections.push("```bash");
22440
+ if (info.isMonorepo) {
22441
+ sections.push("# This is a monorepo using bun workspaces");
22442
+ }
22443
+ if (info.buildCommand) {
22444
+ sections.push(`# Build`);
22445
+ sections.push(`${info.packageManager} run build`);
22446
+ sections.push("");
22447
+ }
22448
+ if (info.testCommand) {
22449
+ sections.push(`# Run tests`);
22450
+ sections.push(`${info.packageManager} ${info.testCommand === "bun test" ? "test" : "run test"}`);
22451
+ sections.push("");
22452
+ }
22453
+ if (info.devCommand) {
22454
+ sections.push(`# Development mode`);
22455
+ sections.push(`${info.packageManager} run dev`);
22456
+ }
22457
+ sections.push("```\n");
22458
+ sections.push(`## Technology Stack
22459
+ `);
22460
+ sections.push(`- **Language**: ${info.language}`);
22461
+ sections.push(`- **Package Manager**: ${info.packageManager}`);
22462
+ if (info.testFramework) {
22463
+ sections.push(`- **Test Framework**: ${info.testFramework}`);
22464
+ }
22465
+ if (info.isMonorepo) {
22466
+ sections.push(`- **Structure**: Monorepo with workspaces`);
22467
+ }
22468
+ sections.push("");
22469
+ sections.push(`## Code Style
22470
+ `);
22471
+ sections.push(`Follow existing patterns in the codebase.
22472
+ `);
22473
+ sections.push(`## Architecture Principles
22474
+ `);
22475
+ sections.push(`Document key architectural decisions here.
22476
+ `);
22477
+ return sections.join(`
22478
+ `);
22479
+ }
22480
+ }
22481
+
22482
+ class DockerSandboxService {
22483
+ static detectImage(worktreePath) {
22484
+ if (existsSync5(join8(worktreePath, "Dockerfile"))) {
22485
+ return null;
22486
+ }
22487
+ if (existsSync5(join8(worktreePath, "package.json"))) {
22488
+ return "node:22-slim";
22489
+ }
22490
+ if (existsSync5(join8(worktreePath, "requirements.txt")) || existsSync5(join8(worktreePath, "pyproject.toml"))) {
22491
+ return "python:3.12-slim";
22492
+ }
22493
+ if (existsSync5(join8(worktreePath, "go.mod"))) {
22494
+ return "golang:1.22-slim";
22495
+ }
22496
+ if (existsSync5(join8(worktreePath, "Cargo.toml"))) {
22497
+ return "rust:1.77-slim";
22498
+ }
22499
+ return "ubuntu:24.04";
22500
+ }
22501
+ static buildRunCommand(worktreePath, command, image) {
22502
+ const escapedCommand = command.replace(/'/g, "'\\''");
22503
+ return `docker run --rm -v ${worktreePath}:/app -w /app ${image} sh -c '${escapedCommand}'`;
22504
+ }
22505
+ static containerName(worktreePath) {
22506
+ const parts = worktreePath.split(sep);
22507
+ const worktreeIdx = parts.indexOf(".worktrees");
22508
+ if (worktreeIdx === -1 || worktreeIdx + 2 >= parts.length) {
22509
+ return `hive-sandbox-${Date.now()}`;
22510
+ }
22511
+ const feature = parts[worktreeIdx + 1];
22512
+ const task = parts[worktreeIdx + 2];
22513
+ const name = `hive-${feature}-${task}`.replace(/[^a-z0-9-]/gi, "-").toLowerCase();
22514
+ return name.slice(0, 63);
22515
+ }
22516
+ static ensureContainer(worktreePath, image) {
22517
+ const name = this.containerName(worktreePath);
22518
+ try {
22519
+ execSync(`docker inspect --format='{{.State.Running}}' ${name}`, { stdio: "pipe" });
22520
+ return name;
22521
+ } catch {
22522
+ execSync(`docker run -d --name ${name} -v ${worktreePath}:/app -w /app ${image} tail -f /dev/null`, { stdio: "pipe" });
22523
+ return name;
22524
+ }
22525
+ }
22526
+ static buildExecCommand(containerName, command) {
22527
+ const escapedCommand = command.replace(/'/g, "'\\''");
22528
+ return `docker exec ${containerName} sh -c '${escapedCommand}'`;
22529
+ }
22530
+ static stopContainer(worktreePath) {
22531
+ const name = this.containerName(worktreePath);
22532
+ try {
22533
+ execSync(`docker rm -f ${name}`, { stdio: "ignore" });
22534
+ } catch {}
22535
+ }
22536
+ static isDockerAvailable() {
22537
+ try {
22538
+ execSync("docker info", { stdio: "ignore" });
22539
+ return true;
22540
+ } catch {
22541
+ return false;
22542
+ }
22543
+ }
22544
+ static wrapCommand(worktreePath, command, config2) {
22545
+ if (command.startsWith("HOST: ")) {
22546
+ return command.substring(6);
22547
+ }
22548
+ if (config2.mode === "none") {
22549
+ return command;
22550
+ }
22551
+ let image;
22552
+ if (config2.image) {
22553
+ image = config2.image;
22554
+ } else {
22555
+ image = this.detectImage(worktreePath);
22556
+ if (image === null) {
22557
+ return command;
22558
+ }
22559
+ }
22560
+ if (config2.persistent) {
22561
+ const containerName = this.ensureContainer(worktreePath, image);
22562
+ return this.buildExecCommand(containerName, command);
22563
+ } else {
22564
+ return this.buildRunCommand(worktreePath, command, image);
22565
+ }
22566
+ }
21626
22567
  }
21627
22568
  function computeRunnableAndBlocked(tasks) {
21628
22569
  const statusByFolder = new Map;
@@ -22306,6 +23247,7 @@ var plugin = async (ctx) => {
22306
23247
  const planService = new PlanService(directory);
22307
23248
  const taskService = new TaskService(directory);
22308
23249
  const contextService = new ContextService(directory);
23250
+ const agentsMdService = new AgentsMdService(directory, contextService);
22309
23251
  const configService = new ConfigService;
22310
23252
  const disabledMcps = configService.getDisabledMcps();
22311
23253
  const disabledSkills = configService.getDisabledSkills();
@@ -22314,7 +23256,7 @@ var plugin = async (ctx) => {
22314
23256
  const effectiveAutoLoadSkills = configService.getAgentConfig("hive-master").autoLoadSkills ?? [];
22315
23257
  const worktreeService = new WorktreeService({
22316
23258
  baseDir: directory,
22317
- hiveDir: path7.join(directory, ".hive")
23259
+ hiveDir: path8.join(directory, ".hive")
22318
23260
  });
22319
23261
  const isOmoSlimEnabled = () => {
22320
23262
  return configService.isOmoSlimEnabled();
@@ -22341,7 +23283,7 @@ var plugin = async (ctx) => {
22341
23283
  };
22342
23284
  const checkBlocked = (feature) => {
22343
23285
  const fs9 = __require("fs");
22344
- const blockedPath = path7.join(directory, ".hive", "features", feature, "BLOCKED");
23286
+ const blockedPath = path8.join(directory, ".hive", "features", feature, "BLOCKED");
22345
23287
  if (fs9.existsSync(blockedPath)) {
22346
23288
  const reason = fs9.readFileSync(blockedPath, "utf-8").trim();
22347
23289
  return `⛔ BLOCKED by Beekeeper
@@ -22426,6 +23368,31 @@ To unblock: Remove .hive/features/${feature}/BLOCKED`;
22426
23368
  output.message.variant = configuredVariant;
22427
23369
  }
22428
23370
  },
23371
+ "tool.execute.before": async (input, output) => {
23372
+ if (input.tool !== "bash")
23373
+ return;
23374
+ const sandboxConfig = configService.getSandboxConfig();
23375
+ if (sandboxConfig.mode === "none")
23376
+ return;
23377
+ const command = output.args?.command?.trim();
23378
+ if (!command)
23379
+ return;
23380
+ if (/^HOST:\s*/i.test(command)) {
23381
+ const strippedCommand = command.replace(/^HOST:\s*/i, "");
23382
+ console.warn(`[hive:sandbox] HOST bypass: ${strippedCommand.slice(0, 80)}${strippedCommand.length > 80 ? "..." : ""}`);
23383
+ output.args.command = strippedCommand;
23384
+ return;
23385
+ }
23386
+ const workdir = output.args?.workdir;
23387
+ if (!workdir)
23388
+ return;
23389
+ const hiveWorktreeBase = path8.join(directory, ".hive", ".worktrees");
23390
+ if (!workdir.startsWith(hiveWorktreeBase))
23391
+ return;
23392
+ const wrapped = DockerSandboxService.wrapCommand(workdir, command, sandboxConfig);
23393
+ output.args.command = wrapped;
23394
+ output.args.workdir = undefined;
23395
+ },
22429
23396
  mcp: builtinMcps,
22430
23397
  tool: {
22431
23398
  hive_skill: createHiveSkillTool(filteredSkills),
@@ -22494,8 +23461,8 @@ NEXT: Ask your first clarifying question about this feature.`;
22494
23461
  const feature = resolveFeature(explicitFeature);
22495
23462
  if (!feature)
22496
23463
  return "Error: No feature specified. Create a feature or provide feature param.";
22497
- const hasDiscovery = content.toLowerCase().includes("## discovery");
22498
- if (!hasDiscovery) {
23464
+ const discoveryMatch = content.match(/^##\s+Discovery\s*$/im);
23465
+ if (!discoveryMatch) {
22499
23466
  return `BLOCKED: Discovery section required before planning.
22500
23467
 
22501
23468
  Your plan must include a \`## Discovery\` section documenting:
@@ -22504,6 +23471,19 @@ Your plan must include a \`## Discovery\` section documenting:
22504
23471
  - Key decisions made
22505
23472
 
22506
23473
  Add this section to your plan content and try again.`;
23474
+ }
23475
+ const afterDiscovery = content.slice(discoveryMatch.index + discoveryMatch[0].length);
23476
+ const nextHeading = afterDiscovery.search(/^##\s+/m);
23477
+ const discoveryContent = nextHeading > -1 ? afterDiscovery.slice(0, nextHeading).trim() : afterDiscovery.trim();
23478
+ if (discoveryContent.length < 100) {
23479
+ return `BLOCKED: Discovery section is too thin (${discoveryContent.length} chars, minimum 100).
23480
+
23481
+ A substantive Discovery section should include:
23482
+ - Original request quoted
23483
+ - Interview summary (key decisions)
23484
+ - Research findings with file:line references
23485
+
23486
+ Expand your Discovery section and try again.`;
22507
23487
  }
22508
23488
  captureSession(feature, toolContext);
22509
23489
  const planPath = planService.write(feature, content);
@@ -22724,9 +23704,9 @@ Reminder: start work with hive_worktree_create to use its worktree, and ensure a
22724
23704
  spec: specContent,
22725
23705
  workerPrompt
22726
23706
  });
22727
- const hiveDir = path7.join(directory, ".hive");
23707
+ const hiveDir = path8.join(directory, ".hive");
22728
23708
  const workerPromptPath = writeWorkerPromptFile(feature, task, workerPrompt, hiveDir);
22729
- const relativePromptPath = normalizePath(path7.relative(directory, workerPromptPath));
23709
+ const relativePromptPath = normalizePath(path8.relative(directory, workerPromptPath));
22730
23710
  const PREVIEW_MAX_LENGTH = 200;
22731
23711
  const workerPromptPreview = workerPrompt.length > PREVIEW_MAX_LENGTH ? workerPrompt.slice(0, PREVIEW_MAX_LENGTH) + "..." : workerPrompt;
22732
23712
  const taskToolPrompt = `Follow instructions in @${relativePromptPath}`;
@@ -23066,6 +24046,47 @@ Files changed: ${result.filesChanged?.length || 0}`;
23066
24046
  nextAction: getNextAction(planStatus, tasksSummary, runnable)
23067
24047
  });
23068
24048
  }
24049
+ }),
24050
+ hive_agents_md: tool({
24051
+ description: "Initialize or sync AGENTS.md. init: scan codebase and generate (preview only). sync: propose updates from feature contexts. apply: write approved content to disk.",
24052
+ args: {
24053
+ action: tool.schema.enum(["init", "sync", "apply"]).describe("Action to perform"),
24054
+ feature: tool.schema.string().optional().describe("Feature name for sync action"),
24055
+ content: tool.schema.string().optional().describe("Content to write (required for apply action)")
24056
+ },
24057
+ async execute({ action, feature, content }) {
24058
+ if (action === "init") {
24059
+ const result = await agentsMdService.init();
24060
+ if (result.existed) {
24061
+ return `AGENTS.md already exists (${result.content.length} chars). Use 'sync' to propose updates.`;
24062
+ }
24063
+ return `Generated AGENTS.md from codebase scan (${result.content.length} chars):
24064
+
24065
+ ${result.content}
24066
+
24067
+ ⚠️ This has NOT been written to disk. Ask the user via question() whether to write it to AGENTS.md.`;
24068
+ }
24069
+ if (action === "sync") {
24070
+ if (!feature)
24071
+ return "Error: feature name required for sync action";
24072
+ const result = await agentsMdService.sync(feature);
24073
+ if (result.proposals.length === 0) {
24074
+ return "No new findings to sync to AGENTS.md.";
24075
+ }
24076
+ return `Proposed AGENTS.md updates from feature "${feature}":
24077
+
24078
+ ${result.diff}
24079
+
24080
+ ⚠️ These changes have NOT been applied. Ask the user via question() whether to apply them.`;
24081
+ }
24082
+ if (action === "apply") {
24083
+ if (!content)
24084
+ return "Error: content required for apply action. Use init or sync first to get content, then apply with the approved content.";
24085
+ const result = agentsMdService.apply(content);
24086
+ return `AGENTS.md ${result.isNew ? "created" : "updated"} (${result.chars} chars) at ${result.path}`;
24087
+ }
24088
+ return "Error: unknown action";
24089
+ }
23069
24090
  })
23070
24091
  },
23071
24092
  command: {