ultimate-pi 0.11.0 → 0.13.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.
Files changed (137) hide show
  1. package/.agents/skills/ck-search/SKILL.md +11 -87
  2. package/.agents/skills/cocoindex-search/SKILL.md +35 -0
  3. package/.agents/skills/harness-debate-plan/SKILL.md +44 -0
  4. package/.agents/skills/harness-decisions/SKILL.md +1 -1
  5. package/.agents/skills/harness-orchestration/SKILL.md +54 -28
  6. package/.agents/skills/harness-plan/SKILL.md +15 -20
  7. package/.pi/PACKAGING.md +1 -0
  8. package/.pi/SYSTEM.md +21 -20
  9. package/.pi/agents/harness/adversary.md +0 -1
  10. package/.pi/agents/harness/evaluator.md +0 -1
  11. package/.pi/agents/harness/executor.md +1 -2
  12. package/.pi/agents/harness/incident-recorder.md +0 -1
  13. package/.pi/agents/harness/meta-optimizer.md +0 -1
  14. package/.pi/agents/harness/planning/decompose.md +3 -4
  15. package/.pi/agents/harness/planning/execution-plan-author.md +30 -0
  16. package/.pi/agents/harness/planning/hypothesis-validator.md +23 -0
  17. package/.pi/agents/harness/planning/hypothesis.md +3 -4
  18. package/.pi/agents/harness/planning/plan-adversary.md +10 -42
  19. package/.pi/agents/harness/planning/plan-evaluator.md +18 -0
  20. package/.pi/agents/harness/planning/review-integrator.md +23 -0
  21. package/.pi/agents/harness/planning/scout-graphify.md +13 -5
  22. package/.pi/agents/harness/planning/scout-semantic.md +23 -11
  23. package/.pi/agents/harness/planning/scout-structure.md +12 -6
  24. package/.pi/agents/harness/planning/sprint-contract-auditor.md +18 -0
  25. package/.pi/agents/harness/planning/stack-researcher.md +24 -0
  26. package/.pi/agents/harness/tie-breaker.md +0 -1
  27. package/.pi/agents/harness/trace-librarian.md +0 -1
  28. package/.pi/extensions/debate-orchestrator.ts +90 -53
  29. package/.pi/extensions/harness-plan-approval.ts +2 -2
  30. package/.pi/extensions/harness-run-context.ts +150 -5
  31. package/.pi/extensions/harness-subagents.ts +17 -6
  32. package/.pi/extensions/lib/harness-cocoindex-refresh.ts +49 -0
  33. package/.pi/extensions/lib/harness-posthog.ts +6 -1
  34. package/.pi/extensions/lib/harness-spawn-budget.ts +75 -0
  35. package/.pi/extensions/lib/harness-subagent-auth.ts +123 -0
  36. package/.pi/extensions/lib/{harness-subagents/harness-subagent-policy.ts → harness-subagent-policy.ts} +8 -7
  37. package/.pi/extensions/lib/harness-subagent-precheck.ts +95 -0
  38. package/.pi/extensions/lib/harness-subagents-bridge.ts +122 -0
  39. package/.pi/extensions/lib/plan-approval/create-plan.ts +4 -7
  40. package/.pi/extensions/lib/plan-approval/plan-review.ts +1 -1
  41. package/.pi/extensions/lib/plan-approval/types.ts +7 -1
  42. package/.pi/extensions/lib/plan-debate-envelope.ts +84 -0
  43. package/.pi/extensions/lib/{harness-subagents/spawn-policy.ts → spawn-policy.ts} +1 -0
  44. package/.pi/extensions/policy-gate.ts +1 -1
  45. package/.pi/extensions/review-integrity.ts +48 -29
  46. package/.pi/harness/agents.manifest.json +37 -25
  47. package/.pi/harness/docs/adrs/0032-harness-command-orchestration.md +4 -3
  48. package/.pi/harness/docs/adrs/0033-parent-orchestrated-planning.md +2 -2
  49. package/.pi/harness/docs/adrs/0035-plan-phase-review-gate.md +27 -0
  50. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/artifacts/review-round-r1.yaml +25 -0
  51. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/artifacts/review-round-r4.yaml +26 -0
  52. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/artifacts/sprint-audit-r4.yaml +5 -0
  53. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/plan-packet.yaml +196 -0
  54. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/plan-review.md +14 -0
  55. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/research-brief.yaml +32 -0
  56. package/.pi/harness/evals/smoke/run-context.fixture.json +1 -1
  57. package/.pi/harness/evals/smoke/smoke-harness-plan.mjs +88 -0
  58. package/.pi/harness/specs/harness-posthog-event.schema.json +6 -1
  59. package/.pi/harness/specs/plan-execution-plan-brief.schema.json +13 -0
  60. package/.pi/harness/specs/plan-execution-plan.schema.json +255 -0
  61. package/.pi/harness/specs/plan-packet.schema.json +14 -5
  62. package/.pi/harness/specs/plan-review-round-draft.schema.json +68 -0
  63. package/.pi/harness/specs/plan-sprint-audit-turn.schema.json +29 -0
  64. package/.pi/harness/specs/plan-stack-brief.schema.json +65 -0
  65. package/.pi/harness/specs/plan-validation-turn.schema.json +42 -0
  66. package/.pi/harness/specs/round-result.schema.json +16 -9
  67. package/.pi/lib/debate-orchestrator-types.ts +38 -0
  68. package/.pi/lib/harness-agent-discovery.mjs +81 -0
  69. package/.pi/lib/harness-run-context.ts +64 -38
  70. package/.pi/lib/harness-yaml.mjs +73 -0
  71. package/.pi/lib/harness-yaml.ts +90 -0
  72. package/.pi/prompts/harness-auto.md +13 -11
  73. package/.pi/prompts/harness-critic.md +2 -2
  74. package/.pi/prompts/harness-eval.md +3 -3
  75. package/.pi/prompts/harness-incident.md +2 -2
  76. package/.pi/prompts/harness-plan.md +83 -92
  77. package/.pi/prompts/harness-review.md +2 -2
  78. package/.pi/prompts/harness-router-tune.md +1 -1
  79. package/.pi/prompts/harness-run.md +2 -2
  80. package/.pi/prompts/harness-setup.md +30 -17
  81. package/.pi/prompts/harness-trace.md +2 -2
  82. package/.pi/scripts/README.md +1 -0
  83. package/.pi/scripts/harness-agents-manifest.mjs +1 -1
  84. package/.pi/scripts/harness-cli-verify.sh +24 -14
  85. package/.pi/scripts/harness-cocoindex-bootstrap.sh +182 -0
  86. package/.pi/scripts/harness-verify.mjs +38 -19
  87. package/.pi/scripts/validate-plan-dag.mjs +258 -0
  88. package/.pi/scripts/vendor-sync-pi-subagents.sh +19 -0
  89. package/.pi/skills/ast-grep/SKILL.md +2 -2
  90. package/.pi/skills/ccc/SKILL.md +142 -0
  91. package/.pi/skills/ccc/references/management.md +110 -0
  92. package/CHANGELOG.md +22 -0
  93. package/THIRD_PARTY_NOTICES.md +15 -0
  94. package/biome.json +2 -2
  95. package/package.json +7 -4
  96. package/vendor/pi-subagents/LICENSE +21 -0
  97. package/vendor/pi-subagents/UPSTREAM_PIN.md +11 -0
  98. package/vendor/pi-subagents/src/agents.ts +357 -0
  99. package/vendor/pi-subagents/src/subagents.ts +1463 -0
  100. package/.pi/agents/harness/planner.md +0 -13
  101. package/.pi/agents/harness/planning/hypothesis-eval.md +0 -59
  102. package/.pi/agents/harness/planning/planner.md +0 -20
  103. package/.pi/extensions/lib/harness-subagents/agent-loader.ts +0 -126
  104. package/.pi/extensions/lib/harness-subagents/agent-manifest.ts +0 -119
  105. package/.pi/extensions/lib/harness-subagents/agent-parser.ts +0 -87
  106. package/.pi/extensions/lib/harness-subagents/blackboard-tool.ts +0 -118
  107. package/.pi/extensions/lib/harness-subagents/blackboard.ts +0 -175
  108. package/.pi/extensions/lib/harness-subagents/parent-ask-user-bridge.ts +0 -10
  109. package/.pi/extensions/lib/harness-subagents/parent-harness-ui-bridge.ts +0 -137
  110. package/.pi/extensions/lib/harness-subagents/parent-harness-ui-hooks.ts +0 -77
  111. package/.pi/extensions/lib/harness-subagents/types-blackboard.ts +0 -27
  112. package/.pi/extensions/lib/harness-subagents/vendored/agent-manager.ts +0 -558
  113. package/.pi/extensions/lib/harness-subagents/vendored/agent-runner.ts +0 -666
  114. package/.pi/extensions/lib/harness-subagents/vendored/agent-types.ts +0 -175
  115. package/.pi/extensions/lib/harness-subagents/vendored/context.ts +0 -59
  116. package/.pi/extensions/lib/harness-subagents/vendored/cross-extension-rpc.ts +0 -134
  117. package/.pi/extensions/lib/harness-subagents/vendored/custom-agents.ts +0 -5
  118. package/.pi/extensions/lib/harness-subagents/vendored/default-agents.ts +0 -123
  119. package/.pi/extensions/lib/harness-subagents/vendored/env.ts +0 -43
  120. package/.pi/extensions/lib/harness-subagents/vendored/group-join.ts +0 -144
  121. package/.pi/extensions/lib/harness-subagents/vendored/index.ts +0 -2460
  122. package/.pi/extensions/lib/harness-subagents/vendored/invocation-config.ts +0 -52
  123. package/.pi/extensions/lib/harness-subagents/vendored/memory.ts +0 -182
  124. package/.pi/extensions/lib/harness-subagents/vendored/model-resolver.ts +0 -92
  125. package/.pi/extensions/lib/harness-subagents/vendored/output-file.ts +0 -115
  126. package/.pi/extensions/lib/harness-subagents/vendored/prompts.ts +0 -103
  127. package/.pi/extensions/lib/harness-subagents/vendored/schedule-store.ts +0 -177
  128. package/.pi/extensions/lib/harness-subagents/vendored/schedule.ts +0 -416
  129. package/.pi/extensions/lib/harness-subagents/vendored/settings.ts +0 -210
  130. package/.pi/extensions/lib/harness-subagents/vendored/skill-loader.ts +0 -108
  131. package/.pi/extensions/lib/harness-subagents/vendored/types.ts +0 -187
  132. package/.pi/extensions/lib/harness-subagents/vendored/ui/agent-widget.ts +0 -639
  133. package/.pi/extensions/lib/harness-subagents/vendored/ui/conversation-viewer.ts +0 -324
  134. package/.pi/extensions/lib/harness-subagents/vendored/ui/schedule-menu.ts +0 -110
  135. package/.pi/extensions/lib/harness-subagents/vendored/usage.ts +0 -71
  136. package/.pi/extensions/lib/harness-subagents/vendored/worktree.ts +0 -195
  137. /package/.pi/extensions/{00-ultimate-pi-system-prompt.ts → custom-system-prompt.ts} +0 -0
@@ -156,7 +156,7 @@ bash "$UP_PKG/.pi/scripts/harness-cli-verify.sh"
156
156
 
157
157
  **Required (script must exit 0):** scrapling + harness-web smoke, ctx7, biome, ast-grep (`sg`), sentrux (when harness manifest present).
158
158
 
159
- **Warnings allowed:** gh (if not authenticated), agent-browser (if OS libs need manual `sudo apt-get install`), ck (empty corpus on tiny repos).
159
+ **Warnings allowed:** gh (if not authenticated), agent-browser (if OS libs need manual `sudo apt-get install`), cocoindex-code (empty corpus on tiny repos; first `[full]` install downloads local embedding model).
160
160
 
161
161
  If the script reports **agent-browser shared library errors** on Linux/WSL, run the fix it prints, then re-verify:
162
162
 
@@ -232,20 +232,24 @@ if [ ! -f .pi/harness/browser.json ]; then
232
232
  fi
233
233
  ```
234
234
 
235
- ### 2.4 — ck-search (Semantic Code Search)
235
+ ### 2.4 — CocoIndex Code (semantic code search)
236
+
237
+ Offline semantic search via [CocoIndex Code](https://cocoindex.io/cocoindex-code/) (`ccc`). **CLI only** — do not register `ccc mcp` in harness setup (MCP defaults to refresh-before-search and is slower).
236
238
 
237
239
  ```bash
238
- if ! command -v ck &>/dev/null || [ "$FORCE" = "true" ]; then
239
- npm install -g @beaconbay/ck-search
240
- fi
240
+ command -v uv &>/dev/null || curl -LsSf https://astral.sh/uv/install.sh | sh
241
+ export PATH="$HOME/.local/bin:$PATH"
242
+ uv tool install 'cocoindex-code[full]' # or: pipx install 'cocoindex-code[full]'
243
+ bash "$UP_PKG/.pi/scripts/harness-cocoindex-bootstrap.sh"
244
+ # Rebuild index: bash "$UP_PKG/.pi/scripts/harness-cocoindex-bootstrap.sh" --force
245
+ ccc status
241
246
  ```
242
247
 
243
- Verify: `ck --version`
248
+ **Indexing before scouts is automatic:** `harness-subagents` runs incremental `ccc index` before plan/execute subagent batches. Agents use `ccc search` only.
244
249
 
245
- Register as MCP server (if Claude MCP available):
246
- ```bash
247
- claude mcp list 2>/dev/null && claude mcp add ck-search -s user -- ck --serve || echo "MCP not available — ck will be used as CLI only"
248
- ```
250
+ **First install:** `[full]` pulls sentence-transformers + torch (~hundreds of MB–1GB+). Run bootstrap once; do not run `ccc index` inside scouts.
251
+
252
+ Verify: `ccc doctor` and `ccc search --limit 3 "export function"` (no `--refresh`).
249
253
 
250
254
  ### 2.5 — biome (Lint + Format Gate)
251
255
 
@@ -345,7 +349,7 @@ Verify each package:
345
349
  |---------|---------|-------|
346
350
  | `@posthog/pi` | Analytics event capture | F0 |
347
351
  | `pi-lean-ctx` | Context runtime (read/bash/find/grep/MCP bridge) | F0 |
348
- | `harness-subagents` (bundled extension) | L4 sub-agent spawn, blackboard, package agents | P16 |
352
+ | `harness-subagents` (bundled extension) | L4 `subagent` tool, subprocess spawns, package agents | P16 |
349
353
  | Vendored `pi-vcc` (`vendor/pi-vcc`, `.pi/extensions/ultimate-pi-vcc.ts`) | VCC compaction / `vcc_recall` — env-only: `HARNESS_VCC_COMPACTION` (default on), `HARNESS_VCC_DEBUG` | Shipped |
350
354
  | `pi-model-router` | Vendored (`vendor/`); activates after `.pi/model-router.json` exists | F0 |
351
355
 
@@ -383,11 +387,11 @@ Manual override: **`/router profile auto`** anytime after reload if they changed
383
387
 
384
388
  ## Step 3.6 — Harness agents (package-resolved)
385
389
 
386
- `harness-subagents` loads agents from the installed **`ultimate-pi`** package (`$UP_PKG/.pi/agents/**`) with namespaced ids (`harness/planner`, `pi-pi/agent-expert`). **Do not copy** agents into the project unless you want a deliberate override.
390
+ `harness-subagents` loads agents from the installed **`ultimate-pi`** package (`$UP_PKG/.pi/agents/**`) with namespaced ids (`harness/executor`, `harness/planning/scout-graphify`, `pi-pi/agent-expert`). **Do not copy** agents into the project unless you want a deliberate override.
387
391
 
388
392
  **Slash commands are orchestrators:** `/harness-plan`, `/harness-run`, etc. spawn `harness/*` agents via the `Agent` tool — bootstrap stays **script-first**; only optionally spawn `harness/sentrux-bootstrap` for Sentrux (see Step 4.2).
389
393
 
390
- Optional per-repo overrides: place `.md` files at the **same relative path** (e.g. `.pi/agents/harness/planning/scout-graphify.md` overrides the package scout). Deprecated: `harness/planner.md` — use `harness/planning/` agents instead.
394
+ Optional per-repo overrides: place `.md` files at the **same relative path** (e.g. `.pi/agents/harness/planning/scout-graphify.md` overrides the package scout).
391
395
 
392
396
  Verify manifest drift after `pi update ultimate-pi`:
393
397
 
@@ -478,16 +482,25 @@ Template keys (placeholders — user fills secrets): `HARNESS_TELEMETRY_ENABLED`
478
482
 
479
483
  ### 4.1 — .gitignore Entries
480
484
 
481
- Ensure `.gitignore` contains:
485
+ Ensure `.gitignore` contains harness runtime entries (see repo root `.gitignore` — **do not** ignore `.pi/harness/specs/`; JSON schemas are shared contracts):
486
+
482
487
  ```
483
488
  .env
484
489
  .web/
485
490
  .searxng/
486
491
  .raw/
487
492
  .vault-meta/
488
- .pi/harness/critics/
493
+ .pi/harness/active-run.json
494
+ .pi/harness/release-readiness-report.md
489
495
  .pi/harness/plans/
490
- .pi/harness/specs/
496
+ .pi/harness/critics/
497
+ .pi/harness/runs/**
498
+ !.pi/harness/runs/README.md
499
+ .pi/harness/incidents/*
500
+ !.pi/harness/incidents/README.md
501
+ .pi/harness/debates/*
502
+ !.pi/harness/debates/README.md
503
+ .pi/harness/router/proposals/*
491
504
 
492
505
  # Model router config (user-specific — generated from env)
493
506
  .pi/model-router.json
@@ -657,7 +670,7 @@ Output summary table:
657
670
  | scrapling / harness-web | ✓/✗ | Auth: yes/no |
658
671
  | ctx7 | ✓/✗ | Login: yes/no |
659
672
  | agent-browser | ✓/✗ | Config: .pi/harness/browser.json |
660
- | ck-search | ✓/✗ | MCP: registered/CLI-only |
673
+ | cocoindex-code | ✓/✗ | `ccc status`; index auto-refreshed before harness scouts |
661
674
  | biome | ✓/✗ | Project config: found/default |
662
675
  | ast-grep | ✓/✗ | AST-aware code search (`sg`)
663
676
  | gh CLI | ✓/✗ | Auth: yes/no |
@@ -20,10 +20,10 @@ Happy path: omit `--run`.
20
20
  2. Spawn:
21
21
 
22
22
  ```
23
- Agent({ subagent_type: "harness/trace-librarian", prompt: "…" })
23
+ subagent({ agentScope: "both", agent: "harness/trace-librarian", task: "…" })
24
24
  ```
25
25
 
26
- 3. `get_subagent_result` — present timeline and artifact index to user.
26
+ 3. Present timeline and artifact index from tool result to user.
27
27
 
28
28
  ## Completion
29
29
 
@@ -21,6 +21,7 @@ From **Typescript extensions**, use `resolveHarnessScript()` / `getHarnessPackag
21
21
  | Action | Command |
22
22
  |--------|---------|
23
23
  | Graphify bootstrap | `bash "$UP_PKG/.pi/scripts/harness-graphify-bootstrap.sh"` |
24
+ | CocoIndex Code bootstrap | `bash "$UP_PKG/.pi/scripts/harness-cocoindex-bootstrap.sh"` |
24
25
  | CLI tool install + smoke tests | `bash "$UP_PKG/.pi/scripts/harness-cli-verify.sh"` |
25
26
  | Deterministic harness checks | `node "$UP_PKG/.pi/scripts/harness-verify.mjs"` |
26
27
  | Sentrux rules bootstrap (harness-setup) | `node "$UP_PKG/.pi/scripts/harness-sentrux-bootstrap.mjs"` |
@@ -14,7 +14,7 @@ import {
14
14
  isSafeAgentId,
15
15
  sha256Content,
16
16
  walkAgentsDir,
17
- } from "../../test/harness-subagents-loader.core.mjs";
17
+ } from "../lib/harness-agent-discovery.mjs";
18
18
 
19
19
  const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
20
20
  const MANIFEST_PATH = join(ROOT, ".pi", "harness", "agents.manifest.json");
@@ -231,22 +231,32 @@ verify_ctx7() {
231
231
  fi
232
232
  }
233
233
 
234
- verify_ck() {
235
- log "[ck-search]"
236
- npm_global_install "@beaconbay/ck-search" "ck" || { fail "ck-search npm install"; return; }
237
- if ! ck --version &>/dev/null; then
238
- fail "ck --version failed"
234
+ verify_cocoindex() {
235
+ log "[cocoindex-code]"
236
+ local _bootstrap
237
+ _bootstrap="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/harness-cocoindex-bootstrap.sh"
238
+ if [ ! -f "$_bootstrap" ]; then
239
+ fail "harness-cocoindex-bootstrap.sh missing"
239
240
  return
240
241
  fi
241
- # Fast grep-mode smoke (no embedding model download)
242
- local ck_target="."
243
- [ -d .pi ] && ck_target=".pi"
244
- if ck -l 1 "export" "$ck_target" 2>/dev/null | head -1 | grep -q .; then
245
- pass "ck $(ck --version 2>/dev/null | head -1)"
246
- elif ck --status "$ck_target" 2>/dev/null | head -1 | grep -q .; then
247
- pass "ck $(ck --version 2>/dev/null | head -1) (index status ok)"
242
+ if [ "$FORCE" = true ]; then
243
+ bash "$_bootstrap" --force || { fail "cocoindex bootstrap --force"; return; }
244
+ else
245
+ bash "$_bootstrap" || { fail "cocoindex bootstrap"; return; }
246
+ fi
247
+ if ! command -v ccc &>/dev/null; then
248
+ fail "ccc not on PATH after bootstrap"
249
+ return
250
+ fi
251
+ if ! ccc doctor &>/dev/null; then
252
+ warn "ccc doctor reported issues (daemon/model/SQLite)"
253
+ fi
254
+ if ccc search --limit 3 "export function" 2>/dev/null | head -1 | grep -qE '\.(ts|js|py|md)|\[|score|path'; then
255
+ pass "cocoindex-code (ccc search smoke)"
256
+ elif ccc status 2>/dev/null | head -1 | grep -q .; then
257
+ pass "cocoindex-code (index present; search empty on tiny corpus)"
248
258
  else
249
- warn "ck installed but smoke search empty"
259
+ warn "cocoindex installed but smoke search empty — first [full] install downloads local embedding model"
250
260
  fi
251
261
  }
252
262
 
@@ -335,7 +345,7 @@ log ""
335
345
  verify_scrapling
336
346
  verify_ctx7
337
347
  verify_agent_browser
338
- verify_ck
348
+ verify_cocoindex
339
349
  verify_biome
340
350
  verify_sg
341
351
  verify_gh
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env bash
2
+ # harness-cocoindex-bootstrap — install CocoIndex Code (ccc), seed settings, build index.
3
+ # Non-interactive (no `ccc init` prompts). Used by harness-cli-verify and /harness-setup.
4
+
5
+ set -euo pipefail
6
+
7
+ FORCE=false
8
+ for arg in "$@"; do
9
+ case "$arg" in
10
+ --force) FORCE=true ;;
11
+ -h | --help)
12
+ echo "Usage: $0 [--force]"
13
+ echo " --force rebuild index even when cocoindex.db exists"
14
+ exit 0
15
+ ;;
16
+ *)
17
+ echo "Unknown argument: $arg" >&2
18
+ exit 2
19
+ ;;
20
+ esac
21
+ done
22
+
23
+ export PATH="${HOME}/.local/bin:${PATH}"
24
+
25
+ log() { printf '%s\n' "$*"; }
26
+ die() { printf 'error: %s\n' "$*" >&2; exit 1; }
27
+
28
+ ROOT="$(pwd)"
29
+
30
+ if ! python3 --version 2>/dev/null | grep -qE 'Python 3\.(1[0-9]|[2-9][0-9])'; then
31
+ die "Python 3.10+ required (got: $(python3 --version 2>/dev/null || echo missing))"
32
+ fi
33
+ log "✓ Python 3.10+"
34
+
35
+ cocoindex_installed() {
36
+ command -v ccc &>/dev/null && return 0
37
+ command -v uv &>/dev/null && uv tool list 2>/dev/null | grep -qE '(^|[[:space:]])cocoindex-code([[:space:]]|$)' && return 0
38
+ return 1
39
+ }
40
+
41
+ install_cocoindex() {
42
+ if command -v uv &>/dev/null; then
43
+ log "Installing cocoindex-code[full] via uv tool..."
44
+ uv tool install 'cocoindex-code[full]'
45
+ elif command -v pipx &>/dev/null; then
46
+ log "Installing cocoindex-code[full] via pipx..."
47
+ pipx install 'cocoindex-code[full]'
48
+ else
49
+ die "Need uv or pipx to install cocoindex-code[full]"
50
+ fi
51
+ export PATH="${HOME}/.local/bin:${PATH}"
52
+ command -v ccc &>/dev/null || die "ccc not on PATH after install"
53
+ }
54
+
55
+ if ! cocoindex_installed; then
56
+ install_cocoindex
57
+ fi
58
+ command -v ccc &>/dev/null || die "ccc CLI not found"
59
+ log "✓ ccc ($(command -v ccc))"
60
+
61
+ CCC_BIN="$(command -v ccc)"
62
+ CCC_PYTHON=""
63
+ if [ -f "$CCC_BIN" ]; then
64
+ CCC_PYTHON="$(sed -n '1s/^#!//p' "$CCC_BIN" | tr -d '\r')"
65
+ fi
66
+ if [ -z "$CCC_PYTHON" ] || [ ! -x "$CCC_PYTHON" ]; then
67
+ CCC_VENV="$(cd "$(dirname "$CCC_BIN")/.." && pwd)"
68
+ CCC_PYTHON="$CCC_VENV/bin/python"
69
+ fi
70
+ if [ ! -x "$CCC_PYTHON" ]; then
71
+ CCC_PYTHON="$(command -v python3)"
72
+ fi
73
+
74
+ # Seed global + project settings and merge harness exclude_patterns (non-interactive).
75
+ "$CCC_PYTHON" - <<'PY'
76
+ from __future__ import annotations
77
+
78
+ import os
79
+ import sys
80
+ from pathlib import Path
81
+
82
+ try:
83
+ import yaml
84
+ except ImportError:
85
+ print("error: PyYAML required for harness cocoindex bootstrap", file=sys.stderr)
86
+ sys.exit(1)
87
+
88
+ ROOT = Path(os.environ.get("HARNESS_COCOINDEX_ROOT", ".")).resolve()
89
+ SETTINGS_DIR = ROOT / ".cocoindex_code"
90
+ PROJECT_SETTINGS = SETTINGS_DIR / "settings.yml"
91
+ USER_DIR = Path.home() / ".cocoindex_code"
92
+ USER_SETTINGS = USER_DIR / "global_settings.yml"
93
+
94
+ HARNESS_EXCLUDES = [
95
+ "graphify-out/**",
96
+ "raw/**",
97
+ ".raw/**",
98
+ ".pi/wiki-search/**",
99
+ "vendor/**",
100
+ "node_modules/**",
101
+ "**/graph.html",
102
+ "**/*.jsonl",
103
+ ".cursor/**",
104
+ ]
105
+
106
+ DEFAULT_GLOBAL = {
107
+ "embedding": {
108
+ "provider": "sentence-transformers",
109
+ "model": "Snowflake/snowflake-arctic-embed-xs",
110
+ }
111
+ }
112
+
113
+
114
+ def load_yaml(path: Path) -> dict:
115
+ if not path.is_file():
116
+ return {}
117
+ data = yaml.safe_load(path.read_text(encoding="utf-8"))
118
+ return data if isinstance(data, dict) else {}
119
+
120
+
121
+ def save_yaml(path: Path, data: dict) -> None:
122
+ path.parent.mkdir(parents=True, exist_ok=True)
123
+ path.write_text(yaml.safe_dump(data, default_flow_style=False), encoding="utf-8")
124
+
125
+
126
+ # Global settings (offline embeddings — no LiteLLM prompt).
127
+ if not USER_SETTINGS.is_file():
128
+ save_yaml(USER_SETTINGS, DEFAULT_GLOBAL)
129
+ print(f"Created {USER_SETTINGS}")
130
+
131
+ # Project settings — minimal file with merged excludes only.
132
+ project = load_yaml(PROJECT_SETTINGS)
133
+ excludes = list(project.get("exclude_patterns") or [])
134
+ seen = set(excludes)
135
+ for pat in HARNESS_EXCLUDES:
136
+ if pat not in seen:
137
+ excludes.append(pat)
138
+ seen.add(pat)
139
+ project["exclude_patterns"] = excludes
140
+ save_yaml(PROJECT_SETTINGS, project)
141
+ print(f"Ensured project settings: {PROJECT_SETTINGS}")
142
+
143
+ # .gitignore entry (mirror ccc init behavior).
144
+ gitignore = ROOT / ".gitignore"
145
+ entry = "/.cocoindex_code/"
146
+ comment = "# CocoIndex Code (ccc)"
147
+ if (ROOT / ".git").is_dir() and gitignore.is_file():
148
+ lines = gitignore.read_text(encoding="utf-8").splitlines()
149
+ if entry not in lines:
150
+ content = gitignore.read_text(encoding="utf-8")
151
+ if content and not content.endswith("\n"):
152
+ content += "\n"
153
+ content += f"{comment}\n{entry}\n"
154
+ gitignore.write_text(content, encoding="utf-8")
155
+ elif (ROOT / ".git").is_dir():
156
+ gitignore.write_text(f"{comment}\n{entry}\n", encoding="utf-8")
157
+ PY
158
+
159
+ NEED_INDEX=true
160
+ if [ "$FORCE" = false ] && [ -f ".cocoindex_code/cocoindex.db" ]; then
161
+ NEED_INDEX=false
162
+ log "✓ Existing cocoindex.db (use --force to rebuild)"
163
+ fi
164
+
165
+ if [ "$NEED_INDEX" = true ] || [ "$FORCE" = true ]; then
166
+ log "Building semantic code index (ccc index)..."
167
+ ccc index
168
+ fi
169
+
170
+ if ccc doctor 2>/dev/null; then
171
+ log "✓ ccc doctor"
172
+ else
173
+ log "! ccc doctor reported issues (see output above)"
174
+ fi
175
+
176
+ if ccc status 2>/dev/null | head -5; then
177
+ log "✓ ccc status"
178
+ else
179
+ log "! ccc status unavailable"
180
+ fi
181
+
182
+ log "CocoIndex output: .cocoindex_code/"
@@ -202,32 +202,51 @@ async function main() {
202
202
  if (!(await fileExists(runCtxLib))) fail("missing lib/harness-run-context.ts");
203
203
  ok("lib/harness-run-context.ts");
204
204
 
205
- const vendoredIndex = join(
205
+ const pkgJson = JSON.parse(
206
+ await readFile(join(ROOT, "package.json"), "utf-8"),
207
+ );
208
+ if (!pkgJson.files?.includes("vendor/pi-subagents")) {
209
+ fail(
210
+ 'package.json "files" must include vendor/pi-subagents (npm publish ships subagents vendor)',
211
+ );
212
+ }
213
+ ok('package.json files includes vendor/pi-subagents');
214
+
215
+ const subagentsVendor = join(
216
+ ROOT,
217
+ "vendor",
218
+ "pi-subagents",
219
+ "src",
220
+ "subagents.ts",
221
+ );
222
+ if (!(await fileExists(subagentsVendor))) {
223
+ fail("missing vendor/pi-subagents/src/subagents.ts");
224
+ }
225
+ const bridgePath = join(
206
226
  ROOT,
207
227
  ".pi",
208
228
  "extensions",
209
229
  "lib",
210
- "harness-subagents",
211
- "vendored",
212
- "index.ts",
230
+ "harness-subagents-bridge.ts",
213
231
  );
214
- const vendoredSrc = await readFile(vendoredIndex, "utf-8");
215
- const runCtxImport = vendoredSrc.match(
216
- /from ["']([^"']*harness-run-context\.js)["']/,
217
- );
218
- if (!runCtxImport) {
219
- fail("vendored/index.ts must import harness-run-context.js");
232
+ if (!(await fileExists(bridgePath))) {
233
+ fail("missing harness-subagents-bridge.ts");
220
234
  }
221
- const runCtxImportPath = resolve(
222
- dirname(vendoredIndex),
223
- runCtxImport[1].replace(/\.js$/, ".ts"),
224
- );
225
- if (runCtxImportPath !== runCtxLib) {
226
- fail(
227
- `vendored/index.ts harness-run-context import resolves to ${runCtxImportPath}, expected ${runCtxLib}`,
228
- );
235
+ const bridgeSrc = await readFile(bridgePath, "utf-8");
236
+ if (!bridgeSrc.includes("precheckHarnessSubagentSpawn")) {
237
+ fail("harness-subagents-bridge must run precheckHarnessSubagentSpawn");
238
+ }
239
+ if (!bridgeSrc.includes("packageRoot")) {
240
+ fail("harness-subagents-bridge must pass packageRoot for agent discovery");
241
+ }
242
+ const subagentsSrc = await readFile(subagentsVendor, "utf-8");
243
+ if (!subagentsSrc.includes("discoverAgents")) {
244
+ fail("vendor subagents.ts must implement discoverAgents");
245
+ }
246
+ if (!subagentsSrc.includes("packageRoot")) {
247
+ fail("vendor subagents.ts must pass packageRoot into discovery");
229
248
  }
230
- ok("vendored/index.ts harness-run-context import path");
249
+ ok("vendor pi-subagents + harness bridge");
231
250
 
232
251
  const policyGateSrc = await readFile(
233
252
  join(ROOT, ".pi", "extensions", "policy-gate.ts"),