pcode 0.1.0__tar.gz
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.
- pcode-0.1.0/.gitignore +12 -0
- pcode-0.1.0/LICENSE +21 -0
- pcode-0.1.0/PKG-INFO +145 -0
- pcode-0.1.0/README.md +108 -0
- pcode-0.1.0/pyproject.toml +99 -0
- pcode-0.1.0/src/pcode/__init__.py +7 -0
- pcode-0.1.0/src/pcode/_job_supervisor.py +65 -0
- pcode-0.1.0/src/pcode/agent.py +592 -0
- pcode-0.1.0/src/pcode/anthropic_oauth.py +469 -0
- pcode-0.1.0/src/pcode/app.py +3165 -0
- pcode-0.1.0/src/pcode/appearance.py +181 -0
- pcode-0.1.0/src/pcode/aside.py +541 -0
- pcode-0.1.0/src/pcode/aside_guard.py +39 -0
- pcode-0.1.0/src/pcode/aside_ui.py +683 -0
- pcode-0.1.0/src/pcode/auth.py +113 -0
- pcode-0.1.0/src/pcode/block.py +39 -0
- pcode-0.1.0/src/pcode/browser.py +393 -0
- pcode-0.1.0/src/pcode/cache_diagnostics.py +336 -0
- pcode-0.1.0/src/pcode/cache_settings.py +58 -0
- pcode-0.1.0/src/pcode/cache_warnings.py +139 -0
- pcode-0.1.0/src/pcode/claude_sdk/__init__.py +96 -0
- pcode-0.1.0/src/pcode/claude_sdk/cli.py +52 -0
- pcode-0.1.0/src/pcode/claude_sdk/errors.py +61 -0
- pcode-0.1.0/src/pcode/claude_sdk/messages.py +154 -0
- pcode-0.1.0/src/pcode/claude_sdk/model.py +179 -0
- pcode-0.1.0/src/pcode/claude_sdk/resume.py +114 -0
- pcode-0.1.0/src/pcode/claude_sdk/session.py +547 -0
- pcode-0.1.0/src/pcode/claude_sdk/session_pool.py +251 -0
- pcode-0.1.0/src/pcode/claude_sdk/workspace.py +34 -0
- pcode-0.1.0/src/pcode/cli.py +73 -0
- pcode-0.1.0/src/pcode/clipboard.py +76 -0
- pcode-0.1.0/src/pcode/code_mode.py +43 -0
- pcode-0.1.0/src/pcode/codex_login.py +189 -0
- pcode-0.1.0/src/pcode/command_transcript.py +71 -0
- pcode-0.1.0/src/pcode/commands.py +145 -0
- pcode-0.1.0/src/pcode/compaction.py +457 -0
- pcode-0.1.0/src/pcode/completion.py +263 -0
- pcode-0.1.0/src/pcode/config.py +223 -0
- pcode-0.1.0/src/pcode/context_breakdown.py +178 -0
- pcode-0.1.0/src/pcode/context_usage.py +52 -0
- pcode-0.1.0/src/pcode/controller.py +3496 -0
- pcode-0.1.0/src/pcode/conversation_ids.py +27 -0
- pcode-0.1.0/src/pcode/conversation_tree.py +160 -0
- pcode-0.1.0/src/pcode/copy_ui.py +172 -0
- pcode-0.1.0/src/pcode/delegation.py +236 -0
- pcode-0.1.0/src/pcode/delta.py +295 -0
- pcode-0.1.0/src/pcode/diagnostics.py +226 -0
- pcode-0.1.0/src/pcode/edit_preview.py +158 -0
- pcode-0.1.0/src/pcode/edit_transcript.py +287 -0
- pcode-0.1.0/src/pcode/edit_ui.py +850 -0
- pcode-0.1.0/src/pcode/edits.py +162 -0
- pcode-0.1.0/src/pcode/email_remote/__init__.py +14 -0
- pcode-0.1.0/src/pcode/email_remote/cli.py +133 -0
- pcode-0.1.0/src/pcode/email_remote/listener.py +695 -0
- pcode-0.1.0/src/pcode/email_remote/mailbox.py +336 -0
- pcode-0.1.0/src/pcode/email_remote/outbound.py +75 -0
- pcode-0.1.0/src/pcode/email_remote/parsing.py +226 -0
- pcode-0.1.0/src/pcode/email_remote/render.py +175 -0
- pcode-0.1.0/src/pcode/email_remote/state.py +79 -0
- pcode-0.1.0/src/pcode/error_report.py +38 -0
- pcode-0.1.0/src/pcode/ext.py +602 -0
- pcode-0.1.0/src/pcode/extension_guide.md +311 -0
- pcode-0.1.0/src/pcode/extensions/browser.py +284 -0
- pcode-0.1.0/src/pcode/extensions/ponytail.py +217 -0
- pcode-0.1.0/src/pcode/extensions/sandbox.py +138 -0
- pcode-0.1.0/src/pcode/extensions/session_history.py +170 -0
- pcode-0.1.0/src/pcode/extensions/web_research.py +89 -0
- pcode-0.1.0/src/pcode/file_refs.py +265 -0
- pcode-0.1.0/src/pcode/filesystem.py +138 -0
- pcode-0.1.0/src/pcode/frame.py +149 -0
- pcode-0.1.0/src/pcode/gateway.py +465 -0
- pcode-0.1.0/src/pcode/git_diff.py +497 -0
- pcode-0.1.0/src/pcode/history.py +589 -0
- pcode-0.1.0/src/pcode/history_cursor.py +147 -0
- pcode-0.1.0/src/pcode/history_embeddings.py +102 -0
- pcode-0.1.0/src/pcode/host.py +941 -0
- pcode-0.1.0/src/pcode/host_protocol.py +291 -0
- pcode-0.1.0/src/pcode/host_ui.py +225 -0
- pcode-0.1.0/src/pcode/input_keys.py +35 -0
- pcode-0.1.0/src/pcode/inspection.py +289 -0
- pcode-0.1.0/src/pcode/inspector_ui.py +448 -0
- pcode-0.1.0/src/pcode/isolated_delegation.py +425 -0
- pcode-0.1.0/src/pcode/job_notices.py +54 -0
- pcode-0.1.0/src/pcode/jobs.py +584 -0
- pcode-0.1.0/src/pcode/jobs_ui.py +265 -0
- pcode-0.1.0/src/pcode/keymap.py +215 -0
- pcode-0.1.0/src/pcode/layout_speed.py +103 -0
- pcode-0.1.0/src/pcode/links.py +90 -0
- pcode-0.1.0/src/pcode/links_ui.py +200 -0
- pcode-0.1.0/src/pcode/live.py +1301 -0
- pcode-0.1.0/src/pcode/llm_proxy.py +44 -0
- pcode-0.1.0/src/pcode/logins.py +233 -0
- pcode-0.1.0/src/pcode/mcp.py +683 -0
- pcode-0.1.0/src/pcode/mcp_notice.py +91 -0
- pcode-0.1.0/src/pcode/mcp_oauth.py +381 -0
- pcode-0.1.0/src/pcode/meridian.py +233 -0
- pcode-0.1.0/src/pcode/meridian_process.py +337 -0
- pcode-0.1.0/src/pcode/meridian_reminders.py +107 -0
- pcode-0.1.0/src/pcode/meridian_setup.py +356 -0
- pcode-0.1.0/src/pcode/model_metadata.py +451 -0
- pcode-0.1.0/src/pcode/model_ui.py +168 -0
- pcode-0.1.0/src/pcode/models.py +209 -0
- pcode-0.1.0/src/pcode/native_results.py +119 -0
- pcode-0.1.0/src/pcode/oauth_pages.py +66 -0
- pcode-0.1.0/src/pcode/output_limits.py +41 -0
- pcode-0.1.0/src/pcode/paste.py +45 -0
- pcode-0.1.0/src/pcode/path_completion.py +66 -0
- pcode-0.1.0/src/pcode/plan_preview.py +131 -0
- pcode-0.1.0/src/pcode/plan_sizes.py +35 -0
- pcode-0.1.0/src/pcode/planning.py +161 -0
- pcode-0.1.0/src/pcode/popup_ui.py +873 -0
- pcode-0.1.0/src/pcode/preferences.py +1176 -0
- pcode-0.1.0/src/pcode/prefix_keys.py +490 -0
- pcode-0.1.0/src/pcode/profile_benchmark.py +332 -0
- pcode-0.1.0/src/pcode/profiling.py +566 -0
- pcode-0.1.0/src/pcode/project_trust.py +94 -0
- pcode-0.1.0/src/pcode/prompt_keys.py +286 -0
- pcode-0.1.0/src/pcode/remote.py +717 -0
- pcode-0.1.0/src/pcode/remote_print.py +125 -0
- pcode-0.1.0/src/pcode/remote_profile.py +237 -0
- pcode-0.1.0/src/pcode/replay_benchmark.py +319 -0
- pcode-0.1.0/src/pcode/repo_context.py +158 -0
- pcode-0.1.0/src/pcode/retries.py +28 -0
- pcode-0.1.0/src/pcode/rpc.py +280 -0
- pcode-0.1.0/src/pcode/runtime.py +244 -0
- pcode-0.1.0/src/pcode/sandbox.py +454 -0
- pcode-0.1.0/src/pcode/session_naming.py +82 -0
- pcode-0.1.0/src/pcode/session_ui.py +550 -0
- pcode-0.1.0/src/pcode/sessions.py +892 -0
- pcode-0.1.0/src/pcode/shell.py +113 -0
- pcode-0.1.0/src/pcode/shell_mode.py +172 -0
- pcode-0.1.0/src/pcode/shell_tools.py +459 -0
- pcode-0.1.0/src/pcode/skills.py +161 -0
- pcode-0.1.0/src/pcode/stall_log.py +187 -0
- pcode-0.1.0/src/pcode/startup_input.py +96 -0
- pcode-0.1.0/src/pcode/steering.py +27 -0
- pcode-0.1.0/src/pcode/stream_display.py +188 -0
- pcode-0.1.0/src/pcode/stream_events.py +437 -0
- pcode-0.1.0/src/pcode/strict_tools.py +130 -0
- pcode-0.1.0/src/pcode/syntax.py +43 -0
- pcode-0.1.0/src/pcode/syntax_colors.py +206 -0
- pcode-0.1.0/src/pcode/task_prompt.py +28 -0
- pcode-0.1.0/src/pcode/task_worktrees.py +482 -0
- pcode-0.1.0/src/pcode/terminal_notify.py +383 -0
- pcode-0.1.0/src/pcode/theme.py +135 -0
- pcode-0.1.0/src/pcode/theme_gallery.py +88 -0
- pcode-0.1.0/src/pcode/thinking_markdown.py +41 -0
- pcode-0.1.0/src/pcode/token_accounting.py +67 -0
- pcode-0.1.0/src/pcode/tool_display.py +784 -0
- pcode-0.1.0/src/pcode/tool_output_limits.py +108 -0
- pcode-0.1.0/src/pcode/tool_panel.py +377 -0
- pcode-0.1.0/src/pcode/transcript_log.py +127 -0
- pcode-0.1.0/src/pcode/transcript_notice.py +103 -0
- pcode-0.1.0/src/pcode/tree_ui.py +288 -0
- pcode-0.1.0/src/pcode/turn.py +44 -0
- pcode-0.1.0/src/pcode/ui.py +3745 -0
- pcode-0.1.0/src/pcode/usage.py +293 -0
- pcode-0.1.0/src/pcode/word_wrap.py +107 -0
- pcode-0.1.0/src/pcode/worker_ui.py +235 -0
- pcode-0.1.0/src/pcode/workers.py +136 -0
- pcode-0.1.0/src/pcode/workspace.py +57 -0
- pcode-0.1.0/src/pcode/workspace_filesystem.py +72 -0
- pcode-0.1.0/src/pcode/worktree.py +650 -0
pcode-0.1.0/.gitignore
ADDED
pcode-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aaron Weisberg
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pcode-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pcode
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Terminal-native AI coding agent with background jobs, parallel worktrees, forkable sessions, and multi-model support
|
|
5
|
+
Project-URL: Homepage, https://github.com/cruxwell/pcode
|
|
6
|
+
Project-URL: Documentation, https://cruxwell.github.io/pcode/
|
|
7
|
+
Project-URL: Source, https://github.com/cruxwell/pcode
|
|
8
|
+
Project-URL: Issues, https://github.com/cruxwell/pcode/issues
|
|
9
|
+
Author: Aaron Weisberg
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: cli,coding-agent,llm,pydantic-ai,terminal
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Software Development
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: filelock<4,>=3.16
|
|
25
|
+
Requires-Dist: genai-prices<0.2,>=0.1.7
|
|
26
|
+
Requires-Dist: httpx2<3,>=2.13
|
|
27
|
+
Requires-Dist: prompt-toolkit==3.0.53
|
|
28
|
+
Requires-Dist: psutil<8,>=6
|
|
29
|
+
Requires-Dist: pydantic-ai-harness[codemode,coder,exa,playwright]<0.53,>=0.52.0
|
|
30
|
+
Requires-Dist: pydantic-ai-slim[anthropic,bedrock,duckduckgo,google,groq,mcp,openai,web-fetch,xai]<3,>=2.52.0
|
|
31
|
+
Requires-Dist: rich<15,>=14
|
|
32
|
+
Requires-Dist: websockets<17,>=15.0.1
|
|
33
|
+
Requires-Dist: yappi<2,>=1.7.6
|
|
34
|
+
Provides-Extra: claude
|
|
35
|
+
Requires-Dist: claude-agent-sdk<0.3,>=0.2.160; extra == 'claude'
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
<img width="1512" height="947" alt="Screenshot 2026-10-06 at 7 23 29 PM" src="https://github.com/user-attachments/assets/a648fede-d703-44ef-8b52-895d3a0cd2af" />
|
|
39
|
+
<img width="1360" alt="pcode fixing a bug: a word-level diff of the edit, then a worker sub-agent reviewing it with its own plan nested under the task list" src="https://raw.githubusercontent.com/cruxwell/pcode/master/docs/assets/screenshots/readme.png" />
|
|
40
|
+
|
|
41
|
+
# pcode
|
|
42
|
+
|
|
43
|
+
pcode is a terminal-native coding agent built for long-running and parallel
|
|
44
|
+
work. Background commands wake the agent when they finish, every session can
|
|
45
|
+
use its own git worktree, conversations can be rewound and forked, and every
|
|
46
|
+
tool call stays inspectable.
|
|
47
|
+
|
|
48
|
+
- **Slow work doesn't block you.** Long commands become background jobs, and a
|
|
49
|
+
finished job wakes the agent, so it can watch tests or CI and fix what fails.
|
|
50
|
+
- **Agents in parallel.** A git worktree per session lets several agents work
|
|
51
|
+
on one repo at once.
|
|
52
|
+
- **Rewind and fork.** `/tree` returns to any point in a conversation and
|
|
53
|
+
branches from there. Every session is kept, so you can resume or search it.
|
|
54
|
+
- **Nothing hidden.** `/tools` shows every command the agent ran and its full
|
|
55
|
+
output, and scrollback re-renders to show or fold every command and diff.
|
|
56
|
+
|
|
57
|
+
It runs on any model [Pydantic AI](https://ai.pydantic.dev/) supports, or on
|
|
58
|
+
your Claude or ChatGPT subscription.
|
|
59
|
+
|
|
60
|
+
**Documentation: [cruxwell.github.io/pcode](https://cruxwell.github.io/pcode/)**
|
|
61
|
+
|
|
62
|
+
## Install
|
|
63
|
+
|
|
64
|
+
With [Homebrew](https://brew.sh/):
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
brew tap cruxwell/pcode https://github.com/cruxwell/pcode.git
|
|
68
|
+
brew install --HEAD cruxwell/pcode/pcode
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Quick start
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
codex login # or /login [claude|openai-codex] inside pcode, or export a provider API key
|
|
75
|
+
pcode -m openai-codex:gpt-5.6-luna # interactive; /model (Ctrl+L) saves a default
|
|
76
|
+
pcode # reuses the saved model, or opens the offline preview
|
|
77
|
+
pcode -C /path/to/repo "Summarize the open TODOs"
|
|
78
|
+
git diff | pcode -p --no-save # non-interactive: reply to stdout
|
|
79
|
+
pcode --continue # resume this directory's newest session
|
|
80
|
+
pcode --theme-preview # offline sample output and the style gallery
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Live mode edits files and runs shell commands with your permissions and no
|
|
84
|
+
approval prompt.** Read [tool permissions](https://cruxwell.github.io/pcode/tools/#tool-permissions)
|
|
85
|
+
before pointing it at anything you care about.
|
|
86
|
+
|
|
87
|
+
## More
|
|
88
|
+
|
|
89
|
+
- **Your subscription:** Claude runs through Anthropic's own Agent SDK and
|
|
90
|
+
Claude Code login, the way Anthropic supports, and ChatGPT through a Codex
|
|
91
|
+
login. See [providers](https://cruxwell.github.io/pcode/providers/).
|
|
92
|
+
- [Email remote control](https://cruxwell.github.io/pcode/email/): send a task
|
|
93
|
+
from Gmail on your phone, reply to keep going, and take the session over at a
|
|
94
|
+
terminal with `pcode --attach`.
|
|
95
|
+
- [Custom keybindings and Vim editing](https://cruxwell.github.io/pcode/keybindings/):
|
|
96
|
+
map keys to commands with arguments, add a Space leader in normal mode, or use
|
|
97
|
+
`jj` to leave insert mode.
|
|
98
|
+
- `/btw` side questions, background sessions, recall of past sessions, a
|
|
99
|
+
browser the agent can drive, and Python extensions.
|
|
100
|
+
- Pydantic AI's Harness coder capabilities, with the rest of a finished agent
|
|
101
|
+
on top: MCP with OAuth and tool search, searchable sessions, jobs,
|
|
102
|
+
worktrees. Extensions are plain Pydantic AI capabilities. The conversation
|
|
103
|
+
tree follows [pi](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/tree.md)'s.
|
|
104
|
+
|
|
105
|
+
See [PLAN.md](https://github.com/cruxwell/pcode/blob/master/PLAN.md) for the longer-term direction.
|
|
106
|
+
|
|
107
|
+
## Documentation
|
|
108
|
+
|
|
109
|
+
| Page | What it covers |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| [Getting started](https://cruxwell.github.io/pcode/getting-started/) | Homebrew and source installs, `-C`, `--print`, shell completion |
|
|
112
|
+
| [Scrollback and transparency](https://cruxwell.github.io/pcode/guide/scrollback/) | Guide: what goes into scrollback, `/tools`, `/diffs` |
|
|
113
|
+
| [A shell for long-running work](https://cruxwell.github.io/pcode/guide/shell/) | Guide: background jobs, watching CI |
|
|
114
|
+
| [Parallel agents](https://cruxwell.github.io/pcode/guide/parallel/) | Guide: worktrees, parallel sub-agents, `/agents` |
|
|
115
|
+
| [Extending pcode](https://cruxwell.github.io/pcode/guide/extending/) | Guide: extensions, skills, settings |
|
|
116
|
+
| [Providers and models](https://cruxwell.github.io/pcode/providers/) | Authentication, supported providers, the model picker, reasoning effort, Claude Code, Meridian, proxies |
|
|
117
|
+
| [Configuration](https://cruxwell.github.io/pcode/configuration/) | `pcode config`, per-repository overrides, trusting repository code, the settings table, syntax styles |
|
|
118
|
+
| [Commands and keys](https://cruxwell.github.io/pcode/commands/) | Slash commands, key bindings, vi mode, tmux newlines, status line, `!command`, the diff and tool inspectors |
|
|
119
|
+
| [Keybindings](https://cruxwell.github.io/pcode/keybindings/) | Custom command mappings with `/bind`, Ctrl shortcuts, vi editing, a normal-mode leader, and custom escape sequences such as `jj` |
|
|
120
|
+
| [Tools](https://cruxwell.github.io/pcode/tools/) | Tool permissions, web search, the browser, code mode |
|
|
121
|
+
| [MCP servers](https://cruxwell.github.io/pcode/mcp/) | Opt-in MCP configuration, OAuth sign-in, deferred tool search |
|
|
122
|
+
| [Working in a repository](https://cruxwell.github.io/pcode/workspace/) | `AGENTS.md`/`CLAUDE.md`, skills as slash commands, one worktree per session |
|
|
123
|
+
| [Sessions and recovery](https://cruxwell.github.io/pcode/sessions/) | Saving, resuming, recalling earlier sessions, checkpoints, retries |
|
|
124
|
+
| [Context, limits and caching](https://cruxwell.github.io/pcode/context/) | Prompt overhead, compaction, output limits, prompt cache notices |
|
|
125
|
+
| [The transcript](https://cruxwell.github.io/pcode/transcript/) | What lands in scrollback: diffs, thinking, errors, command output, `/redraw` |
|
|
126
|
+
| [Conversation tree](https://cruxwell.github.io/pcode/conversation-tree/) | `/tree`: rewinding and forking a conversation |
|
|
127
|
+
| [Side questions](https://cruxwell.github.io/pcode/side-questions/) | `/btw`: asking about the running turn without interrupting it |
|
|
128
|
+
|
|
129
|
+
The same pages build into a browsable site with `make docs-serve`; `make docs`
|
|
130
|
+
checks every page and anchor link.
|
|
131
|
+
|
|
132
|
+
## Contributing
|
|
133
|
+
|
|
134
|
+
Bugs: [open an issue](https://github.com/cruxwell/pcode/issues/new/choose).
|
|
135
|
+
Security problems: see [SECURITY.md](https://github.com/cruxwell/pcode/blob/master/SECURITY.md). Setup and checks are in
|
|
136
|
+
[CONTRIBUTING.md](https://github.com/cruxwell/pcode/blob/master/CONTRIBUTING.md).
|
|
137
|
+
|
|
138
|
+
```sh
|
|
139
|
+
make test # fast suite; real-tmux regressions skipped
|
|
140
|
+
make test-all # everything, before touching layout, streaming, the editor, or the prompt
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
[AGENTS.md](https://github.com/cruxwell/pcode/blob/master/AGENTS.md) has the worktree workflow and the traps worth knowing
|
|
144
|
+
before editing. Contributor notes (architecture, dependencies, profiling, prompt
|
|
145
|
+
caching, provider design) live in [`dev/`](https://github.com/cruxwell/pcode/tree/master/dev), outside the published docs.
|
pcode-0.1.0/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<img width="1512" height="947" alt="Screenshot 2026-10-06 at 7 23 29 PM" src="https://github.com/user-attachments/assets/a648fede-d703-44ef-8b52-895d3a0cd2af" />
|
|
2
|
+
<img width="1360" alt="pcode fixing a bug: a word-level diff of the edit, then a worker sub-agent reviewing it with its own plan nested under the task list" src="https://raw.githubusercontent.com/cruxwell/pcode/master/docs/assets/screenshots/readme.png" />
|
|
3
|
+
|
|
4
|
+
# pcode
|
|
5
|
+
|
|
6
|
+
pcode is a terminal-native coding agent built for long-running and parallel
|
|
7
|
+
work. Background commands wake the agent when they finish, every session can
|
|
8
|
+
use its own git worktree, conversations can be rewound and forked, and every
|
|
9
|
+
tool call stays inspectable.
|
|
10
|
+
|
|
11
|
+
- **Slow work doesn't block you.** Long commands become background jobs, and a
|
|
12
|
+
finished job wakes the agent, so it can watch tests or CI and fix what fails.
|
|
13
|
+
- **Agents in parallel.** A git worktree per session lets several agents work
|
|
14
|
+
on one repo at once.
|
|
15
|
+
- **Rewind and fork.** `/tree` returns to any point in a conversation and
|
|
16
|
+
branches from there. Every session is kept, so you can resume or search it.
|
|
17
|
+
- **Nothing hidden.** `/tools` shows every command the agent ran and its full
|
|
18
|
+
output, and scrollback re-renders to show or fold every command and diff.
|
|
19
|
+
|
|
20
|
+
It runs on any model [Pydantic AI](https://ai.pydantic.dev/) supports, or on
|
|
21
|
+
your Claude or ChatGPT subscription.
|
|
22
|
+
|
|
23
|
+
**Documentation: [cruxwell.github.io/pcode](https://cruxwell.github.io/pcode/)**
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
With [Homebrew](https://brew.sh/):
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
brew tap cruxwell/pcode https://github.com/cruxwell/pcode.git
|
|
31
|
+
brew install --HEAD cruxwell/pcode/pcode
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick start
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
codex login # or /login [claude|openai-codex] inside pcode, or export a provider API key
|
|
38
|
+
pcode -m openai-codex:gpt-5.6-luna # interactive; /model (Ctrl+L) saves a default
|
|
39
|
+
pcode # reuses the saved model, or opens the offline preview
|
|
40
|
+
pcode -C /path/to/repo "Summarize the open TODOs"
|
|
41
|
+
git diff | pcode -p --no-save # non-interactive: reply to stdout
|
|
42
|
+
pcode --continue # resume this directory's newest session
|
|
43
|
+
pcode --theme-preview # offline sample output and the style gallery
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Live mode edits files and runs shell commands with your permissions and no
|
|
47
|
+
approval prompt.** Read [tool permissions](https://cruxwell.github.io/pcode/tools/#tool-permissions)
|
|
48
|
+
before pointing it at anything you care about.
|
|
49
|
+
|
|
50
|
+
## More
|
|
51
|
+
|
|
52
|
+
- **Your subscription:** Claude runs through Anthropic's own Agent SDK and
|
|
53
|
+
Claude Code login, the way Anthropic supports, and ChatGPT through a Codex
|
|
54
|
+
login. See [providers](https://cruxwell.github.io/pcode/providers/).
|
|
55
|
+
- [Email remote control](https://cruxwell.github.io/pcode/email/): send a task
|
|
56
|
+
from Gmail on your phone, reply to keep going, and take the session over at a
|
|
57
|
+
terminal with `pcode --attach`.
|
|
58
|
+
- [Custom keybindings and Vim editing](https://cruxwell.github.io/pcode/keybindings/):
|
|
59
|
+
map keys to commands with arguments, add a Space leader in normal mode, or use
|
|
60
|
+
`jj` to leave insert mode.
|
|
61
|
+
- `/btw` side questions, background sessions, recall of past sessions, a
|
|
62
|
+
browser the agent can drive, and Python extensions.
|
|
63
|
+
- Pydantic AI's Harness coder capabilities, with the rest of a finished agent
|
|
64
|
+
on top: MCP with OAuth and tool search, searchable sessions, jobs,
|
|
65
|
+
worktrees. Extensions are plain Pydantic AI capabilities. The conversation
|
|
66
|
+
tree follows [pi](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/tree.md)'s.
|
|
67
|
+
|
|
68
|
+
See [PLAN.md](https://github.com/cruxwell/pcode/blob/master/PLAN.md) for the longer-term direction.
|
|
69
|
+
|
|
70
|
+
## Documentation
|
|
71
|
+
|
|
72
|
+
| Page | What it covers |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| [Getting started](https://cruxwell.github.io/pcode/getting-started/) | Homebrew and source installs, `-C`, `--print`, shell completion |
|
|
75
|
+
| [Scrollback and transparency](https://cruxwell.github.io/pcode/guide/scrollback/) | Guide: what goes into scrollback, `/tools`, `/diffs` |
|
|
76
|
+
| [A shell for long-running work](https://cruxwell.github.io/pcode/guide/shell/) | Guide: background jobs, watching CI |
|
|
77
|
+
| [Parallel agents](https://cruxwell.github.io/pcode/guide/parallel/) | Guide: worktrees, parallel sub-agents, `/agents` |
|
|
78
|
+
| [Extending pcode](https://cruxwell.github.io/pcode/guide/extending/) | Guide: extensions, skills, settings |
|
|
79
|
+
| [Providers and models](https://cruxwell.github.io/pcode/providers/) | Authentication, supported providers, the model picker, reasoning effort, Claude Code, Meridian, proxies |
|
|
80
|
+
| [Configuration](https://cruxwell.github.io/pcode/configuration/) | `pcode config`, per-repository overrides, trusting repository code, the settings table, syntax styles |
|
|
81
|
+
| [Commands and keys](https://cruxwell.github.io/pcode/commands/) | Slash commands, key bindings, vi mode, tmux newlines, status line, `!command`, the diff and tool inspectors |
|
|
82
|
+
| [Keybindings](https://cruxwell.github.io/pcode/keybindings/) | Custom command mappings with `/bind`, Ctrl shortcuts, vi editing, a normal-mode leader, and custom escape sequences such as `jj` |
|
|
83
|
+
| [Tools](https://cruxwell.github.io/pcode/tools/) | Tool permissions, web search, the browser, code mode |
|
|
84
|
+
| [MCP servers](https://cruxwell.github.io/pcode/mcp/) | Opt-in MCP configuration, OAuth sign-in, deferred tool search |
|
|
85
|
+
| [Working in a repository](https://cruxwell.github.io/pcode/workspace/) | `AGENTS.md`/`CLAUDE.md`, skills as slash commands, one worktree per session |
|
|
86
|
+
| [Sessions and recovery](https://cruxwell.github.io/pcode/sessions/) | Saving, resuming, recalling earlier sessions, checkpoints, retries |
|
|
87
|
+
| [Context, limits and caching](https://cruxwell.github.io/pcode/context/) | Prompt overhead, compaction, output limits, prompt cache notices |
|
|
88
|
+
| [The transcript](https://cruxwell.github.io/pcode/transcript/) | What lands in scrollback: diffs, thinking, errors, command output, `/redraw` |
|
|
89
|
+
| [Conversation tree](https://cruxwell.github.io/pcode/conversation-tree/) | `/tree`: rewinding and forking a conversation |
|
|
90
|
+
| [Side questions](https://cruxwell.github.io/pcode/side-questions/) | `/btw`: asking about the running turn without interrupting it |
|
|
91
|
+
|
|
92
|
+
The same pages build into a browsable site with `make docs-serve`; `make docs`
|
|
93
|
+
checks every page and anchor link.
|
|
94
|
+
|
|
95
|
+
## Contributing
|
|
96
|
+
|
|
97
|
+
Bugs: [open an issue](https://github.com/cruxwell/pcode/issues/new/choose).
|
|
98
|
+
Security problems: see [SECURITY.md](https://github.com/cruxwell/pcode/blob/master/SECURITY.md). Setup and checks are in
|
|
99
|
+
[CONTRIBUTING.md](https://github.com/cruxwell/pcode/blob/master/CONTRIBUTING.md).
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
make test # fast suite; real-tmux regressions skipped
|
|
103
|
+
make test-all # everything, before touching layout, streaming, the editor, or the prompt
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
[AGENTS.md](https://github.com/cruxwell/pcode/blob/master/AGENTS.md) has the worktree workflow and the traps worth knowing
|
|
107
|
+
before editing. Contributor notes (architecture, dependencies, profiling, prompt
|
|
108
|
+
caching, provider design) live in [`dev/`](https://github.com/cruxwell/pcode/tree/master/dev), outside the published docs.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pcode"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Terminal-native AI coding agent with background jobs, parallel worktrees, forkable sessions, and multi-model support"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "Aaron Weisberg" }]
|
|
9
|
+
keywords = ["pydantic-ai", "coding-agent", "terminal", "llm", "cli"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"Environment :: Console",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Operating System :: MacOS",
|
|
15
|
+
"Operating System :: POSIX :: Linux",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Topic :: Software Development",
|
|
21
|
+
]
|
|
22
|
+
requires-python = ">=3.11"
|
|
23
|
+
dependencies = [
|
|
24
|
+
"filelock>=3.16,<4",
|
|
25
|
+
"genai-prices>=0.1.7,<0.2",
|
|
26
|
+
"httpx2>=2.13,<3",
|
|
27
|
+
# Exact: pcode relies on prompt_toolkit internals, and point releases
|
|
28
|
+
# change them. Bump on purpose after tests/test_prompt_toolkit_internals.py
|
|
29
|
+
# and make test-all pass on the new version.
|
|
30
|
+
"prompt-toolkit==3.0.53",
|
|
31
|
+
"psutil>=6,<8",
|
|
32
|
+
"yappi>=1.7.6,<2",
|
|
33
|
+
# playwright backs the bundled browser extension (/browser on); Chromium
|
|
34
|
+
# itself is downloaded on first use, not at install.
|
|
35
|
+
# Harness ships from the pydantic-ai repo with every Pydantic AI release and
|
|
36
|
+
# pins pydantic-ai-slim to the same minor; bump both together.
|
|
37
|
+
"pydantic-ai-harness[exa,coder,codemode,playwright]>=0.52.0,<0.53",
|
|
38
|
+
# duckduckgo and web-fetch back the bundled web_research extension when no
|
|
39
|
+
# provider-native search or Exa key is available.
|
|
40
|
+
# google covers both google and google-cloud providers; bedrock pulls boto3.
|
|
41
|
+
"pydantic-ai-slim[anthropic,bedrock,duckduckgo,google,groq,mcp,openai,web-fetch,xai]>=2.52.0,<3",
|
|
42
|
+
"rich>=14,<15",
|
|
43
|
+
# FastMCP 4.x OAuth callback server selects Uvicorn's websockets-sansio protocol.
|
|
44
|
+
"websockets>=15.0.1,<17",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[project.optional-dependencies]
|
|
48
|
+
# claude: models. Optional because each wheel bundles the Claude Code CLI
|
|
49
|
+
# (about 95 MB to download, 215 MB installed); the sdist would run whatever
|
|
50
|
+
# `claude` is on PATH instead of the CLI version pcode was verified against.
|
|
51
|
+
claude = [
|
|
52
|
+
"claude-agent-sdk>=0.2.160,<0.3",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[project.urls]
|
|
56
|
+
Homepage = "https://github.com/cruxwell/pcode"
|
|
57
|
+
Documentation = "https://cruxwell.github.io/pcode/"
|
|
58
|
+
Source = "https://github.com/cruxwell/pcode"
|
|
59
|
+
Issues = "https://github.com/cruxwell/pcode/issues"
|
|
60
|
+
|
|
61
|
+
[project.scripts]
|
|
62
|
+
pcode = "pcode.cli:main"
|
|
63
|
+
pcode-benchmark = "pcode.profile_benchmark:main"
|
|
64
|
+
|
|
65
|
+
[build-system]
|
|
66
|
+
# 1.27 is the first to accept an SPDX `license` string with `license-files`.
|
|
67
|
+
requires = ["hatchling>=1.27"]
|
|
68
|
+
build-backend = "hatchling.build"
|
|
69
|
+
|
|
70
|
+
[tool.hatch.build.targets.sdist]
|
|
71
|
+
# An explicit list: hatch otherwise ships every non-ignored file, including
|
|
72
|
+
# local scratch under tmp/ and agent config. Tests stay out: they read docs/,
|
|
73
|
+
# dev/, scripts/ and .githooks/ and expect a git checkout.
|
|
74
|
+
include = ["/src", "/LICENSE", "/README.md", "/pyproject.toml"]
|
|
75
|
+
|
|
76
|
+
[tool.hatch.metadata]
|
|
77
|
+
allow-direct-references = true
|
|
78
|
+
|
|
79
|
+
[dependency-groups]
|
|
80
|
+
dev = [
|
|
81
|
+
"pcode[claude]",
|
|
82
|
+
"pytest>=8",
|
|
83
|
+
"pexpect>=4.9; sys_platform != 'win32'",
|
|
84
|
+
"ruff>=0.11",
|
|
85
|
+
"pytest-xdist>=3.6",
|
|
86
|
+
]
|
|
87
|
+
docs = [
|
|
88
|
+
"zensical>=0.0.63",
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
[tool.pytest.ini_options]
|
|
92
|
+
testpaths = ["tests"]
|
|
93
|
+
markers = ["tmux: real-tmux layout regression (slow; opt in with --tmux)"]
|
|
94
|
+
|
|
95
|
+
[tool.ruff]
|
|
96
|
+
line-length = 100
|
|
97
|
+
|
|
98
|
+
[tool.ruff.lint]
|
|
99
|
+
select = ["E", "F", "I"]
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""Detached supervisor: owns one command's lifetime and publishes its exit status.
|
|
2
|
+
|
|
3
|
+
Runs in its own interpreter and its own session so the command survives agent
|
|
4
|
+
run teardown, event-loop shutdown, and pcode itself. It writes `status.json`
|
|
5
|
+
atomically, which is the only thing the parent polls: a supervisor killed
|
|
6
|
+
between publications leaves the last consistent snapshot rather than a partial
|
|
7
|
+
file.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import signal
|
|
15
|
+
import subprocess
|
|
16
|
+
import sys
|
|
17
|
+
import time
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def main() -> None: # pragma: no cover -- exercised through a real subprocess.
|
|
22
|
+
directory = Path(sys.argv[1])
|
|
23
|
+
command = sys.argv[2]
|
|
24
|
+
status = directory / "status.json"
|
|
25
|
+
pending = directory / "status.tmp"
|
|
26
|
+
|
|
27
|
+
def publish(*, pid: int, exit_code: int | None, started_at: float) -> None:
|
|
28
|
+
pending.write_text(
|
|
29
|
+
json.dumps(
|
|
30
|
+
{
|
|
31
|
+
"pid": pid,
|
|
32
|
+
"exit_code": exit_code,
|
|
33
|
+
"started_at": started_at,
|
|
34
|
+
"ended_at": None if exit_code is None else time.time(),
|
|
35
|
+
}
|
|
36
|
+
),
|
|
37
|
+
encoding="utf-8",
|
|
38
|
+
)
|
|
39
|
+
pending.replace(status)
|
|
40
|
+
|
|
41
|
+
with (directory / "output.log").open("ab", buffering=0) as output:
|
|
42
|
+
started_at = time.time()
|
|
43
|
+
process = subprocess.Popen(
|
|
44
|
+
command,
|
|
45
|
+
shell=True,
|
|
46
|
+
stdin=subprocess.DEVNULL,
|
|
47
|
+
stdout=output,
|
|
48
|
+
stderr=output,
|
|
49
|
+
)
|
|
50
|
+
publish(pid=process.pid, exit_code=None, started_at=started_at)
|
|
51
|
+
exit_code = process.wait()
|
|
52
|
+
publish(pid=process.pid, exit_code=exit_code, started_at=started_at)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__": # pragma: no cover
|
|
56
|
+
# The parent starts a new session for us. Ignore terminal hangups without
|
|
57
|
+
# changing how the child command itself handles termination. A stop is
|
|
58
|
+
# SIGTERM to the whole group: survive it here so the command's own exit
|
|
59
|
+
# under it still gets published. A Python handler rather than SIG_IGN,
|
|
60
|
+
# because an ignored disposition is inherited across exec and would make
|
|
61
|
+
# the command itself immune to the stop; a handler resets to default.
|
|
62
|
+
if os.name != "nt":
|
|
63
|
+
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
|
64
|
+
signal.signal(signal.SIGTERM, lambda *_: None)
|
|
65
|
+
main()
|