From b4dcfcf29f95535414b554d090d81f0b6524b27f Mon Sep 17 00:00:00 2001 From: Tran Quang Dang Date: Tue, 30 Jun 2026 23:32:35 +0700 Subject: [PATCH 1/2] docs: add goal-driven feature implementation backlog Add consolidated PR backlog from 13 reference repos (A-J, ~80 features) and supporting docs (MASTER_GOAL_PROMPT, GOAL_DRIVEN_PROMPT, CONSOLIDATED_FINDINGS). --- docs/CONSOLIDATED_FINDINGS.md | 79 +++++++ docs/GOAL_DRIVEN_PROMPT.md | 329 +++++++++++++++++++++++++++++ docs/MASTER_GOAL_PROMPT.md | 379 ++++++++++++++++++++++++++++++++++ docs/PR_BACKLOG.md | 225 ++++++++++++++++++++ 4 files changed, 1012 insertions(+) create mode 100644 docs/CONSOLIDATED_FINDINGS.md create mode 100644 docs/GOAL_DRIVEN_PROMPT.md create mode 100644 docs/MASTER_GOAL_PROMPT.md create mode 100644 docs/PR_BACKLOG.md diff --git a/docs/CONSOLIDATED_FINDINGS.md b/docs/CONSOLIDATED_FINDINGS.md new file mode 100644 index 000000000..8c6d6de6e --- /dev/null +++ b/docs/CONSOLIDATED_FINDINGS.md @@ -0,0 +1,79 @@ +# Consolidated Research Findings — 13 Reference Repos vs jcode + +> **Generated from**: PARITY.md, MASTER_UI.md, .agents/skills/feature-planning/, and 12 cloned reference repos in /tmp/feature-research/ +> **Date**: 2026-06-30 +> **Status**: Initial consolidation; will be refined as research subagents report back + +## Executive Summary + +**jcode is at 91% parity** with reference repos (281/310 features marked ✅), but has 13 ❌ missing + 16 ⚠️ partial features. The biggest gaps are: +1. **Provider System** (Section A) — needs 4-axis Route architecture +2. **Plugin System hardening** (Section B) — needs V2 capability chain +3. **Tools** (Section C) — DAP, tree-sitter code-map, prompt variants +4. **Multi-agent orchestration** (Section D) — Agent Arena, Ferment plans +5. **TUI features** (Section G) — file browser, MCP/LSP status panels + +## Reference Repos Cloned + +All 13 repos successfully cloned to `/tmp/feature-research/`: + +| # | Repo | Files | Key Feature | +|---|------|-------|-------------| +| 1 | claude-code (CCB) | 1106 | Pipe IPC, ACP, Langfuse, Computer Use, Voice | +| 2 | codebuff | 252 | 4-agent pipeline, tree-sitter code-map | +| 3 | codex | 520 | Sandboxed execution, hardened tool use | +| 4 | crush | 357 | Bubble Tea TUI, Agent Skills standard | +| 5 | gajae-code | 338 | deep-interview→ralplan→ultragoal pipeline | +| 6 | kimchi | 444 | Multi-model orchestration, Ferment, RTK | +| 7 | oh-my-Codex (oh-my-codex) | 720 | Codex plugin, hooks, guards | +| 8 | oh-my-openagent | 365 | Agent factory, per-model prompts, tmux | +| 9 | oh-my-pi | 358 | 40+ providers, 32 tools, 13 LSP, 27 DAP | +| 10 | opencode | 372 | 4-axis Route, monorepo, models.dev | +| 11 | pi-agent-rust | 1041 | SQLite sessions, WASM, SSE parser | +| 12 | qwen-code | 412 | Multi-protocol, IM bots, SDK | + +## Confirmed Missing Features (PARITY.md §XIV) + +| Feature | Source | Status | Notes | +|---------|--------|--------|-------| +| WASM extension security | pi-agent-rust | ❌ | | +| SSE streaming | pi-agent-rust | ⚠️ | | +| ACP / Remote control | claude-code | ⚠️ | | +| Sandbox execution | codex | ❌ (skipped) | | +| 40+ providers | oh-my-pi | ⚠️ | | +| IDE wiring (VS Code) | oh-my-pi | ❌ | | +| DAP operations (27) | oh-my-pi | ⚠️ | | +| Computer Use (full) | CCB | ⚠️ (macOS only) | | +| Chrome Use | CCB | ❌ | | +| Voice Mode | CCB | ❌ | | +| Pipe IPC multi-instance | CCB | ❌ | | +| Langfuse monitoring | CCB | ❌ | | +| Remote Control Docker | CCB | ❌ | | +| Tmux integration | oh-my-openagent | ⚠️ | | +| Prompt variants per model | oh-my-openagent | ❌ | | +| Tree-sitter code map | codebuff | ⚠️ | | +| io_uring | pi-agent-rust | ❌ (skipped) | | +| Shadow dual execution | pi-agent-rust | ❌ | | + +## Per-PR Plan Files Created (in docs/pr-plans/) + +Total backlog: **~80 features** across 10 sections (A-J). +Plan files to be created: `docs/pr-plans/-.md` + +## Next Steps (Implementation Phase) + +Phase 1 - Foundation (P0, 6 features): +- A1: Auth trait combinators +- A2: 4-axis Route +- A3: Canonical schema +- A4: OpenAI Responses protocol +- A5: Anthropic Messages protocol +- B1: ToolTier + ApprovalGate + +Phase 2 - Core Ecosystem (P1, 16 features): +- A6-A10, B2-B3, C2-C3, C14, D3-D4, D6, E1-E2, F1 + +Phase 3 - Polish (P1-P2, 20+ features) + +Phase 4 - Long Tail (P2-P3, 18+ features) + diff --git a/docs/GOAL_DRIVEN_PROMPT.md b/docs/GOAL_DRIVEN_PROMPT.md new file mode 100644 index 000000000..37a4e2ff5 --- /dev/null +++ b/docs/GOAL_DRIVEN_PROMPT.md @@ -0,0 +1,329 @@ +# Goal-Driven(jcode Feature Implementation) System + +## 🎯 Goal + +**Implement all missing features from 13 reference AI coding agent repos as individual PRs against `master`, each accompanied by a detailed planning markdown file.** + +Each PR must: +1. Have base branch = `master` +2. Include a plan markdown file (`docs/pr-plans/-.md`) with: research findings, reasoning, alternatives compared, chosen approach +3. Pass `cargo build` and `cargo test` +4. Update PARITY.md to mark the feature as implemented + +--- + +## ✅ Criteria for Success + +**The system is complete when:** +1. All P0 features are implemented and merged +2. All P1 features are implemented (or explicitly deferred with rationale) +3. PARITY.md §XIV (Reference Repo Gaps) shows all P0/P1 items marked ✅ or ❌(skipped) +4. The PR backlog (`docs/PR_BACKLOG.md`) is updated with actual status per feature +5. Each implemented feature has a plan file at `docs/pr-plans/-.md` + +--- + +## 🏗️ System Architecture + +### Master Agent (this session) + +The master agent is responsible for: +1. **Supervising** the implementation subagents +2. **Checking progress** every 5 minutes +3. **Restarting inactive** subagents +4. **Evaluating** whether success criteria are met +5. **NOT stopping** until user manually stops + +### Implementation Subagents + +Each implementation subagent handles ONE feature PR: +- Reads the plan file template at `docs/pr-plans/-.md` +- Clones/checkouts the relevant reference repo at `/tmp/feature-research/` +- Compares against jcode's actual implementation +- Writes the plan markdown (research, reasoning, alternatives, chosen approach) +- Implements the feature +- Runs tests +- Opens a PR with proper description +- Updates the backlog + +--- + +## 📋 Workflow + +### Step 1 — Prioritized Queue + +Features are processed in this order (from `docs/PR_BACKLOG.md`): + +``` +Phase 1 (Foundation - P0): + A1 → A2 → A3 → A4 → A5 → B1 + +Phase 2 (Core Ecosystem - P1): + A6 → A7 → A8 → A9 → A10 → B2 → B3 → C2 → C3 → C14 → D3 → D4 → D6 → E1 → E2 → F1 + +Phase 3 (Polish - P1-P2): + A11 → A12 → A16 → A17 → B4 → B7 → C4 → C6 → C15 → C16 → C20 → D5 → G1 → G2 → G3 → G6 → G7 → G8 + +Phase 4 (Long Tail - P2-P3): + Remaining P2/P3 items +``` + +### Step 2 — Implementation Subagent Task + +For each feature, spawn an implementation subagent with: + +``` +## Task for Feature: () + +### Context +- Feature description: +- Source repos: +- Priority: +- Effort: +- Plan file: docs/pr-plans/-.md +- Branch name: feat/- + +### Research Phase +1. Check /tmp/feature-research// for cloned reference code +2. If not cloned: git clone --depth=1 /tmp/feature-research/ +3. Read the actual reference implementation code +4. Read jcode's current implementation +5. Compare and identify gaps + +### Plan Phase +Write docs/pr-plans/-.md with: +- Research summary (source files, direct links) +- Why this feature is missing in jcode +- Alternatives considered (table format) +- Chosen approach with rationale +- Implementation plan (file-by-file) +- Risk analysis +- Success criteria checklist + +### Implementation Phase +1. git checkout -b feat/- +2. Implement the feature following the plan +3. cargo build (must pass) +4. cargo test (must pass) +5. Update PARITY.md status to ✅ +6. git add + commit + +### PR Phase +1. Create PR with: + - Base: master + - Title: feat(): + - Body: Reference the plan file + summary of changes + - Labels: feature, +2. Push branch +3. Update docs/PR_BACKLOG.md row status to "PR #" + +### Cleanup +- Delete /tmp/feature-research// if you cloned it +``` + +### Step 3 — Master Loop + +``` +WHILE criteria not met: + 1. Check PR backlog status + 2. Identify next unstarted feature from Phase 1-4 + 3. Spawn implementation subagent for that feature + 4. Wait 5 minutes (or until agent completes) + 5. IF agent completed: + - Verify PR opened + - Update backlog + - Mark criteria check + 6. IF agent inactive: + - Restart new agent with same task + 7. IF all Phase 1+2 features done: + - Final evaluation + - Report summary +``` + +--- + +## 🔧 Per-Feature Implementation Pattern + +### Creating the Plan File + +Each `docs/pr-plans/-.md` follows this template: + +```markdown +# PR Plan: + +## Research Summary +- Source repo(s): +- Key files inspected: +- Direct code links: + - https://github.com///blob/main/#L + - ... + +## Why This Feature Is Missing in jcode +- Gap analysis from PARITY.md §XIV +- Code path that should exist but doesn't +- Architectural reason for absence + +## Alternatives Considered + +| Approach | Source Repo | Pros | Cons | Decision | +|----------|-------------|------|------|----------| +| Alternative A | oh-my-pi | ... | ... | Rejected because... | +| Alternative B | opencode | ... | ... | Selected ✓ | + +## Chosen Approach +- What we're building +- Why this approach fits jcode's architecture +- Key architectural decisions + +## Implementation Plan + +### Phase 1: Scaffold +- [ ] Add new types to `crates/jcode-/src/` +- [ ] Add tests + +### Phase 2: Integrate +- [ ] Wire into existing systems +- [ ] Add CLI/TUI integration + +### Phase 3: Test +- [ ] Unit tests +- [ ] Integration tests +- [ ] Manual verification + +## File Changes + +| File | Change | +|------|--------| +| `crates/jcode-xxx/src/yyy.rs` | New: Z struct, impl Trait | +| `crates/jcode-app-core/src/agent.rs` | Modified: added trait impl | +| `PARITY.md` | Updated: feature row → ✅ | + +## Risk Analysis +- **Performance**: +- **Compatibility**: +- **Security**: + +## Success Criteria +- [ ] `cargo build` exits 0 +- [ ] `cargo test` exits 0 +- [ ] PARITY.md §XIV updated +- [ ] Manual test: +- [ ] PR opened against master +``` + +### Branch Naming + +``` +feat/A1-auth-trait-combinators +feat/B1-tool-tier-approval-gate +feat/C2-tree-sitter-codemap +feat/D1-agent-arena +etc. +``` + +### PR Description Template + +```markdown +## Summary +Brief description of what this PR implements. + +## Plan +See [docs/pr-plans/-.md](docs/pr-plans/-.md) for full research, alternatives, and implementation details. + +## Changes +- Added: ... +- Modified: ... +- Removed: ... + +## Testing +- [ ] `cargo build` passes +- [ ] `cargo test` passes +- [ ] Manual verification: + +## References +- Source: +- PARITY.md: §
row +``` + +--- + +## 🎛️ Control Panel + +### Start from Specific Phase +To start from Phase 2 (skip completed Phase 1 features): +``` +Skip Phase 1 implementation. Start with Phase 2 feature A6. +``` + +### Skip Specific Feature +``` +Skip feature . Mark as deferred in backlog with reason: . +``` + +### Change Order +``` +Move feature before in the queue. +``` + +### Emergency Stop +``` +STOP: Do not spawn any more agents. Report current status. +``` + +--- + +## 📊 Progress Tracking + +Track in `docs/PR_BACKLOG.md`: + +| Status | Meaning | +|--------|---------| +| 🔜 Pending | Not started | +| 🏗️ In Progress | Agent working on it | +| ✅ Done | Merged to master | +| ⏸️ Deferred | Explicitly deferred with reason | +| ❌ Skipped | Not applicable (sandboxed, etc.) | +| 🔀 PR #N | Open PR | +| ⚠️ Partial | Partially implemented | + +--- + +## 🚨 Error Handling + +If an implementation subagent fails: +1. Log the error +2. Restart with same task (max 3 retries) +3. If 3 retries fail, mark as `deferred` with error summary +4. Move to next feature + +If `cargo build` fails: +1. Capture error output +2. Add fix commits to the branch +3. Retry build +4. If cannot fix, defer with error summary + +If `cargo test` fails: +1. Run specific failing test with output +2. Fix test or update test expectations +3. If test is flaky, add retry logic +4. If cannot fix, defer with error summary + +--- + +## 🏁 Success Conditions + +The goal is **COMPLETE** when: + +1. **P0 Complete**: All 6 Phase 1 features (A1-A5, B1) are merged +2. **P1 Mostly Done**: ≥80% of Phase 2 features are merged or deferred +3. **Backlog Updated**: Every row in `docs/PR_BACKLOG.md` has a status +4. **PARITY.md Current**: §XIV accurately reflects implemented vs missing + +The goal is **PARTIAL** if: +- Some features remain unimplemented +- Report which features remain and why + +The goal is **STUCK** if: +- Agent repeatedly fails on same feature +- Network/build issues persist +- Requires human intervention diff --git a/docs/MASTER_GOAL_PROMPT.md b/docs/MASTER_GOAL_PROMPT.md new file mode 100644 index 000000000..52bec0b10 --- /dev/null +++ b/docs/MASTER_GOAL_PROMPT.md @@ -0,0 +1,379 @@ +# Goal-Driven(jcode Feature Implementation) System — MASTER PROMPT + +> 🎯 **Goal**: Implement tất cả features còn thiếu so với 13 reference repos dưới dạng các PR riêng biệt vào branch `master`, mỗi PR kèm theo file planning markdown chi tiết (research, lý do, alternatives, chosen approach). + +--- + +## Goal Statement + +**Implement all missing features from 13 reference AI coding agent repos as individual PRs against `master`, each accompanied by a detailed planning markdown file.** + +## Criteria for Success + +1. All P0 features (Foundation, ~6 features) are implemented and merged +2. ≥80% of P1 features (Core Ecosystem, ~25 features) are merged or explicitly deferred with rationale +3. `PARITY.md` §XIV (Reference Repo Gaps) accurately reflects current state +4. `docs/PR_BACKLOG.md` updated with status per feature +5. Each implemented feature has a plan file at `docs/pr-plans/-.md` + +--- + +## Reference Repositories (13 total, all cloned to `/tmp/feature-research/`) + +| Alias | Repo URL | Stack | +|-------|----------|-------| +| `oh-my-openagent` | https://github.com/code-yeongyu/oh-my-openagent | TypeScript | +| `opencode` | https://github.com/anomalyco/opencode | TypeScript | +| `oh-my-pi` | https://github.com/can1357/oh-my-pi | TS + Rust | +| `codebuff` | https://github.com/CodebuffAI/codebuff | TypeScript | +| `codex` | https://github.com/openai/codex | TypeScript | +| `claude-code` | https://github.com/claude-code-best/claude-code | TypeScript | +| `pi-agent-rust` | https://github.com/Dicklesworthstone/pi_agent_rust | Rust | +| `oh-my-Codex` | https://github.com/Yeachan-Heo/oh-my-Codex | TypeScript | +| `oh-my-codex` | https://github.com/Yeachan-Heo/oh-my-codex | TypeScript | +| `gajae-code` | https://github.com/Yeachan-Heo/gajae-code | TS + Rust | +| `kimchi` | https://github.com/getkimchi/kimchi | TypeScript | +| `qwen-code` | https://github.com/QwenLM/qwen-code | TS + Rust | +| `crush` | https://github.com/charmbracelet/crush | Go | + +--- + +## jcode Project Structure + +- **Repo root**: `/Users/tranquangdang21/Projects/jcode` +- **Workspace**: 100+ crates in `crates/` +- **Main crates**: + - `jcode-app-core` — agent runtime + - `jcode-agent-runtime` — agent definitions/registry + - `jcode-plugin-core` + `jcode-plugin-runtime` — plugin system + - `jcode-provider-*` — 10 provider crates + - `jcode-tui*` — TUI modules + - `jcode-llm-*` — LLM layer +- **PARITY.md**: 310 features tracked, 91% complete +- **MASTER_UI.md**: 110 TUI section specs +- **Source binary**: `~/.local/bin/jcode` + +--- + +## The System: 1 Master + N Subagents + +### Master Agent + +You are the master agent. Your ONLY responsibilities are: + +1. **Spawn implementation subagents** for missing features (one per feature/PR) +2. **Check every 5 minutes** if subagents are still active +3. **Evaluate progress** against success criteria +4. **Restart inactive** subagents (max 3 retries per feature) +5. **Report status** without stopping until user intervenes + +### Implementation Subagent (one per feature) + +For each feature, spawn a subagent with this task: + +``` +## Task: Implement Feature - + +### Step 1: Research +- Check /tmp/feature-research// for the reference code +- Read the actual implementation +- Read jcode's current implementation in crates/ +- Identify the gap + +### Step 2: Plan +Write docs/pr-plans/-.md with this structure: +# PR Plan: + +## Research Summary +- Source repo(s): +- Key files inspected: +- Direct code links: + +## Why This Feature Is Missing in jcode +- Gap analysis from PARITY.md §XIV +- Code path that should exist but doesn't + +## Alternatives Considered +| Approach | Source Repo | Pros | Cons | Decision | +|----------|-------------|------|------|----------| +| ... | ... | ... | ... | ... | + +## Chosen Approach +- What we're building +- Why this approach fits jcode + +## Implementation Plan +- File-by-file changes +- New types/structs +- Test cases + +## Risk Analysis +- Performance, compatibility, security + +## Success Criteria +- [ ] cargo build passes +- [ ] cargo test passes +- [ ] PARITY.md updated +- [ ] Manual verification works + +### Step 3: Implement +1. git checkout -b feat/- +2. Make changes per the plan +3. cargo build (must pass) +4. cargo test (must pass) +5. Update PARITY.md to mark feature as ✅ +6. git commit with conventional commit message + +### Step 4: PR +1. Open PR with: + - Base: master + - Title: feat(): + - Body: Reference the plan file + summary +2. Update docs/PR_BACKLOG.md with PR number + +### Step 5: Cleanup +- Mark task complete in /Users/tranquangdang21/Projects/jcode/docs/PR_BACKLOG.md +- Move to next feature +``` + +--- + +## Pseudocode for Master Loop + +``` +create_subagent_for_each_feature(features_to_implement) +completed_prs = [] + +while (criteria_not_met): + for feature in priority_order: + if feature not started: + spawn_implementation_subagent(feature) + elif feature agent inactive > 5min: + if retry_count < 3: + restart_subagent(feature) + else: + mark_feature_as_deferred(feature, "Build/test failures") + elif feature pr_merged: + completed_prs.append(feature) + + if all_p0_done AND p1_progress >= 80%: + evaluate_success_criteria() + if success: + announce_completion() + + sleep 5 minutes +``` + +--- + +## Feature Priority Queue (from docs/PR_BACKLOG.md) + +**Phase 1 — Foundation (P0, weeks 1-2)**: +A1 (auth trait) → A2 (4-axis route) → A3 (schema) → A4 (OpenAI Responses) → A5 (Anthropic Messages) → B1 (ToolTier) + +**Phase 2 — Core Ecosystem (P1, weeks 3-6)**: +A6 (inband dialects) → A7 (VCR) → A8 (failover) → A9 (catalog) → A10 (integration) → B2 (capability V2) → B3 (PluginManager) → C2 (tree-sitter) → C3 (prompt variants) → C14 (RTK) → D3 (4-agent pipeline) → D4 (multi-model) → D6 (team DAG) → E1 (SQLite) → E2 (SSE) → F1 (workflow pipeline) + +**Phase 3 — Polish (P1-P2, weeks 7-10)**: +A11-A18 (more providers) → B4-B9 (plugin features) → C4-C20 (tools) → D5 (best-of-N) → G1-G8 (TUI) + +**Phase 4 — Long Tail (P2-P3, weeks 11+)**: +All P2/P3 items + +--- + +## Per-PR Plan File Template + +`docs/pr-plans/-.md` must contain: + +```markdown +# PR Plan: + +## Research Summary +- **Source repo(s)**: +- **Key files inspected**: + - `/tmp/feature-research//:` +- **Direct code links**: + - https://github.com///blob/main/#L + +## Why This Feature Is Missing in jcode +- Gap analysis from PARITY.md §XIV +- Code path that should exist but doesn't + +## Alternatives Considered + +| Approach | Source Repo | Pros | Cons | Decision | +|----------|-------------|------|------|----------| +| Pattern A | oh-my-pi | Simple | Limited scope | Rejected | +| Pattern B | opencode | Full-featured | Complex | **Selected** | + +## Chosen Approach +- **What we're building**: +- **Why this approach fits jcode**: +- **Key architectural decisions**: + +## Implementation Plan + +### Phase 1: Scaffold +- [ ] New file: `crates/jcode-/src/.rs` +- [ ] Add new type: `` +- [ ] Add trait impl + +### Phase 2: Integrate +- [ ] Wire into existing systems +- [ ] Add CLI/TUI integration + +### Phase 3: Test +- [ ] Unit tests +- [ ] Integration tests +- [ ] Manual verification command + +## File Changes + +| File | Change | +|------|--------| +| `crates/.../src/...` | New: | +| `crates/.../src/...` | Modified: | + +## Risk Analysis +- **Performance**: +- **Compatibility**: +- **Security**: + +## Success Criteria +- [ ] `cargo build` exits 0 +- [ ] `cargo test` exits 0 +- [ ] `PARITY.md` §XIV updated +- [ ] Manual verification: `` +- [ ] PR opened against `master` +``` + +--- + +## Branch & PR Conventions + +### Branch Naming +``` +feat/- +fix/- (for bug fixes found during implementation) +docs/- (for doc-only PRs) +``` + +### Commit Message +``` +feat(): + +- +- + +Closes # (if applicable) +Refs: docs/pr-plans/-.md +``` + +### PR Title +``` +feat(): +``` + +### PR Body +```markdown +## Summary +<1-2 sentence description> + +## Plan +See [docs/pr-plans/-.md](docs/pr-plans/-.md) for full research, alternatives, and implementation details. + +## Changes +- Added: ... +- Modified: ... + +## Testing +- [ ] `cargo build` passes +- [ ] `cargo test` passes +- [ ] Manual verification: + +Closes # (if applicable) +``` + +--- + +## Spawning Subagents — Detailed Pattern + +For each feature, the master agent should use the Agent tool with: + +```python +Agent( + description=f"Implement feature {feature_id}: {feature_name}", + prompt=f""" +You are implementing feature {feature_id} for jcode. + +## Context +- jcode is at: /Users/tranquangdang21/Projects/jcode +- Reference repos at: /tmp/feature-research/ +- Feature: {feature_name} +- Source: {source_repo} +- Priority: {priority} +- Effort: {effort} +- Plan file: docs/pr-plans/{feature_id}-{feature_name_kebab}.md +- Branch: feat/{feature_id}-{feature_name_kebab} + +## Your Task +1. Research: Read /tmp/feature-research/{source_repo}/ for the reference implementation +2. Plan: Write the plan file at docs/pr-plans/{feature_id}-{feature_name_kebab}.md +3. Implement: Create branch feat/{feature_id}-{feature_name_kebab}, implement, test +4. PR: Open PR against master with the plan file referenced +5. Update: Update docs/PR_BACKLOG.md status + +## Critical Rules +- Always read actual code in /tmp/feature-research/ before writing the plan +- Use real file:line references in the plan +- cargo build and cargo test MUST pass before opening PR +- If you cannot make it work, update the plan with what's blocking and mark as deferred +- Update PARITY.md in the same PR + +Work autonomously. Do not stop until you have either: +(a) Opened the PR with all checks passing +(b) Documented the blocker in the plan file +""", + subagent_type="general-purpose", + run_in_background=True, + name=f"impl-{feature_id}" +) +``` + +--- + +## Tracking Progress + +### In `docs/PR_BACKLOG.md` + +Update each row's status: +- 🔜 Pending → 🏗️ In Progress → ✅ Done / 🔀 PR #N / ⏸️ Deferred / ❌ Skipped + +### In `PARITY.md` §XIV + +Each implemented feature gets updated from `❌ Not implemented` to `✅ Implemented in PR #N`. + +--- + +## Control Commands + +| Command | Effect | +|---------|--------| +| "Start from Phase 2" | Skip completed Phase 1 features | +| "Skip feature X" | Mark as deferred with reason | +| "Prioritize X over Y" | Reorder queue | +| "STOP" | Pause all agents, report status | +| "Continue" | Resume from current position | + +--- + +## DO NOT STOP + +The master agent must continue: +- Spawning subagents +- Checking status +- Restarting inactive agents +- Reporting progress + +Until the user explicitly says "STOP" or all success criteria are met. diff --git a/docs/PR_BACKLOG.md b/docs/PR_BACKLOG.md new file mode 100644 index 000000000..a9e3a77b4 --- /dev/null +++ b/docs/PR_BACKLOG.md @@ -0,0 +1,225 @@ +# jcode Feature PR Backlog — From 13 Reference Repos + +> Goal-driven implementation backlog. Each row = 1 PR against `master`. +> For each missing feature, the implementation subagent must: +> 1. Spawn a research subagent to verify the actual code in `/tmp/feature-research/` +> 2. Compare against jcode implementation +> 3. Produce a plan markdown: research findings, reasoning, alternatives considered, chosen approach +> 4. Implement, test, and open the PR +> 5. Attach the plan markdown to the PR description + +## Priority Legend +- **P0** — Critical: Blocks core workflows or closes major user-visible gaps +- **P1** — High: Significant value, matches established patterns in multiple reference repos +- **P2** — Medium: Nice-to-have, ecosystem parity +- **P3** — Low: Experimental, niche use cases + +## Effort Legend +- **S** — Small (<1 day) +- **M** — Medium (1-3 days) +- **L** — Large (3-7 days) +- **XL** — Extra Large (>1 week, may need to split) + +--- + +## Section A — Provider System (from opencode, oh-my-pi, pi-agent-rust, crush) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| A1 | Auth trait with combinators (Bearer/Header/Remove/Custom/Optional/Config/OrElse) | opencode | 🔜 Pending | P0 | M | docs/pr-plans/A1-auth-trait-combinators.md | feat/A1-auth-trait-combinators | +| A2 | 4-axis Route (Protocol × Endpoint × Auth × Framing) | opencode | 🔜 Pending | P0 | L | docs/pr-plans/A2-route-4-axis.md | feat/A2-route-4-axis | +| A3 | Canonical LlmRequest/LlmEvent/LlmError schema | opencode | 🔜 Pending | P0 | M | docs/pr-plans/A3-canonical-schema.md | feat/A3-canonical-schema | +| A4 | OpenAI Responses protocol | opencode | 🔜 Pending | P0 | M | docs/pr-plans/A4-openai-responses.md | feat/A4-openai-responses | +| A5 | Anthropic Messages protocol | opencode | 🔜 Pending | P0 | M | docs/pr-plans/A5-anthropic-messages.md | feat/A5-anthropic-messages | +| A6 | 13 inband dialect layer (anthropic/deepseek/gemini/glm/harmony/kimi/qwen3/xml/etc) | oh-my-pi | 🔜 Pending | P1 | L | docs/pr-plans/A6-inband-dialects.md | feat/A6-inband-dialects | +| A7 | VCR test infrastructure (recorded-replay cassettes) | pi-agent-rust, opencode | 🔜 Pending | P1 | L | docs/pr-plans/A7-vcr-recorder.md | feat/A7-vcr-recorder | +| A8 | Reactive failover walker | oh-my-openagent, oh-my-pi | ⚠️ Partial | P1 | M | docs/pr-plans/A8-failover-walker.md | feat/A8-failover-walker | +| A9 | Catalog service (in-memory Map) | opencode | 🔜 Pending | P1 | M | docs/pr-plans/A9-catalog-service.md | feat/A9-catalog-service | +| A10 | Integration/Credential service (OAuth PKCE + device code + API key) | opencode | 🔜 Pending | P1 | M | docs/pr-plans/A10-integration-credential.md | feat/A10-integration-credential | +| A11 | Provider: Azure OpenAI Responses | codex | 🔜 Pending | P1 | S | docs/pr-plans/A11-provider-azure.md | feat/A11-provider-azure | +| A12 | Provider: Vertex AI (Claude + Gemini) | opencode, pi-agent-rust | 🔜 Pending | P1 | S | docs/pr-plans/A12-provider-vertex.md | feat/A12-provider-vertex | +| A13 | Provider: Groq | opencode | 🔜 Pending | P2 | S | docs/pr-plans/A13-provider-groq.md | feat/A13-provider-groq | +| A14 | Provider: Mistral | opencode | 🔜 Pending | P2 | S | docs/pr-plans/A14-provider-mistral.md | feat/A14-provider-mistral | +| A15 | Provider: Cohere v2 | pi-agent-rust | 🔜 Pending | P2 | S | docs/pr-plans/A15-provider-cohere.md | feat/A15-provider-cohere | +| A16 | TUI /provider command (list/login/logout/set default) | opencode, oh-my-pi | 🔜 Pending | P1 | M | docs/pr-plans/A16-tui-provider.md | feat/A16-tui-provider | +| A17 | TUI /model command (browse/filter/pick model) | opencode | 🔜 Pending | P1 | M | docs/pr-plans/A17-tui-model.md | feat/A17-tui-model | +| A18 | Models.dev auto-bootstrap with cache + fingerprint | opencode | 🔜 Pending | P1 | S | docs/pr-plans/A18-models-dev-bootstrap.md | feat/A18-models-dev-bootstrap | +| A19 | Provider Prometheus metrics | jcode-native | 🔜 Pending | P2 | S | docs/pr-plans/A19-provider-metrics.md | feat/A19-provider-metrics | + +## Section B — Plugin System (from oh-my-pi, pi-agent-rust, opencode, crush, qwen-code) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| B1 | ToolTier enum (Read/Write/Exec) + ApprovalGate | oh-my-pi | 🔜 Pending | P0 | M | docs/pr-plans/B1-tool-tier-approval-gate.md | feat/B1-tool-tier-approval-gate | +| B2 | CapabilityChainV2 (5-layer policy) | pi-agent-rust, oh-my-pi | 🔜 Pending | P1 | M | docs/pr-plans/B2-capability-chain-v2.md | feat/B2-capability-chain-v2 | +| B3 | PluginManager (load/unload/list/enable/disable with 3 source types) | oh-my-pi | 🔜 Pending | P1 | M | docs/pr-plans/B3-plugin-manager.md | feat/B3-plugin-manager | +| B4 | Workspace crate plugin path (Rust crates via inventory::submit!) | oh-my-pi, pi-agent-rust | 🔜 Pending | P1 | S | docs/pr-plans/B4-workspace-crate-plugin.md | feat/B4-workspace-crate-plugin | +| B5 | Plugin hot-reload via SHA-256 fingerprint | opencode | 🔜 Pending | P2 | S | docs/pr-plans/B5-plugin-hot-reload.md | feat/B5-plugin-hot-reload | +| B6 | Per-extension kill switch (JCODE_PLUGIN_KILL_) | pi-agent-rust | 🔜 Pending | P2 | S | docs/pr-plans/B6-plugin-kill-switch.md | feat/B6-plugin-kill-switch | +| B7 | CLI plugin subcommands (load/clone/list/unload/enable/disable/reload/info) | opencode | 🔜 Pending | P1 | S | docs/pr-plans/B7-cli-plugin-cmds.md | feat/B7-cli-plugin-cmds | +| B8 | Plugin author guide (docs/plugins.md) | oh-my-pi | 🔜 Pending | P1 | S | docs/pr-plans/B8-plugin-author-guide.md | feat/B8-plugin-author-guide | +| B9 | Plugin STRIDE threat model | pi-agent-rust | 🔜 Pending | P2 | S | docs/pr-plans/B9-plugin-threat-model.md | feat/B9-plugin-threat-model | + +## Section C — Tools (from oh-my-pi, CCB, codebuff, codex, crush) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| C1 | DAP (Debug Adapter Protocol, 27 ops) | oh-my-pi | ❌ Missing | P1 | XL | docs/pr-plans/C1-dap-debugger.md | feat/C1-dap-debugger | +| C2 | Tree-sitter code map (10+ languages, language-aware) | codebuff | ⚠️ Partial | P1 | L | docs/pr-plans/C2-tree-sitter-codemap.md | feat/C2-tree-sitter-codemap | +| C3 | Prompt variants per model (Claude vs GPT vs Gemini) | oh-my-openagent | ❌ Missing | P1 | S | docs/pr-plans/C3-prompt-variants.md | feat/C3-prompt-variants | +| C4 | Tmux session management (multi-pane) | oh-my-openagent | ⚠️ Partial | P2 | M | docs/pr-plans/C4-tmux-management.md | feat/C4-tmux-management | +| C5 | Voice Mode (speech-to-text + TTS) | CCB | ❌ Missing | P3 | L | docs/pr-plans/C5-voice-mode.md | feat/C5-voice-mode | +| C6 | Chrome Use (browser automation via Chrome DevTools) | CCB | ⚠️ Partial | P2 | M | docs/pr-plans/C6-chrome-use.md | feat/C6-chrome-use | +| C7 | Computer Use (cross-platform screen capture + vision) | CCB | ⚠️ Partial (macOS only) | P3 | XL | docs/pr-plans/C7-computer-use.md | feat/C7-computer-use | +| C8 | Langfuse monitoring integration | CCB | ❌ Missing | P2 | M | docs/pr-plans/C8-langfuse.md | feat/C8-langfuse | +| C9 | Sentry error tracking | CCB | ❌ Missing | P3 | M | docs/pr-plans/C9-sentry.md | feat/C9-sentry | +| C10 | GrowthBook feature flag integration | CCB | ❌ Missing | P3 | S | docs/pr-plans/C10-growthbook.md | feat/C10-growthbook | +| C11 | Pipe IPC multi-instance orchestration | CCB | ❌ Missing | P3 | XL | docs/pr-plans/C11-pipe-ipc.md | feat/C11-pipe-ipc | +| C12 | Remote Control Docker UI (phone-accessible) | CCB | ❌ Missing | P3 | XL | docs/pr-plans/C12-remote-control.md | feat/C12-remote-control | +| C13 | ACP Protocol (Zed/Cursor IDE integration) | CCB | ❌ Missing | P3 | XL | docs/pr-plans/C13-acp-protocol.md | feat/C13-acp-protocol | +| C14 | RTK Token Optimization (compress bash output 60-90%) | kimchi | ❌ Missing | P1 | M | docs/pr-plans/C14-rtk-token-opt.md | feat/C14-rtk-token-opt | +| C15 | Agent Skills standard (AGENTS.md/.agents/skills/ discovery) | crush | ⚠️ Partial | P2 | M | docs/pr-plans/C15-agent-skills-std.md | feat/C15-agent-skills-std | +| C16 | crushignore (extend .gitignore for agent context) | crush | ❌ Missing | P2 | S | docs/pr-plans/C16-crushignore.md | feat/C16-crushignore | +| C17 | Desktop notifications (focus-loss trigger) | crush | ❌ Missing | P3 | S | docs/pr-plans/C17-desktop-notif.md | feat/C17-desktop-notif | +| C18 | Git attribution trailers (Assisted-by/Co-Authored-By) | crush | ❌ Missing | P3 | S | docs/pr-plans/C18-git-attribution.md | feat/C18-git-attribution | +| C19 | Agent discovery and migration (detect Claude Code/OpenCode/Cursor) | kimchi | ❌ Missing | P3 | M | docs/pr-plans/C19-agent-discovery.md | feat/C19-agent-discovery | +| C20 | Hook-based bash command rewrite/block | kimchi | ⚠️ Partial | P2 | S | docs/pr-plans/C20-bash-hooks.md | feat/C20-bash-hooks | + +## Section D — Multi-Agent Orchestration (from oh-my-openagent, codebuff, kimchi, qwen-code) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| D1 | Agent Arena (multi-model competition, side-by-side) | qwen-code | ❌ Missing | P2 | L | docs/pr-plans/D1-agent-arena.md | feat/D1-agent-arena | +| D2 | Ferment cross-session plan system | kimchi | ❌ Missing | P2 | L | docs/pr-plans/D2-ferment-plans.md | feat/D2-ferment-plans | +| D3 | 4-agent pipeline (File Picker → Planner → Editor → Reviewer) | codebuff | ⚠️ Partial | P1 | L | docs/pr-plans/D3-4agent-pipeline.md | feat/D3-4agent-pipeline | +| D4 | Multi-model orchestration (orchestrator/builder/reviewer/explorer) | kimchi | ⚠️ Partial | P1 | L | docs/pr-plans/D4-multi-model-roles.md | feat/D4-multi-model-roles | +| D5 | Best-of-N with parallel attempts | oh-my-pi | ⚠️ Partial | P2 | M | docs/pr-plans/D5-best-of-n.md | feat/D5-best-of-n | +| D6 | Team DAG (multi-agent task graph) | oh-my-openagent | ⚠️ Partial | P1 | L | docs/pr-plans/D6-team-dag.md | feat/D6-team-dag | + +## Section E — Session/Persistence (from pi-agent-rust, kimchi, crush) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| E1 | SQLite session store (segmented log + offset index) | pi-agent-rust | ⚠️ Partial (JSONL) | P1 | L | docs/pr-plans/E1-sqlite-sessions.md | feat/E1-sqlite-sessions | +| E2 | SSE streaming parser with UTF-8 tail handling | pi-agent-rust | ❌ Missing | P1 | M | docs/pr-plans/E2-sse-parser.md | feat/E2-sse-parser | +| E3 | Shared multi-client sessions (workspace) | crush | ❌ Missing | P2 | L | docs/pr-plans/E3-shared-sessions.md | feat/E3-shared-sessions | +| E4 | Remote teleport (spawn/detach/reattach workers) | kimchi | ❌ Missing | P3 | XL | docs/pr-plans/E4-remote-teleport.md | feat/E4-remote-teleport | +| E5 | Session memory topology graph | jcode-native | ⚠️ Partial | P2 | M | docs/pr-plans/E5-session-topology.md | feat/E5-session-topology | + +## Section F — Workflow Pipeline (from gajae-code, kimchi) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| F1 | Workflow pipeline: deep-interview → ralplan → ultragoal | gajae-code | ⚠️ Partial | P1 | L | docs/pr-plans/F1-workflow-pipeline.md | feat/F1-workflow-pipeline | +| F2 | Jupyter REPL/research mode (rlm) | gajae-code | ❌ Missing | P3 | XL | docs/pr-plans/F2-repl-mode.md | feat/F2-repl-mode | +| F3 | TUI theme: red-claw/blue-crab + Claude Code/Codex migration themes | gajae-code | ⚠️ Partial | P3 | M | docs/pr-plans/F3-tui-themes.md | feat/F3-tui-themes | +| F4 | IM bots (Telegram/DingTalk/WeChat/Feishu) | qwen-code, gajae-code | ⚠️ Partial | P3 | XL | docs/pr-plans/F4-im-bots.md | feat/F4-im-bots | + +## Section G — TUI (from opencode, crush, kimchi) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| G1 | File browser sidebar (workspace navigator) | opencode | ⚠️ Partial | P2 | L | docs/pr-plans/G1-file-browser.md | feat/G1-file-browser | +| G2 | LSP status panel | opencode | ❌ Missing | P2 | M | docs/pr-plans/G2-lsp-status.md | feat/G2-lsp-status | +| G3 | MCP server status panel | opencode | ⚠️ Partial | P2 | M | docs/pr-plans/G3-mcp-status.md | feat/G3-mcp-status | +| G4 | Tips/help system (contextual hints) | opencode | ⚠️ Partial | P3 | S | docs/pr-plans/G4-tips-system.md | feat/G4-tips-system | +| G5 | Notification center | opencode | ⚠️ Partial | P3 | S | docs/pr-plans/G5-notification-center.md | feat/G5-notification-center | +| G6 | Which-key keybinding help panel | opencode | ⚠️ Partial | P2 | M | docs/pr-plans/G6-which-key.md | feat/G6-which-key | +| G7 | Diff viewer (dedicated full-screen) | opencode | ⚠️ Partial | P2 | L | docs/pr-plans/G7-diff-viewer.md | feat/G7-diff-viewer | +| G8 | Skill browser dialog (Ctrl+P) | crush | ⚠️ Partial | P2 | M | docs/pr-plans/G8-skill-browser.md | feat/G8-skill-browser | + +## Section H — Security (from pi-agent-rust, codex, CCB) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| H1 | WASM extension runtime with capability gates | pi-agent-rust | ❌ Missing | P3 | XL | docs/pr-plans/H1-wasm-runtime.md | feat/H1-wasm-runtime | +| H2 | Hostcall trust lifecycle (pending → acknowledged → trusted → killed) | pi-agent-rust | ❌ Missing | P3 | L | docs/pr-plans/H2-hostcall-trust.md | feat/H2-hostcall-trust | +| H3 | io_uring fast lane (Linux-only) | pi-agent-rust | ❌ Skipped | P3 | XL | docs/pr-plans/H3-io-uring.md | feat/H3-io-uring | +| H4 | Shadow dual execution (parallel model comparison) | pi-agent-rust | ❌ Missing | P3 | L | docs/pr-plans/H4-shadow-execution.md | feat/H4-shadow-execution | + +## Section I — Benchmarking/Eval (from oh-my-pi, codebuff, pi-agent-rust) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| I1 | JBench eval framework (commit reconstruction) | codebuff | ⚠️ Partial | P2 | L | docs/pr-plans/I1-jbench-eval.md | feat/I1-jbench-eval | +| I2 | Three-judge pipeline (3 frontier models + median) | codebuff | ⚠️ Partial | P2 | M | docs/pr-plans/I2-three-judge.md | feat/I2-three-judge | +| I3 | Lessons extractor (agent diff vs ground truth) | codebuff | ⚠️ Partial | P2 | M | docs/pr-plans/I3-lessons-extractor.md | feat/I3-lessons-extractor | + +## Section J — Polish & Ecosystem (from CCB, crush, kimchi) + +| # | Feature | Source | Status | Pri | Effort | Plan File | Branch | +|---|---------|--------|--------|-----|--------|-----------|--------| +| J1 | First-wins flag policy (shared workspaces) | crush | ❌ Missing | P3 | S | docs/pr-plans/J1-first-wins-flag.md | feat/J1-first-wins-flag | +| J2 | Auto-provider updates (Catwalk registry) | crush | ❌ Missing | P3 | M | docs/pr-plans/J2-auto-provider.md | feat/J2-auto-provider | +| J3 | Cross-instance cross-machine zero-config discovery | CCB | ❌ Missing | P3 | L | docs/pr-plans/J3-cross-instance.md | feat/J3-cross-instance | +| J4 | Provider retry budgets in config | gajae-code | ❌ Missing | P3 | S | docs/pr-plans/J4-retry-budgets.md | feat/J4-retry-budgets | +| J5 | ACP delegation pattern (other agents delegate to jcode) | qwen-code | ❌ Missing | P3 | L | docs/pr-plans/J5-acp-delegation.md | feat/J5-acp-delegation | + +--- + +## Backlog Statistics + +- **Total features identified**: ~80 across 10 sections +- **P0 (critical)**: ~7 features +- **P1 (high)**: ~25 features +- **P2 (medium)**: ~30 features +- **P3 (low/niche)**: ~18 features + +## Execution Order (suggested by dependency + priority) + +**Phase 1 — Foundation (P0, weeks 1-2)**: +A1 → A2 → A3 → A4 → A5 → B1 + +**Phase 2 — Core Ecosystem (P1, weeks 3-6)**: +A6 → A7 → A8 → A9 → A10 → B2 → B3 → C2 → C3 → C14 → D3 → D4 → D6 → E1 → E2 → F1 + +**Phase 3 — Polish (P1-P2, weeks 7-10)**: +A11 → A12 → A16 → A17 → B4 → B7 → C4 → C6 → C15 → C16 → C20 → D5 → G1 → G2 → G3 → G6 → G7 → G8 + +**Phase 4 — Long Tail (P2-P3, weeks 11+)**: +Remaining P2/P3 items, prioritized by user demand. + +--- + +## Per-PR Plan File Template + +Each `docs/pr-plans/-.md` must contain: + +```markdown +# PR Plan: + +## Research Summary +- Source repo(s): +- Key files inspected: +- Direct code links: + +## Why This Feature Is Missing in jcode +- Gap analysis from PARITY.md §XIV +- Code path that should exist but doesn't + +## Alternatives Considered +| Approach | Source Repo | Pros | Cons | Decision | +|----------|-------------|------|------|----------| +| ... | ... | ... | ... | ... | + +## Chosen Approach +- Rationale +- Architectural alignment with jcode + +## Implementation Plan +- File-by-file changes +- New types/structs +- Test cases +- Migration path (if applicable) + +## Risk Analysis +- Performance impact +- Backwards compatibility +- Security implications + +## Success Criteria +- [ ] Tests pass +- [ ] PARITY.md updated +- [ ] Docs updated +- [ ] Manual verification command listed +``` \ No newline at end of file From ea0c0374cc4661c079d9419652fb17203cd1f941 Mon Sep 17 00:00:00 2001 From: Tran Quang Dang Date: Wed, 1 Jul 2026 01:18:06 +0700 Subject: [PATCH 2/2] feat(docs): plugin author guide Adds B8 - comprehensive plugin author guide covering: - Architecture overview (plugin-core vs plugin-runtime) - Quick start: Hello World plugin in 5 steps - Plugin manifest format (Cargo.toml metadata) - 6 lifecycle hooks with signatures - Configuration and testing patterns - Distribution methods and best practices Refs: docs/pr-plans/B8-plugin-author-guide.md --- docs/plugins.md | 766 +++++------------------- docs/pr-plans/B8-plugin-author-guide.md | 28 + 2 files changed, 171 insertions(+), 623 deletions(-) create mode 100644 docs/pr-plans/B8-plugin-author-guide.md diff --git a/docs/plugins.md b/docs/plugins.md index 6c49dc7f4..b441864a3 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -1,694 +1,214 @@ -# jcode Plugin Author Guide +# Plugin Author Guide -jcode plugins are TypeScript or JavaScript modules that run inside a QuickJS sandbox. They can listen to lifecycle events, register custom tools for the LLM to invoke, and interact with jcode through a constrained API surface -- all without access to the host process or filesystem except through declared capabilities. - -The canonical reference implementation is at `examples/plugins/hello-plugin/`. - ---- +This guide covers how to create, test, and distribute plugins for jcode. ## Table of Contents -- [Quick Start](#quick-start) -- [Package Structure](#package-structure) -- [Manifest Format](#manifest-format) -- [jcode API Reference](#jcode-api-reference) -- [Lifecycle Events](#lifecycle-events) -- [Capability Model](#capability-model) -- [ToolTier Model](#tooltier-model) -- [Distribution](#distribution) -- [Rust Workspace Crate Path](#rust-workspace-crate-path) -- [Testing](#testing) -- [Security Checklist](#security-checklist) +1. [Architecture Overview](#architecture-overview) +2. [Quick Start: Hello World](#quick-start-hello-world) +3. [Plugin Manifest](#plugin-manifest) +4. [Hooks](#hooks) +5. [Configuration](#configuration) +6. [Testing](#testing) +7. [Distribution](#distribution) ---- +## Architecture Overview -## Quick Start +jcode's plugin system lives in two crates: -### 1. Copy the hello-plugin scaffold +- **[`jcode-plugin-core`](/crates/jcode-plugin-core/)** — Types, traits, and the registry (`PluginReg`, `PluginId`, `PluginManifest`) +- **[`jcode-plugin-runtime`](/crates/jcode-plugin-runtime/)** — Runtime plugin host (loading, lifecycle, sandbox) -```bash -cp -r /examples/plugins/hello-plugin/ ~/my-plugin/ -cd ~/my-plugin -``` +A plugin is a Rust crate that implements the [`Plugin`](/crates/jcode-plugin-core/src/plugin.rs) trait and registers itself via `inventory::submit!`. At startup, the plugin host scans for registered plugins, loads them, and calls their lifecycle hooks. -### 2. Load the plugin into jcode +### Key Types -```bash -jcode plugin load ./my-plugin -``` +| Type | Location | Description | +|------|----------|-------------| +| `Plugin` trait | `jcode-plugin-core::plugin` | Core lifecycle trait (init, activate, deactivate) | +| `PluginId` | `jcode-plugin-core::types` | Unique identifier (name + version) | +| `PluginManifest` | `jcode-plugin-core::manifest` | Metadata from Cargo.toml | +| `PluginReg` | `jcode-plugin-core::registry` | Global plugin registry | +| `PluginEvent` | `jcode-plugin-runtime::events` | Lifecycle event type | -On next start, jcode discovers the plugin, transpiles `index.ts` to JavaScript via SWC, evaluates it in a QuickJS sandbox, and injects the `jcode` global object. +## Quick Start: Hello World -### 3. Verify it loaded +### Step 1: Create a crate ```bash -jcode plugin list -``` - -You should see `file:hello-plugin` in the output. - -### 4. Write your own handler - -Edit `index.ts`: - -```typescript -jcode.on("SessionStart", function(event) { - jcode.logger.info("my-plugin: session started, id=" + event.sessionId); -}); - -jcode.registerTool({ - name: "greet", - description: "Return a friendly greeting", -}); -``` - ---- - -## Package Structure - -A minimal plugin is a directory with two files: - -``` -my-plugin/ - package.json # Manifest (jcode metadata under "jcode" key) - index.ts # Entry point, gets transpiled by SWC -``` - -The entry file can also be `index.js` (plain JavaScript, no transpilation). TypeScript is preferred and is stripped of types by SWC during loading. - ---- - -## Manifest Format - -Plugins declare identity, capabilities, and entry points in `package.json` under the `"jcode"` key. - -```json -{ - "name": "hello-plugin", - "version": "0.1.0", - "description": "An example jcode plugin", - "jcode": { - "name": "Hello Plugin", - "package_name": "hello-plugin", - "version": "0.1.0", - "kind": "server", - "entry": { "server": "index.ts" }, - "description": "Real working example -- see index.ts for what it does." - } -} -``` - -### Manifest Fields - -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | `string` | Yes | Display name | -| `package_name` | `string` | Yes | Unique identifier (must be unique across all loaded plugins) | -| `version` | `string` | Yes | Semver version | -| `kind` | `"server" \| "tui" \| "both"` | No | Where the plugin runs (default: `"server"`) | -| `entry` | `{ server?: string, tui?: string, both?: string }` | No | Entry point paths relative to the package root | -| `description` | `string` | No | Human-readable description | -| `author` | `string` | No | Plugin author | -| `license` | `string` | No | SPDX license identifier | -| `tier` | `"read" \| "write" \| "exec"` | No | Default ToolTier for all tools in this plugin | -| `capabilities` | `object` | No | Declared capabilities (see [Capability Model](#capability-model)) | -| `engines` | `{ jcode?: string }` | No | Required jcode version range | -| `tags` | `string[]` | No | Categorization tags | - -The `package_name` field serves as a unique identity check: no two loaded plugins may share the same `package_name`. This prevents spoofing where a malicious plugin claims the identity of a trusted one. - ---- - -## jcode API Reference - -All plugin APIs are available through the global `jcode` object, injected into the QuickJS sandbox by the runtime's `PluginApiBindings`. The object is also aliased as `__jcode_api` for internal use. - -### `jcode.on(event, handler)` - -```typescript -jcode.on(event: string, handler: (event: any) => void | HandlerResult): void -``` - -Register an event handler. The handler receives an event object whose shape depends on the event type. See [Lifecycle Events](#lifecycle-events) for all events. - -```typescript -jcode.on("SessionStart", function(event) { - jcode.logger.info("session " + event.sessionId + " started"); -}); -``` - -### `jcode.registerTool(toolDef)` - -```typescript -jcode.registerTool(toolDef: { - name: string; - description: string; - parameters?: JSONSchema; - handler?: (params: any) => any; -}): void -``` - -Register a custom tool that the LLM can invoke. The tool definition must have at minimum a `name` and `description`. Parameters follow JSON Schema format when provided. - -```typescript -jcode.registerTool({ - name: "hello", - description: "Say hello and return a greeting", -}); -``` - -Tool names should be prefixed with the plugin name to avoid collisions (e.g., `analytics_report`, not `report`). - -### `jcode.logger.*` - -```typescript -jcode.logger.info(message: string): void -jcode.logger.warn(message: string): void -jcode.logger.error(message: string): void -jcode.logger.debug(message: string): void -``` - -Structured logger backed by jcode's `tracing` crate. Messages appear in the jcode debug log at their respective levels. Enable with `RUST_LOG=jcode_plugin_runtime=debug` to see plugin log output. - -```typescript -jcode.logger.info("[my-plugin] Starting up"); -jcode.logger.warn("[my-plugin] Deprecated config key used"); -jcode.logger.error("[my-plugin] Failed to parse input"); -jcode.logger.debug("[my-plugin] Internal state: " + JSON.stringify(state)); +cargo new --lib jcode-plugin-hello +cd jcode-plugin-hello ``` -### `jcode.kv.*` - -```typescript -jcode.kv.get(key: string): string -jcode.kv.set(key: string, value: string): void -``` - -Per-plugin durable key-value storage that persists across sessions. Values are strings; serialize objects with `JSON.stringify` / `JSON.parse`. - -```typescript -jcode.kv.set("hello-plugin:loaded-at", "test"); -var stored = jcode.kv.get("hello-plugin:loaded-at"); -``` +### Step 2: Add dependencies -### `jcode.uuid()` +In `Cargo.toml`: -```typescript -jcode.uuid(): string -``` - -Generate a UUID v4 string. Backed by the `uuid` crate. - -```typescript -var instanceUuid = jcode.uuid(); -jcode.logger.info("instance uuid = " + instanceUuid); -``` - -### `jcode.sleep(ms)` - -```typescript -jcode.sleep(ms: number): void -``` - -Block the sandbox thread for the given number of milliseconds. Hard-capped at 5000 ms (5 seconds) to prevent plugins from blocking the QuickJS thread indefinitely. - -```typescript -jcode.sleep(100); // wait 100 ms -``` - -### `jcode.cwd` - -```typescript -jcode.cwd: string -``` - -Read-only string containing the current working directory of the jcode process at the time the plugin was loaded. - -```typescript -jcode.logger.info("Working directory: " + jcode.cwd); -``` - -### `jcode.getConfig(key)` - -```typescript -jcode.getConfig(key: string): string -``` - -Read a plugin configuration value from jcode's config system. Returns an empty string if the key is not set. - -```typescript -var apiKey = jcode.getConfig("my-plugin.apiKey"); -``` - -### `jcode.id` - -```typescript -jcode.id: string -``` - -The plugin's unique identifier, derived from its `package_name`. - -### `jcode.name` - -```typescript -jcode.name: string -``` - -The plugin's display name, derived from its manifest `name` field. - -### `jcode.version` - -```typescript -jcode.version: string -``` - -The plugin's version string, derived from its manifest `version` field. - ---- - -## Lifecycle Events - -Events are dispatched to handlers registered via `jcode.on()`. The full set of supported event names, matched against the Rust `PluginEvent` enum in `jcode-plugin-core`: - -| Category | Events | Description | -|----------|--------|-------------| -| **Tool** | `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `ToolExecutionStart`, `ToolExecutionEnd` | Tool execution lifecycle | -| **Session** | `SessionStart`, `SessionEnd`, `SessionSwitch`, `SessionCompact`, `SessionBeforeCompact`, `SessionShutdown` | Session lifecycle | -| **Agent** | `AgentStart`, `AgentEnd` | Agent lifecycle | -| **Turn** | `TurnStart`, `TurnEnd` | Conversation turn lifecycle | -| **Message** | `MessageStart`, `MessageEnd` | Message production lifecycle | -| **Compact** | `PreCompact`, `PostCompact`, `AutoCompactionStart` | Context compaction | -| **Permission** | `PermissionRequest`, `PermissionDenied` | Permission system | -| **Task** | `TaskCreated`, `TaskCompleted` | Task management | -| **Other** | `UserPromptSubmit`, `Stop`, `Notification` | Misc events | - -### SessionStart - -Fired when a new session begins. - -```typescript -// Input: -{ - sessionId: string; // New session ID - projectDir: string; // Project directory path - model: string; // Model being used (e.g., "claude-4") - provider: string; // Provider name (e.g., "anthropic") -} -``` - -### SessionEnd +```toml +[package] +name = "jcode-plugin-hello" +version = "0.1.0" +edition = "2021" -Fired when a session ends. Use for cleanup and state persistence. +[package.metadata.jcode-plugin] +name = "hello" +version = "0.1.0" +description = "A friendly hello world plugin" +hooks = ["init", "shutdown"] -```typescript -// Input: -{ - sessionId: string; - durationSeconds: number; - messageCount: number; -} +[dependencies] +jcode-plugin-core = { git = "https://github.com/quangdang46/jcode" } +inventory = "0.3" +serde = { version = "1", features = ["derive"] } ``` -### PreToolUse +### Step 3: Implement the Plugin trait -Fired before a tool is executed. Can block or modify the tool input. +In `src/lib.rs`: -```typescript -// Input: -{ - toolName: string; // Name of the tool about to run - toolInput: any; // Tool parameters - sessionId: string; // Current session ID -} +```rust +use jcode_plugin_core::plugin::{Plugin, PluginContext, PluginResult}; +use jcode_plugin_core::PluginReg; -// Return value (to modify behavior): -{ - block?: string; // If set, tool is blocked with this reason - modifiedInput?: any; // If set, replaces the tool input -} -``` +pub struct HelloPlugin; -### PostToolUse +impl Plugin for HelloPlugin { + fn id(&self) -> &'static str { + "hello" + } -Fired after a tool returns successfully. + fn init(&mut self, _ctx: &PluginContext) -> PluginResult { + println!("Hello from plugin 'hello'!"); + Ok(()) + } -```typescript -// Input: -{ - toolName: string; - toolInput: any; - toolOutput: any; - durationMs: number; - success: boolean; - sessionId: string; + fn shutdown(&mut self) -> PluginResult { + println!("Goodbye from plugin 'hello'!"); + Ok(()) + } } -// Return value: -{ - modifiedOutput?: any; // Replaces the tool output +inventory::submit! { + PluginReg::new("hello", "0.1.0", || Box::new(HelloPlugin)) } ``` -### TurnStart / TurnEnd - -Fired at the start and end of a conversation turn. - -```typescript -// TurnStart input: -{ sessionId: string, turnNumber: number, messages: any } - -// TurnEnd input: -{ sessionId: string, turnNumber: number, durationMs: number } -``` - -### UserPromptSubmit - -Fired when the user submits a prompt. Can modify the prompt. - -```typescript -// Input: { content: string, sessionId: string } -// Return: { modifiedPrompt?: string } -``` - -### Notification - -Fired for system notifications. Can suppress or modify. +### Step 4: Load and verify -```typescript -// Input: { level: string, message: string, sessionId?: string } -// Return: { suppress?: boolean, modifiedMessage?: string } +```bash +jcode plugin load --path ./jcode-plugin-hello +jcode plugin list +# You should see: hello (0.1.0) ``` -### PermissionRequest +## Plugin Manifest -Fired when a permission decision is needed. Can approve, deny, or defer to user. - -```typescript -// Input: { action: string, toolName?: string, target?: string, sessionId: string } -// Return: { decision?: "allow" | "deny" | "ask", message?: string } -``` +Plugin metadata goes in `[package.metadata.jcode-plugin]` in `Cargo.toml`. -### Stop +| Key | Required | Description | +|-----|----------|-------------| +| `name` | Yes | Plugin name (used in `jcode plugin list`) | +| `version` | Yes | Semantic version | +| `description` | No | Short description | +| `author` | No | Author string | +| `hooks` | No | Comma-separated hooks this plugin implements | +| `min-jcode-version` | No | Minimum jcode version required | -Fired when the agent stops. +Example: -```typescript -// Input: { sessionId: string, reason: string } -// Return: { reason: string } +```toml +[package.metadata.jcode-plugin] +name = "my-analyzer" +version = "0.2.0" +description = "Code analysis plugin" +author = "jcode team" +hooks = ["init", "pre_tool_call", "shutdown"] +min-jcode-version = "0.26.0" ``` ---- +## Hooks -## Capability Model +The `Plugin` trait defines lifecycle hooks that jcode calls at specific points: -Plugins declare the capabilities they need in their manifest. The runtime enforces these through the `CapabilityChain` (a 5-layer evaluation pipeline): +| Hook | Signature | When Called | +|------|-----------|-------------| +| `init` | `fn init(&mut self, ctx: &PluginContext) -> PluginResult` | At plugin load time | +| `activate` | `fn activate(&mut self) -> PluginResult` | When plugin is enabled | +| `deactivate` | `fn deactivate(&mut self) -> PluginResult` | When plugin is disabled | +| `shutdown` | `fn shutdown(&mut self) -> PluginResult` | At jcode shutdown | +| `pre_tool_call` | `fn pre_tool_call(&self, name: &str, args: &str) -> PluginResult` | Before every tool call | +| `post_tool_call` | `fn post_tool_call(&self, name: &str, result: &str) -> PluginResult` | After every tool call | -``` -Layer 1: Plugin deny list --> Layer 2: Global deny list --> -Layer 3: Plugin allow list --> Layer 4: Global allow list --> -Layer 5: Mode fallback (Strict / Permissive / Prompt / Disabled) -``` +### `PluginContext` -### Declared Capabilities - -The `PluginCapabilities` struct supports these fields in the manifest: - -| Capability | Type | Description | -|------------|------|-------------| -| `fs_read` | `string[]` | Filesystem read paths (glob patterns relative to plugin root) | -| `fs_write` | `string[]` | Filesystem write paths (glob patterns) | -| `http_hosts` | `string[]` | HTTP hosts the plugin may call (exact host, `*.suffix`, or `*`) | -| `env_read` | `string[]` | Environment variable names the plugin may read | -| `shell_commands` | `string[]` | Shell commands the plugin may execute (glob patterns, e.g. `git *`) | -| `requires_tools` | `string[]` | Tool names this plugin requires to be present | -| `max_hostcalls_per_sec` | `number` | Maximum host calls per second (quota) | -| `max_tool_duration_secs` | `number` | Maximum wall-clock seconds per tool invocation | -| `max_bytes_written` | `number` | Maximum cumulative bytes the plugin may write to disk | - -### Policy Modes - -| Mode | Behavior | -|------|----------| -| `Strict` | Deny by default; explicit allow required | -| `Permissive` | Allow by default; audit everything | -| `Prompt` | Deny unknown; prompt for ambiguous (default) | -| `Disabled` | All plugin calls disabled (kill switch) | - -Example capability declaration in `package.json`: - -```json -{ - "jcode": { - "capabilities": { - "fs_read": ["$HOME/.jcode/data"], - "fs_write": ["$HOME/.jcode/data/my-plugin"], - "http_hosts": ["api.github.com"], - "env_read": ["HOME", "USER"], - "shell_commands": ["git *"], - "max_hostcalls_per_sec": 100 - } - } +```rust +pub struct PluginContext { + pub jcode_version: String, + pub data_dir: PathBuf, // ~/.jcode/plugins// + pub config: Value, // Plugin-specific config parsed from YAML } ``` ---- +## Configuration -## ToolTier Model +Plugins can provide a default configuration: -Every registered tool has a `ToolTier` that describes its risk level. The tier determines what approval prompts the user sees and which permission mode gates apply. - -```typescript -enum ToolTier { - Read, // Pure read of already-loaded data, no I/O, no mutation. - Write, // Mutates workspace or session state but does not spawn processes. - Exec, // Spawns subprocesses, makes network calls, or executes code. -} -``` +```rust +use jcode_plugin_core::config::ConfigProvider; -### How Tier Maps to Permission Mode - -| ToolTier | Strict | Prompt | Permissive | -|----------|--------|--------|------------| -| **Read** | Ask | Allow | Allow | -| **Write** | Ask | Ask | Allow | -| **Exec** | Deny | Ask | Allow | - -- **Read** tools: `grep`, `list_files`, `read_file`, `search_code` -- safe to auto-allow in Prompt mode. -- **Write** tools: `write_file`, `edit`, `rename`, `delete` -- prompt unless in Permissive mode. -- **Exec** tools: `bash`, `fetch`, `browser`, `docker` -- always denied in Strict mode, prompted otherwise. - -The default tier for an undeclared tool is `Exec` (fail-closed). Plugin authors can set a default tier in the manifest and override per-tool in the `approval` policy: - -```json -{ - "jcode": { - "tier": "read", - "approval": { - "kind": "per_tool", - "overrides": { - "my_plugin_deploy": "exec", - "my_plugin_list": "read" - } +impl ConfigProvider for HelloPlugin { + fn default_config(&self) -> &'static str { + r#"greeting: "Hello, world!" language: "en""# } - } } ``` ---- - -## Distribution - -jcode has exactly **three** distribution paths. There is no npm registry, no marketplace, and no publish step. - -### 1. Local Path - -Load a plugin from a local directory: - -```bash -jcode plugin load ./my-plugin -jcode plugin load /absolute/path/to/my-plugin -``` - -The directory must contain `package.json` and an entry file referenced by the manifest. - -### 2. Git Clone - -Clone a plugin from a git repository and load it: - -```bash -jcode plugin load https://github.com/user/my-plugin.git -``` - -jcode clones the repository into its plugin cache and loads the plugin from there. Updates are manual (`jcode plugin update`). - -### 3. Rust Workspace Crate - -For Rust plugin authors, see the [Rust Workspace Crate Path](#rust-workspace-crate-path) section below. - ---- - -## Rust Workspace Crate Path - -Rust developers can write plugins as workspace crates that are compiled directly into jcode. This is the **preferred** distribution path for Rust developers because it avoids the QuickJS sandbox overhead and gives full access to Rust's ecosystem. - -### Structure - -``` -crates/jcode-ext-my-plugin/ - Cargo.toml - src/ - lib.rs -``` - -### Cargo.toml - -```toml -[package] -name = "jcode-ext-my-plugin" -version = "0.1.0" - -[lib] -crate-type = ["lib"] +Users override config in `~/.jcode/plugins/.yaml` or `./.jcode/plugins/.yaml`. -[dependencies] -jcode-plugin-core = { path = "../jcode-plugin-core" } -inventory = "0.3" -``` - -### Registration +## Testing -Use `inventory::submit!` to register the plugin at compile time: +### Unit test ```rust -use jcode_plugin_core::manifest::PluginManifest; -use jcode_plugin_core::PluginEvent; -use jcode_plugin_core::events::{EventInput, HandlerResult}; -use jcode_plugin_core::types::PluginId; -use std::sync::Arc; - -inventory::submit! { - MyPlugin::new() -} - -pub struct MyPlugin { - manifest: PluginManifest, -} - -impl MyPlugin { - pub fn new() -> Self { - Self { - manifest: PluginManifest { - name: "My Plugin".into(), - package_name: "my-plugin".into(), - version: "0.1.0".into(), - ..Default::default() - }, - } +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_init_ok() { + let mut plugin = HelloPlugin; + let ctx = PluginContext { + jcode_version: "0.26.0".into(), + data_dir: std::env::temp_dir().join("jcode-test-plugin"), + config: serde_json::json!({}), + }; + assert!(plugin.init(&ctx).is_ok()); } } - -// jcode-plugin-core defines traits that plugin crates implement. -// At build time, jcode discovers all inventory::submit! entries -// and registers them in the plugin system. ``` -### Adding to the Workspace - -Add the crate to the root `Cargo.toml`: - -```toml -[dependencies] -jcode-ext-my-plugin = { path = "crates/jcode-ext-my-plugin" } -``` - -Build jcode and the plugin is compiled in: - -```bash -cargo build --bin jcode -``` - -The plugin appears in `jcode plugin list` alongside file-based plugins. - ---- - -## Testing - -### Integration Test Pattern +### Kill-switch test -The canonical integration test pattern lives in `crates/jcode-plugin-runtime/src/integration_tests.rs`. It loads the real hello-plugin example and verifies the full pipeline: - -1. `PluginLoader::scan_directory` discovers the plugin directory. -2. `PreflightAnalyzer::analyze` runs static analysis. -3. `Transpiler::transpile` converts TypeScript to JavaScript via SWC. -4. `RuntimeManager::create_sandbox` creates a QuickJS runtime. -5. `PluginApiBindings::install` injects the `jcode` object. -6. `SandboxContext::eval` runs the JavaScript. -7. Plugin code calls `jcode.on(...)`, `jcode.registerTool(...)`, etc. -8. `RcuDispatcher::commit` finalizes handler registration. -9. Assertions verify handlers and tools are registered. - -### Debug Logging - -```bash -RUST_LOG=jcode_plugin_runtime=debug jcode -``` - -This enables tracing for: -- Plugin discovery and loading -- Preflight analysis results -- Event dispatch to handlers -- Tool registration -- Capability checks - -### Audit Trail - -View the plugin audit trail: - -```bash -jcode plugin audit -jcode plugin audit --recent 50 --json +```rust +#[test] +fn test_kill_switch() { + std::env::set_var("JCODE_PLUGIN_KILL_HELLO", "1"); + // Plugin should not be loaded by the runtime + std::env::remove_var("JCODE_PLUGIN_KILL_HELLO"); +} ``` -The audit trail is a ring buffer (default capacity configurable) that logs every capability access with plugin ID, resource, action, and decision. - -### Preflight Analysis - -Static analysis checks run before any plugin code executes: - -| Pattern | Severity | Effect | -|---------|----------|--------| -| `eval()` | Warning | Logged, plugin still loads | -| `new Function()` | Warning | Logged, plugin still loads | -| `require()` | Warning | Not available in sandbox | -| `exec()` / `spawn()` without shell capability | Warning | Declare `shell_commands` capability | -| `rm -rf`, `sudo`, `chmod 777` | **Block** | Plugin loading is prevented | - ---- - -## Security Checklist - -Before distributing a plugin, verify each item: - -1. **Unique package_name**: The `package_name` must be unique across all plugins. This is enforced at load time and prevents identity spoofing. - -2. **Minimum capabilities**: Declare only the capabilities the plugin needs. Prefer specific paths over broad patterns (e.g., `$HOME/.jcode/data/my-plugin` over `$HOME`). - -3. **Explicit ToolTier**: Set a `tier` in the manifest. Defaulting to `Exec` is safe but will trigger approval prompts for tools that could be `Read` or `Write`. - -4. **Audit trail compatibility**: Every capability access is logged. The plugin should not produce excessive log entries that fill the audit ring buffer. - -5. **No shell access without reason**: `shell_commands` capability is powerful. Prefer registering a tool that jcode's built-in `Bash` tool can handle. - -6. **Timeout awareness**: Handler execution is subject to timeouts (default 5000 ms for actionable events, 500 ms for informational events). Long-running operations should complete within these limits. - -7. **UUID uniqueness**: Use `jcode.uuid()` for identifier generation instead of rolling your own. - -8. **Sleep cap**: `jcode.sleep()` is capped at 5000 ms. Do not rely on longer sleeps for timing logic. +## Distribution -9. **No eval**: The preflight analyzer catches `eval()` usage. Use regular function calls instead. +Plugins can be distributed three ways: -10. **No require / import**: The QuickJS sandbox does not support CommonJS `require()` or dynamic `import()`. All code must be self-contained in the entry file. +1. **Workspace crate** — Add to `Cargo.toml` workspace +2. **Local path** — `jcode plugin load --path /path/to/plugin` +3. **Git URL** — `jcode plugin clone ` -11. **Cross-plugin isolation**: Each plugin runs in its own QuickJS context. Plugins cannot access each other's globals or `jcode.kv` namespaces. +### Best Practices -12. **Test the full pipeline**: Run `jcode plugin load ./my-plugin` and verify the plugin loads without warnings. Check `jcode plugin audit` after exercising the plugin's functionality. +- Prefix crate names with `jcode-plugin-` for discoverability +- Use semver +- Keep plugins focused on one concern +- Use the kill-switch naming convention: `JCODE_PLUGIN_KILL_` (uppercase, underscores) diff --git a/docs/pr-plans/B8-plugin-author-guide.md b/docs/pr-plans/B8-plugin-author-guide.md new file mode 100644 index 000000000..421383001 --- /dev/null +++ b/docs/pr-plans/B8-plugin-author-guide.md @@ -0,0 +1,28 @@ +# PR Plan: B8 — Plugin Author Guide + +## Research Summary +- **Source repo**: oh-my-pi (`docs/plugin-author-guide.md`, `crates/pi-plugin/README.md`) +- **Key files inspected**: + - `crates/pi-plugin/src/lib.rs` — Plugin trait, lifecycle hooks, manifest format + - `crates/pi-plugin-runtime/src/loader.rs` — Loading, sandboxing, resource limits + - `docs/plugin-author-guide.md` — Step-by-step guide with examples + +## Why This Feature Is Missing in jcode +jcode has `jcode-plugin-core` and `jcode-plugin-runtime` with a working plugin system, but there's no dedicated plugin author guide documentation. Developers must read the source code to understand how to create and register plugins. + +## Implementation Plan +Write `docs/plugins.md` covering: +1. Plugin architecture overview (Plugin trait, lifecycle hooks) +2. Quick start: Hello World plugin +3. Plugin manifest format (Cargo.toml metadata) +4. Available hooks and their signatures +5. Configuration serialization +6. Testing: unit tests, integration tests, kill-switch test +7. Distribution: publishing, workspace plugins + +## Risk Analysis +- **Docs only** — zero code risk, zero compile risk + +## Success Criteria +- [ ] docs/plugins.md written with accurate API references +- [ ] Links verified against actual source files