docs: planning notes from Claude-Code parity sprint

ober

750168125e519d193df6fb0626bcedb1b530cd05

diff --git a/zerostack-harvest.md b/zerostack-harvest.md
new file mode 100644
index 0000000..df0b33e
--- /dev/null
+++ b/zerostack-harvest.md
@@ -0,0 +1,678 @@
+# zerostack Harvest Notes for jcode
+
+Date: 2026-05-16
+
+Scope: read-only review of `../zerostack` for ideas worth adapting into
+`jcode`. No source files were changed during the review.
+
+Implementation update: the first sprint recommendations from this report have
+now been started in this working tree: prompt profiles, TUI `@file` completion,
+and safer edit/grep tool behavior. Broader safety/workflow items such as the
+full permission engine, `/loop`, git worktrees, and Linux `bwrap` sandboxing
+remain future work.
+
+## Executive Summary
+
+`zerostack` is a compact Rust coding agent with a few very useful product
+ideas that would fit well in `jcode`. `jcode` already has stronger foundations
+in several areas: SQLite sessions, shadow-git checkpoints, hierarchical
+instruction loading, Jerboa-specific tools, provider model popups, external CLI
+tabs, sandboxed second-opinion agents, and in-process web search.
+
+The best harvest is therefore not "copy zerostack", but selectively port its
+small, focused UX and safety features:
+
+1. Full permission engine with per-tool rules, external path checks, session
+   allowlists, and repeated-call detection.
+2. First-class prompt profiles via `/prompt`, separate from skills.
+3. TUI `@` file picker that inserts jcode's existing mention syntax.
+4. Safer tool behavior: better edit diagnostics, grep context, gitignore-aware
+   walks, binary and large-file skipping.
+5. Long-horizon `/loop` workflow adapted to Jerboa build/test habits.
+6. Git worktree slash commands.
+7. Linux `bwrap` bash sandbox.
+
+Recommended first sprint: tool ergonomics, prompt profiles, and TUI `@` picker.
+Those are high value, low architectural risk, and make `jcode` feel noticeably
+sharper without disturbing the core agent loop.
+
+## Existing jcode Strengths
+
+These are areas where `jcode` already equals or exceeds zerostack.
+
+- SQLite-backed sessions:
+  `src/jcode/core/session.ss`
+- Shadow-git checkpoints and undo:
+  `src/jcode/core/checkpoints.ss`
+- Hierarchical instruction loading:
+  `src/jcode/core/agents-md.ss`
+- Claude-compatible skill loading:
+  `src/jcode/core/skill.ss`
+- Jerboa-specific MCP workflow and tools:
+  MCP integration plus built-in skills.
+- External CLI tabs for Claude, Codex, Gemini, and opencode:
+  `src/jcode/ui/tui.ss`, `src/jcode/tool/external-llm.ss`
+- Sandboxed second-opinion LLM runner:
+  `src/jcode/tool/external-llm.ss`
+- In-process web search through jerbsearch:
+  `src/jcode/tool/web.ss`
+- Rich TUI status/sidebar:
+  `src/jcode/ui/tui-status.ss`, `src/jcode/ui/tui-sidebar.ss`
+- Reasoning collapse/toggle for `<think>` blocks:
+  `src/jcode/ui/tui-message.ss`, `src/jcode/ui/tui.ss`
+- Model/provider popups and live model refresh:
+  `src/jcode/ui/tui.ss`, `src/jcode/core/models.ss`
+
+## Priority 1: Full Permission Engine
+
+### What zerostack Has
+
+zerostack has a real permission checker:
+
+- Per-tool rules for `bash`, `read`, `write`, `edit`, `grep`, `find_files`,
+  `list_dir`, and todo updates.
+- Four modes: `standard`, `restrictive`, `accept`, `yolo`.
+- External directory checks so permissive modes still ask before touching paths
+  outside the working directory.
+- Session allowlists for "allow always" decisions.
+- Doom-loop detection: repeated identical tool calls can ask or deny.
+
+Relevant files:
+
+- `../zerostack/src/permission/checker.rs`
+- `../zerostack/src/permission/mod.rs`
+- `../zerostack/src/permission/pattern.rs`
+- `../zerostack/src/ui/slash.rs`
+
+### What jcode Has Now
+
+jcode has plan/build gating and bash-focused permission rules:
+
+- `src/jcode/tool/registry.ss`
+- `src/jcode/core/permissions.ss`
+- `src/jcode/tool/bash.ss`
+- `src/jcode/ui/tui-dialog.ss`
+
+Current permission rules only gate bash in practice. Write tools are blocked in
+PLAN mode, but BUILD mode generally lets them run. The dialog already has
+`Allow`, `Deny`, and `Always`, but there is no broad per-tool permission engine
+behind it.
+
+### Harvest Plan
+
+Add a generalized permission layer that wraps all tool execution:
+
+- Extend config:
+
+```json
+{
+  "permission": {
+    "*": "allow",
+    "bash": {
+      "git status": "allow",
+      "git diff **": "allow",
+      "rm -rf /**": "deny",
+      "sudo **": "ask"
+    },
+    "read": "allow",
+    "write": {
+      "src/**": "allow",
+      "lib/**": "deny",
+      "/**": "ask"
+    },
+    "edit": {
+      "src/**": "allow",
+      "lib/**": "deny",
+      "/**": "ask"
+    },
+    "external_directory": {
+      "/tmp/**": "allow",
+      "$HOME/**": "ask"
+    },
+    "doom_loop": "ask"
+  }
+}
+```
+
+- Keep the existing `permissions` bash block as a backward-compatible alias.
+- Add `current-permission-mode` separate from `current-mode`.
+- Add slash commands:
+  - `/mode` remains PLAN/BUILD or maybe aliases to `/access`.
+  - `/permission` or `/security` shows/sets `standard|restrictive|accept|yolo`.
+  - If preserving zerostack naming is preferable, use `/mode standard` etc. and
+    rename plan/build to `/plan` and `/build` only.
+- Store session allowlist entries in SQLite or in-memory first.
+- Use `tui-dialog.ss` for permission prompts.
+- Add repeated-call detection in `tool-execute`, before handler invocation.
+
+### Why It Matters
+
+This is the most important safety feature. It protects against accidental
+external writes, tool-call loops, and high-risk bash commands while still
+allowing a fast workflow inside the repo.
+
+## Priority 2: Prompt Profiles via `/prompt`
+
+### What zerostack Has
+
+zerostack ships prompt markdown files and lets users activate one at runtime.
+Built-ins include:
+
+- `code`
+- `plan`
+- `review`
+- `debug`
+- `ask`
+- `brainstorm`
+- `frontend-design`
+- `review-security`
+- `simplify`
+- `write-prompt`
+
+It loads embedded prompts, global prompts, and local project prompts:
+
+- `../zerostack/src/context/prompts.rs`
+- `../zerostack/prompts/*.md`
+
+The active prompt is appended to the system preamble:
+
+- `../zerostack/src/agent/builder.rs`
+
+### What jcode Has Now
+
+jcode has:
+
+- PLAN/BUILD mode in the system prompt:
+  `src/jcode/core/agent.ss`
+- Skills loaded through `/skill-name`:
+  `src/jcode/core/skill.ss`
+- Built-in Jerboa workflow skills:
+  `src/jcode/core/builtin-skills.ss`
+
+It does not have a first-class active prompt profile that changes the session's
+behavior until cleared.
+
+### Harvest Plan
+
+Add a prompt profile subsystem:
+
+- New file: `src/jcode/core/prompts.ss`
+- Search paths:
+  - built-in bundled prompt directory, if practical
+  - `$HOME/.jcode/prompts/*.md`
+  - `$HOME/.claude/prompts/*.md` if useful
+  - `<cwd>/.jcode/prompts/*.md`
+  - `<cwd>/prompts/*.md`
+- State:
+  - `current-prompt-name`
+  - `current-prompt-body`
+- System prompt:
+  - Append active prompt after project instructions or before them.
+  - Make active prompt visible in TUI status.
+- Commands:
+  - `/prompt` lists available profiles.
+  - `/prompt <name>` activates a profile.
+  - `/prompt default` clears it.
+  - `/regen-prompts` writes built-ins into `~/.jcode/prompts`.
+
+### Suggested Built-In Profiles for jcode
+
+- `default`: current jcode behavior.
+- `code`: implementation mode, asks only when necessary, verifies.
+- `plan`: stricter planning-only mode than current PLAN, optionally writes no
+  plan files unless asked.
+- `debug`: root-cause-first workflow.
+- `review`: code review stance.
+- `review-security`: high-confidence security findings only.
+- `ask`: read-only answering.
+- `simplify`: behavior-preserving simplification.
+- `jerboa`: strict Jerboa/MCP workflow, possibly lifting much of `AGENTS.md`.
+
+### Why It Matters
+
+Skills are one-shot commands. Prompt profiles are persistent session posture.
+This gives users a direct way to steer behavior without editing config or
+repeating instructions.
+
+## Priority 3: TUI `@` File Picker
+
+### What zerostack Has
+
+Typing `@` at word start opens a file picker. It scans files respecting
+`.gitignore`, filters by substring, lets the user navigate with arrows/tab, and
+inserts the selected path.
+
+Relevant files:
+
+- `../zerostack/src/ui/input.rs`
+- `../zerostack/src/ui/picker.rs`
+
+### What jcode Has Now
+
+jcode has strong mention expansion:
+
+- `@file:path/to/foo.ss`
+- `@diff`
+- `@diff:staged`
+- `@ls:src/jcode/tool`
+- `@symbol:make-provider`
+- `@url:...` stub
+
+Relevant file:
+
+- `src/jcode/core/mentions.ss`
+
+The missing piece is discoverable TUI insertion.
+
+### Harvest Plan
+
+Extend `src/jcode/ui/tui-input.ss`:
+
+- Add picker state to `input-state`, or add a separate `file-picker` module.
+- Trigger only for `@` at word boundary.
+- Prefer inserting `@file:<path>` instead of raw path so it integrates with
+  existing mention expansion.
+- Add quick mention completions:
+  - `@diff`
+  - `@diff:staged`
+  - `@ls:`
+  - `@symbol:`
+  - `@file:`
+- Use gitignore-aware discovery if available through Jerboa stdlib or shell out
+  to `rg --files` in read-only fashion.
+- Keep max results small, for example 50.
+
+### Why It Matters
+
+This turns an already powerful but hidden feature into a normal TUI workflow.
+It also reduces user typing and path mistakes.
+
+## Priority 4: Safer Tool Ergonomics
+
+### Edit Tool Improvements
+
+zerostack's edit tool:
+
+- Rejects empty `old_text`.
+- Normalizes CRLF internally and writes CRLF back if present.
+- Detects duplicate matches and returns line numbers.
+- Supports `replace_all`.
+- Returns a small unified diff for short edits.
+
+Relevant file:
+
+- `../zerostack/src/agent/tools/edit.rs`
+
+jcode's edit tool is simpler:
+
+- `src/jcode/tool/file.ss`
+
+Harvest changes:
+
+- Reject empty `old_str`.
+- Count matches before editing.
+- If multiple matches, return line-number previews and ask for more context.
+- Add optional `replace_all`.
+- Preserve CRLF.
+- Return a small diff in the tool result.
+- Reuse existing `multi-edit`, `edit_block`, and `apply_patch` rather than
+  replacing them.
+
+### Grep and Glob Improvements
+
+zerostack grep:
+
+- Uses gitignore-aware walking.
+- Skips binary files.
+- Skips files over 10 MB.
+- Supports `context_lines`, like `grep -C`.
+- Supports include glob filtering.
+
+Relevant file:
+
+- `../zerostack/src/agent/tools/grep.rs`
+
+jcode grep:
+
+- Requires `path`.
+- Uses glob expansion.
+- No context lines.
+- No binary/large-file skip.
+
+Harvest changes:
+
+- Make `path` optional, default to current directory.
+- Add `context_lines`.
+- Add large-file and binary skip.
+- Prefer `rg` if available or implement a safe walker.
+- Keep existing schema fields backward compatible.
+
+### List Directory Improvements
+
+zerostack `list_dir` shows:
+
+- type
+- size
+- child count for directories
+- directories first
+
+Relevant file:
+
+- `../zerostack/src/agent/tools/list_dir.rs`
+
+jcode `ls` currently returns names and trailing `/` for directories. Consider
+adding `details: true` rather than changing default output.
+
+### Why It Matters
+
+These changes reduce failed edits and repeated read/edit loops. They are small,
+local, and easy to test.
+
+## Priority 5: Long-Horizon `/loop`
+
+### What zerostack Has
+
+zerostack has a loop state with:
+
+- original task prompt
+- `LOOP_PLAN.md`
+- iteration count and optional max
+- previous iteration summary
+- previous validation output
+- optional validation command
+
+Relevant files:
+
+- `../zerostack/src/extras/loop/mod.rs`
+- `../zerostack/src/extras/loop/plan.rs`
+- `../zerostack/src/extras/loop/transcript.rs`
+
+The loop prompt instructs the agent to choose one task from the plan, work on
+that task, run tests, update the plan, and continue.
+
+### jcode Adaptation
+
+Add:
+
+- `/loop <prompt>`
+- `/loop stop`
+- `/loop status`
+- CLI flags later if useful:
+  - `--loop`
+  - `--loop-prompt`
+  - `--loop-plan`
+  - `--loop-max`
+  - `--loop-run`
+
+For jcode specifically:
+
+- Use `JCODE_LOOP_PLAN.md` or `.jcode/loop-plan.md` to avoid clutter.
+- Do not commit automatically by default. jcode has checkpoints, and users may
+  not want real git commits each iteration.
+- Run Jerboa-aware validation:
+  - `jerboa_verify` for changed `.ss` files if MCP is available.
+  - `jerboa_make` or `make build`.
+  - `jerboa_run_tests` when tests exist.
+- Store transcripts in `~/.jcode/loops/<session-id>/iter-0001.json`.
+- Block normal input while active except `/loop stop`, like zerostack does.
+
+### Why It Matters
+
+This is useful for large refactors and "keep going until green" tasks. The
+right jcode flavor should lean on checkpoints and Jerboa verification instead
+of automatic commits.
+
+## Priority 6: Git Worktree Commands
+
+### What zerostack Has
+
+Commands:
+
+- `/worktree <name>`
+- `/wt-merge [branch]`
+- `/wt-exit`
+
+Relevant file:
+
+- `../zerostack/src/extras/git_worktree/mod.rs`
+
+The implementation creates `../<name>`, switches cwd, reloads context, and then
+can generate a merge task for the agent.
+
+### jcode Adaptation
+
+Add worktree helpers under something like:
+
+- `src/jcode/core/worktree.ss`
+
+Add TUI commands:
+
+- `/worktree <name>`
+- `/wt-exit`
+- `/wt-merge [branch]`
+
+Important details:
+
+- Validate branch/worktree names carefully.
+- Refuse if dirty unless user confirms.
+- After changing cwd:
+  - reload project instructions
+  - refresh sidebar git status
+  - update current session title or cwd display
+  - ensure checkpoint directory belongs to the new worktree
+- For merge:
+  - generate a normal agent task or run a guarded sequence.
+  - ask before push and deletion.
+
+### Why It Matters
+
+jcode is already a coding agent with checkpoints and git tools. Worktrees would
+make branch-per-task workflows much smoother.
+
+## Priority 7: Linux Bash Sandbox
+
+### What zerostack Has
+
+zerostack can wrap bash with `bwrap`:
+
+- read-only bind `/`
+- writable bind current working directory
+- tmpfs `/tmp`
+- unshare all
+- die with parent
+
+Relevant file:
+
+- `../zerostack/src/sandbox.rs`
+
+### What jcode Has Now
+
+jcode's bash sandbox supports macOS Seatbelt but says Linux is currently no-op:
+
+- `src/jcode/core/sandbox.ss`
+
+jcode external LLM sandboxing is already stronger and cross-platform through
+`(std os sandbox)`:
+
+- `src/jcode/tool/external-llm.ss`
+
+### Harvest Plan
+
+Add Linux support to `sandbox-wrap-command`:
+
+- Detect `bwrap`.
+- Add config:
+  - `sandbox.enabled`
+  - `sandbox.allow_network`
+  - `sandbox.extra_writable`
+  - maybe `sandbox.linux_backend: "bwrap"`
+- Build command with proper shell quoting.
+- If `bwrap` missing and sandbox enabled, return a clear error instead of
+  silently running unsandboxed.
+
+### Why It Matters
+
+This closes a cross-platform safety gap for normal bash commands.
+
+## Secondary Ideas
+
+### Better Session UX
+
+zerostack supports:
+
+- list recent sessions with previews
+- load by ID prefix
+- delete by ID prefix
+- show message count, model, and last message preview
+
+Relevant files:
+
+- `../zerostack/src/session/storage.rs`
+- `../zerostack/src/ui/slash.rs`
+
+jcode already has SQLite sessions and search. Add:
+
+- `/sessions <prefix>` to load
+- `/sessions delete <prefix>` to delete
+- richer TUI session picker popup
+- most recent resume from CLI if not already present
+
+### Structured Todo Tool
+
+zerostack has a `write_todo_list` tool:
+
+- `../zerostack/src/agent/tools/todo.rs`
+
+jcode already has the host-side `update_plan` tool in this Codex environment,
+but the actual jcode app could expose an agent-visible todo tool and render it
+in the sidebar.
+
+Possible design:
+
+- Tool: `todo_write`
+- Fields:
+  - `content`
+  - `status`: `pending|in_progress|completed|cancelled`
+  - `priority`: `high|medium|low`
+- Store per session.
+- Render in sidebar.
+
+### Status Badges
+
+zerostack status line includes active prompt, permission mode, loop label,
+context percent, and compaction count.
+
+jcode's status bar already shows mode, provider, model, tokens, cache, cost,
+cwd, CPU, memory, and GPU. Add only the missing badges:
+
+- active prompt profile
+- permission mode
+- loop label
+- worktree branch
+
+### Tool Result Detail Toggle
+
+zerostack has `show_tool_details` for displaying result previews. jcode already
+tracks tool events mostly in the sidebar and collapses tool blocks. A small
+config option to show/hide inline tool result previews may be useful.
+
+## Things to Skip or Deprioritize
+
+- Multi-provider support: jcode already has broad provider support.
+- MCP basics: jcode already has MCP.
+- Web search: jcode has in-process jerbsearch and fetch.
+- Reasoning visibility: jcode already handles `<think>` blocks with collapse.
+- JSON-file sessions: jcode's SQLite DB is better.
+- Bubblewrap as the only sandbox story: useful for bash on Linux, but jcode's
+  external LLM sandbox approach is broader.
+- zerostack's exact prompt text: harvest the concept, then write jcode-native
+  prompts that respect Jerboa, MCP, and repository rules.
+
+## Suggested Implementation Order
+
+### Sprint 1: Low-Risk UX and Tool Quality
+
+1. Improve `edit` diagnostics in `src/jcode/tool/file.ss`.
+2. Add grep context and file skipping in `src/jcode/tool/file.ss`.
+3. Add TUI `@file` picker in `src/jcode/ui/tui-input.ss`.
+4. Add `/prompt` profile loader and status badge.
+
+Verification:
+
+- Jerboa verify changed `.ss` files.
+- Run `make build`.
+- Add focused tests if the repo has coverage for tool handlers.
+
+### Sprint 2: Safety
+
+1. Generalize permissions beyond bash.
+2. Wire TUI permission prompts to all sensitive tools.
+3. Add session allowlists.
+4. Add repeated-call detection.
+5. Add Linux `bwrap` sandbox.
+
+Verification:
+
+- Unit-test rule matching.
+- Manually test read/write/edit/bash allow, ask, deny.
+- Test external path behavior.
+- Test repeated identical calls.
+
+### Sprint 3: Workflow Automation
+
+1. Add `/worktree`, `/wt-exit`, `/wt-merge`.
+2. Add `/loop` state and plan file.
+3. Add loop transcript storage.
+4. Add optional validation command.
+
+Verification:
+
+- Test in a temporary git repo.
+- Ensure cwd changes update project instructions and status bar.
+- Ensure loop can stop cleanly.
+- Ensure no automatic push/delete happens without explicit confirmation.
+
+## File Reference Map
+
+zerostack:
+
+- `../zerostack/README.md`
+- `../zerostack/src/permission/checker.rs`
+- `../zerostack/src/permission/mod.rs`
+- `../zerostack/src/permission/pattern.rs`
+- `../zerostack/src/context/prompts.rs`
+- `../zerostack/prompts/*.md`
+- `../zerostack/src/ui/input.rs`
+- `../zerostack/src/ui/picker.rs`
+- `../zerostack/src/ui/slash.rs`
+- `../zerostack/src/agent/tools/edit.rs`
+- `../zerostack/src/agent/tools/grep.rs`
+- `../zerostack/src/agent/tools/list_dir.rs`
+- `../zerostack/src/agent/tools/todo.rs`
+- `../zerostack/src/extras/loop/mod.rs`
+- `../zerostack/src/extras/loop/plan.rs`
+- `../zerostack/src/extras/loop/transcript.rs`
+- `../zerostack/src/extras/git_worktree/mod.rs`
+- `../zerostack/src/sandbox.rs`
+
+jcode:
+
+- `src/jcode/core/agent.ss`
+- `src/jcode/core/session.ss`
+- `src/jcode/core/checkpoints.ss`
+- `src/jcode/core/permissions.ss`
+- `src/jcode/core/sandbox.ss`
+- `src/jcode/core/agents-md.ss`
+- `src/jcode/core/skill.ss`
+- `src/jcode/core/mentions.ss`
+- `src/jcode/tool/file.ss`
+- `src/jcode/tool/bash.ss`
+- `src/jcode/tool/registry.ss`
+- `src/jcode/tool/web.ss`
+- `src/jcode/tool/external-llm.ss`
+- `src/jcode/ui/tui.ss`
+- `src/jcode/ui/tui-input.ss`
+- `src/jcode/ui/tui-dialog.ss`
+- `src/jcode/ui/tui-status.ss`
+- `src/jcode/ui/tui-sidebar.ss`
+- `src/jcode/ui/tui-message.ss`