@automagik/genie 4.260411.1 → 4.260411.2

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 (98) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.genie/agents/metrics-updater/runs.jsonl +1 -0
  3. package/.genie/agents/metrics-updater/state.json +2 -2
  4. package/.github/workflows/ci.yml +16 -9
  5. package/README.md +8 -10
  6. package/package.json +1 -1
  7. package/plugins/genie/.claude-plugin/plugin.json +1 -1
  8. package/plugins/genie/package.json +1 -1
  9. package/.genie/wishes/genie-wishes-backup/agent-flexibility-guide/WISH.md +0 -155
  10. package/.genie/wishes/genie-wishes-backup/agent-stability-hardening/WISH.md +0 -346
  11. package/.genie/wishes/genie-wishes-backup/auto-orchestrate/WISH.md +0 -232
  12. package/.genie/wishes/genie-wishes-backup/daily-metrics-agent/WISH.md +0 -360
  13. package/.genie/wishes/genie-wishes-backup/docs-overhaul/WISH.md +0 -238
  14. package/.genie/wishes/genie-wishes-backup/docs-readme-review/AUDIT-REPORT.md +0 -227
  15. package/.genie/wishes/genie-wishes-backup/docs-readme-review/WISH.md +0 -175
  16. package/.genie/wishes/genie-wishes-backup/dx-800-closeout/WISH.md +0 -160
  17. package/.genie/wishes/genie-wishes-backup/feature-matrix-page/WISH.md +0 -97
  18. package/.genie/wishes/genie-wishes-backup/fire-and-forget/WISH.md +0 -282
  19. package/.genie/wishes/genie-wishes-backup/fix-agent-join-delay/WISH.md +0 -92
  20. package/.genie/wishes/genie-wishes-backup/fix-cli-polish/WISH.md +0 -197
  21. package/.genie/wishes/genie-wishes-backup/fix-depends-parser/WISH.md +0 -89
  22. package/.genie/wishes/genie-wishes-backup/fix-dispatch-initial-prompt/WISH.md +0 -67
  23. package/.genie/wishes/genie-wishes-backup/fix-first-run/WISH.md +0 -98
  24. package/.genie/wishes/genie-wishes-backup/fix-genie-v4-stability/WISH.md +0 -224
  25. package/.genie/wishes/genie-wishes-backup/fix-metrics-agent/WISH.md +0 -97
  26. package/.genie/wishes/genie-wishes-backup/fix-native-inbox/WISH.md +0 -93
  27. package/.genie/wishes/genie-wishes-backup/fix-omni-bridge-hardening/WISH.md +0 -87
  28. package/.genie/wishes/genie-wishes-backup/fix-release-blockers/WISH.md +0 -184
  29. package/.genie/wishes/genie-wishes-backup/fix-session-continue-fallback/WISH.md +0 -215
  30. package/.genie/wishes/genie-wishes-backup/fix-session-hook-channel/WISH.md +0 -141
  31. package/.genie/wishes/genie-wishes-backup/fix-session-uuid-resume/WISH.md +0 -164
  32. package/.genie/wishes/genie-wishes-backup/fix-short-name-resolver/WISH.md +0 -86
  33. package/.genie/wishes/genie-wishes-backup/fix-task-project/WISH.md +0 -93
  34. package/.genie/wishes/genie-wishes-backup/fix-team-lead-exit/WISH.md +0 -112
  35. package/.genie/wishes/genie-wishes-backup/fix-team-lead-polling/WISH.md +0 -62
  36. package/.genie/wishes/genie-wishes-backup/fix-test-safety/WISH.md +0 -151
  37. package/.genie/wishes/genie-wishes-backup/fix-tmux-dual-statusbar/WISH.md +0 -162
  38. package/.genie/wishes/genie-wishes-backup/fix-tmux-session-explosion/WISH.md +0 -116
  39. package/.genie/wishes/genie-wishes-backup/fix-trust-prompt/WISH.md +0 -159
  40. package/.genie/wishes/genie-wishes-backup/genie-app-v2-ui/WISH.md +0 -936
  41. package/.genie/wishes/genie-wishes-backup/genie-base-skill/WISH.md +0 -138
  42. package/.genie/wishes/genie-wishes-backup/genie-boards-workflows/WISH.md +0 -345
  43. package/.genie/wishes/genie-wishes-backup/genie-dx-polish/WISH.md +0 -197
  44. package/.genie/wishes/genie-wishes-backup/genie-export-import/WISH.md +0 -291
  45. package/.genie/wishes/genie-wishes-backup/genie-final-polish/WISH.md +0 -206
  46. package/.genie/wishes/genie-wishes-backup/genie-hacks-community-docs/WISH.md +0 -195
  47. package/.genie/wishes/genie-wishes-backup/genie-hardening/WISH.md +0 -241
  48. package/.genie/wishes/genie-wishes-backup/genie-item-registry/WISH.md +0 -341
  49. package/.genie/wishes/genie-wishes-backup/genie-metaverse/WISH.md +0 -339
  50. package/.genie/wishes/genie-wishes-backup/genie-observability/WISH.md +0 -203
  51. package/.genie/wishes/genie-wishes-backup/genie-omni-marriage/WISH.md +0 -322
  52. package/.genie/wishes/genie-wishes-backup/genie-orchestration-fix/WISH.md +0 -236
  53. package/.genie/wishes/genie-wishes-backup/genie-resume/WISH.md +0 -273
  54. package/.genie/wishes/genie-wishes-backup/genie-scheduler/WISH.md +0 -243
  55. package/.genie/wishes/genie-wishes-backup/genie-simulations/WISH.md +0 -488
  56. package/.genie/wishes/genie-wishes-backup/genie-stats-command/WISH.md +0 -148
  57. package/.genie/wishes/genie-wishes-backup/genie-task-tables/WISH.md +0 -97
  58. package/.genie/wishes/genie-wishes-backup/genie-workflow-engine/WISH.md +0 -60
  59. package/.genie/wishes/genie-wishes-backup/hook-only-first-install/WISH.md +0 -108
  60. package/.genie/wishes/genie-wishes-backup/inbox-driven-sessions/WISH.md +0 -254
  61. package/.genie/wishes/genie-wishes-backup/messaging-refresh/WISH.md +0 -215
  62. package/.genie/wishes/genie-wishes-backup/multi-agent-session-isolation/WISH.md +0 -158
  63. package/.genie/wishes/genie-wishes-backup/omni-session-isolation/WISH.md +0 -125
  64. package/.genie/wishes/genie-wishes-backup/parallel-execution/WISH.md +0 -220
  65. package/.genie/wishes/genie-wishes-backup/pg-state-migration/WISH.md +0 -134
  66. package/.genie/wishes/genie-wishes-backup/pg-total-migration/WISH.md +0 -329
  67. package/.genie/wishes/genie-wishes-backup/pgserve-embed/WISH.md +0 -229
  68. package/.genie/wishes/genie-wishes-backup/qa-dev-to-main/WISH.md +0 -232
  69. package/.genie/wishes/genie-wishes-backup/readme-v4-agent-first/WISH.md +0 -378
  70. package/.genie/wishes/genie-wishes-backup/resilient-messaging/WISH.md +0 -198
  71. package/.genie/wishes/genie-wishes-backup/resilient-resume/WISH.md +0 -86
  72. package/.genie/wishes/genie-wishes-backup/session-auto-create/WISH.md +0 -36
  73. package/.genie/wishes/genie-wishes-backup/session-continue-by-name/WISH.md +0 -222
  74. package/.genie/wishes/genie-wishes-backup/skills-v4-upgrade/WISH.md +0 -266
  75. package/.genie/wishes/genie-wishes-backup/stable-release-fixes/WISH.md +0 -211
  76. package/.genie/wishes/genie-wishes-backup/task-auto-close-on-merge/WISH.md +0 -79
  77. package/.genie/wishes/genie-wishes-backup/task-external-linking/WISH.md +0 -72
  78. package/.genie/wishes/genie-wishes-backup/task-lifecycle-foundation/WISH.md +0 -1066
  79. package/.genie/wishes/genie-wishes-backup/task-projects/WISH.md +0 -235
  80. package/.genie/wishes/genie-wishes-backup/team-lead-minimal/WISH.md +0 -124
  81. package/.genie/wishes/genie-wishes-backup/test-pg-ram-isolation/TRACE.md +0 -66
  82. package/.genie/wishes/genie-wishes-backup/test-pg-ram-isolation/WISH.md +0 -225
  83. package/.genie/wishes/genie-wishes-backup/test-schema-isolation/WISH.md +0 -147
  84. package/.genie/wishes/genie-wishes-backup/tmux-split-tabbar/WISH.md +0 -255
  85. package/.genie/wishes/genie-wishes-backup/tmux-tui/WISH.md +0 -186
  86. package/.genie/wishes/genie-wishes-backup/transcript-docs/WISH.md +0 -137
  87. package/.genie/wishes/genie-wishes-backup/unified-executor-layer/AUDIT.md +0 -322
  88. package/.genie/wishes/genie-wishes-backup/unified-executor-layer/WISH.md +0 -782
  89. package/.genie/wishes/genie-wishes-backup/unified-omni-bridge/INTEGRATION-FROM-OMNI.md +0 -212
  90. package/.genie/wishes/genie-wishes-backup/unified-omni-bridge/WISH.md +0 -416
  91. package/.genie/wishes/genie-wishes-backup/unify-bridge-revamp-skills/WISH.md +0 -271
  92. package/.genie/wishes/genie-wishes-backup/unique-leader-names/WISH.md +0 -349
  93. package/.genie/wishes/genie-wishes-backup/v3-fixes-release/WISH.md +0 -219
  94. package/.genie/wishes/genie-wishes-backup/v4-critical-fixes/WISH.md +0 -197
  95. package/.genie/wishes/genie-wishes-backup/voice-personality-pass/WISH.md +0 -143
  96. package/.genie/wishes/genie-wishes-backup/work-fire-forget/WISH.md +0 -160
  97. package/.genie/wishes/genie-wishes-backup/workflow-engine-runtime/WISH.md +0 -310
  98. package/.genie/wishes/genie-wishes-backup/worktree-out-of-repo/WISH.md +0 -139
@@ -10,7 +10,7 @@
10
10
  "plugins": [
11
11
  {
12
12
  "name": "genie",
13
- "version": "4.260411.1",
13
+ "version": "4.260411.2",
14
14
  "source": "./plugins/genie",
15
15
  "description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, wish them into plans, make with parallel agents, ship as one team. A coding genie that grows with your project."
16
16
  }
@@ -21,3 +21,4 @@
21
21
  {"timestamp":"2026-04-06T12:29:47.000Z","duration_ms":12500,"api_calls":0,"tools_generated":1,"errors":["gh_cli_unavailable: fallback to last_metrics from state.json"],"metrics":{"releases_24h":2,"merged_prs_7d":35,"avg_merge_time_h":0.3,"ship_rate_pct":85}}
22
22
  {"timestamp":"2026-04-07T12:04:30Z","duration_ms":27000,"api_calls":0,"tools_generated":0,"errors":["gh CLI not available","no GitHub token or MCP GitHub tools present in session"],"status":"failed","fallback":false,"metrics":null}
23
23
  {"timestamp":"2026-04-08T00:00:00.000Z","duration_ms":18000,"api_calls":0,"tools_generated":0,"errors":["gh CLI not available","GitHub MCP tools not present in session","fallback data older than current README — README update skipped"],"status":"failed","fallback":false,"metrics":null}
24
+ {"timestamp":"2026-04-11T12:35:40Z","duration_ms":72153,"api_calls":0,"tools_generated":0,"errors":["gh CLI not available","GitHub MCP tools not present in session"],"status":"success","fallback":true,"metrics":{"releases_24h":2,"merged_prs_7d":35,"avg_merge_time_h":0.3,"ship_rate_pct":85}}
@@ -1,6 +1,6 @@
1
1
  {
2
- "last_run": "2026-04-08T00:00:00.000Z",
3
- "last_run_status": "failed",
2
+ "last_run": "2026-04-11T12:35:40.000Z",
3
+ "last_run_status": "success",
4
4
  "last_metrics": {
5
5
  "releases_24h": 2,
6
6
  "merged_prs_7d": 35,
@@ -42,15 +42,16 @@ jobs:
42
42
  with:
43
43
  bun-version: "1.3.11"
44
44
 
45
- - name: Cache bun packages
46
- uses: actions/cache@v4
47
- with:
48
- path: ~/.bun/install/cache
49
- key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
50
- restore-keys: |
51
- bun-${{ runner.os }}-
52
-
45
+ # Per-run scratch cache dir. Prior config used a persistent
46
+ # ~/.bun/install/cache restored via actions/cache, which cross-
47
+ # polluted runs on the self-hosted Blacksmith runner and was
48
+ # suspected of serving stale transpile artifacts on flaky runs.
49
+ # Scoping to ${{ runner.temp }}/<run-id>/<run-attempt> gives
50
+ # every attempt a clean cache without sacrificing dep download
51
+ # speed (Blacksmith has fast registry access).
53
52
  - name: Install dependencies
53
+ env:
54
+ BUN_INSTALL_CACHE_DIR: ${{ runner.temp }}/bun-cache-${{ github.run_id }}-${{ github.run_attempt }}
54
55
  run: bun install
55
56
 
56
57
  - name: Build
@@ -65,8 +66,14 @@ jobs:
65
66
  - name: Dead code check (knip)
66
67
  run: bunx knip
67
68
 
69
+ # No `|| bun test` retry. If the test suite is flaky, the retry
70
+ # masks the signal and causes cache corruption when two overlapping
71
+ # bun processes race on the install cache. Surface real failures;
72
+ # root-cause the flakes in #<bun-test-hang-issue>.
68
73
  - name: Test
69
- run: bun test || bun test
74
+ env:
75
+ BUN_INSTALL_CACHE_DIR: ${{ runner.temp }}/bun-cache-${{ github.run_id }}-${{ github.run_attempt }}
76
+ run: bun test
70
77
 
71
78
  publish-next:
72
79
  name: Publish @next
package/README.md CHANGED
@@ -27,16 +27,14 @@
27
27
  <!-- METRICS:START -->
28
28
  <p align="center">
29
29
 
30
- | Metric | 7 days | 24h |
31
- |--------|--------|-----|
32
- | Commits | 445 | 38 |
33
- | Lines changed | 57,462 | 3,917 |
34
- | Files touched | 1,062 | 80 |
35
- | Merged PRs | 87 | 10 |
36
- | npm releases | 68 | 7 |
37
- | Avg merge time | 3.3h | 5.4h |
38
-
39
- *Last updated: 2026-04-07*
30
+ | Metric | Value |
31
+ |--------|-------|
32
+ | Releases / day | 2 |
33
+ | Merged PRs (7d) | 35 |
34
+ | Avg merge time | 0.3h |
35
+ | SHIP rate (7d) | 85% |
36
+
37
+ *Last updated: 2026-04-11*
40
38
  </p>
41
39
  <!-- METRICS:END -->
42
40
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/genie",
3
- "version": "4.260411.1",
3
+ "version": "4.260411.2",
4
4
  "description": "Collaborative terminal toolkit for human + AI workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie",
3
- "version": "4.260411.1",
3
+ "version": "4.260411.2",
4
4
  "description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, turn them into wishes, execute with /work, validate with /review, and ship as one team.",
5
5
  "author": {
6
6
  "name": "Namastex Labs"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genie-plugin",
3
- "version": "4.260411.1",
3
+ "version": "4.260411.2",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for genie bundled CLIs",
6
6
  "type": "module",
@@ -1,155 +0,0 @@
1
- # Wish: Agent Flexibility Guide (Provider Switching + BYOA)
2
-
3
- | Field | Value |
4
- |-------|-------|
5
- | **Status** | APPROVED |
6
- | **Slug** | `agent-flexibility-guide` |
7
- | **Date** | 2026-03-24 |
8
-
9
- ## Summary
10
-
11
- Document how to use Genie with different AI agents. Create a new page showing provider switching patterns, /spawn --provider flag usage, auto-respawn templates, and real multi-provider team examples. Position Genie as provider-agnostic.
12
-
13
- ## Scope
14
-
15
- ### IN
16
- - New page: `genie/concepts/byoa.mdx` — BYOA positioning, examples, agent neutrality
17
- - Document `/spawn --provider` flag with examples
18
- - Show provider switching patterns (Claude ↔ Codex ↔ BYOA)
19
- - Document auto-respawn template system
20
- - Real examples: multi-provider teams, cost optimization, failover patterns
21
- - Update `docs.json` to include BYOA concept page
22
-
23
- ### OUT
24
- - Automatic failover logic (manual only, documented as patterns)
25
- - Custom agent implementation guide (separate wish)
26
- - Testing harness for agent compatibility (out of scope)
27
-
28
- ## Decisions
29
-
30
- | Decision | Rationale |
31
- |----------|-----------|
32
- | New concept page | BYOA deserves first-class documentation, not buried in skills |
33
- | `/spawn --provider` examples | Users need to know how to actually use it |
34
- | Real patterns over theory | Show actual multi-provider teams, cost models |
35
-
36
- ## Success Criteria
37
-
38
- - [ ] `genie/concepts/byoa.mdx` created with BYOA positioning
39
- - [ ] `/spawn --provider` flag documented with 5+ examples
40
- - [ ] Auto-respawn template system explained
41
- - [ ] 3 real multi-provider team patterns shown (cost optimization, specialization, failover)
42
- - [ ] BYOA concept in docs.json navigation
43
- - [ ] No broken links
44
- - [ ] Tone: vendor-neutral, empowering
45
-
46
- ## Execution Strategy
47
-
48
- ### Wave 1
49
- | Group | Agent | Description |
50
- |-------|-------|-------------|
51
- | 1 | writer | Create BYOA concept page + /spawn --provider docs |
52
- | 2 | writer | Multi-provider patterns + examples |
53
-
54
- ### Wave 2
55
- | Group | Agent | Description |
56
- |-------|-------|-------------|
57
- | 3 | reviewer | Validate accuracy, no broken links, tone consistent |
58
-
59
- ## Execution Groups
60
-
61
- ### Group 1: BYOA Concept Page
62
-
63
- **Goal:** Create new page explaining Genie's provider agnosticism.
64
-
65
- **Deliverables:**
66
- 1. `genie/concepts/byoa.mdx` with:
67
- - Definition: BYOA = Bring Your Own Agent
68
- - Genie doesn't care which agent backs workers
69
- - List providers: Claude Code, Codex, Gemini CLI, custom
70
- - `/spawn --provider <provider>` flag usage
71
- - Auto-respawn template system (if agent goes offline, respawned from saved config)
72
- - Why it matters: future-proofs, no vendor lock-in
73
-
74
- **Acceptance Criteria:**
75
- - [ ] File exists at `/tmp/automagik-docs/genie/concepts/byoa.mdx`
76
- - [ ] Explains /spawn --provider flag
77
- - [ ] Lists 5+ provider options
78
- - [ ] Auto-respawn system documented
79
- - [ ] No broken links
80
-
81
- **Validation:**
82
- ```bash
83
- grep -q "BYOA\|--provider\|provider" /tmp/automagik-docs/genie/concepts/byoa.mdx
84
- grep -q "auto-respawn\|template" /tmp/automagik-docs/genie/concepts/byoa.mdx
85
- ```
86
-
87
- **depends-on:** none
88
-
89
- ---
90
-
91
- ### Group 2: Multi-Provider Patterns
92
-
93
- **Goal:** Show 3 real patterns for using different agents together.
94
-
95
- **Deliverables:**
96
- 1. Three patterns in BYOA page:
97
- - **Pattern 1: Specialization** — Claude for reasoning, Codex for parsing, BYOA for domain logic
98
- - **Pattern 2: Cost Optimization** — Use Codex for fast iteration, Claude for final review
99
- - **Pattern 3: Manual Fallback** — If one provider is down, spawn with another (not automatic)
100
-
101
- 2. Each pattern includes:
102
- - Problem statement
103
- - Solution (how to do it)
104
- - Code example (`genie spawn --provider <provider>`)
105
- - Benefit + trade-offs
106
- - When to use
107
-
108
- **Acceptance Criteria:**
109
- - [ ] 3 patterns documented
110
- - [ ] Each has: problem, solution, code, benefit, when-to-use
111
- - [ ] Examples are realistic, not aspirational
112
- - [ ] Code examples show actual --provider flags
113
-
114
- **Validation:**
115
- ```bash
116
- grep -c "Pattern\|Example" /tmp/automagik-docs/genie/concepts/byoa.mdx
117
- grep "genie spawn.*--provider" /tmp/automagik-docs/genie/concepts/byoa.mdx
118
- ```
119
-
120
- **depends-on:** 1
121
-
122
- ---
123
-
124
- ### Group 3: Review
125
-
126
- **Goal:** Validate accuracy and consistency.
127
-
128
- **Deliverables:**
129
- 1. Checklist:
130
- - `/spawn --provider` syntax is accurate (not invented)
131
- - Patterns are realistic (not aspirational)
132
- - Links to other doc pages work
133
- - Tone is neutral (no vendor criticism)
134
- - Examples use actual provider names
135
-
136
- **Acceptance Criteria:**
137
- - [ ] No broken links
138
- - [ ] Patterns match actual Genie capabilities
139
- - [ ] Tone is neutral and empowering
140
-
141
- **Validation:**
142
- ```bash
143
- # Check for invented features
144
- ! grep -q "automatic failover\|auto-failover" /tmp/automagik-docs/genie/concepts/byoa.mdx
145
- ```
146
-
147
- **depends-on:** 1, 2
148
-
149
- ## Files to Create/Modify
150
-
151
- ```
152
- /tmp/automagik-docs/genie/concepts/byoa.mdx (create)
153
- /tmp/automagik-docs/docs.json (add BYOA page to navigation)
154
- ```
155
-
@@ -1,346 +0,0 @@
1
- # Wish: Agent Stability Hardening + Remote Approval
2
-
3
- | Field | Value |
4
- |-------|-------|
5
- | **Status** | APPROVED |
6
- | **Slug** | `agent-stability-hardening` |
7
- | **Date** | 2026-04-08 |
8
- | **Design** | [DESIGN.md](../../brainstorms/agent-stability-hardening/DESIGN.md) |
9
- | **GitHub Issues** | #1094, #1093, #1064 |
10
- | **Repo** | automagik-dev/genie |
11
-
12
- ## Summary
13
-
14
- Fix three agent runtime reliability bugs (permission deadlock, clipboard breakage, silent message loss) and introduce a new `remoteApproval` permission mode that routes tool-use approval requests to humans via Omni (WhatsApp) and the Genie desktop app. This transforms the broken permission system from a source of deadlocks into a powerful human-in-the-loop control plane.
15
-
16
- ## Scope
17
-
18
- ### IN
19
- - Fix `permissionMode` spread override that causes agent deadlock (#1094)
20
- - Change scaffold default from `permissionMode: default` to `bypassPermissions`
21
- - Defense-in-depth: strip `permissionMode` from `translateSdkConfig`, call `ensureTeammateBypassPermissions` at SDK spawn
22
- - New `permissionMode: remoteApproval` with PG-backed approval queue
23
- - Omni approval frontend: WhatsApp message + reaction/text reply approval
24
- - App approval frontend: toast notification + interactive chat message with Approve/Deny/Preview
25
- - Configurable approve/deny tokens in `workspace.json`
26
- - Fix `osc52-copy.sh` to use `$SSH_TTY` as primary clipboard target (#1093)
27
- - Add `GENIE_TMUX_MOUSE=off` env var opt-out
28
- - Inbox delivery retry (3x) with escalation to team-lead (#1064)
29
- - Fix `isTeamActive` to check per-agent pane liveness
30
-
31
- ### OUT
32
- - WhatsApp interactive buttons (requires Business API — text reply + reactions are universal)
33
- - Per-agent approval config (workspace-level is sufficient)
34
- - Approval audit dashboard UI (PG table is queryable, UI deferred)
35
- - Full inbox-watcher redesign (incremental fix only)
36
- - OSC52 terminal compatibility matrix testing (fix the script, document Shift workaround)
37
-
38
- ## Decisions
39
-
40
- | # | Decision | Rationale |
41
- |---|----------|-----------|
42
- | D1 | Strip `permissionMode` from `translateSdkConfig()` | SDK executor must always bypass — frontmatter `permissionMode` only meaningful for tmux CLI path |
43
- | D2 | Scaffold default `bypassPermissions` | Current `default` causes deadlock for every new agent |
44
- | D3 | PG LISTEN/NOTIFY for approval resolution | Proven pattern (mailbox delivery), works cross-process |
45
- | D4 | Accept both text reply and reaction emoji | Channel-agnostic — works on WhatsApp, Telegram, Slack |
46
- | D5 | Configurable approve/deny tokens in `workspace.json` | Multilingual support ("sim"/"nao"), custom emoji |
47
- | D6 | Timeout 300s default, `defaultAction: deny` | Safe default — no unauthorized tool use |
48
- | D7 | Mode name: `remoteApproval` | Transport-agnostic — works via Omni, app, future channels |
49
- | D8 | Toast + in-chat for app UI | Toast alerts from any tab, chat message is persistent and actionable |
50
- | D9 | Medium preview for Omni, full via app Preview button | WhatsApp can't handle 500-line diffs |
51
- | D10 | `$SSH_TTY` as primary OSC52 target | More reliable than `who -m` in nested tmux |
52
- | D11 | `GENIE_TMUX_MOUSE=off` env opt-out, default on | Preserves behavior, escape hatch for SSH users |
53
- | D12 | 3 delivery retries then escalate to team-lead | Matches existing `spawnFailures` pattern |
54
-
55
- ## Success Criteria
56
-
57
- - [ ] Agent with `permissionMode: bypassPermissions` (new scaffold default) executes tools without approval prompt
58
- - [ ] Agent with `permissionMode: remoteApproval` blocks on tool use, writes approval to PG
59
- - [ ] Approval request appears in genie-app chat as interactive message with Approve/Deny/Preview
60
- - [ ] Approval request delivered via Omni to configured WhatsApp chat
61
- - [ ] Human approves via WhatsApp reaction (configurable, default 👍) — agent resumes within 2s
62
- - [ ] Human approves via WhatsApp text reply (configurable, default "y") — agent resumes within 2s
63
- - [ ] Human approves via app Approve button — agent resumes within 1s
64
- - [ ] Timeout (300s default) with no response — auto-deny
65
- - [ ] Custom approve/deny tokens work from `workspace.json`
66
- - [ ] `osc52-copy.sh` uses `$SSH_TTY` as primary clipboard target
67
- - [ ] `GENIE_TMUX_MOUSE=off` disables mouse capture, native Cmd+C works
68
- - [ ] `deliverToPane()` failure triggers retry (3x) then escalation to team-lead
69
- - [ ] `translateSdkConfig()` never copies `permissionMode` into SDK options
70
- - [ ] `ensureTeammateBypassPermissions()` called at SDK executor spawn path
71
- - [ ] Existing tests pass (`tsc --noEmit` + `biome check`)
72
-
73
- ## Execution Strategy
74
-
75
- ### Wave 1 (parallel — independent bug fixes)
76
- | Group | Agent | Description |
77
- |-------|-------|-------------|
78
- | 1 | engineer | Permission fix: spread order, strip translateSdkConfig, scaffold default, ensureTeammate |
79
- | 5 | engineer | OSC52 clipboard: `$SSH_TTY` in osc52-copy.sh, `GENIE_TMUX_MOUSE` env opt-out |
80
- | 6 | engineer | Inbox retry: delivery_status column, retry loop, escalation, isAgentAlive |
81
-
82
- ### Wave 2 (after Group 1 — approval core depends on permission system)
83
- | Group | Agent | Description |
84
- |-------|-------|-------------|
85
- | 2 | engineer | Remote approval core: PG table, migration, hook factory, workspace config, CLI command |
86
- | review-w1 | reviewer | Review Groups 1, 5, 6 |
87
-
88
- ### Wave 3 (after Group 2 — frontends depend on approval core)
89
- | Group | Agent | Description |
90
- |-------|-------|-------------|
91
- | 3 | engineer | Omni approval frontend: message handler, reaction/text matching, rate limiting |
92
- | 4 | engineer | App approval frontend: toast, chat message component, sidecar NATS subjects |
93
- | review-w2 | reviewer | Review Group 2 |
94
-
95
- ### Wave 4 (final)
96
- | Group | Agent | Description |
97
- |-------|-------|-------------|
98
- | review-w3 | reviewer | Review Groups 3, 4 |
99
- | qa | qa | End-to-end QA: all success criteria |
100
-
101
- ## Execution Groups
102
-
103
- ### Group 1: Permission Fix
104
- **Goal:** Eliminate the `permissionMode` spread override that causes agent deadlock.
105
-
106
- **Deliverables:**
107
- 1. `src/lib/providers/claude-sdk.ts` — Delete line that copies `permissionMode` from `translateSdkConfig()` (line 42). Reorder options spread so `permissionMode: 'bypassPermissions'` and `allowDangerouslySkipPermissions: true` come AFTER `...translatedSdk` and `...extraOptions`.
108
- 2. `src/lib/providers/claude-sdk.ts` — Call `ensureTeammateBypassPermissions()` at top of `runQuery()`.
109
- 3. `src/templates/index.ts` — Change `permissionMode: default` to `permissionMode: bypassPermissions` (line ~93).
110
- 4. `src/templates/genie-agents.md` — Change `permissionMode: default` to `permissionMode: bypassPermissions` (line ~9).
111
- 5. `src/lib/defaults.ts` — Change `permissionMode: 'default'` to `permissionMode: 'bypassPermissions'` (line ~27).
112
- 6. Update existing tests that assert `permissionMode: default` or the old spread order.
113
-
114
- **Acceptance Criteria:**
115
- - [ ] `translateSdkConfig()` output never contains `permissionMode` key
116
- - [ ] Options object has `permissionMode: 'bypassPermissions'` after all spreads
117
- - [ ] New scaffolded agent has `permissionMode: bypassPermissions` in frontmatter
118
- - [ ] `ensureTeammateBypassPermissions()` called before SDK query
119
-
120
- **Validation:**
121
- ```bash
122
- cd repos/genie && npx tsc --noEmit && npx biome check src/
123
- grep -r "permissionMode: 'default'" src/templates/ src/lib/defaults.ts && echo "FAIL: default still present" && exit 1 || echo "PASS"
124
- ```
125
-
126
- **depends-on:** none
127
-
128
- ---
129
-
130
- ### Group 2: Remote Approval Core
131
- **Goal:** Build the PG-backed approval queue and SDK hook that blocks until a human decides.
132
-
133
- **Deliverables:**
134
- 1. `src/db/migrations/030_approvals.sql` — Create `approvals` table with columns: `id`, `executor_id`, `agent_name`, `tool_name`, `tool_input_preview`, `decision` (pending/allow/deny), `decided_by`, `decided_at`, `timeout_at`, `created_at`. Add trigger `notify_approval_resolved` that fires `pg_notify('genie_approval_resolved', id)` on decision change from pending.
135
- 2. `src/lib/providers/claude-sdk-remote-approval.ts` — New file. Export `createRemoteApprovalGate(config)` that returns a PreToolUse hook. Hook inserts approval row, subscribes to LISTEN channel, safety-net polls every 5s, returns allow/deny on resolution or timeout.
136
- 3. `src/lib/providers/claude-sdk.ts` — When `sdkConfig.permissionMode === 'remoteApproval'`, wire `createRemoteApprovalGate` as PreToolUse hook instead of the standard permission gate. Keep `permissionMode: 'bypassPermissions'` in SDK options (the hook handles blocking).
137
- 4. `src/lib/workspace.ts` — Add `permissions` section to workspace schema: `approveTokens`, `denyTokens`, `timeout`, `defaultAction`, `omniChat`, `omniInstance`.
138
- 5. `src/term-commands/approval.ts` — New CLI command `genie approval request --tool <name> --input <preview> --agent <name> --wait` for tmux-path agents. Writes to same PG approvals table, blocks until resolved. Also `genie approval resolve <id> --decision allow|deny --by <actor>`.
139
- 6. Register approval CLI commands in `src/genie.ts`.
140
-
141
- **Acceptance Criteria:**
142
- - [ ] `approvals` table created by migration
143
- - [ ] `genie approval request --tool Write --input "test" --agent test-agent --wait` blocks and returns on resolve
144
- - [ ] `genie approval resolve <id> --decision allow --by human` resolves pending approval within 2s
145
- - [ ] Timeout auto-resolves with configured `defaultAction`
146
- - [ ] Hook returns `{ permissionDecision: 'allow' }` or `'deny'` correctly
147
-
148
- **Validation:**
149
- ```bash
150
- cd repos/genie && npx tsc --noEmit && npx biome check src/
151
- ```
152
-
153
- **depends-on:** Group 1
154
-
155
- ---
156
-
157
- ### Group 3: Omni Approval Frontend
158
- **Goal:** Route approval requests to WhatsApp and accept human decisions via text reply or reaction.
159
-
160
- **Deliverables:**
161
- 1. `src/lib/providers/claude-sdk-remote-approval.ts` — Add Omni send on approval creation: format message with tool name + target + ~200 char preview. Read `omniChat` and `omniInstance` from workspace config. Use `omni send` CLI.
162
- 2. Omni incoming message handler — Match incoming text replies against `approveTokens`/`denyTokens` from workspace config. Match reaction emoji on the approval message. On match, call `genie approval resolve <id> --decision allow|deny --by <sender>`.
163
- 3. Rate limiting — If >3 pending approvals within 10s, batch into single summary message with count.
164
-
165
- **Acceptance Criteria:**
166
- - [ ] Approval request sends formatted WhatsApp message via Omni
167
- - [ ] Reply "y" on WhatsApp resolves approval as allow
168
- - [ ] Reply "n" resolves as deny
169
- - [ ] Reaction 👍 resolves as allow
170
- - [ ] Reaction 👎 resolves as deny
171
- - [ ] Custom tokens from workspace.json work
172
- - [ ] >3 rapid approvals are batched
173
-
174
- **Validation:**
175
- ```bash
176
- cd repos/genie && npx tsc --noEmit && npx biome check src/
177
- ```
178
-
179
- **depends-on:** Group 2
180
-
181
- ---
182
-
183
- ### Group 4: App Approval Frontend
184
- **Goal:** Show approval requests in the Genie desktop app as toasts and interactive chat messages.
185
-
186
- **Deliverables:**
187
- 1. `packages/genie-app/src-backend/index.ts` — Add NATS subjects: `genie.approval.request` (subscribe to PG LISTEN, publish to frontend), `genie.approval.resolve` (req/reply — update PG), `genie.approval.list` (req/reply — list pending).
188
- 2. `packages/genie-app/views/shared/ApprovalToast.tsx` — New component. Non-blocking toast notification when approval arrives. Shows agent name + tool name + "View in Chat" link. Auto-dismisses after 10s.
189
- 3. `packages/genie-app/views/` (chat view) — New `ApprovalMessage.tsx` component. Renders in chat as interactive card: tool info, Approve/Deny buttons, Preview expand. Buttons send NATS `genie.approval.resolve` request.
190
- 4. Wire toast into `App.tsx` — subscribe to `events.approval_request` NATS event, render `ApprovalToast`.
191
-
192
- **Acceptance Criteria:**
193
- - [ ] Toast appears when approval request fires
194
- - [ ] Chat message renders with Approve/Deny/Preview buttons
195
- - [ ] Approve button resolves approval, agent resumes within 1s
196
- - [ ] Deny button resolves approval, agent gets deny
197
- - [ ] Preview button shows full tool input
198
- - [ ] Agent state shows `permission` in AgentsView during pending approval
199
-
200
- **Validation:**
201
- ```bash
202
- cd repos/genie && npx tsc --noEmit && npx biome check src/ packages/
203
- ```
204
-
205
- **depends-on:** Group 2
206
-
207
- ---
208
-
209
- ### Group 5: OSC52 Clipboard Fix
210
- **Goal:** Fix clipboard copy over SSH and add mouse capture opt-out.
211
-
212
- **Deliverables:**
213
- 1. `scripts/tmux/osc52-copy.sh` — Add `$SSH_TTY` as primary target before `who -m` fallback:
214
- ```bash
215
- if [ -n "$SSH_TTY" ]; then
216
- printf '%s' "$seq" > "$SSH_TTY" 2>/dev/null || true
217
- fi
218
- ```
219
- 2. `scripts/tmux/genie.tmux.conf` — Wrap mouse setting: `if-shell '[ "$GENIE_TMUX_MOUSE" != "off" ]' 'set -g mouse on'`
220
- 3. `scripts/tmux/tui-tmux.conf` — Same conditional mouse wrapping.
221
- 4. `src/term-commands/serve.ts` — Conditional `set-option mouse on` only when `GENIE_TMUX_MOUSE !== 'off'`.
222
- 5. Update `src/__tests__/tmux-config.test.ts` if tests assert unconditional `mouse on`.
223
-
224
- **Acceptance Criteria:**
225
- - [ ] `osc52-copy.sh` tries `$SSH_TTY` before `who -m`
226
- - [ ] `GENIE_TMUX_MOUSE=off genie serve` starts without mouse capture
227
- - [ ] Default (no env var) preserves current mouse-on behavior
228
- - [ ] Existing tmux config tests pass
229
-
230
- **Validation:**
231
- ```bash
232
- cd repos/genie && grep -q 'SSH_TTY' scripts/tmux/osc52-copy.sh && echo "PASS: SSH_TTY present" || exit 1
233
- grep -q 'GENIE_TMUX_MOUSE' scripts/tmux/genie.tmux.conf && echo "PASS: mouse opt-out present" || exit 1
234
- npx tsc --noEmit && npx biome check src/
235
- ```
236
-
237
- **depends-on:** none
238
-
239
- ---
240
-
241
- ### Group 6: Inbox Delivery Retry + Escalation
242
- **Goal:** Stop messages from silently vanishing when target agent is unreachable.
243
-
244
- **Deliverables:**
245
- 1. `src/db/migrations/031_mailbox_delivery_status.sql` — Add columns to `mailbox` table: `delivery_status TEXT DEFAULT 'pending'` (pending/delivered/failed/escalated), `delivery_attempts INT DEFAULT 0`. Backfill: set existing rows with `delivered_at IS NOT NULL` to `delivery_status = 'delivered'`.
246
- 2. `src/lib/mailbox.ts` — Add `markFailed(messageId)` (increment attempts, set status=failed), `getRetryable(maxAttempts)` (return failed messages with attempts < max), `markEscalated(messageId)`.
247
- 3. `src/lib/protocol-router.ts` — In `deliverToPane()`, on failure call `mailbox.markFailed()` instead of silent return.
248
- 4. `src/lib/scheduler-daemon.ts` — New retry loop every 60s: `getRetryable(3)` → attempt `deliverToPane()` → on 3rd failure call `mailbox.markEscalated()` + send escalation to team-lead via mailbox.
249
- 5. `src/lib/team-auto-spawn.ts` — Add `isAgentAlive(agentName): Promise<boolean>` that checks if the specific agent's pane exists (not just the team window). Export for use by inbox-watcher.
250
- 6. `src/lib/inbox-watcher.ts` — Use `isAgentAlive` for per-recipient check alongside existing `isTeamActive`.
251
-
252
- **Acceptance Criteria:**
253
- - [ ] Failed delivery increments `delivery_attempts` and sets `delivery_status = 'failed'`
254
- - [ ] Retry loop picks up failed messages and re-attempts delivery
255
- - [ ] After 3 failures, message is escalated to team-lead
256
- - [ ] `isAgentAlive` correctly detects dead agent panes
257
- - [ ] Existing mailbox tests pass
258
-
259
- **Validation:**
260
- ```bash
261
- cd repos/genie && npx tsc --noEmit && npx biome check src/
262
- ```
263
-
264
- **depends-on:** none
265
-
266
- ---
267
-
268
- ## QA Criteria
269
-
270
- _What must be verified on dev after merge._
271
-
272
- - [ ] Spawn agent with default frontmatter → tools execute without approval prompt (no deadlock)
273
- - [ ] Spawn agent with `permissionMode: remoteApproval` → tool use triggers approval request in PG
274
- - [ ] Approve via app chat → agent resumes, tool executes
275
- - [ ] Approve via WhatsApp reply "y" → agent resumes within 2s
276
- - [ ] Deny via WhatsApp reaction 👎 → agent gets deny, continues gracefully
277
- - [ ] Timeout with no response → auto-deny after configured timeout
278
- - [ ] SSH session: drag-select text, Cmd+C copies to clipboard (via OSC52)
279
- - [ ] `GENIE_TMUX_MOUSE=off` → Cmd+C works natively without OSC52
280
- - [ ] Send message to dead agent → message retried 3x → escalated to team-lead
281
- - [ ] No regressions: `tsc --noEmit`, `biome check`, existing test suite green
282
-
283
- ## Assumptions / Risks
284
-
285
- | Risk | Severity | Mitigation |
286
- |------|----------|------------|
287
- | PG LISTEN missed → hook blocks forever | High | 300s timeout + safety-net polling every 5s |
288
- | Multiple approvals flood WhatsApp | Medium | Rate limit: batch if >3 pending within 10s |
289
- | Approval latency slows agent execution | Medium | Only `remoteApproval` mode — `bypassPermissions` remains default |
290
- | PG approvals table grows unbounded | Low | TTL cleanup: resolved approvals >7d auto-purged by scheduler |
291
- | `$SSH_TTY` not set in all SSH configs | Low | Fallback chain: `$SSH_TTY` → `who -m` → stdout passthrough |
292
- | Inbox retry storms on dead agents | Low | Max 3 retries then escalate once and stop |
293
- | Omni not configured | Low | App UI works independently. If neither configured, timeout auto-denies. |
294
-
295
- ## Review Results
296
-
297
- _Populated by `/review` after execution completes._
298
-
299
- ---
300
-
301
- ## Files to Create/Modify
302
-
303
- ```
304
- # Group 1 — Permission Fix
305
- src/lib/providers/claude-sdk.ts (modify — spread order, strip permissionMode, ensureTeammate)
306
- src/templates/index.ts (modify — scaffold default)
307
- src/templates/genie-agents.md (modify — scaffold default)
308
- src/lib/defaults.ts (modify — builtin default)
309
- src/lib/providers/__tests__/claude-sdk.test.ts (modify — update assertions)
310
- src/__tests__/defaults.test.ts (modify — update assertions)
311
- src/__tests__/mini-wizard.test.ts (modify — update assertions)
312
-
313
- # Group 2 — Remote Approval Core
314
- src/db/migrations/030_approvals.sql (create)
315
- src/lib/providers/claude-sdk-remote-approval.ts (create)
316
- src/lib/providers/claude-sdk.ts (modify — wire remoteApproval hook)
317
- src/lib/workspace.ts (modify — permissions schema)
318
- src/term-commands/approval.ts (create)
319
- src/genie.ts (modify — register approval commands)
320
-
321
- # Group 3 — Omni Approval Frontend
322
- src/lib/providers/claude-sdk-remote-approval.ts (modify — add Omni send)
323
- src/lib/omni-approval-handler.ts (create — incoming message matching)
324
-
325
- # Group 4 — App Approval Frontend
326
- packages/genie-app/src-backend/index.ts (modify — approval NATS subjects)
327
- packages/genie-app/views/shared/ApprovalToast.tsx (create)
328
- packages/genie-app/views/shared/ApprovalMessage.tsx (create)
329
- packages/genie-app/src/App.tsx (modify — wire toast subscription)
330
- packages/genie-app/lib/subjects.ts (modify — add approval subjects)
331
-
332
- # Group 5 — OSC52 Clipboard Fix
333
- scripts/tmux/osc52-copy.sh (modify — SSH_TTY primary)
334
- scripts/tmux/genie.tmux.conf (modify — conditional mouse)
335
- scripts/tmux/tui-tmux.conf (modify — conditional mouse)
336
- src/term-commands/serve.ts (modify — conditional mouse)
337
- src/__tests__/tmux-config.test.ts (modify — update assertions)
338
-
339
- # Group 6 — Inbox Delivery Retry
340
- src/db/migrations/031_mailbox_delivery_status.sql (create)
341
- src/lib/mailbox.ts (modify — markFailed, getRetryable, markEscalated)
342
- src/lib/protocol-router.ts (modify — call markFailed on delivery failure)
343
- src/lib/scheduler-daemon.ts (modify — retry loop)
344
- src/lib/team-auto-spawn.ts (modify — isAgentAlive)
345
- src/lib/inbox-watcher.ts (modify — per-agent check)
346
- ```