@cydm/pie
@cydm/pie is a minimal, powerful, embeddable agent suite for game developers.
It gives you a terminal-first agent experience out of the box, while staying modular enough to embed into other runtimes and products. Pie is designed for teams that want a small surface area, strong defaults, persistent sessions, tool use, and a clean path from CLI usage to deeper integration.
Pie is developed by cydream.
Why Pie
- Minimal interface, low ceremony
- Powerful coding-agent workflow in the terminal
- Embeddable architecture built on reusable
@pie/*packages - Persistent sessions, slash commands, and skill loading
- Works well as both a daily CLI and a building block for custom agent products
Install
npm install -g @cydm/pie
Pie requires Node.js 20.19 or newer. Release builds are validated with npm's lockfile workflow (npm ci) so dependency resolution is reproducible.
Quick Start
Set an API key for the provider you want to use:
export KIMI_API_KEY="your-kimi-api-key"
# or
export BIGMODEL_API_KEY="your-bigmodel-api-key"
You can also configure defaults in:
~/.pie/settings.json~/.pie/models.json~/.pie/config.jsonfor legacy-compatible defaults
Minimal ~/.pie/models.json:
{
"profiles": {
"cy-gpt": {
"api": "openai-completions",
"baseUrl": "https://token.magicshell.ai/v1",
"apiKey": "YOUR_API_KEY",
"models": [
{
"id": "gpt-5.4",
"name": "GPT 5.4",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 128000,
"maxTokens": 16384,
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
}
}
]
}
},
"defaults": {
"provider": "cy-gpt",
"modelId": "gpt-5.4"
}
}
Required profile fields:
apibaseUrlapiKeyorapiKeyEnvmodels
Required model fields:
idinputcost(input,output,cacheRead,cacheWrite; optionalcacheWriteLong)contextWindowmaxTokens
Validate the file explicitly:
pie models validate
pie models validate --path /abs/path/to/models.json
pie models validate --probe web_search
Generate a starter template:
pie models init
pie models init --stdout
For editor auto-complete and validation, you can also point the optional "$schema" field in your local models.json at your installed @cydm/pie/models.schema.json file.
cost may additionally carry cacheWriteLong — the per-million-token rate for 1h-TTL cache writes on providers that report a TTL breakdown (Anthropic-style routes). It is optional; legacy configs without it keep working. When it is absent, long writes are priced at the Anthropic 2x-input estimate and the calculated cost is marked cacheWriteLongEstimated so it is not presented as a precise provider bill.
Settings
~/.pie/settings.json (or ./.pie/settings.json for project scope) holds CLI defaults. Relevant prompt-cache keys:
{
// Explicit Anthropic prompt-cache TTL: "none" | "short" | "long".
// Absent keeps the provider default (Anthropic: short/5m).
"promptCacheRetention": "short"
}
Priority is per-request option > CLI setting > provider default. The setting is forwarded only on Anthropic prompt-cache routes; it never forces OpenAI-compatible store or another provider's cache mode. Pie does not auto-switch TTL from observed hit rates — choose long explicitly when the 1h write premium is worth it.
Remote model catalogs
Pie can add centrally managed models without replacing local profiles or defaults. Add a catalog to ~/.pie/models.json and keep the virtual key in an environment variable:
{
"remoteCatalogs": [
{
"id": "token-manager",
"url": "https://token.magicshell.ai/v1/client-catalogs/pie.json",
"apiKeyEnv": "TOKEN_MANAGER_API_KEY"
}
]
}
Remote catalogs use a three-second timeout, reject redirects, and fall back to the last valid cached response. A local profile with the same id always wins. Remote catalogs never modify defaults.
Per-model overrides
Use top-level modelOverrides to patch descriptive fields of any loaded model (declared locally or provided by a remote catalog) without redeclaring the whole profile. Keys are "provider/modelId":
{
"modelOverrides": {
"cydream/gpt-5.6-terra": {
"contextWindow": 256000,
"maxTokens": 16384,
"compat": { "streamRequiresDone": false }
}
}
}
Overridable fields: name, displayName, reasoning, input, cost, contextWindow, maxTokens, headers, compat, cacheCapability, webSearch, fileCapabilities. Nested objects deep-merge; arrays replace. Identity and routing fields (id, provider, api, baseUrl, apiKeyEnv, filePlatform, attachmentPlatform) cannot be overridden. Overrides apply after profiles and remote catalogs merge, and re-apply when a catalog refreshes; keys that match no loaded model are ignored.
Start Pie in interactive mode:
pie
Or pass an initial prompt:
pie chat "Summarize this repository"
Use Pie in one-shot mode:
pie "List the files in the current directory"
pie chat "Write a quick Python script for merge sort"
Core Ideas
Pie is not just a chat CLI. It is a compact agent suite with a terminal UI on top of a reusable runtime.
- The CLI is intentionally small and fast to learn
- The agent can work with files, shell commands, sessions, and skills
- The architecture is modular, so the same foundation can be embedded into other apps and environments
If you want an agent that feels lightweight but still has serious capability, that is the design target for Pie.
Architecture Position
@cydm/pie is the CLI product layer in the repo architecture.
@pie/agent-coreprovides runtime semantics and the agent loop@pie/agent-frameworkprovides shared application infrastructure such as sessions, skills, and extension protocols@pie/shared-headless-capabilitiesprovides shared headless capabilities used across hostsproducts/cliadds terminal bindings, CLI workflows, and host-specific capabilities such as shell execution
The CLI should consume shared capability and framework contracts; it should not redefine shared runtime or extension semantics locally.
Interactive Experience
Run:
pie
# or
pie chat
Main key bindings:
Entersubmit messageShift+Enterinsert a new line\+Enterinsert a new line in terminals without modified-enter supportCtrl+Cclear the editor; press twice within 500 ms to exitCtrl+Dexit when the editor is empty; forward-delete otherwiseCtrl+V/Alt+V/Cmd+Vpaste an image from the clipboard when the main chat editor owns focus (terminal clipboard first, OS helper fallback). Plan refinement, extension input/editor/custom UI, visible overlays, and the mention picker retain their own paste keys.Ctrl+Oexpand or collapse tool outputCtrl+Xtoggle YOLO mode (Alt+Ois an optional alias where the terminal delivers Alt)Ctrl+Rset up or toggle IM forwarding (Alt+Iis an optional alias where the terminal delivers Alt)/open the slash command menu
OS clipboard images are staged in per-read private temporary directories (0700 directories and exclusively reserved 0600 files on POSIX), including subprocess output, and removed after staging or on failure. Windows uses the user's temporary directory and inherited OS access controls. Terminal OSC 5522 frames and CSI 5522 support replies are incrementally framed, size-bounded, and never flushed as keyboard input while recognized: the default inter-chunk deadline is 1s, with a 10s absolute frame deadline. Failed frames discard their tails through the terminator or until 1s of idle recovery. An ambiguous lone Escape keeps its normal keyboard timeout unless a clipboard request is active; even then it is eventually delivered as Escape. After idle recovery, arbitrarily late bare payload bytes cannot be distinguished from new typing.
Direct shell mode:
!!git status
!!npm test
Commands prefixed with !! run directly in the shell without going through the agent.
Slash Commands
Pie uses a hierarchical slash-command menu. The current built-in commands include:
| Command | Description |
|---|---|
pie doctor [--json] | Diagnose local config, model setup, writable paths, browser automation, and Unity bridge hints |
pie models init | Create a starter ~/.pie/models.json |
pie models validate | Validate ~/.pie/models.json |
pie permissions | Explain tool and shell safety defaults (--json returns the structured safety model) |
pie capabilities [--json] | Report the command surface, flags, exit codes, and output schema for agents |
pie sessions list/read/rename/rewind/fork | Inspect and manage stored sessions non-interactively (each supports --json and --help) |
pie extensions list/enable/disable | Inspect and toggle extensions non-interactively |
/sessions/compact | Summarize history and create a compact checkpoint |
/sessions/new | Start a new session |
/sessions/resume | Resume a session (defaults to current-directory sessions; press g in the selector to show the full loaded recent list) |
/sessions/tree | Navigate the session tree |
/sessions/info | Show session information |
/sessions/fork | Fork from an earlier message |
/settings | Open the settings menu |
/settings/model | Choose a model |
/settings/theme | Change the theme |
/settings/thinking | Set reasoning depth |
/settings/yolo | Toggle less restricted filesystem mode |
/settings/hotkeys | Show keyboard shortcuts |
/settings/quit | Exit Pie |
/skills/list | List available skills |
/skills/use | Use a skill |
/skills/reload | Reload skills from disk |
/settings/extensions | List extensions and toggle enable/disable |
/tools/subagent | Spawn a subagent for a task |
/tools/init | Create or update the project AGENTS.md |
/settings/debugs/cache-test | Run provider cache diagnostics with a dedicated 2-request probe |
/settings/debugs/context | Append a context summary to ~/.pie/logs/pie-cli.log |
/settings/debugs/package | Append a package summary to ~/.pie/logs/pie-cli.log |
Pie can also load extension-provided commands at runtime.
Sessions
Pie keeps persistent sessions so you can come back to earlier work.
- Sessions are stored in
~/.pie/sessions/ - You can switch sessions from the command menu
- You can fork a session to branch off a previous line of work
- You can compact long sessions to keep context focused
This makes Pie useful for ongoing coding tasks, not just one-off prompts.
Scheduled Session Prompts
The builtin cron extension persists scheduled prompts bound to the original session and working directory:
/tools/cron add {"prompt":"Continue the investigation above.","schedule":{"every":3600}}
/tools/cron list
/tools/cron pause <job-id>
/tools/cron resume <job-id>
/tools/cron remove <job-id>
Keep at least one cron-enabled interactive Pie open in the same config space. The original session need not stay open: an unhosted session is resumed by a temporary worker, while a hosted session receives an ordinary follow-up. No task means no footer or startup notification; unrelated/follower windows remain quiet. Five-field cron schedules use UTC. Model-requested changes require explicit confirmation.
Coordination is cooperative, not a session-store lock: do not open a worker's session in a nonparticipating CLI. Crashes can require offline lock/outcome review instead of automatic replay. See cron design, recovery and dogfood.
Skills And Extensibility
Pie supports Markdown-based skills and built-in extensions.
- Built-in skills ship with the CLI
- User skills can live under
~/.agents/skills(cross-tool standard) or~/.pie/skills - Project-local skills can live under
.agents/skills(discovered from the project root down to the cwd, mirroring AGENTS.md discovery) or.pie/skills - Override order on name collision (later wins): built-in <
~/.agents<~/.pie< ancestor.agents(far to near) <./.pie - Extensions can register additional commands and workflows
That is part of what makes Pie embeddable: the CLI is only one interface on top of a broader agent toolkit.
Extension Sources, Priority, And Toggles
Extensions are discovered from four sources in ascending priority (later sources shadow earlier ones by stable extension identity):
builtin— shipped with the CLI (ask-user,todo,plan-mode,subagent,init,changelog, attachment handlers)global—~/.pie/extensions/project—./.pie/extensions/configured— repeated--extension-path <dir>flags
Every extension is enabled by default. Toggles are sparse overrides stored in settings and applied by extension identity across all sources:
- Interactive: choose Extensions in
/settings, or use/settings/extensions, to open the user-default toggle menu./settings/extensions --projectedits project overrides;/settings/extensions/list|enable|disable ...remains available for command-driven use. - Scripts and third-party UIs:
pie extensions list [--json],pie extensions enable|disable <name> [--project|--user] - Process flags:
--no-builtin-extensions(skip built-ins) and--no-extensions(skip all discovered sources;--extension-pathstill loads)
Example override in ~/.pie/settings.json (or ./.pie/settings.json for project scope, which wins per identity):
{
"extensions": {
"plan-mode": { "enabled": false }
}
}
The full contract (identity rules, schema, host integration) lives in docs/extensions-enablement.md.
Browser Tools
The built-in chrome-devtools-axi skill uses the chrome-devtools-axi CLI to drive a real Chrome browser over the Chrome DevTools Protocol. Its runtime dependencies ship with the CLI; do not run npm install inside the skill directory.
Resolve the skill resource and run browser commands:
node <resolvedPath for chrome-devtools-axi/chrome-devtools-axi-cli.js> open https://example.com
node <resolvedPath for chrome-devtools-axi/chrome-devtools-axi-cli.js> snapshot
node <resolvedPath for chrome-devtools-axi/chrome-devtools-axi-cli.js> screenshot /tmp/page.png
node <resolvedPath for chrome-devtools-axi/chrome-devtools-axi-cli.js> console
node <resolvedPath for chrome-devtools-axi/chrome-devtools-axi-cli.js> network
The CLI launches or attaches to a real Chrome/Edge browser; see --help for connection modes (headed mode, auto-connect, custom profile, remote browser URL) and CHROME_DEVTOOLS_AXI_SESSION for concurrent isolated sessions.
Run pie doctor to check whether chrome-devtools-axi and a Chrome browser are discoverable.
Terminal UI Automation
The built-in tui-use skill drives interactive terminal programs - REPLs, pdb/gdb debugger sessions, and full-screen TUI apps - through Pie's packaged PTY runtime. Run node <skill-baseDir>/tui-use-cli.js --help; no first-use dependency download or global CLI is required. Windows uses native PowerShell and ConPTY. State lives in ~/.pie/tui-use, or a dedicated PIE_TUI_USE_STATE_DIR. Always target sessions with --session <id>, confirm termination with wait --exit, and clean up only sessions and daemons you own. Use the shell tool for non-interactive commands.
Desktop Control (computer-use)
The built-in computer-use-axi skill controls real desktop applications on macOS, Windows, and Linux through a native accessibility helper. Desktop control is a last resort - prefer API, CLI, or web tools whenever they can accomplish the task. Invoke the skill's CLI through the shell tool (node <skill-baseDir>/computer-use-axi-cli.js <command>); observation commands read UI state, while act synthesizes real input. These are CLI operations, not a separate model-visible extension tool tier, so normal shell confirmation policy applies.
Read builtin/skills/computer-use-axi/SKILL.md for roots, bounded observation, checked actions and browser workflows. On macOS, run the CLI's permissions setup and then permissions recheck after granting Accessibility and Screen Recording; starting Pie interactively is not a substitute for that setup flow.
Platform notes:
- macOS (14+): the signed helper app installs to
~/.pie/computer-use/pie-computer-use.appon first use. Grant Accessibility and Screen Recording topie-computer-use.appin System Settings → Privacy & Security; interactive sessions guide you through the prompts. Re-grant after helper updates (re-signing invalidates old grants). - Windows: the helper installs to
~/.pie/helpers/computer-use/windows-bridge.exeand needs an interactive desktop session. - Linux: the helper installs to
~/.pie/helpers/computer-use/linux-bridgeand needs an AT-SPI2 bus (a running desktop session; headless servers are not supported).
Config: ~/.pie/extensions/computer-use.json (user) or .pie/computer-use.json (project) with browser_use, headless, cursor_overlay, managed_browser; env overrides PIE_COMPUTER_USE_BROWSER_USE / PIE_COMPUTER_USE_HEADLESS / PIE_COMPUTER_USE_CURSOR_OVERLAY / PIE_COMPUTER_USE_MANAGED_BROWSER. Run pie doctor for helper install status.
Web Research
Pie exposes one default model-visible web tool: web_research. Use it for public web research, current information, online documentation, and internet inspiration. Pass query for research, url to fetch a known page/PDF, or query with mode: "search" for low-level search results. Workspace search remains separate: use grep_text, find_files, and list_dir for local repository content.
web_search and web_fetch remain lower-level internal primitives for probes, diagnostics, and tests; they are not separate default model-visible tools. web_search does not scrape DuckDuckGo or fall back to bash with curl or Python HTTP scripts. If the configured provider/model cannot perform native web search, Pie returns a clear unavailable result with provider/configuration details. In the CLI, web_research can use chrome-devtools-axi for browser-rendered sources when a Chrome browser is available; Unity reports those pages as requires_browser.
web_research records route health and latency in Pie's state directory so later runs can prefer providers with better source quality, fewer timeouts, and lower rate-limit pressure. pie doctor --json reports the recorded provider health, and verify:web writes web metrics including p50/p95 latency, failure categories, and citation quality artifacts.
Permissions
Interactive Pie starts with YOLO mode on: filesystem sandbox directory restrictions are disabled and high-risk shell commands are auto-approved. Use /settings/yolo off in trusted workflows that need workspace-scoped file tools and confirmations; ~/.pie remains allowlisted for Pie configuration/session support in that mode. Headless print/json-events hosts retain their non-YOLO composition. Shell commands return structured timeout/truncation/error details. The canonical executable tool is named shell; bash remains only a historical replay/rendering and policy identifier, not a second executable alias. On Windows shell:auto uses PowerShell, and callers can explicitly request the bash, powershell, or cmd dialect. High-risk shell commands require confirmation outside YOLO mode; the confirmation dialog also offers a time-boxed Yolo (5 min) option that suppresses further high-risk prompts for five minutes without enabling full YOLO mode. Explicitly turning /settings/yolo off revokes both persistent YOLO and any live temporary grant; status reports a remaining grant separately. pie permissions prints the current policy-derived safety summary.
In interactive Plan mode (/tools/plan), workspace editing tools are unavailable. The Plan-mode shell guard accepts simple read commands and read-only pipelines such as rg 'TODO' . | head -20; it blocks redirects, command substitution, and write-capable subcommands. Use plan_scratch to write, read, or list temporary text drafts in a directory dedicated to the current session. Shell redirection to /tmp remains blocked in Plan mode. When the plan is ready, the agent submits the ordered steps with plan_submit and you choose to execute immediately (progress is tracked through [DONE:n] markers in responses), keep planning, or refine the plan in a prefilled editor; a plan written as plain text under a Plan:/计划: heading is still detected as a fallback. Leave Plan mode before changing workspace files.
Code Intelligence
The CLI's former TypeScript-service code_intel tool has been retired. Unity currently exposes a lightweight provider for read-only JS/TS diagnostics, definition, references, symbols, and hover; do not infer a CLI TypeScript worker or a Unity Node sidecar from the old documentation.
Diagnostics
Use:
pie doctor
pie doctor --json
Doctor checks Node/npm, model configuration, API key availability, writable Pie data paths, chrome-devtools-axi and Chrome browser readiness, Unity bridge hints, and runtime log location. User-facing errors stay concise; detailed debugging goes to ~/.pie/logs/pie-cli.log and session trace artifacts.
Output Modes
For non-interactive usage, Pie supports structured output options:
pie "summarize this file" --raw-output
pie "summarize this file" --json-output
pie "continue previous task" --session-id my-session
Resuming Sessions From Another Directory
Sessions record the directory they were created in. When you resume a
session that belongs to another project (by --session-id or the
interactive /resume picker), Pie restarts itself in that project's
directory BEFORE loading anything cwd-sensitive (AGENTS.md discovery,
project skills, project memory) — a resumed session behaves exactly like
a fresh start in its project. A one-line banner shows the switch, and an
OSC 7 escape sequence tells supporting terminals where new panes belong.
- The shell you launched from keeps its own cwd (Unix shells cannot be driven by child processes); the printed banner is the source of truth.
--no-cdskips the restart (scripted/CI use).session.resume.chdir: falsein~/.pie/settings.jsondisables it permanently.- If the recorded directory no longer exists, Pie warns and resumes in the current directory instead of failing.
Machine-Readable Output (Agents And Hosts)
Every management command (sessions, doctor, models, extensions, permissions, capabilities) emits one compact JSON envelope when given --json:
{"v":1,"ok":true,"kind":"sessions.list","data":[...],"meta":{"count":10,"total":42,"nextCursor":"..."},"help":["..."]}
vis a constant output-schema generation marker;kindidentifies the command.metacarries pagination (nextCursor) and aggregates;help[]lists concrete next steps when they exist and never duplicates large payloads.- Errors are structured on stdout:
{"v":1,"ok":false,"kind":"...","error":{"code":"session_not_found","message":"...","hint":"..."}}. - Exit codes:
0success,1business failure,2usage error. Unknown flags fail loudly; every subcommand supports--help. sessions list --jsondefaults to the current project (--alllists every project). Rows are minimal (id,name,updatedAt,count) with--fieldsand--fullopt-ins;sessions readtruncates content by default with the same opt-ins.- JSONL protocol mode (
--json-events) identifies entries byentryIdonly (the legacycheckpointIdalias is gone) and caps large tool results and turn summaries by default; pass--event-detail fullfor larger but still bounded payloads (including a 4,000-character string cap, depth/item/key limits). Affected tool-result strings carrytruncated/fullLength; other bounded structures may use onlytruncated.
Run pie capabilities --json to discover the full command surface, flags, and exit-code contract programmatically.
Terminal Notes
For the best multiline editing experience, use a terminal with good modified-key support, such as:
Development
npm ci
npm run verify:quality
npm run verify:release
npm run verify:browser
npm run verify:terminal:matrix
Use npm run verify:agent when model credentials are available and you want the real daily agent gate.
Use npm run verify:agent:nightly before release candidates that claim real-provider reliability.
Unity checks in the default chain are offline tests and static package/bundle
checks only. Real Editor, reload, Play Mode, and Player verification use the
manual checklist in products/pie-unity/TESTING.md, not an automated Unity gate.
Set PIE_REAL_BROWSER=1 when you want verify:browser to open a real browser session instead of only checking the chrome-devtools-axi CLI contract.
Set PIE_REAL_WEB=1 when you want verify:web to run real provider web research smoke with fetched or browser-read citations.
Publishing
Publish @cydm/pie from the monorepo root.
Set the npm token first:
npm config set //registry.npmjs.org/:_authToken <YOUR_TOKEN>
Then publish:
npm run verify:release
npm publish --workspace products/cli --access public
If the package version already exists on npm, bump products/cli/package.json first.
License
MIT
Experimental Responses profiles
In models.json, set a profile's api to "openai-responses", baseUrl to
its API root (for example https://api.openai.com/v1), and apiKeyEnv to your
credential environment variable. Supply model IDs and limits in models as
usual. Optional profile/model transport is "sse" (default), "websocket"
(strict), or "auto" (WS with conservative pre-submission SSE fallback).
Model transport overrides profile transport. API selection is explicit.
A profile may declare endpoints: { "<api>": "https://..." } and each model
may select api (otherwise it inherits the profile API). Supported keys are
openai-completions, openai-responses, and anthropic-messages; endpoint URLs
follow the same absolute HTTP(S) validation as baseUrl. The resolved API uses
endpoints[api] when present, otherwise baseUrl. An explicitly different model
API requires its endpoint entry; an explicit same-API selection can use
baseUrl. Remote catalogs additionally require every endpoint to share the
authenticated catalog origin. modelOverrides cannot change these routes.
For example, Bigmodel's Chat Completions and Responses roots differ. This is a configuration example, not special provider logic; use distinct model IDs within the profile (replace the Chat model ID with your supported model):
{
"profiles": {
"bigmodel": {
"api": "openai-completions",
"baseUrl": "https://open.bigmodel.cn/api/coding/paas/v4",
"endpoints": {
"openai-responses": "https://open.bigmodel.cn/api/v1"
},
"apiKeyEnv": "BIGMODEL_API_KEY",
"transport": "sse",
"models": [
{
"id": "glm-5.2", "api": "openai-completions", "input": ["text"],
"contextWindow": 128000, "maxTokens": 4096,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
},
{
"id": "glm-5.3", "api": "openai-responses", "input": ["text"],
"contextWindow": 128000, "maxTokens": 4096,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
}
Limits/prices above are illustrative, not provider metadata. Keep Bigmodel and Kimi Responses on SSE for the tested endpoints/accounts: Responses support does not imply usable WS sessions. Current benchmarks show continuation upload savings, not consistent latency improvement; SSE stays default, WS/continuation opt-in.
Pie defaults to store: false. Optional compat fields are store,
supportsStore, supportsReasoningEffort, supportsEncryptedReasoning, and
responsesContinuation. Set the latter to true to enable verified same-connection
WS delta requests. SSE remains full-context. Local history remains authoritative;
rewind, compact, reset and model/credential changes discard or re-evaluate anchors.
Connection loss after submission is surfaced without automatic replay.
Text/images and function tools are supported; audio/video inputs fail explicitly. Connection reuse, delta continuation and prompt-cache hits are separate facts. See transport validation and opt-in benchmarks.