@automagik/genie 4.260410.2 → 4.260410.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 (55) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.genie/brainstorm.md +61 -11
  3. package/.genie/wishes/_archive/agent-stability-hardening/WISH.md +346 -0
  4. package/.genie/wishes/_archive/brain-embeddings/WISH.md +72 -0
  5. package/.genie/wishes/_archive/brain-foundation/WISH.md +228 -0
  6. package/.genie/wishes/_archive/brain-identity-impl/WISH.md +72 -0
  7. package/.genie/wishes/_archive/brain-init-skill/WISH.md +57 -0
  8. package/.genie/wishes/_archive/brain-intelligence/WISH.md +83 -0
  9. package/.genie/wishes/_archive/brain-observability/WISH.md +70 -0
  10. package/.genie/wishes/_archive/brain-obsidian/WISH.md +1930 -0
  11. package/.genie/wishes/_archive/env-defaults-local-mode/WISH.md +148 -0
  12. package/.genie/wishes/_archive/genie-app/WISH.md +590 -0
  13. package/.genie/wishes/_archive/genie-layout-migration/WISH.md +292 -0
  14. package/.genie/wishes/_archive/genie-model-resolution/WISH.md +477 -0
  15. package/.genie/wishes/_archive/genie-onboarding-flow/WISH.md +453 -0
  16. package/.genie/wishes/_archive/omni-lifecycle-hardening/WISH.md +401 -0
  17. package/.genie/wishes/_archive/omni-skill-upgrade/WISH.md +309 -0
  18. package/.genie/wishes/_archive/omni-version-unify/WISH.md +257 -0
  19. package/.genie/wishes/_archive/os-services-orphan-leak/WISH.md +143 -0
  20. package/.genie/wishes/_archive/pgserve-daemon-ownership/WISH.md +140 -0
  21. package/.genie/wishes/_archive/remove-openclaw/WISH.md +178 -0
  22. package/.genie/wishes/_archive/rlmx-v02/WISH.md +478 -0
  23. package/.genie/wishes/_archive/rlmx-v03-cag/WISH.md +455 -0
  24. package/.genie/wishes/_archive/rlmx-v04-gemini3/WISH.md +533 -0
  25. package/.genie/wishes/_archive/session-capture-v2/WISH.md +452 -0
  26. package/.genie/wishes/_archive/session-ingester-perf/WISH.md +148 -0
  27. package/.genie/wishes/_archive/v4-database-layer/WISH.md +116 -0
  28. package/.genie/wishes/_archive/v4-hook-cli-safety/WISH.md +89 -0
  29. package/.genie/wishes/_archive/v4-message-routing/WISH.md +131 -0
  30. package/.genie/wishes/_archive/v4-session-executor/WISH.md +141 -0
  31. package/.genie/wishes/_archive/v4-spawn-resilience/WISH.md +176 -0
  32. package/.genie/wishes/_archive/v4-team-lifecycle/WISH.md +137 -0
  33. package/.genie/wishes/brain-benchmark-loop/WISH.md +130 -0
  34. package/.genie/wishes/brain-cag/WISH.md +37 -0
  35. package/.genie/wishes/brain-cag-v2-polish/WISH.md +177 -0
  36. package/.genie/wishes/brain-help-passthrough/WISH.md +159 -0
  37. package/.genie/wishes/brain-optimizer/WISH.md +59 -0
  38. package/.genie/wishes/crew-simplification/WISH.md +178 -0
  39. package/.genie/wishes/genie-app-v1/WISH.md +1098 -0
  40. package/.genie/wishes/genie-simulations/WISH.md +488 -0
  41. package/.genie/wishes/genie-skill-graph/WISH.md +354 -0
  42. package/.genie/wishes/omni-turn-based-dx/SESSION-LEARNINGS.md +53 -0
  43. package/.genie/wishes/omni-turn-based-dx/WISH.md +382 -0
  44. package/.genie/wishes/rlmx-dogfood/WISH.md +595 -0
  45. package/.genie/wishes/rlmx-integration/WISH.md +262 -0
  46. package/.genie/wishes/rlmx-readme/WISH.md +243 -0
  47. package/.genie/wishes/sac-agent/WISH.md +595 -0
  48. package/.genie/wishes/scaffold-auto-memory/WISH.md +168 -0
  49. package/.genie/wishes/sdk-executor-full/WISH.md +697 -0
  50. package/.genie/wishes/unified-executor-layer/WISH.md +732 -0
  51. package/.genie/wishes/workflow-action-engine/WISH.md +380 -0
  52. package/.genie/wishes/x-tool/WISH.md +254 -0
  53. package/package.json +1 -1
  54. package/plugins/genie/.claude-plugin/plugin.json +1 -1
  55. package/plugins/genie/package.json +1 -1
@@ -10,7 +10,7 @@
10
10
  "plugins": [
11
11
  {
12
12
  "name": "genie",
13
- "version": "4.260410.2",
13
+ "version": "4.260410.3",
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
  }
@@ -1,12 +1,62 @@
1
1
  # Brainstorm Jar
2
- ## Raw
3
- ## Simmering
4
- ## Ready
5
- ## Poured
6
- - **genie-simulations**Agent eval via real multi-turn Omni conversations, 9-dimension scoring, 100 scenarios per agent [WISH.md](.genie/wishes/genie-simulations/WISH.md)
7
- - **genie-metaverse**Per-workspace instances: unique ID, multi-agent detection, git-controlled publish with sim score gate [WISH.md](.genie/wishes/genie-metaverse/WISH.md)
8
- - **task-leader-architecture** — Task leader built-in role, --wish flag, autonomous lifecycle → [WISH.md](.genie/wishes/task-leader-architecture/WISH.md)
9
- - **skill-refresh** Refresh all 13 skills + orchestration rules rewrite [WISH.md](.genie/wishes/skill-refresh/WISH.md)
10
- - **deps-bump-readme-rewrite** — Deps bump + README rewrite (cognitive load positioning) [WISH.md](.genie/wishes/deps-bump-readme-rewrite/WISH.md)
11
- - **report-skill-plugin-rename** — /report skill + plugin rename + debug->trace → [WISH.md](.genie/wishes/report-skill-plugin-rename/WISH.md)
12
- - **genie-default-command** — tui rename + session-per-folder + onboarding hotfix [WISH.md](.genie/wishes/genie-default-command/WISH.md)
2
+
3
+ ## Sprint Backlog (next sprint — /review + /brainstorm queue)
4
+
5
+ ### Tier 1: Autonomous dispatch (dream-eligible)
6
+ - [scaffold-auto-memory](wishes/scaffold-auto-memory/WISH.md)READY. Auto-configure `autoMemoryEnabled`/`autoMemoryDirectory` in `.claude/settings.local.json` + seed `MEMORY.md` when `genie init agent <name>` scaffolds. Closes automagik-dev/genie#1106. Twin-genie reviewed: scope 2/5, risk 2/5, clarity 4/5.
7
+ - [brain-help-passthrough](wishes/brain-help-passthrough/WISH.md)READY. Add `addHelpText` footer to `genie brain --help` so users see the forwarded subcommands (status, health, init, search, etc.). Passthrough already works at runtime; help text just doesn't advertise it. Closes automagik-dev/genie#1118. Twin-genie reviewed: scope 1/5, risk 1/5, clarity 5/5.
8
+
9
+ ### Tier 2: Agent creation (brainstormwish)
10
+ - **brain-cag-v2** — NEW. Seamless brain→rlmx integration. Brain is the interface, rlmx is the engine. No direct `rlmx` CLI needed.
11
+ - **brain-optimizer-agent** — `/review` existing pipeline create `.genie/agents/brain-optimizer/` sub-agent that uses traces+grades.
12
+ - **rlmx-dogfood-agent** — `/review` rlmx create `.genie/agents/rlmx-dogfood/` sub-agent that uses rlmx on itself.
13
+
14
+ ### Tier 3: Investigation first
15
+ - **dir-scope-architecture** (automagik-dev/genie#1107) — BLOCKED on architecture decision. Twin-genie trace revealed the PG `agents` table has NO scope column; `dir add --global` and `dir add` hit the same row. Fix requires either (a) adding a scope column with migration, or (b) removing the `--global` flag and false success messaging. Human decision needed before any code change. NOT autonomous-friendly.
16
+ - **rlmx-ship-polish** — Merge rlmx-integration + rlmx-readme. `/review` then `/brainstorm`. Live API tests, version fix, README.
17
+ - **genie-studio** — `/review` genie repo app code → compare with genie-app-v1 wish → consolidate/rename.
18
+ - [sdk-executor-full](wishes/sdk-executor-full/WISH.md) — APPROVED. `/review` current 132 executor matches → `/brainstorm` gaps.
19
+ - [agent-stability-hardening](wishes/_archive/agent-stability-hardening/WISH.md) — SHIPPED (PR #1112). Verify on dev.
20
+ - [brain-benchmark-loop](wishes/brain-benchmark-loop/WISH.md) — IN_PROGRESS. `/review` progress → decide next step.
21
+
22
+ ## Deferred
23
+ - [omni-turn-based-dx](wishes/omni-turn-based-dx/WISH.md) — DRAFT. Foundational architecture, not sprint-sized.
24
+ - [unified-executor-layer](wishes/unified-executor-layer/WISH.md) — DRAFT. Depends on omni-turn-based-dx.
25
+ - [workflow-action-engine](wishes/workflow-action-engine/WISH.md) — DRAFT. Depends on genie-app-v1.
26
+ - [sac-agent](wishes/sac-agent/WISH.md) — DRAFT. Niche use case (Itaú Cartões).
27
+ - [crew-simplification](brainstorms/crew-simplification/DESIGN.md) — DRAFT. Housekeeping post-v1.
28
+ - [genie-skill-graph](wishes/genie-skill-graph/WISH.md) — DRAFT. Requires architecture work.
29
+ - tmux+sdk mode coexistence — flagged for future brainstorm.
30
+
31
+ ## Non-engineering (parked)
32
+ - [The Agentic Shift — Mini-Documentary](brainstorms/agentic-shift-documentary/DESIGN.md) — CRYSTALLIZED. 40-shot Veo3 script. Schedule when ready.
33
+ - Viralizador — Recurring DevRel content loop, not a shippable feature.
34
+
35
+ ## Poured (shipped)
36
+
37
+ All shipped wishes live in [`wishes/_archive/`](wishes/_archive/). Listed here for reference.
38
+
39
+ - [Agent Stability Hardening](wishes/_archive/agent-stability-hardening/WISH.md) — SHIPPED (PR #1112, 2026-04-09). Permission spread + remoteApproval + tmux mouse + inbox retry.
40
+ - [Session Capture v2](wishes/_archive/session-capture-v2/WISH.md) — SHIPPED (PR #825, 2026-04-09). Filewatch + lazy backfill + tool event extraction.
41
+ - [pgserve Daemon Ownership](wishes/_archive/pgserve-daemon-ownership/WISH.md) — SHIPPED (PR #827, 2026-04-09). Daemon owns PG, self-heal, doctor --fix.
42
+ - [os-services Orphan Leak](wishes/_archive/os-services-orphan-leak/WISH.md) — SHIPPED (PR #272 + #274, 2026-04-09). Layer 1+2 signal fix + orphan reaper + migration matchAll.
43
+ - [env-defaults-local-mode](wishes/_archive/env-defaults-local-mode/WISH.md) — SHIPPED (incremental, 2026-04-09). All 6 criteria met across multiple PRs.
44
+ - [Onboarding Overhaul](brainstorms/onboarding-overhaul/DRAFT.md) — ALL 3 SUB-WISHES SHIPPED:
45
+ - **1.** [genie-model-resolution](wishes/_archive/genie-model-resolution/WISH.md) — SHIPPED (QA 2026-04-08)
46
+ - **2.** [genie-onboarding-flow](wishes/_archive/genie-onboarding-flow/WISH.md) — SHIPPED (all 7 groups on dev)
47
+ - **3.** [genie-layout-migration](wishes/_archive/genie-layout-migration/WISH.md) — SHIPPED (in binary)
48
+ - [Brain Obsidian](wishes/_archive/brain-obsidian/WISH.md) — ALL 6 SUB-WISHES SHIPPED in @khal-os/brain v1.22.0:
49
+ - brain-foundation, brain-embeddings, brain-intelligence, brain-observability, brain-identity-impl, brain-init-skill
50
+ - [rlmx](wishes/_archive/rlmx-v04-gemini3/WISH.md) — v0.2 + v0.3 + v0.4 ALL SHIPPED (npm v0.260331.5)
51
+ - [Omni Lifecycle Hardening](wishes/_archive/omni-lifecycle-hardening/WISH.md) — SHIPPED (PR #359)
52
+ - [Omni Version Unify](brainstorms/omni-version-unify/DESIGN.md) — SHIPPED (PR #356)
53
+ - [Omni Skill Upgrade](wishes/_archive/omni-skill-upgrade/WISH.md) — SHIPPED (3-tier skills live)
54
+ - [remove-openclaw](wishes/_archive/remove-openclaw/WISH.md) — SHIPPED (absent from binary)
55
+ - **v4 Stability Sprint** — COMPLETE (2026-04-02). All 6 wishes merged: [v4-database-layer](wishes/_archive/v4-database-layer/WISH.md), [v4-hook-cli-safety](wishes/_archive/v4-hook-cli-safety/WISH.md), [v4-message-routing](wishes/_archive/v4-message-routing/WISH.md), [v4-session-executor](wishes/_archive/v4-session-executor/WISH.md), [v4-spawn-resilience](wishes/_archive/v4-spawn-resilience/WISH.md), [v4-team-lifecycle](wishes/_archive/v4-team-lifecycle/WISH.md).
56
+ - [Session Observability](brainstorms/session-observability/DESIGN.md) — CRYSTALLIZED → folds into session-capture-v2
57
+ - [X Tool](brainstorms/x-tool/DESIGN.md) — CRYSTALLIZED (WRS 100/100). Parked.
58
+
59
+ ## Killed
60
+ - [genie-app](wishes/_archive/genie-app/WISH.md) — superseded by genie-app-v1 / genie-studio
61
+ - [session-ingester-perf](wishes/_archive/session-ingester-perf/WISH.md) — superseded by session-capture-v2
62
+ - [brain-obsidian](wishes/_archive/brain-obsidian/WISH.md) (parent spec) — all children shipped, reference only
@@ -0,0 +1,346 @@
1
+ # Wish: Agent Stability Hardening + Remote Approval
2
+
3
+ | Field | Value |
4
+ |-------|-------|
5
+ | **Status** | SHIPPED |
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
+ ```
@@ -0,0 +1,72 @@
1
+ # Wish: brain-embeddings — Gemini Embedding 2, Vector Search, Multimodal
2
+
3
+ | Field | Value |
4
+ |-------|-------|
5
+ | **Status** | SHIPPED (verified 2026-04-08) |
6
+ | **Slug** | `brain-embeddings` |
7
+ | **Date** | 2026-03-27 |
8
+ | **Parent** | [brain-obsidian](../brain-obsidian/WISH.md) |
9
+ | **depends-on** | `brain-foundation` |
10
+ | **blocks** | `brain-intelligence` (semantic linking needs vectors) |
11
+
12
+ ## Summary
13
+
14
+ Add Gemini Embedding 2 Preview as the embedding engine. All 8 task types. Multimodal: text, images (PNG/JPEG), video (MP4/MOV ≤120s), audio (MP3/WAV ≤80s), PDF (≤6 pages). pgvector + pg_trgm extensions. RRF fusion (BM25 + vector + trigram). Media processing pipeline (ffmpeg format conversion, frame extraction, audio extraction from video). Matryoshka dimensions (768/1536/3072). Batch API (50% cheaper). Intent detection (regex vs NL vs symbol vs question vs claim).
15
+
16
+ **After this ships:** `genie brain search` finds meaning, not just keywords. Images, videos, and PDFs are searchable. Cross-modal search works (text query → image result).
17
+
18
+ ## Scope
19
+
20
+ ### IN
21
+ - Migration `002-brain-embeddings.sql`: pgvector + pg_trgm extensions, add embedding/media columns to brain_chunks and brain_documents
22
+ - `src/lib/brain/embedding.ts` — Gemini Embedding 2 client: all 8 task types, Matryoshka, Batch API, normalization for <3072 dims
23
+ - `src/lib/brain/media.ts` — format conversion (ffmpeg), frame extraction, audio extraction from video, derivative files (.desc.md, .transcript.md, .frames/)
24
+ - `src/lib/brain/intent.ts` — query intent detection: regex vs NL vs symbol vs question vs claim → route to optimal backend
25
+ - Extend `update.ts` — multimodal processing: images, video, audio, PDF. Auto-describe via Gemini Vision. Transcription (Groq → Gemini fallback). Double indexing.
26
+ - Extend `search.ts` — vector search (pgvector cosine), trigram (pg_trgm), RRF fusion (4 backends), cross-modal search (--image, --audio, --video), --modality filter, --task code, --intent
27
+ - Extend `brain_chunks` — embedding vector(3072), embed_model, embed_task, embed_dims, modality, media_path columns
28
+ - Extend `brain_documents` — description column (Gemini Vision auto-descriptions)
29
+ - `genie brain search` gains: --semantic, --hybrid, --task, --intent, --image, --audio, --video, --modality, --refs, --outline
30
+ - Absorbed from qmd: RRF fusion (~80 lines), search pipeline orchestration (~200 lines)
31
+ - Absorbed from grepika: intent detection patterns (~60 lines)
32
+
33
+ ### OUT
34
+ - rlmx / analyze (brain-intelligence)
35
+ - Wikilinks / link command (brain-intelligence)
36
+ - Traces / strategy (brain-observability)
37
+ - Full identity (brain-identity-impl)
38
+
39
+ ## Success Criteria
40
+
41
+ - [ ] pgvector and pg_trgm extensions loaded in pgserve
42
+ - [ ] `genie brain update` embeds text chunks via Gemini Embedding 2 (3072 dims stored in pgvector)
43
+ - [ ] `genie brain update` processes images (PNG/JPEG), generates .desc.md, embeds image + description
44
+ - [ ] `genie brain update` processes video (MP4/MOV ≤120s): embeds raw video, extracts audio separately, transcribes, embeds transcript
45
+ - [ ] `genie brain update` processes audio (MP3/WAV ≤80s): embeds raw audio, transcribes, embeds transcript
46
+ - [ ] `genie brain update` processes PDF (≤6 pages): embeds raw PDF, extracts text, embeds text chunks
47
+ - [ ] Unsupported formats auto-converted (OGG→MP3, WebP→PNG, etc.)
48
+ - [ ] `genie brain search "query" --semantic` returns vector cosine results
49
+ - [ ] `genie brain search "query" --hybrid` combines BM25 + vector + trigram via RRF
50
+ - [ ] `genie brain search screenshot.png` returns cross-modal results (text docs matching image)
51
+ - [ ] `genie brain search --task code "how does dispatch work"` uses CODE_RETRIEVAL_QUERY
52
+ - [ ] Intent auto-detection: questions → Q&A, claims → FACT_VERIFICATION, docids → similar
53
+ - [ ] `genie brain update --estimate` shows cost before processing
54
+ - [ ] `genie brain update --budget 0.50` caps spending
55
+ - [ ] `genie brain update --batch` uses Batch API (50% cheaper)
56
+ - [ ] Matryoshka: --dims flag on init, L2 normalization for <3072
57
+ - [ ] `bun run check` passes
58
+
59
+ ## Files to Create/Modify
60
+
61
+ ```
62
+ CREATE repos/genie-brain/src/db/migrations/002-brain-embeddings.sql
63
+ CREATE repos/genie-brain/src/lib/brain/embedding.ts
64
+ CREATE repos/genie-brain/src/lib/brain/media.ts
65
+ CREATE repos/genie-brain/src/lib/brain/intent.ts
66
+ MODIFY repos/genie-brain/src/lib/brain/update.ts (multimodal processing)
67
+ MODIFY repos/genie-brain/src/lib/brain/search.ts (vector + trigram + RRF + cross-modal)
68
+ MODIFY repos/genie-brain/package.json (add google-genai SDK)
69
+
70
+ CREATE repos/genie-brain/src/lib/brain/embedding.test.ts
71
+ CREATE repos/genie-brain/src/lib/brain/media.test.ts
72
+ ```