pi-orchestrator-config 4.2.1 → 4.3.3

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 (92) hide show
  1. package/README.md +52 -61
  2. package/agents/git-expert.md +5 -1
  3. package/agents/github-expert.md +4 -1
  4. package/extensions/acpx-provider/runtime-models.ts +18 -6
  5. package/extensions/cli-provider/agents/claude.ts +3 -2
  6. package/extensions/cli-provider/agents/cursor.ts +3 -5
  7. package/extensions/cli-provider/agents/gemini.ts +3 -2
  8. package/extensions/cli-provider/discover.ts +7 -7
  9. package/extensions/cli-provider/index.ts +5 -0
  10. package/extensions/cli-provider/runtime-models.ts +18 -6
  11. package/extensions/cli-provider/session-reaper.ts +5 -7
  12. package/extensions/cli-provider/sessions.ts +4 -0
  13. package/extensions/cli-provider/shared/discover-cache.ts +17 -176
  14. package/extensions/coms/coms-p2p.ts +1719 -423
  15. package/extensions/coms/coms-shared.ts +261 -39
  16. package/extensions/coms/coms-wrapper.ts +100 -62
  17. package/extensions/coms/index.ts +8 -4
  18. package/extensions/coms/mixed-turn.ts +26 -0
  19. package/extensions/coms/probe-socket.ts +42 -0
  20. package/extensions/coms/themeMap.ts +0 -1
  21. package/extensions/image-gen/image-gen.ts +19 -1
  22. package/extensions/orchestrator/async-agents.ts +509 -85
  23. package/extensions/orchestrator/cron.ts +14 -8
  24. package/extensions/orchestrator/dreaming.ts +31 -24
  25. package/extensions/orchestrator/enforcement-helpers.ts +459 -17
  26. package/extensions/orchestrator/enforcement-rules.ts +5 -4
  27. package/extensions/orchestrator/enforcement.ts +79 -25
  28. package/extensions/orchestrator/extended-autocomplete.ts +7 -0
  29. package/extensions/orchestrator/git-helpers.ts +2 -2
  30. package/extensions/orchestrator/index.ts +23 -10
  31. package/extensions/orchestrator/markdown-transformer.ts +313 -0
  32. package/extensions/orchestrator/memory-embeddings.ts +36 -34
  33. package/extensions/orchestrator/memory-provenance.ts +29 -25
  34. package/extensions/orchestrator/memory-scoring.ts +23 -18
  35. package/extensions/orchestrator/memory-tools.ts +10 -3
  36. package/extensions/orchestrator/overlay-dashboard.ts +17 -5
  37. package/extensions/orchestrator/pi-config-review-state.ts +44 -33
  38. package/extensions/orchestrator/project-settings.ts +220 -21
  39. package/extensions/orchestrator/review-porcelain.ts +4 -0
  40. package/extensions/orchestrator/review-ui.ts +11 -5
  41. package/extensions/orchestrator/rule-placeholders.ts +384 -1
  42. package/extensions/orchestrator/rules.ts +80 -132
  43. package/extensions/orchestrator/settings-tui-helpers.ts +380 -0
  44. package/extensions/orchestrator/settings-tui-submenus.ts +647 -0
  45. package/extensions/orchestrator/settings-tui.ts +636 -0
  46. package/extensions/orchestrator/state-jsonl.ts +431 -0
  47. package/extensions/orchestrator/subagent-tool.ts +105 -50
  48. package/extensions/orchestrator/sync-limit.ts +23 -0
  49. package/extensions/orchestrator/task-lifecycle.ts +77 -67
  50. package/extensions/orchestrator/utils.ts +8 -5
  51. package/extensions/pidash/pidash.ts +193 -156
  52. package/extensions/pidiff/pidiff.ts +64 -38
  53. package/extensions/pidiff/spawn-lock.ts +62 -0
  54. package/extensions/pitasks/index.ts +430 -0
  55. package/extensions/pitasks/reminders.ts +37 -0
  56. package/extensions/pitasks/task-store.ts +467 -0
  57. package/extensions/pitasks/task-tools.ts +375 -0
  58. package/extensions/pitasks/task-widget.ts +181 -0
  59. package/extensions/pitasks/types.ts +38 -0
  60. package/extensions/providers/acpx-driver.ts +12 -2
  61. package/extensions/providers/built-in-drivers.ts +6 -6
  62. package/extensions/providers/claude-driver.ts +1 -1
  63. package/extensions/providers/cursor-cli-driver.ts +1 -1
  64. package/extensions/providers/gemini-driver.ts +1 -1
  65. package/extensions/providers/index.ts +144 -26
  66. package/extensions/providers/initialized-guard.ts +27 -0
  67. package/extensions/providers/restore-default-model.ts +596 -0
  68. package/extensions/providers/session-shutdown.ts +39 -0
  69. package/extensions/shared/coms-active.ts +23 -0
  70. package/extensions/shared/create-runtime-provider.ts +2 -0
  71. package/extensions/shared/daemon-manager.ts +0 -8
  72. package/extensions/shared/file-logger.ts +132 -25
  73. package/extensions/shared/logger.ts +50 -0
  74. package/extensions/shared/models-dev.ts +421 -0
  75. package/extensions/shared/oneshot.ts +116 -0
  76. package/extensions/shared/resolve-binary.ts +191 -0
  77. package/extensions/shared/types.ts +3 -0
  78. package/package.json +7 -2
  79. package/prompts/coderabbit-rate-limit.md +2 -0
  80. package/rules/00-orchestrator-core.md +3 -0
  81. package/rules/10-agent-routing.md +1 -1
  82. package/rules/20-code-review-loop.md +38 -16
  83. package/rules/30-prompt-templates.md +4 -0
  84. package/rules/35-memory.md +3 -3
  85. package/rules/40-critical-rules.md +3 -0
  86. package/rules/55-coms-protocol.md +84 -18
  87. package/rules/60-task-tracking.md +2 -0
  88. package/settings-keys.json +481 -20
  89. package/templates/coms-feature-manager-prompt.md +4 -6
  90. package/extensions/coms/coms-net-server.ts +0 -1642
  91. package/extensions/coms/coms-net-wrapper.ts +0 -521
  92. package/extensions/coms/coms-net.ts +0 -1589
package/README.md CHANGED
@@ -15,7 +15,7 @@ Single extension that provides:
15
15
  | **Subagent tool** | Delegate tasks to specialist agents (single, parallel, chain, async modes); optional `model` param for model override |
16
16
  | **`list_models`** | List available models and providers for subagent model override |
17
17
  | **Async background agents** | Spawn agents in background with `async: true` — results surface automatically when complete. Fullscreen overlay dashboard with live output, keyboard nav, and kill support (`/async-status`, `/async-kill`). On **acpx** parents, optional async is coerced to sync; dream/cron need `internal_operations_provider` + `internal_operations_model`. `cli-*` providers support async natively (see `dev-docs/cli-provider.md`) |
18
- | **CLI / ACPX providers** | Optional `cli_agents` / `acpx_agents` register `cli-*` / `acpx-*` via native `createProvider` (pi ≥ 0.81): `/login cli-<agent>` or `/login acpx-<agent>`, model refresh, filter when unavailable |
18
+ | **CLI / ACPX providers** | Optional `cli_agents` / `acpx_agents` register `cli-*` / `acpx-*` via native `createProvider` (pi ≥ 0.84): `/login cli-<agent>` or `/login acpx-<agent>`, model refresh, filter when unavailable. Missing context window / maxTokens / cost filled from models.dev (`~/.pi/pi-config/models.dev.json`, 1-day refresh). Cold-start default restore (#753): gates `startup`\|`new`, empty `enabledModels`, trusted project merge — see `dev-docs/cli-provider.md` |
19
19
  | **`/btw` command** | Quick side questions without polluting conversation history — ephemeral overlay |
20
20
  | **`/async-status` command** | Show status of background agents — select one for live output streaming |
21
21
  | **`/async-kill` command** | Kill async agents (overlay picker or by name/id) |
@@ -33,10 +33,10 @@ Single extension that provides:
33
33
  | **Dreaming** | Background memory consolidation — extracts memories from sessions, deduplicates, maintains topic-based memory |
34
34
  | **Memory enforcement** | Code-enforced memory entries — triggers on bash/tool/file events, actions: block, run_after, warn. LLM cannot ignore enforced rules. Dreaming-safe via *(enforced)* marker |
35
35
  | **Upgrade changelog** | Shows release notes on session start after pi-config version upgrade |
36
- | **Task tracking** | Structured task lists for multi-step workflows — live widget, progress tracking, reminder nudges ([@tintinweb/pi-tasks](https://github.com/tintinweb/pi-tasks)) |
36
+ | **Task tracking** | Structured task lists for multi-step workflows — live widget, progress tracking, reminder nudges (owned, based on [@tintinweb/pi-tasks](https://github.com/tintinweb/pi-tasks) MIT) |
37
37
  | **Neovim integration** | Send changed files and review findings to nvim's quickfix list — only active when running inside nvim |
38
- | **Inter-agent communication** | P2P (`/coms`) and networked (`/coms-net`) agent communication — on-demand activation via slash commands |
39
- | **Slash commands** | `/pr-review`, `/issue-review`, `/release`, `/review-local`, `/review-status`, `/query-db`, `/btw`, `/async-status`, `/async-kill`, `/status`, `/dream`, `/remember`, `/coms`, `/coms-net` — with autocomplete argument hints |
38
+ | **Inter-agent communication** | P2P (`/coms`) agent communication — on-demand activation via slash command |
39
+ | **Slash commands** | `/pr-review`, `/issue-review`, `/release`, `/review-local`, `/review-status`, `/query-db`, `/btw`, `/async-status`, `/async-kill`, `/status`, `/dream`, `/remember`, `/coms`, `/pi-config-settings` — with autocomplete argument hints |
40
40
  | **GitHub autocomplete** | Type `#` in the editor to get issue/PR suggestions from the current repo — lazy-loaded, 5min cache |
41
41
  | **Command arg completions** | Tab-complete arguments for slash commands — providers and models for `/external-ai`, branches for `/review-local`, PR numbers for `/pr-review`, and more |
42
42
  | **Discord bot** | Control pi sessions from your phone via Discord DMs — send prompts, answer ask_user dialogs, switch sessions |
@@ -77,13 +77,13 @@ Single extension that provides:
77
77
  | `/dream-auto` | Toggle automatic memory dreaming (every 3h + session end) |
78
78
  | `/cron add\|list\|list-all\|remove` | Schedule recurring tasks within the pi session (e.g., `/cron add every 2h check for new issues`, `/cron add at 12:00 /review-handler`). `/cron list` and `/cron list-all` open overlay UI (view / remove; list-all = all sessions). Tasks run while pi is active, survive `/reload`, and stop on exit |
79
79
  | `/async-kill [name\|id\|all]` | Kill async agents (overlay picker or by name/id) |
80
+ | `/pi-config-settings [project\|global]` | Interactive TUI settings editor — browse all pi-config settings with scope indicators, smart pickers for providers/models, and immediate save |
80
81
  | `/status` | Unified session snapshot — async agents, cron tasks, git branch, context usage |
81
82
  | `/nvim-changed-files` | Send git changed files to nvim's quickfix list (only inside nvim) |
82
83
  | `/pidiff start\|stop\|restart\|status` | Manage the pidiff diff viewer server (per-project) |
83
84
  | `/coms start\|stop\|status` | P2P local agent communication (Unix socket) |
84
- | `/coms-net start\|connect\|disconnect\|stop\|status` | Networked agent communication (HTTP/SSE hub) |
85
85
 
86
- ### Inter-Agent Communication (coms & coms-net)
86
+ ### Inter-Agent Communication (coms)
87
87
 
88
88
  Two systems for Pi agents to communicate with each other, activated on-demand via slash commands:
89
89
 
@@ -95,18 +95,6 @@ Two systems for Pi agents to communicate with each other, activated on-demand vi
95
95
  /coms status
96
96
  ```
97
97
 
98
- **Networked (`/coms-net`)** — HTTP/SSE hub for communication across machines. Server auto-starts on localhost.
99
-
100
- ```text
101
- /coms-net start --name dev --purpose "Development agent"
102
- /coms-net connect
103
- /coms-net disconnect
104
- /coms-net stop
105
- /coms-net status
106
- ```
107
-
108
- For LAN/remote access, set `PI_COMS_NET_AUTH_TOKEN` and `PI_COMS_NET_HOST=0.0.0.0` in your environment.
109
-
110
98
  **Tools available once activated:**
111
99
 
112
100
  | Tool | Description |
@@ -238,7 +226,7 @@ After any code change, the orchestrator runs 6 agents **in parallel** (5 reviewe
238
226
  6. **test-automator** — Runs project tests (pytest, node tests, pre-commit)
239
227
 
240
228
  When `review_loop_enforcement` is enabled, the loop stops once all reviewers approve with 0 findings and tests pass
241
- (`tests_passed: true` in `pi-config-review-state.json`), OR after `review_loop_max_cycles` total cycles (default `3`,
229
+ (`tests_passed: true` in `pi-config-review-state.jsonl`), OR after `review_loop_max_cycles` total cycles (default `3`,
242
230
  valid integers `1`-`10`; env: digit string `"1"`-`"10"` only (after trim)) — whichever comes first. Each cycle
243
231
  always completes fix/explain (5a) before the cap check; the cap only blocks re-dispatch
244
232
  (step 2 / all 6 agents, including test-automator), not responding to findings.
@@ -248,6 +236,7 @@ forms like `"10.0"` / `"1e1"`) fall through to the next resolution layer / defau
248
236
  `review_loop_enforcement: false`, not via max_cycles. Commit blocking is code-enforced via `isCommitAllowed`:
249
237
  allows commit when `isReviewClean` (`status: clean` + `tests_passed: true`, or `status: none`), or when max cycles are exhausted
250
238
  (`status` is `has_findings` or `clean`, no pending reviewers, `cycle >= review_loop_max_cycles` — no `tests_passed` requirement).
239
+ Review enforcement and dirty tracking are automatically skipped on `chore/bump-version-<version>` branches (e.g. `chore/bump-version-4.2.1-1234567890`, used by the release workflow).
251
240
 
252
241
  Staged mode (`--autorabbit`/`--autoqodo` in `/review-handler`) shares one total `review_loop_max_cycles` budget
253
242
  across both its Spec Compliance and Code Quality stages — not a separate cap per stage.
@@ -258,35 +247,18 @@ Use `/review-status` to inspect the current review loop state. Pass a worktree p
258
247
 
259
248
  ### Project Settings
260
249
 
261
- Create `.pi/pi-config-settings.json` in your project to override global defaults:
262
-
263
- ```json
264
- {
265
- "commit_trailer": "Assisted-by",
266
- "allow_push_to_protected_branches": false,
267
- "use_worktrees": true,
268
- "dream_interval_hours": 6,
269
- "review_loop_enforcement": false,
270
- "review_loop_max_cycles": 3,
271
- "pidash_enable": true,
272
- "pidiff_enable": true,
273
- "pidash_port": 19190,
274
- "image_model": "gemini-3-pro-image",
275
- "acpx_agents": ["cursor"],
276
- "cli_agents": ["claude", "cursor"],
277
- "internal_operations_provider": "anthropic",
278
- "internal_operations_model": "claude-sonnet-4-20250514",
279
- "agent_provider": "cli-cursor",
280
- "agent_model": "cursor:cursor-grok-4.5-high-fast",
281
- "agent_overrides": {
282
- "git-expert": { "provider": null, "model": null }
283
- }
284
- }
250
+ Copy the example file to your project and customize:
251
+
252
+ ```bash
253
+ cp pi-config-settings.example.jsonc .pi/pi-config-settings.json
285
254
  ```
286
255
 
256
+ Settings files support JSONC (JSON with `//` comments).
257
+ See [`pi-config-settings.example.jsonc`](pi-config-settings.example.jsonc) for all available settings with descriptions.
258
+
287
259
  Resolution order: project file → global `~/.pi/pi-config-settings.json` → env var → default.
288
260
 
289
- See `dev-docs/project-settings.md` for the full settings table and env vars.
261
+ See `dev-docs/project-settings.md` for the full settings table.
290
262
 
291
263
  #### Reviewer Environment Variables
292
264
 
@@ -345,6 +317,17 @@ EOF
345
317
 
346
318
  Rules auto-load alphabetically. Same-filename entries are overridden (project > user > package). Missing directories are silently skipped.
347
319
 
320
+ #### Conditional assembly
321
+
322
+ Rules support settings/feature conditionals at prompt assembly (`assembleRuleText` in
323
+ `rule-placeholders.ts`). Full syntax, truthiness, and assembly order:
324
+ **[dev-docs/project-settings.md](dev-docs/project-settings.md)** (Rules assembly).
325
+
326
+ Markers: `{{IF:key}}…{{/IF}}`, `{{IFNOT:key}}…{{/IFNOT}}`, comparisons
327
+ `{{IF:key==value}}` / `{{IF:key!=value}}`. Whole-file frontmatter: `requires_setting` /
328
+ `requires`. Conditionals run **per file** (no cross-file matching), then bodies are
329
+ joined, then placeholders like `{{REVIEW_LOOP_MAX_CYCLES}}` are substituted.
330
+
348
331
  ### Add project agents
349
332
 
350
333
  Create `.pi/agents/my-agent.md` in your project with frontmatter:
@@ -371,7 +354,7 @@ Set `image_model` in `pi-config-settings.json` or use `PI_IMAGE_MODEL` env var.
371
354
 
372
355
  | Setting / Variable | Description |
373
356
  |----------|-------------|
374
- | `image_model` / `PI_IMAGE_MODEL` | Gemini model name (e.g., `gemini-3-pro-image`). No default. |
357
+ | `image_model` / `PI_IMAGE_MODEL` | Google/Gemini image model for `generate_image` (Settings TUI filters to google; empty = disabled). |
375
358
  | `GEMINI_API_KEY` or `GOOGLE_API_KEY` | Gemini API key (env only) |
376
359
 
377
360
  **Usage:** Ask naturally — "generate an image of a sunset" — or use structured params: `subject`, `action`, `scene`, `composition`, `lighting`, `style`, `text`, `aspect_ratio`.
@@ -404,8 +387,15 @@ Run pi inside a disposable container for **filesystem isolation** — the agent
404
387
  `agent` (Cursor Agent CLI). Enable with `cli_agents` in settings (e.g.
405
388
  `["claude","cursor","gemini"]`). Binary missing at load → `cli-*` not registered.
406
389
  After register, `filterModels` hides models when unavailable: PATH cleared while
407
- agent state remains → restore PATH; after `session_shutdown` (AgentState cleared)
408
- → `/reload` or restart (PATH alone is not enough). See `dev-docs/cli-provider.md`.
390
+ agent state remains, restore PATH; after `session_shutdown` (AgentState cleared
391
+ and `initialized` reset) the next factory re-registers on `/new`|`/resume`|`/fork`
392
+ (PATH alone is not enough). See `dev-docs/cli-provider.md`.
393
+
394
+ **ACPX provider agents (optional `acpx_agents`):** ACPX wraps CLI agents via the
395
+ ACP runtime. Supported agents: `cursor`, `claude`, `gemini`. Enable with
396
+ `acpx_agents` in settings (e.g. `["cursor","claude","gemini"]`). Each ACPX agent
397
+ requires the underlying CLI binary on PATH (`agent` for cursor, `claude` for claude,
398
+ `gemini` for gemini) — missing binary → `acpx-*` not registered.
409
399
 
410
400
  **CLI specialist agents (Cursor / Claude / Gemini):** On container start, `entrypoint.sh`
411
401
  symlinks package `agents/*.md` into the mounted project:
@@ -457,7 +447,9 @@ docker run --rm -it \
457
447
 
458
448
  ### Environment file
459
449
 
460
- Create a `.env` file with container-specific variables:
450
+ Create a `.env` file with external service credentials and container-specific
451
+ variables. Pi-config settings (image_model, acpx_agents, vertex_claude_1m, etc.)
452
+ go in `.pi/pi-config-settings.json` — not here:
461
453
 
462
454
  ```env
463
455
  # Timezone (host timezone for correct timestamps)
@@ -470,9 +462,6 @@ PI_HOST_USER=myakove
470
462
  GOOGLE_CLOUD_PROJECT=your-project-id
471
463
  GOOGLE_CLOUD_LOCATION=us-east5
472
464
  GOOGLE_APPLICATION_CREDENTIALS=/home/myakove/.config/gcloud/application_default_credentials.json
473
- VERTEX_PROJECT_ID=your-project-id
474
- VERTEX_REGION=us-east5
475
- VERTEX_CLAUDE_1M=true
476
465
 
477
466
  # GitHub
478
467
  GITHUB_TOKEN=ghp_xxx
@@ -482,12 +471,6 @@ GH_CONFIG_DIR=/home/myakove/.config/gh
482
471
  # Gemini (optional — required for image generation)
483
472
  GEMINI_API_KEY=xxx
484
473
 
485
- # Image generation model (required for generate_image tool)
486
- PI_IMAGE_MODEL=gemini-3-pro-image
487
-
488
- # acpx agents (optional)
489
- # ACPX_AGENTS=cursor
490
-
491
474
  # mcpl (MCP Launchpad) config path inside the container (must match mount target)
492
475
  # Use your actual home path — it resolves inside the container via the PI_HOST_USER symlink
493
476
  MCPL_CONFIG_FILES=/home/myakove/.config/mcpl/mcp.json
@@ -526,7 +509,8 @@ Pidash is a web-based dashboard that runs alongside the TUI, accessible from any
526
509
  **How it works:**
527
510
 
528
511
  - A daemon (`pidash-server.ts`) runs on port `19190` and aggregates all pi sessions
529
- - Each pi session's extension (`pidash.ts`) connects to the daemon and forwards events
512
+ - Each interactive pi session's extension (`pidash.ts`) connects to the daemon and forwards events
513
+ - Oneshot (`pi -p` / `--print` / `--mode json`) skips pidash register, so no session connects
530
514
  - The React web UI shows live conversations, tool calls, and session status
531
515
 
532
516
  **Features:**
@@ -564,6 +548,10 @@ PI_PIDASH_PORT=9999 pi
564
548
  PI_PIDASH_ENABLE=false pi
565
549
  ```
566
550
 
551
+ Oneshot (`pi -p` / `--print` / `--mode json`) skips register of pidash, pidiff,
552
+ pitasks, and coms so those daemons/watchers do not start. CLI and ACPX providers
553
+ still load. `--mode rpc` is long-lived and is not skipped.
554
+
567
555
  **Management:**
568
556
 
569
557
  ```bash
@@ -588,7 +576,8 @@ Pidiff is a per-project diff viewer that opens in your browser, providing rich b
588
576
 
589
577
  **How it works:**
590
578
 
591
- - Each pi session spawns its own server (`pidiff-server.ts`) on a random free port
579
+ - Each interactive pi session spawns its own server (`pidiff-server.ts`) on a random free port
580
+ - Oneshot (`pi -p` / `--print` / `--mode json`) skips pidiff register, so no per-session server starts
592
581
  - Container and native sessions get separate servers automatically
593
582
  - Lockfiles in `.pi/tmp/` track port and PID for each server
594
583
  - The extension (`pidiff.ts`) connects to its session's server and registers its repo
@@ -629,7 +618,8 @@ PI_PIDIFF_ENABLE=false pi
629
618
  | `-v "<PATH_TO_MCPL_CONFIG>":"$HOME/.config/mcpl/mcp.json":ro` | MCP server config for `mcpl` |
630
619
  | `-v "$HOME/.agents":"$HOME/.agents":rw` | User-level skills (install/uninstall from container) |
631
620
  | `-v "$HOME/.config/gcloud/application_default_credentials.json":"$HOME/.config/gcloud/application_default_credentials.json":ro` | Google Cloud ADC (for Claude via Vertex AI) |
632
- | `-v "$HOME/.config/cursor/auth.json":"$HOME/.config/cursor/auth.json":ro` | Cursor CLI auth (for acpx cursor models) |
621
+ | `-v "$HOME/.config/cursor/auth.json":"$HOME/.config/cursor/auth.json":ro` | Cursor CLI auth (for acpx-cursor / cli-cursor models) |
622
+ | `-v "$HOME/.claude/credentials.json":"$HOME/.claude/credentials.json":ro` | Claude CLI auth (for acpx-claude / cli-claude models) |
633
623
  | `-v "$HOME/.config/glab-cli":"$HOME/.config/glab-cli":ro` | GitLab CLI config (auth tokens, host settings) |
634
624
  | `-v "$HOME/.coderabbit":"$HOME/.coderabbit":rw` | CodeRabbit CLI auth and review data |
635
625
  | `-v "$HOME/screenshots":"$HOME/screenshots"` | Share screenshots/images with the agent |
@@ -721,6 +711,7 @@ alias pi-docker='docker pull ghcr.io/myk-org/pi-config:latest && \
721
711
  -v "$HOME/.agents":"$HOME/.agents":rw \
722
712
  -v "$HOME/.config/gcloud/application_default_credentials.json":"$HOME/.config/gcloud/application_default_credentials.json":ro \
723
713
  -v "$HOME/.config/cursor/auth.json":"$HOME/.config/cursor/auth.json":ro \
714
+ -v "$HOME/.claude/credentials.json":"$HOME/.claude/credentials.json":ro \
724
715
  -v "$HOME/.config/glab-cli":"$HOME/.config/glab-cli":ro \
725
716
  -v "$HOME/screenshots":"$HOME/screenshots":ro \
726
717
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
@@ -800,7 +791,7 @@ See [DEVELOPMENT.md](DEVELOPMENT.md) for tips on testing extensions locally, run
800
791
 
801
792
  ## Prerequisites
802
793
 
803
- - [pi](https://github.com/badlogic/pi-mono) (minimum version: **0.81.0**)
794
+ - [pi](https://github.com/badlogic/pi-mono) (minimum version: **0.84.0**)
804
795
  - `gh` CLI (for GitHub operations)
805
796
  - `uv` (for Python execution)
806
797
  - `myk-pi-tools` (optional, for `/pr-review` and `/release`)
@@ -19,7 +19,11 @@ You are a Git Expert responsible for all local git operations and version contro
19
19
 
20
20
  Before ANY `git commit`, if `review_loop_enforcement` is `true`:
21
21
 
22
- 1. Read `.pi/data/pi-config-review-state.json` (use the `read` tool, NOT `cat`/`grep`) and check the state.
22
+ **Skip this check entirely if the current branch starts with `chore/bump-version`** (release version bump only).
23
+
24
+ 1. Read `.pi/data/pi-config-review-state.jsonl` (use the `read` tool, NOT `cat`/`grep`).
25
+ This is a JSONL file (one JSON object per line); parse the **last valid JSON object line**
26
+ (skip any truncated or corrupt trailing lines) to get current state.
23
27
 
24
28
  2. **BLOCK the commit unless one of the allow cases in step 4 holds.**
25
29
  Common block reasons: `status` is `"needs_review"` / `"in_progress"`,
@@ -31,9 +31,12 @@ This agent does NOT run tests. When tests are required (e.g., before creating a
31
31
 
32
32
  {{SETTINGS:comment_signature}}
33
33
 
34
- - If `comment_signature` is `true`: append a signature to every PR/issue comment body.
34
+ - If `comment_signature` is `true`: append a signature to every GitHub body you write —
35
+ PR/issue **create**, **edit --body**, and **comment**.
35
36
  Format: `\n\n---\n*Assisted-by: PI (<model>)*` using `$PI_MODEL` for model.
36
37
  If `$PI_COMMENT_SIGNATURE` is set, use: `\n\n---\n*$PI_COMMENT_SIGNATURE*`.
38
+ Skip if the body already contains `Assisted-by`.
39
+ Runtime enforcement also injects this on `gh pr|issue create|comment|edit` `--body` / heredoc.
37
40
 
38
41
  ## Core Operations
39
42
 
@@ -4,6 +4,10 @@
4
4
  */
5
5
 
6
6
  import { buildRuntimeModel } from "../shared/create-runtime-provider.js";
7
+ import {
8
+ fillRuntimeModelFromCatalog,
9
+ type ModelsDevCatalog,
10
+ } from "../shared/models-dev.js";
7
11
 
8
12
  export function modelIdToDisplayName(modelId: string): string {
9
13
  // Strip bracket suffixes for display: gpt-5.4[context=272k,...] -> Gpt 5.4
@@ -17,6 +21,7 @@ export function modelIdToDisplayName(modelId: string): string {
17
21
  export function mapAcpxDiscoveredModels(
18
22
  agent: string,
19
23
  modelIds: readonly string[],
24
+ catalog?: ModelsDevCatalog | null,
20
25
  ): ReturnType<typeof buildRuntimeModel>[] {
21
26
  const provider = `acpx-${agent}`;
22
27
  if (modelIds.length === 0) {
@@ -30,11 +35,18 @@ export function mapAcpxDiscoveredModels(
30
35
  ];
31
36
  }
32
37
  return modelIds.map((m) =>
33
- buildRuntimeModel({
34
- id: `${agent}:${m}`,
35
- name: `${modelIdToDisplayName(m)} (${agent})`,
36
- api: "acpx",
37
- provider,
38
- }),
38
+ buildRuntimeModel(
39
+ fillRuntimeModelFromCatalog(
40
+ {
41
+ id: `${agent}:${m}`,
42
+ name: `${modelIdToDisplayName(m)} (${agent})`,
43
+ api: "acpx",
44
+ provider,
45
+ },
46
+ catalog,
47
+ agent,
48
+ m,
49
+ ),
50
+ ),
39
51
  );
40
52
  }
@@ -3,7 +3,8 @@
3
3
  */
4
4
 
5
5
  import { closeSync, openSync, readSync, statSync } from "node:fs";
6
- import { cliProviderLog } from "../../shared/file-logger.js";
6
+ import { createLogger } from "../../shared/logger.js";
7
+ const log = createLogger("cli_provider");
7
8
  import type { CliProviderDef, DiscoveredCliModel } from "../types.js";
8
9
  import {
9
10
  cacheKeyForFile,
@@ -97,7 +98,7 @@ function discoverClaudeModels(): DiscoveredCliModel[] {
97
98
  if (models.length > 0) writeModelCache(key, models);
98
99
  return models;
99
100
  } catch (err) {
100
- cliProviderLog("error", "claude: binary catalog failed", err);
101
+ log.error("claude: binary catalog failed", err);
101
102
  return [];
102
103
  }
103
104
  }
@@ -5,7 +5,8 @@
5
5
  */
6
6
 
7
7
  import { spawnSync } from "node:child_process";
8
- import { cliProviderLog } from "../../shared/file-logger.js";
8
+ import { createLogger } from "../../shared/logger.js";
9
+ const log = createLogger("cli_provider");
9
10
  import type { CliProviderDef, DiscoveredCliModel } from "../types.js";
10
11
  import { resolveBinary } from "../shared/discover-cache.js";
11
12
 
@@ -48,10 +49,7 @@ function discoverCursorModels(): DiscoveredCliModel[] {
48
49
  const out = `${r.stdout || ""}\n${r.stderr || ""}`;
49
50
  const models = parseAgentListModels(out);
50
51
  if (models.length === 0) {
51
- cliProviderLog(
52
- "warn",
53
- `cursor: --list-models failed (status=${r.status}): ${out.slice(0, 200)}`,
54
- );
52
+ log.warn(`cursor: --list-models failed (status=${r.status}): ${out.slice(0, 200)}`);
55
53
  }
56
54
  return models;
57
55
  }
@@ -9,7 +9,8 @@ import {
9
9
  statSync,
10
10
  } from "node:fs";
11
11
  import { dirname, join } from "node:path";
12
- import { cliProviderLog } from "../../shared/file-logger.js";
12
+ import { createLogger } from "../../shared/logger.js";
13
+ const log = createLogger("cli_provider");
13
14
  import type { CliProviderDef, DiscoveredCliModel } from "../types.js";
14
15
  import {
15
16
  cacheKeyForFile,
@@ -71,7 +72,7 @@ function discoverGeminiModels(): DiscoveredCliModel[] {
71
72
  if (models.length > 0) writeModelCache(key, models);
72
73
  return models;
73
74
  } catch (err) {
74
- cliProviderLog("error", "gemini: CLI bundle parse failed", err);
75
+ log.error("gemini: CLI bundle parse failed", err);
75
76
  return [];
76
77
  }
77
78
  }
@@ -5,11 +5,13 @@
5
5
  * IMPORTANT: These IDs are CLI `--model` values, NOT acpx model ids.
6
6
  */
7
7
 
8
- import { cliProviderLog } from "../shared/file-logger.js";
8
+ import { createLogger } from "../shared/logger.js";
9
9
  import { CLI_PROVIDERS, isCliAgentName, type CliAgentName } from "./providers.js";
10
10
  import type { DiscoveredCliModel } from "./types.js";
11
11
  import { modelIdToDisplayName, resolveBinary } from "./shared/discover-cache.js";
12
12
 
13
+ const log = createLogger("cli_provider");
14
+
13
15
  export type { DiscoveredCliModel } from "./types.js";
14
16
  export { modelIdToDisplayName } from "./shared/discover-cache.js";
15
17
  export { parseAgentListModels } from "./agents/cursor.js";
@@ -33,9 +35,7 @@ export async function discoverCliModelsDetailed(
33
35
  ): Promise<DiscoveredCliModel[]> {
34
36
  if (!isCliAgentName(agent)) return [];
35
37
  if (!isCliBinaryAvailable(agent)) {
36
- cliProviderLog(
37
- "warn",
38
- `${agent}: binary not found (${CLI_PROVIDERS[agent].binary})`,
38
+ log.warn(`${agent}: binary not found (${CLI_PROVIDERS[agent].binary})`,
39
39
  );
40
40
  return [];
41
41
  }
@@ -44,13 +44,13 @@ export async function discoverCliModelsDetailed(
44
44
  try {
45
45
  discovered = CLI_PROVIDERS[agent].discoverModels();
46
46
  } catch (err) {
47
- cliProviderLog("error", `${agent}: discovery error`, err);
47
+ log.error(`${agent}: discovery error`, err);
48
48
  }
49
49
 
50
50
  if (discovered.length > 0) {
51
- cliProviderLog("info", `${agent}: discovered ${discovered.length} model(s)`);
51
+ log.info(`${agent}: discovered ${discovered.length} model(s)`);
52
52
  } else {
53
- cliProviderLog("warn", `${agent}: discovery returned no models`);
53
+ log.warn(`${agent}: discovery returned no models`);
54
54
  }
55
55
  return discovered;
56
56
  }
@@ -14,6 +14,11 @@
14
14
  * @module cli-provider (shim)
15
15
  */
16
16
 
17
+ import { createLogger } from "../shared/logger.js";
18
+
19
+ const log = createLogger("cli_provider");
20
+ log.debug("cli-provider shim module loaded");
21
+
17
22
  // Re-export discovery APIs (consumed by pi-sidecar via jiti)
18
23
  export {
19
24
  discoverCliModels,
@@ -4,11 +4,16 @@
4
4
  */
5
5
 
6
6
  import { buildRuntimeModel } from "../shared/create-runtime-provider.js";
7
+ import {
8
+ fillRuntimeModelFromCatalog,
9
+ type ModelsDevCatalog,
10
+ } from "../shared/models-dev.js";
7
11
  import type { DiscoveredCliModel } from "./discover.js";
8
12
 
9
13
  export function mapCliDiscoveredModels(
10
14
  agent: string,
11
15
  discovered: readonly DiscoveredCliModel[],
16
+ catalog?: ModelsDevCatalog | null,
12
17
  ): ReturnType<typeof buildRuntimeModel>[] {
13
18
  const provider = `cli-${agent}`;
14
19
  if (discovered.length === 0) {
@@ -22,11 +27,18 @@ export function mapCliDiscoveredModels(
22
27
  ];
23
28
  }
24
29
  return discovered.map((m) =>
25
- buildRuntimeModel({
26
- id: `${agent}:${m.id}`,
27
- name: `${m.name} (${agent})`,
28
- api: "cli",
29
- provider,
30
- }),
30
+ buildRuntimeModel(
31
+ fillRuntimeModelFromCatalog(
32
+ {
33
+ id: `${agent}:${m.id}`,
34
+ name: `${m.name} (${agent})`,
35
+ api: "cli",
36
+ provider,
37
+ },
38
+ catalog,
39
+ agent,
40
+ m.id,
41
+ ),
42
+ ),
31
43
  );
32
44
  }
@@ -5,9 +5,11 @@
5
5
  */
6
6
 
7
7
  import { unlinkSync } from "node:fs";
8
- import { cliProviderLog } from "../shared/file-logger.js";
8
+ import { createLogger } from "../shared/logger.js";
9
9
  import { listCliSessions } from "./sessions.js";
10
10
 
11
+ const log = createLogger("cli_provider");
12
+
11
13
  export const DEFAULT_INACTIVITY_THRESHOLD_MS = 30 * 60 * 1000;
12
14
  export const DEFAULT_SWEEP_INTERVAL_MS = 5 * 60 * 1000;
13
15
 
@@ -51,16 +53,12 @@ export function reapStaleCliSessions(options?: ReapOptions): number {
51
53
  try {
52
54
  unlinkSync(path);
53
55
  reaped += 1;
54
- cliProviderLog(
55
- "info",
56
- `reaped session ${record.agent}/${record.model} ` +
56
+ log.info(`reaped session ${record.agent}/${record.model} ` +
57
57
  `(status=${record.status}, piSessionId=${record.piSessionId}, ` +
58
58
  `lastSeen=${record.lastSeenAt})`,
59
59
  );
60
60
  } catch (err) {
61
- cliProviderLog(
62
- "error",
63
- `failed to reap session ${record.agent}/${record.model} at ${path}`,
61
+ log.error(`failed to reap session ${record.agent}/${record.model} at ${path}`,
64
62
  err,
65
63
  );
66
64
  }
@@ -11,11 +11,15 @@ import {
11
11
  unlinkSync,
12
12
  writeFileSync,
13
13
  } from "node:fs";
14
+ import { createLogger } from "../shared/logger.js";
14
15
  import { join } from "node:path";
15
16
  import { homedir } from "node:os";
16
17
  import { createHash, randomUUID } from "node:crypto";
17
18
  import type { CliSessionKey, CliSessionRecord } from "./types.js";
18
19
 
20
+ const sessionLog = createLogger("cli_provider");
21
+ sessionLog.debug("cli-provider sessions module loaded");
22
+
19
23
  export type { CliSessionKey, CliSessionRecord } from "./types.js";
20
24
 
21
25
  /** Prefix for per-process ids used before the real pi session UUID is known. */