pi-jar 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +288 -0
- package/docs/DESIGN.md +85 -0
- package/docs/DEVELOPMENT.md +95 -0
- package/docs/FLAME.md +54 -0
- package/docs/INTEGRATIONS.md +82 -0
- package/docs/PLAN.md +68 -0
- package/docs/SHOWCASE.md +22 -0
- package/docs/WORKFLOWS.md +141 -0
- package/extensions/index.ts +773 -0
- package/package.json +62 -0
- package/src/accent.ts +36 -0
- package/src/advisor.ts +194 -0
- package/src/animations.ts +23 -0
- package/src/ask-tool.ts +185 -0
- package/src/attachments.ts +79 -0
- package/src/changes.ts +146 -0
- package/src/commit.ts +61 -0
- package/src/compact-tools.ts +129 -0
- package/src/composer.ts +404 -0
- package/src/context-view.ts +141 -0
- package/src/delegate.ts +208 -0
- package/src/dialogs.ts +127 -0
- package/src/diff-view.ts +160 -0
- package/src/flame.ts +245 -0
- package/src/footer-settings.ts +32 -0
- package/src/footer.ts +147 -0
- package/src/goal-loop.ts +313 -0
- package/src/goals.ts +114 -0
- package/src/history-ui.ts +136 -0
- package/src/history.ts +168 -0
- package/src/info-panels.ts +75 -0
- package/src/mascot.ts +103 -0
- package/src/model-roles.ts +332 -0
- package/src/panel.ts +90 -0
- package/src/plan-utils.ts +191 -0
- package/src/plan-view.ts +149 -0
- package/src/plan.ts +460 -0
- package/src/prompt-search.ts +83 -0
- package/src/quota.ts +134 -0
- package/src/roles-ui.ts +190 -0
- package/src/roles.ts +25 -0
- package/src/session-gallery.ts +52 -0
- package/src/session-ui.ts +76 -0
- package/src/settings-ui.ts +154 -0
- package/src/settings.ts +96 -0
- package/src/shells.ts +319 -0
- package/src/side-model.ts +48 -0
- package/src/split-view.ts +74 -0
- package/src/status.ts +71 -0
- package/src/suggest.ts +89 -0
- package/src/task-tool.ts +135 -0
- package/src/tasks-ui.ts +73 -0
- package/src/tasks.ts +147 -0
- package/src/usage-view.ts +98 -0
- package/src/usage.ts +16 -0
- package/src/welcome.ts +260 -0
- package/src/working.ts +60 -0
- package/themes/pi-jar-dark-amber.json +84 -0
- package/themes/pi-jar-dark-azure.json +84 -0
- package/themes/pi-jar-dark-gray.json +84 -0
- package/themes/pi-jar-dark-pink.json +84 -0
- package/themes/pi-jar-dark-teal.json +84 -0
- package/themes/pi-jar-dark-violet.json +84 -0
- package/themes/pi-jar-dark.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yunaz
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# pi-jar
|
|
2
|
+
|
|
3
|
+
A warm, role-aware TUI and workflow extension for [Pi](https://github.com/earendil-works/pi). pi-jar turns the terminal into a more expressive agent workspace with a living pixel-fire welcome, an adaptive composer, first-class **plan**, **goal** and **role** workflows, tracked tasks, reviewable changes, background shells and parallel subagents.
|
|
4
|
+
|
|
5
|
+
> Works with the current `@earendil-works/*` Pi API. Pi's core packages are peer dependencies (`"*"`), so pi-jar always runs against the Pi you have installed; it is tested against the latest release (0.87.x).
|
|
6
|
+
|
|
7
|
+
## See it in action
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
The showcase is captured from a real pi-jar terminal session: the torch-style `π`, animated flame and embers, live workspace state, tasks, roles and composer are the actual TUI rather than a mockup. Capture and media guidelines live in [docs/SHOWCASE.md](docs/SHOWCASE.md).
|
|
12
|
+
|
|
13
|
+
## Highlights
|
|
14
|
+
|
|
15
|
+
| Area | What you get |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **Welcome** | A natural pixel flame (rounded base, swaying tip, wisps, embers and sparks) over a large `π`; a large, flame-colored welcome message up top; a live card with project, git, session, plan, goal, tasks and roles; clickable actions (fullscreen) or keyboard hints (regular mode). |
|
|
18
|
+
| **Composer** | Rounded input that grows with your draft (up to ~60% of the terminal), click-to-place cursor in fullscreen, dim **next-prompt suggestions** you accept with <kbd>Tab</kbd>, and **Ember** — a tiny flame mascot that blinks, cheers, focuses, dozes and reacts. |
|
|
19
|
+
| **Plan mode** | Read-only exploration; the agent must write a structured plan file and submit it. You review it in a split view (headings on the left, section on the right) and approve, compact-and-approve, refine or stop. |
|
|
20
|
+
| **Goal mode** | Set an outcome; the agent must break it into tracked tasks and keeps working until they are done, then an **auditor** pass verifies the goal before it can be marked complete. |
|
|
21
|
+
| **Roles** | Named model roles (`default`, `smol`, `slow`, `plan`, `implement`, `advisor`, `task`, `commit`, plus your own) with `@alias` chains, `:effort` suffixes and project overrides; switched automatically as you move between plan, execution, goal rounds and audits, and never over a model you picked yourself. |
|
|
22
|
+
| **Advisor** | A second-opinion model: the agent calls `jar_advisor` for risky decisions or when stuck, `/advisor [focus]` asks on demand, and automatic gates consult it when the agent repeats the same tool call or keeps failing. |
|
|
23
|
+
| **Usage & context** | `/usage` shows session cost and tokens per model (advisor and commit calls included) and plan-limit bars with reset times; `/context` draws a grid of what fills the context window, with a per-file, per-skill and per-tool breakdown. |
|
|
24
|
+
| **Commit** | `/jar commit [note]` drafts a message for the staged changes with the `commit` role, lets you edit it, then commits (never pushes). |
|
|
25
|
+
| **Tasks & questions** | A Claude-style `jar_todo` checklist the agent maintains itself, and `jar_ask` structured questions with options, multi-select and free-form answers. |
|
|
26
|
+
| **Change review** | Every file the agent edits is remembered as it was; `/diff` (<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>D</kbd>) shows changed files next to a colored diff, with accept or revert per file or all at once. |
|
|
27
|
+
| **Background shells** | `jar_shell` runs dev servers, watchers and long tests in the background; the agent is woken when a watch pattern matches or the process exits, so it never polls. `/jar shells` tails or kills them. |
|
|
28
|
+
| **Subagents** | `jar_delegate` fans out up to four read-only (or opt-in editing) subagents in parallel on your model roles; they show up live as teammates on the welcome card and footer. |
|
|
29
|
+
| **Sessions & history** | Recent sessions (with their goal and plan) on the welcome card, one click from resuming; <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>H</kbd> searches earlier prompts; pasted images show as chips under the composer. |
|
|
30
|
+
| **Footer & themes** | Responsive footer (model, effort, session, cwd, context, RAM, cost, quota, goal, roles, branch) and seven dark themes. |
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pi install npm:pi-jar
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or track the repository directly with `pi install git:github.com/ygrip/pi-jar`.
|
|
39
|
+
|
|
40
|
+
Restart Pi, then pick a theme with `/settings`: `pi-jar-dark`, or `pi-jar-dark-<accent>` (`gray`, `pink`, `teal`, `azure`, `violet`, `amber`). For the closest match set your terminal background to `#0B1018` (Pi themes cannot change the terminal's own background).
|
|
41
|
+
|
|
42
|
+
Loading only `--extension ./extensions/index.ts` does not register the bundled themes; install the package or also pass `--theme ./themes`. Do not load pi-jar twice.
|
|
43
|
+
|
|
44
|
+
### Mouse, clicks and copy-on-select
|
|
45
|
+
|
|
46
|
+
Pi only delivers mouse events in its **fullscreen** TUI mode. In regular mode the terminal owns scrollback and selection, so pi-jar shows keyboard shortcuts instead of buttons.
|
|
47
|
+
|
|
48
|
+
- Turn it on in **`/jar settings` → Pi → Mouse clicks** (writes Pi's `tuiMode`; restart Pi), or start with `pi --tui-mode fullscreen`.
|
|
49
|
+
- In fullscreen, selecting text copies it automatically (**Pi → Copy on select**, on by default). pi-jar's own views never capture drags, so selection works over the welcome, composer, plan view and dialogs.
|
|
50
|
+
- In regular mode, use your terminal's own copy-on-select option if it has one.
|
|
51
|
+
|
|
52
|
+
## Commands and shortcuts
|
|
53
|
+
|
|
54
|
+
| Command | Purpose |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| `/plan [request]` | Enter plan mode (optionally sending the request). `/plan review` reopens the plan view; `/plan off` exits. |
|
|
57
|
+
| `/goal <outcome>` | Start goal mode. `/goal` edits, `/goal status`, `/goal pause`, `/goal resume`, `/goal clear`. |
|
|
58
|
+
| `/roles` | Role manager. `/roles set ROLE provider/model[:effort]\|@role [--project]`, `/roles clear ROLE`, `/roles <role>` activates, `/roles cycle`, `/roles list`. |
|
|
59
|
+
| `/advisor [focus]` | Ask the advisor for a second opinion on the current work; the answer joins the conversation. |
|
|
60
|
+
| `/usage` · `/context` | Usage (cost, tokens per model, plan limits) and context-window breakdown in one tabbed panel. |
|
|
61
|
+
| `/jar commit [note]` | Draft a commit message for the staged changes with the `commit` role, edit it, and commit. Offers `git add -A` when nothing is staged. |
|
|
62
|
+
| `/jar` · `/jar settings` | Visual and workflow preferences. |
|
|
63
|
+
| `/jar status` | One-line status summary. |
|
|
64
|
+
| `/jar tasks [list\|add\|done\|open\|edit\|delete]` | Human view/editor for the agent's checklist. |
|
|
65
|
+
| `/jar history` | Read-only conversation timeline for the active branch. |
|
|
66
|
+
| `/diff` | Review, accept or revert the files the agent changed. |
|
|
67
|
+
| `/jar shells` | Background shells: live output, kill. |
|
|
68
|
+
| `/jar resume [N]` | Resume recent session `N` from the welcome list, or pick one. |
|
|
69
|
+
| `/jar sessions [query]` · `/jar name <title>` | Search/switch sessions; name the current one. |
|
|
70
|
+
| `/jar welcome` | Replay the welcome screen. |
|
|
71
|
+
| `/jar ask [question]` | Answer a question in a dialog and insert the answer into the editor. |
|
|
72
|
+
| `/jar accent [preset]` · `/jar footer` | Switch a loaded accent theme; toggle footer fields. |
|
|
73
|
+
| `/jar composer on\|off` · `/jar animations on\|off` · `/jar ui on\|off` | Toggle the composer, motion, or all pi-jar UI. |
|
|
74
|
+
| `/jar quota on\|off` | Session-only, read-only quota lookups for supported OAuth providers. |
|
|
75
|
+
| `/jar hub` | Open an installed task or subagent manager command. |
|
|
76
|
+
| `/jar demo` · `/jar reset` | Labeled sample roles in the footer / back to live data. |
|
|
77
|
+
|
|
78
|
+
| Shortcut | Action |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>S</kbd> | Open pi-jar settings |
|
|
81
|
+
| <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>R</kbd> | Refresh the welcome (new message and flame), or show it again |
|
|
82
|
+
| <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>P</kbd> | Toggle plan mode |
|
|
83
|
+
| <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>M</kbd> | Cycle model roles (`cycleOrder`) |
|
|
84
|
+
| <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>D</kbd> | Review agent changes (`/diff`) |
|
|
85
|
+
| <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>H</kbd> | Search earlier prompts into the composer |
|
|
86
|
+
| <kbd>Tab</kbd> / <kbd>→</kbd> in an empty composer | Accept the dim suggestion into the input (it is not sent) |
|
|
87
|
+
|
|
88
|
+
## Welcome screen
|
|
89
|
+
|
|
90
|
+
The welcome stays until your first prompt, then dissolves (or hides immediately with motion off).
|
|
91
|
+
|
|
92
|
+
- **Flame** — one continuous flame with a rounded base and a tip that sways and licks, animated with smooth noise and drawn with half-block "pixels" in a ten-step ember→gold palette. Wisps break off the tip; embers and sparks rise from it. Every frame is deterministic per seed, so motion-off shows a frozen, still-lit flame. Terminals without 24-bit color get shaded blocks in theme colors. See [docs/FLAME.md](docs/FLAME.md).
|
|
93
|
+
- **Card** — `pi-jar` version, model, effort and active role; a large hopeful message; project + git branch/dirty; context, quota and cost; plan state; goal progress; open tasks with the next one; configured roles; live teammates (other extensions and `jar_delegate` subagents); and **RECENT** — the last three sessions with their goal and plan. Click a recent row (or run `/jar resume N`) to continue it.
|
|
94
|
+
- **Actions** — `[ ⚙ Settings ] [ ↻ Refresh ] [ ◆ Roles ] [ ▤ Plan ] [ ◎ Goal ]` in fullscreen (act on press). In regular mode the same row shows `ctrl+alt+s settings · ctrl+alt+r refresh · /roles · /plan · /goal`.
|
|
95
|
+
|
|
96
|
+
## Composer
|
|
97
|
+
|
|
98
|
+
- **Grows with your draft**: the input expands to about 60% of the terminal before it scrolls (overflow shows `↑/↓ N more` in the border).
|
|
99
|
+
- **Click to place the cursor** (fullscreen), including multi-line drafts. Autocomplete menus (including Pi's `@file` fuzzy search) render below the frame.
|
|
100
|
+
- **Image chips**: images you paste (<kbd>Ctrl</kbd>+<kbd>V</kbd>) or reference by path appear under the frame as `▣ pasted png · 1280×720 · 240 KB`.
|
|
101
|
+
- **Prompt history search**: <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>H</kbd> fuzzy-searches every prompt in this session and the opening prompts of recent ones; <kbd>Enter</kbd> puts the pick in the composer to edit. <kbd>↑</kbd>/<kbd>↓</kbd> still walks Pi's history.
|
|
102
|
+
- **Next-prompt suggestions**: when the agent finishes a request it proposes one likely next prompt (`jar_suggest`). It appears as dim ghost text in the empty input; <kbd>Tab</kbd> (or <kbd>→</kbd>, or a click on it) fills it in so you can edit and press <kbd>Enter</kbd>. Typing, sending, or a new run clears it. Toggle in settings.
|
|
103
|
+
- **Ember the mascot** perches on the top-left of the input — the face sits in the border, the flickering tips just above:
|
|
104
|
+
|
|
105
|
+
| Mood | Face | When |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| idle / blink | `(•ᴗ•)` `(-ᴗ-)` | waiting for you; blinks every few seconds |
|
|
108
|
+
| happy / thinking | `(^ᴗ^)` `(°ᴗ°)` | the agent is generating |
|
|
109
|
+
| focused | `(>ᴗ<)` | a tool is running (sparks fly) |
|
|
110
|
+
| curious | `(•o•)` | a question or dialog is open |
|
|
111
|
+
| sleepy | `(-ω-)` | idle for two minutes (`z` rises) |
|
|
112
|
+
| oops | `(×_×)` | a run failed |
|
|
113
|
+
| proud | `(★ᴗ★)` | a goal was completed |
|
|
114
|
+
| poked | `(^o^)` | you clicked it |
|
|
115
|
+
|
|
116
|
+
The title also shows Pi's session name (or a stable readable alias like `silver-lantern`). Toggle the mascot in settings; `/jar composer off` restores Pi's editor with your draft intact.
|
|
117
|
+
|
|
118
|
+
## Plan mode
|
|
119
|
+
|
|
120
|
+
`/plan` switches Pi into read-only planning:
|
|
121
|
+
|
|
122
|
+
1. **Tools are gated.** Only known read-only tools stay active; `bash` is limited to an inspection allowlist; a second guard blocks unsafe calls even if another extension exposes them. `write`/`edit` are allowed **only** for markdown files in the plan directory (`$TMPDIR/pi-jar/plans/<session>/`, resolved through symlinks).
|
|
123
|
+
2. **The `plan` role is applied** if assigned, and restored afterwards. An active goal loop pauses.
|
|
124
|
+
3. **The agent writes a plan file** such as `<slug>-plan.md` and must end its turn with `jar_plan_submit`. The file is validated; an incomplete plan is sent back with the missing parts. If the agent ends a turn without submitting, pi-jar reminds it (at most twice per prompt) instead of accepting a chat-only plan.
|
|
125
|
+
|
|
126
|
+
Required structure:
|
|
127
|
+
|
|
128
|
+
```markdown
|
|
129
|
+
# <Plan title>
|
|
130
|
+
|
|
131
|
+
## Context
|
|
132
|
+
Why, the literal request, and the intended end state.
|
|
133
|
+
|
|
134
|
+
## Approach
|
|
135
|
+
1. Ordered steps grouped by behavior, naming exact files, symbols, reused helpers and error handling.
|
|
136
|
+
|
|
137
|
+
## Critical files
|
|
138
|
+
- `path/to/file.ts` — symbol — why it changes
|
|
139
|
+
|
|
140
|
+
## Verification
|
|
141
|
+
- Exact commands and at least one concrete check of new behavior.
|
|
142
|
+
|
|
143
|
+
## Assumptions
|
|
144
|
+
- Decisions the user could override, each with a fallback.
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
4. **Plan view** — a full-screen split view: headings on the left (the lone `#` title becomes the header, `###` steps are indented), the selected section rendered as markdown on the right, actions below.
|
|
148
|
+
- Keys: <kbd>Tab</kbd> cycles focus (headings → body → actions), <kbd>↑↓</kbd>/<kbd>j k</kbd> move or scroll, <kbd>g</kbd>/<kbd>G</kbd>, <kbd>PgUp</kbd>/<kbd>PgDn</kbd>, <kbd>1–4</kbd> pick an action, <kbd>e</kbd> edits the plan (saved back to the file), <kbd>r</kbd> cycles the **continue with** role, <kbd>Esc</kbd> stops. Fullscreen: click headings and actions, wheel scrolls the pane under the pointer.
|
|
149
|
+
- Actions: **Approve & execute**, **Approve, compact & execute** (compaction keeps the plan), **Refine** (send feedback, stay in plan mode), **Stop**.
|
|
150
|
+
5. **Execution** seeds `jar_todo` from the Approach steps, restores tools and model, optionally switches to the chosen role, and sends the full plan inline (`<plan path="…">…</plan>`) with instructions to work step by step and verify each step.
|
|
151
|
+
|
|
152
|
+
Plan state is stored in the session branch, so reloading or navigating the tree restores it. Narrow terminals collapse the headings into a `‹ n/m heading ›` pager.
|
|
153
|
+
|
|
154
|
+
## Goal mode
|
|
155
|
+
|
|
156
|
+
`/goal Ship the export command` starts an implement → audit loop:
|
|
157
|
+
|
|
158
|
+
- **Tasks first.** While a goal is active and no task is open, `write`/`edit` and non-read-only shell commands are blocked with "create jar_todo tasks for the goal first". The agent sees the goal and its current checklist at the start of every run.
|
|
159
|
+
- **Implementor.** When a turn ends normally with open tasks (or none yet), pi-jar continues automatically with a hidden continuation listing the goal and open tasks.
|
|
160
|
+
- **Auditor.** When every task is done, the next round switches to the `advisor` role (if assigned) and asks for an independent audit against the repository: run the checks, look for missed requirements. The auditor either adds tasks for gaps (edits stay blocked during the audit), which sends work back to the implementor, or calls `jar_goal complete` with concrete evidence. Completion is refused outside the audit, while tasks are open, or without evidence.
|
|
161
|
+
- **Guard rails.** The loop pauses when you interrupt (<kbd>Esc</kbd>), a run fails, plan mode starts, the agent calls `jar_goal block` (it needs you), or the round budget runs out (default 8 automatic rounds per user message; settings → Pi → Goal auto rounds). A new message from you resets the budget. `/goal resume` continues.
|
|
162
|
+
- The footer and welcome show progress: `◎ goal · Ship · 3/5 tasks · round 2/8 · auditing`.
|
|
163
|
+
|
|
164
|
+
## Model roles
|
|
165
|
+
|
|
166
|
+
Roles map a purpose to a model. They live in `~/.pi/agent/pi-jar-roles.json` (Pi's agent directory), with optional per-project overrides in `<project>/.pi/pi-jar-roles.json`:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"version": 2,
|
|
171
|
+
"roles": {
|
|
172
|
+
"default": "anthropic/claude-sonnet-5",
|
|
173
|
+
"slow": "anthropic/claude-opus-5-5:high",
|
|
174
|
+
"plan": "@slow",
|
|
175
|
+
"advisor": "@slow:xhigh",
|
|
176
|
+
"smol": "anthropic/claude-haiku-4-5-20251001",
|
|
177
|
+
"review": "openai/gpt-5:medium"
|
|
178
|
+
},
|
|
179
|
+
"cycleOrder": ["smol", "default", "slow"],
|
|
180
|
+
"tags": { "review": { "name": "Reviewer" } }
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
- Specs are `provider/model[:effort]`, `@role[:effort]` (alias) or `*` (= `@default`). An effort on the referring role wins over the target's. Alias chains are followed up to five levels; cycles are reported.
|
|
185
|
+
- **Built-in roles and where pi-jar uses them:**
|
|
186
|
+
| Role | Used for |
|
|
187
|
+
| --- | --- |
|
|
188
|
+
| `default` | applied at session start |
|
|
189
|
+
| `plan` | plan mode (restored when you leave it) |
|
|
190
|
+
| `implement` | executing an approved plan and goal implement rounds (falls back to the current model) |
|
|
191
|
+
| `advisor` | `jar_advisor`, `/advisor`, stuck-work gates and the goal audit |
|
|
192
|
+
| `task` | `jar_delegate` subagents |
|
|
193
|
+
| `commit` | `/jar commit` messages |
|
|
194
|
+
| `smol` / `slow` | cycling with <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>M</kbd> |
|
|
195
|
+
|
|
196
|
+
Any other valid name (`a-z`, `0-9`, `-`) is a custom role.
|
|
197
|
+
- **Switching is automatic and scoped.** Entering plan mode applies `plan`; approving applies your chosen role or `implement` for the run; goal rounds alternate `implement` and `advisor`. Each temporary switch restores the previous model afterwards — unless you picked a model or effort yourself in the meantime, which always wins.
|
|
198
|
+
- `/roles` opens a split manager: role list on the left; resolved model, alias chain, effort, scope and usage on the right. Keys: `m` model, `a` alias, `t` effort, `s` move between global/project scope, <kbd>Enter</kbd> activate, `c` clear, `n` new role, `d` delete custom role.
|
|
199
|
+
- Older v1 files are read and upgraded in memory; they are rewritten as v2 only when you change a role.
|
|
200
|
+
|
|
201
|
+
## Advisor
|
|
202
|
+
|
|
203
|
+
The advisor is a second model (the `advisor` role; the current model if unassigned) that sees a fresh view of the recent conversation plus `git status` and a diff stat, but cannot run tools.
|
|
204
|
+
|
|
205
|
+
- **`jar_advisor({ question?, draft? })`** — the agent is told to use it before risky or hard-to-reverse choices, after two failed attempts, and before declaring complex work done; it passes its own candidate as `draft`. Available in plan mode too.
|
|
206
|
+
- **`/advisor [focus]`** — ask on demand; the answer is added to the conversation (visible) for the agent's next turn.
|
|
207
|
+
- **Gates** — when the agent makes the same tool call three times within its last eight calls, the call is blocked and the advisor's review is returned instead; after three failing tool results in a row, the advice is steered into the running turn. At most two automatic consultations per prompt.
|
|
208
|
+
- Settings → Pi toggles the advisor and the gates. Advisor calls are counted in `/usage`. The footer and welcome show it as a working teammate while it thinks.
|
|
209
|
+
|
|
210
|
+
## Usage and context
|
|
211
|
+
|
|
212
|
+
`/usage` and `/context` open one tabbed panel (<kbd>Tab</kbd> switches, <kbd>Esc</kbd> closes):
|
|
213
|
+
|
|
214
|
+
- **Usage** — total cost, duration, prompts and responses, tokens (input, output, cache read/write); a per-model breakdown including advisor and commit calls; and, for Anthropic and OpenAI Codex subscriptions, 5-hour and weekly limit bars with reset times (lookups follow `/jar quota on|off`).
|
|
215
|
+
- **Context** — a 10×10 grid (each cell ≈ 1% of the window) beside a legend: system prompt, tools, context files, skills, compaction summary, user and assistant messages, tool results, extension messages, free space and the autocompact buffer. Parts are estimated at ~4 characters per token and scaled to the provider-reported total when one is known; context files, skills and tools are listed individually below.
|
|
216
|
+
|
|
217
|
+
## Tasks, questions and history
|
|
218
|
+
|
|
219
|
+
- **`jar_todo`** — a Claude-style task list the agent keeps for any multi-step request. It writes the full list at once; each task is `pending`, `in_progress` (exactly one at a time) or `completed`, with an `activeForm` ("Running tests") that replaces the working spinner text while it runs. The live checklist above the composer shows `✔` struck-through done tasks, a bold `◼` current task and `☐` pending ones; a finished list stays until your next prompt. `/jar tasks` is your view/editor: `a` add, <kbd>Space</kbd>/<kbd>Enter</kbd> check, `e` edit, `d` delete, `f` filter.
|
|
220
|
+
- **`jar_ask`** — structured questions: numbered options with descriptions, single or multi-select, *Type your own answer* (multi-line, paste-friendly) and *Chat about this* to discuss before choosing.
|
|
221
|
+
- **`/diff`** — review what the agent changed since its first edit to each file: files with `+/−` counts on the left, a numbered, colored diff on the right. `a` accept (keep, stop tracking), `r` then `y` revert (restore the original, or remove a file it created), `A`/`R` for all. The footer shows `± N files · /diff` while anything is unreviewed. Only `edit`/`write` changes inside the project are tracked; shell-made changes are not.
|
|
222
|
+
- **`jar_shell`** — `start` (with optional `name`, `watch` regex and `notify`), `list`, `output`, `kill`. Output is ANSI-stripped and bounded (2000 lines). When a watch matches or the process ends, a visible message wakes the agent (queued if it is busy). The footer shows `⚙ N shells`; `/jar shells` opens a live view (`x` kill, `f` follow). All shells stop when the session ends.
|
|
223
|
+
- **`jar_delegate`** — up to four subagents run in parallel as separate one-shot Pi processes with a fresh context, on a role (default `task`, then `default`, then the current model). They are read-only (`read`, `grep`, `find`, `ls`) unless `write: true`; subagents cannot delegate further; aborting the turn stops them. Each shows as a working teammate until it finishes, and the tool result lists every report.
|
|
224
|
+
- **`/jar history`** — separate, read-only timeline of the active branch (paging, search, expandable details). Pi's native transcript is untouched.
|
|
225
|
+
- Pi's built-in read/shell/edit/write tool cards render compactly; the full output or diff stays one click or <kbd>Ctrl</kbd>+<kbd>O</kbd> away.
|
|
226
|
+
|
|
227
|
+
## Settings
|
|
228
|
+
|
|
229
|
+
`/jar settings` (or <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>S</kbd>, or the welcome's Settings action) has three tabs:
|
|
230
|
+
|
|
231
|
+
- **Appearance** — accent, motion, rounded composer, Ember mascot, next-prompt suggestions, pi-jar UI.
|
|
232
|
+
- **Footer** — field visibility.
|
|
233
|
+
- **Pi** — mouse clicks (Pi fullscreen mode), copy on select, goal auto rounds, advisor, advisor gates.
|
|
234
|
+
|
|
235
|
+
pi-jar preferences are saved in `pi-jar-settings.json` in Pi's agent directory; the Pi tab writes Pi's own settings.
|
|
236
|
+
|
|
237
|
+
## Integrations
|
|
238
|
+
|
|
239
|
+
Other extensions can publish teammate roles and quota windows through Pi's public status API; see [docs/INTEGRATIONS.md](docs/INTEGRATIONS.md).
|
|
240
|
+
|
|
241
|
+
## Repository structure
|
|
242
|
+
|
|
243
|
+
```text
|
|
244
|
+
pi-jar/
|
|
245
|
+
├── extensions/index.ts extension entry: wiring, welcome, footer, commands
|
|
246
|
+
├── src/
|
|
247
|
+
│ ├── flame.ts pixel fire simulation
|
|
248
|
+
│ ├── mascot.ts Ember's moods and sprites
|
|
249
|
+
│ ├── composer.ts rounded composer, ghost text, mouse mapping
|
|
250
|
+
│ ├── suggest.ts jar_suggest tool and suggestion state
|
|
251
|
+
│ ├── plan*.ts plan mode, plan parsing/validation, plan view
|
|
252
|
+
│ ├── goal*.ts goal state and the implement → audit loop
|
|
253
|
+
│ ├── model-roles.ts role config, resolution, activation
|
|
254
|
+
│ ├── roles-ui.ts role manager
|
|
255
|
+
│ ├── advisor.ts jar_advisor, /advisor and stuck-work gates
|
|
256
|
+
│ ├── side-model.ts one-shot role model calls and their usage
|
|
257
|
+
│ ├── commit.ts /jar commit
|
|
258
|
+
│ ├── usage-view.ts /usage; context-view.ts is /context; panel.ts frames both
|
|
259
|
+
│ ├── split-view.ts shared two-pane frame
|
|
260
|
+
│ ├── changes.ts change tracker and line diff; diff-view.ts is /diff
|
|
261
|
+
│ ├── shells.ts background shells, jar_shell and /jar shells
|
|
262
|
+
│ ├── delegate.ts jar_delegate subagents
|
|
263
|
+
│ ├── attachments.ts image chips; prompt-search.ts is prompt history
|
|
264
|
+
│ ├── session-gallery.ts recent sessions for the welcome
|
|
265
|
+
│ ├── welcome.ts welcome layout and hit-testing
|
|
266
|
+
│ └── … footer, tasks, questions, history, settings, quota
|
|
267
|
+
├── themes/ native Pi themes
|
|
268
|
+
├── tests/ node:test suites
|
|
269
|
+
└── docs/ design, workflows, flame, integrations, development
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Documentation
|
|
273
|
+
|
|
274
|
+
- [docs/SHOWCASE.md](docs/SHOWCASE.md) — README demo capture and media guidelines.
|
|
275
|
+
- [docs/WORKFLOWS.md](docs/WORKFLOWS.md) — plan, goal, roles and suggestions in depth.
|
|
276
|
+
- [docs/DESIGN.md](docs/DESIGN.md) — palette, motion, layout and accessibility.
|
|
277
|
+
- [docs/FLAME.md](docs/FLAME.md) — how the flame and mascot are drawn.
|
|
278
|
+
- [docs/INTEGRATIONS.md](docs/INTEGRATIONS.md) — public status contracts.
|
|
279
|
+
- [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) — setup, testing and release checks.
|
|
280
|
+
- [docs/PLAN.md](docs/PLAN.md) — roadmap.
|
|
281
|
+
|
|
282
|
+
## Contributing
|
|
283
|
+
|
|
284
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
MIT. See [LICENSE](LICENSE).
|
package/docs/DESIGN.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Design
|
|
2
|
+
|
|
3
|
+
## Identity
|
|
4
|
+
|
|
5
|
+
pi-jar should feel technical, calm and readable, warm enough not to look like another neon-blue terminal, clearly aware of who (or which role) is doing what, and useful during long sessions.
|
|
6
|
+
|
|
7
|
+
Rule of thumb: **state first, useful telemetry second, decoration last.** Every animation carries meaning, and everything still works with motion off.
|
|
8
|
+
|
|
9
|
+
The public README demo is intentionally a real terminal capture rather than a mockup. It should show the flame, workspace card and composer at a readable scale without presenting decorative states that users cannot actually reach. See [SHOWCASE.md](SHOWCASE.md) for capture rules.
|
|
10
|
+
|
|
11
|
+
## Palette
|
|
12
|
+
|
|
13
|
+
| Purpose | Color |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| suggested terminal background | `#0B1018` |
|
|
16
|
+
| surface | `#111927` |
|
|
17
|
+
| default accent (teal) | `#00C2B8` |
|
|
18
|
+
| technical blue | `#7FA8EE` |
|
|
19
|
+
| warning amber | `#E5A940` |
|
|
20
|
+
| success green | `#35C79A` |
|
|
21
|
+
| text | `#F3F6FA` |
|
|
22
|
+
| muted text | `#98A5B6` |
|
|
23
|
+
| danger terracotta | `#EE7A5E` |
|
|
24
|
+
|
|
25
|
+
`pi-jar-dark` uses the teal accent on deep navy surfaces with semantic status colors. Six alternate themes change only the accent and selection: gray, pink, teal, azure, violet and amber. Success, warning and error never change. `/jar accent <preset>` switches between loaded bundled themes; `default` restores teal. The fire palette used by the flame and mascot is documented in [FLAME.md](FLAME.md).
|
|
26
|
+
|
|
27
|
+
## Role language
|
|
28
|
+
|
|
29
|
+
Live teammate names and labels come from publishers (`pi-jar.role.<id>`, see [INTEGRATIONS.md](INTEGRATIONS.md)); pi-jar never invents them. `/jar demo` shows clearly labeled generic samples. Model roles (`/roles`) are a separate concept: they choose which model runs a workflow. The active one shows as `role:<name>` in the footer and on the welcome card.
|
|
30
|
+
|
|
31
|
+
State colors: thinking/working → accent · reviewing → warning · done → success · failed → error · waiting/idle → dim.
|
|
32
|
+
|
|
33
|
+
## Motion language
|
|
34
|
+
|
|
35
|
+
| Surface | Motion | Stops when |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| Welcome flame | pixel fire, embers, sparks (90 ms) | the welcome closes, or motion is off (frozen frame) |
|
|
38
|
+
| Ember mascot | blinks, mood changes, tip flicker (repaints only on change) | motion off (calm face) or mascot off |
|
|
39
|
+
| Working indicator | `✢ ✣ ✤` while generating, `◐ ◓ ◑ ◒` for tools | the run settles |
|
|
40
|
+
| Footer roles | `◈ ◆`, `◐ ◓ ◑ ◒`, `◔ ◑ ◕ ●` | the role is idle, done or failed |
|
|
41
|
+
|
|
42
|
+
Rules:
|
|
43
|
+
|
|
44
|
+
1. labels never move; only glyphs animate;
|
|
45
|
+
2. completed and failed states are static;
|
|
46
|
+
3. idle UI does not repaint continuously;
|
|
47
|
+
4. at most two prominent animations compete at once;
|
|
48
|
+
5. motion is optional and never the only carrier of information.
|
|
49
|
+
|
|
50
|
+
## Layout
|
|
51
|
+
|
|
52
|
+
### Welcome
|
|
53
|
+
|
|
54
|
+
- **Wide (≥ 72 columns):** flame and large `π` in a 28-column art column, with the card on the right, vertically centered.
|
|
55
|
+
- **Medium (32–71):** a slightly cropped flame and compact `π` stacked above the card.
|
|
56
|
+
- **Narrow (< 32):** cropped flame, compact `π` and a single Settings action.
|
|
57
|
+
|
|
58
|
+
Card sections, top to bottom: header (version · model · effort · role), the **message hero**, workspace (project · git · session), workflow (plan · goal · tasks · roles · team), actions. The hero is the focal point: bold, painted in the flame's gold-to-orange ramp and set in double-width (fullwidth) letters when it fits in three lines, otherwise bold at normal width, with a dim "— welcome to pi-jar —" byline. **Refresh** picks a new message and flame. Long values truncate at the right. Actions are bracketed chips in fullscreen and plain keyboard hints in regular mode. A button is never advertised where it cannot be clicked.
|
|
59
|
+
|
|
60
|
+
### Composer
|
|
61
|
+
|
|
62
|
+
The Ember tip row sits above a rounded frame. The top border carries the face, the session title and the `↑ N more` overflow label; the bottom border carries `↓ N more` and dim key hints (hidden below 60 columns). Autocomplete menus render below the frame, aligned with the text. Ghost suggestions are dim and followed by `⇥ tab`.
|
|
63
|
+
|
|
64
|
+
### Split views (plan view, roles, changes, shells)
|
|
65
|
+
|
|
66
|
+
A shared frame (`src/split-view.ts`): title bar with a clickable `×`, a sidebar of `clamp(round(w × 0.26), 18, 32)` columns, a `│` divider, a body pane, a divider row, footer rows, and a closing border. Below 64 columns the sidebar collapses into a header pager.
|
|
67
|
+
|
|
68
|
+
### Footer
|
|
69
|
+
|
|
70
|
+
- **Wide (100+):** model · effort · session · cwd · context · RAM · cost, then roles and branch, with quota on a third line if needed.
|
|
71
|
+
- **Medium (52–99):** fewer extras; context is always visible.
|
|
72
|
+
- **Narrow (< 52):** model, effort, the active or failed role, context.
|
|
73
|
+
|
|
74
|
+
The goal line shows `◎ goal · <progress>` when a goal exists.
|
|
75
|
+
|
|
76
|
+
## Conversation timeline
|
|
77
|
+
|
|
78
|
+
`/jar history` is an overlay built from a snapshot of the active branch. It is not a restyled transcript. Visible messages, compactions and branch summaries become rows; reasoning, hidden custom messages and image bytes are excluded. Paging (80 rows), 2 KiB / 30-line chunks and page-local search keep it bounded.
|
|
79
|
+
|
|
80
|
+
## Accessibility
|
|
81
|
+
|
|
82
|
+
- state never relies on color alone: every active state has a glyph or word;
|
|
83
|
+
- motion-off preserves all information;
|
|
84
|
+
- keyboard paths exist for every pointer action;
|
|
85
|
+
- core rendering uses ordinary Unicode and works without 24-bit color.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
## Requirements
|
|
4
|
+
|
|
5
|
+
- Node.js 22.6+ (native TypeScript test runner)
|
|
6
|
+
- npm
|
|
7
|
+
- a current Pi installation
|
|
8
|
+
|
|
9
|
+
## Local setup
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
git clone https://github.com/ygrip/pi-jar.git
|
|
13
|
+
cd pi-jar
|
|
14
|
+
npm install
|
|
15
|
+
npm run check
|
|
16
|
+
npm test
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Load locally in Pi
|
|
20
|
+
|
|
21
|
+
Install the working copy as a local Pi package:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pi install "$(pwd)"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or run against a temporary checkout without publishing it.
|
|
28
|
+
|
|
29
|
+
Use `pi list` to verify the package is loaded. Loading only `--extension ./extensions/index.ts` does not register bundled themes: either install the package and restart Pi, or also pass `--theme ./themes` for a standalone development run. Avoid loading the extension twice by combining a package install with `--extension`.
|
|
30
|
+
|
|
31
|
+
## Theme testing
|
|
32
|
+
|
|
33
|
+
Select a theme with `/settings`: `pi-jar-dark`, or a `pi-jar-dark-<accent>` variant (gray/pink/teal/azure/violet/amber). Accent themes are generated from `src/accent.ts` and `themes/pi-jar-dark.json` with `npm run themes:build`. Pi hot-reloads custom theme files; package development may need `/reload`.
|
|
34
|
+
|
|
35
|
+
Check user messages, tool pending/success/error states, diffs, markdown, syntax highlighting, every thinking level, bash mode, and narrow and wide terminals.
|
|
36
|
+
|
|
37
|
+
## Extension testing
|
|
38
|
+
|
|
39
|
+
Automated:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm run check # tsc --noEmit
|
|
43
|
+
npm test # node:test suites in tests/
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Tests isolate `PI_CODING_AGENT_DIR`, so they never touch your real preferences. Suites cover the flame simulation, welcome layout and hit-testing, composer framing/expansion/ghost text/mouse mapping, the mascot, plan mode (guards, submission, reminders, restore), the plan view, plan parsing, the goal loop, roles v2, suggestions and settings.
|
|
47
|
+
|
|
48
|
+
Manual smoke test (offline, throwaway agent directory, nothing sent to a model):
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
PI_OFFLINE=1 PI_SKIP_VERSION_CHECK=1 PI_TELEMETRY=0 \
|
|
52
|
+
PI_CODING_AGENT_DIR="$(mktemp -d)" pi -e ./extensions
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Then check:
|
|
56
|
+
|
|
57
|
+
- the welcome at 24, 40, 80 and 120+ columns; <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>R</kbd> refresh; motion off (`/jar animations off`) freezes the flame;
|
|
58
|
+
- the composer: typing `/pl` shows autocomplete below the frame; long drafts grow before scrolling; Ember changes mood while dialogs are open;
|
|
59
|
+
- `/jar settings`: Tab through Appearance → Footer → Pi, toggle mouse mode and check Pi's `settings.json` in the temporary agent dir;
|
|
60
|
+
- `/roles`: the split manager, `n` new role, `a` alias, `s` scope;
|
|
61
|
+
- `/plan`: the status shows `◆ PLAN · read-only` and a directory appears under `$TMPDIR/pi-jar/plans/`.
|
|
62
|
+
|
|
63
|
+
For pointer interaction start with `--tui-mode fullscreen` (or enable **Pi → Mouse clicks** and restart). Check that welcome actions fire once per press, that clicking composer text moves the cursor, that clicking Ember pokes it, that plan-view headings and actions respond to clicks and the wheel, and that selecting text anywhere still copies it.
|
|
64
|
+
|
|
65
|
+
With a logged-in model, run end to end:
|
|
66
|
+
|
|
67
|
+
1. `/plan add a hello command`: the agent writes `<slug>-plan.md`, submits it, the plan view opens; approve and watch `jar_todo` fill from the Approach steps.
|
|
68
|
+
2. `/goal add a hello command with a test`: edits are blocked until tasks exist; the loop continues while tasks are open, then runs an audit and completes with evidence.
|
|
69
|
+
3. After an ordinary request, a dim suggestion appears in the input; <kbd>Tab</kbd> accepts it.
|
|
70
|
+
|
|
71
|
+
`/jar history` uses the public active-branch `getBranch()` snapshot and `ctx.ui.custom` overlays: `p`/`o` page, `/` search, `n`/`N` matches, `e` expand, `d`/`u` scroll details, `[`/`]` output chunks, <kbd>Esc</kbd> closes. It never mutates the branch.
|
|
72
|
+
|
|
73
|
+
## Development rules
|
|
74
|
+
|
|
75
|
+
- keep idle CPU and repaint overhead negligible (unref timers, render only on change);
|
|
76
|
+
- use Pi's public extension API; do not couple to other extensions' internals;
|
|
77
|
+
- keep role rendering generic;
|
|
78
|
+
- no decorative animation that carries no state; preserve behavior with motion off;
|
|
79
|
+
- never swallow pointer drags in pi-jar views (selection and copy-on-select belong to Pi);
|
|
80
|
+
- tolerate hosts without optional APIs (`registerTool`, `registerShortcut`, mouse).
|
|
81
|
+
|
|
82
|
+
## Startup performance
|
|
83
|
+
|
|
84
|
+
pi-jar adds about 0.2 s to Pi's first render (mostly module import). To keep startup lean it never blocks `session_start`: the provider quota lookup, the welcome's recent-session scan and its `git` calls start 1.5 s after the session starts, and the card and footer fill in when they finish.
|
|
85
|
+
|
|
86
|
+
Most startup time in a full setup comes from extension loading, which Pi does one package at a time. Measure a package by launching it alone (`pi -ne -e <path>`) and compare with `pi --no-extensions`. Large packages and ones installed from git (loaded as TypeScript source) cost the most, and the first launch after `pi update` is slow while Pi rebuilds its transpile cache. Keep rarely used packages out of the global `packages` list (load them with `-e`, or in project settings).
|
|
87
|
+
|
|
88
|
+
## Publishing
|
|
89
|
+
|
|
90
|
+
pi-jar is published to npm as `pi-jar`. The `pi-package` keyword lists it in the [Pi package gallery](https://pi.dev/packages), and `pi.image` in `package.json` supplies the gallery preview (the demo GIF, served from GitHub rather than shipped in the tarball).
|
|
91
|
+
|
|
92
|
+
1. `npm run check && npm test`
|
|
93
|
+
2. Bump `version` in `package.json`, commit and push.
|
|
94
|
+
3. `npm pack --dry-run` — the tarball holds `extensions/`, `src/`, `themes/`, `docs/*.md`, `README.md` and `LICENSE` only.
|
|
95
|
+
4. `npm login` (once), then `npm publish`.
|
package/docs/FLAME.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Flame and mascot
|
|
2
|
+
|
|
3
|
+
Both are original, dependency-free and rendered as plain terminal text inside Pi components.
|
|
4
|
+
|
|
5
|
+
## Welcome flame (`src/flame.ts`)
|
|
6
|
+
|
|
7
|
+
### Simulation
|
|
8
|
+
|
|
9
|
+
One continuous flame on a 21 × 24 grid of intensities `0…9`. The width is odd so the flame has a true center column, which also lines up with the `π` beneath it.
|
|
10
|
+
|
|
11
|
+
1. **Profile.** The half width at a height `h` (0 = base, 1 = tip) is a circular bulb below the belly (`h < 0.3`, up to 5.6 columns) and a smooth taper above it. The base is rounded and narrower than the belly, never a flat bar.
|
|
12
|
+
2. **Motion.** Everything moves through smooth, seeded value noise rather than per-cell randomness: the flame's height breathes, the axis sways and wanders (more at the tip than at the base), and the edges ripple upward — barely at the base, strongly near the tip, so the top licks while the bottom stays calm.
|
|
13
|
+
3. **Heat.** Each cell's heat falls off from the axis toward the rim (`1 − d^1.8`) and cools with height, so the core low in the flame is pale gold and the rim and tip are orange-red. A slow noise texture keeps the interior shimmering.
|
|
14
|
+
4. **Wisps.** Occasionally a small piece breaks off the tip, rises and fades (at most two at a time).
|
|
15
|
+
5. **Particles.** At most eight live particles lift off the upper flame near its axis. Embers rise at 0.3–0.8 rows/frame with a small drift, living 8–20 frames (`•` → `∙` → `·`, fading down the palette). Sparks (≈8% per frame) are fast, bright `✦`/`*` and last 2–4 frames. Particles only draw over empty cells and never on the outer columns.
|
|
16
|
+
|
|
17
|
+
Randomness comes from a seeded PRNG (mulberry32), and the simulation warms up for 28 steps. So `flameFrame(frame, seed)` is a pure function: tests are deterministic, motion-off shows a still-lit frame, and **Refresh** simply picks a new seed.
|
|
18
|
+
|
|
19
|
+
### Rendering
|
|
20
|
+
|
|
21
|
+
Two simulated rows share one terminal row through half blocks: `▀` with the upper cell as foreground and the lower cell as background (`▄` when only the lower cell is lit). The output is 12 rows × 21 columns, fixed width.
|
|
22
|
+
|
|
23
|
+
Palette (index 0 is transparent):
|
|
24
|
+
|
|
25
|
+
| Heat | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
|
26
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
27
|
+
| Color | `#2B0A05` | `#5C1407` | `#8F2207` | `#C7400C` | `#E8601A` | `#F58A24` | `#FFB23A` | `#FFD56A` | `#FFF3C4` |
|
|
28
|
+
|
|
29
|
+
Without 24-bit color (`COLORTERM` is not `truecolor`/`24bit`), cells become `░▒▓█` shaded with the theme's `dim`, `error` and `warning` colors.
|
|
30
|
+
|
|
31
|
+
The welcome ticks every 90 ms only while it is visible and motion is on. On terminals narrower than 32 columns the flame is cropped around its center.
|
|
32
|
+
|
|
33
|
+
## Ember, the composer mascot (`src/mascot.ts`)
|
|
34
|
+
|
|
35
|
+
Ember is two layers:
|
|
36
|
+
|
|
37
|
+
- a **face** in the composer's top border — always `( + three glyphs + )`, five columns wide in every mood, so the title never shifts;
|
|
38
|
+
- **flame tips** on the row above the frame, five columns wide, aligned over the face.
|
|
39
|
+
|
|
40
|
+
Moods come from Pi's observed activity plus local timers:
|
|
41
|
+
|
|
42
|
+
| Mood | Face | Tips | Trigger |
|
|
43
|
+
| --- | --- | --- | --- |
|
|
44
|
+
| idle | `(•ᴗ•)` | swaying `▴▲▴` | nothing happening |
|
|
45
|
+
| blink | `(-ᴗ-)` | still | 180 ms, every 3–6 s at random |
|
|
46
|
+
| happy / thinking | `(^ᴗ^)` / `(°ᴗ°)` | bouncing / orbiting `∙` | generating (alternates every few seconds) |
|
|
47
|
+
| tool | `(>ᴗ<)` | sparks `*` `·` | a tool is running |
|
|
48
|
+
| waiting | `(•o•)` | `?` | a dialog or question is open |
|
|
49
|
+
| sleepy | `(-ω-)` | dimmed, rising `z` | idle for two minutes |
|
|
50
|
+
| error | `(×_×)` | drooping `ˇ` | a run failed (3 s) |
|
|
51
|
+
| complete | `(★ᴗ★)` | star and sparks | a goal was completed (4 s) |
|
|
52
|
+
| poke | `(^o^)` | bounce | you clicked the face (1.5 s) |
|
|
53
|
+
|
|
54
|
+
Faces and tips are painted from the flame palette (pale-gold eyes, orange shell, redder when upset) or theme colors without 24-bit color. One unref'd 240 ms timer drives expressions, and it requests a render **only when the sprite actually changes**. Motion-off stops the timer and shows a calm face; turning the mascot off removes both layers. Below 40 columns the tips row is dropped.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Integrations
|
|
2
|
+
|
|
3
|
+
pi-jar presents public statuses from other extensions and owns its own session-local workflows (tasks, plans, goals, suggestions). It never reads another extension's private state. It targets the current `@earendil-works/*` Pi API; the legacy `@mariozechner/*` packages are not supported.
|
|
4
|
+
|
|
5
|
+
## Public data
|
|
6
|
+
|
|
7
|
+
The footer reads Pi's model, thinking level, context usage and git branch. It also shows the texts that other extensions publish with `ctx.ui.setStatus(key, text)`, which Pi exposes to custom footers through `footerData.getExtensionStatuses()`. Free-form status text stays free-form: pi-jar never infers roles, ordering or failure from prose.
|
|
8
|
+
|
|
9
|
+
## Opt-in role contract
|
|
10
|
+
|
|
11
|
+
An extension with authoritative teammate state can publish it:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
ctx.ui.setStatus("pi-jar.role.worker-17", JSON.stringify({
|
|
15
|
+
name: "API Builder", label: "API", state: "working", task: "implement",
|
|
16
|
+
expiresAt: Date.now() + 30_000
|
|
17
|
+
}));
|
|
18
|
+
// Refresh before expiry while it is live; clear it when finished.
|
|
19
|
+
ctx.ui.setStatus("pi-jar.role.worker-17", undefined);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- Key suffix: lowercase alphanumerics and hyphens, 1–32 characters.
|
|
23
|
+
- `name` is required. `label` and `task` are optional human-readable strings.
|
|
24
|
+
- `state`: `idle | thinking | working | waiting | reviewing | done | failed`.
|
|
25
|
+
- `expiresAt`: epoch milliseconds, in the future and at most 30 s ahead. An expired, malformed or unsupported entry displays as `<id>: unavailable` until the publisher updates or clears it.
|
|
26
|
+
- Fields are sanitized and bounded. The JSON may be at most 4096 characters.
|
|
27
|
+
|
|
28
|
+
The welcome card's **TEAM** row and the footer roles use this data. Without a publisher, no teammate is shown.
|
|
29
|
+
|
|
30
|
+
## Quota publisher (preferred over the network fallback)
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
ctx.ui.setStatus("pi-jar.quota.openai-codex", JSON.stringify({
|
|
34
|
+
fiveHour: { used: 42 }, week: { used: 15 },
|
|
35
|
+
expiresAt: Date.now() + 60_000
|
|
36
|
+
}));
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- `used` is a percentage from 0 to 100. Either window may be omitted, and each can carry an optional `resetsAt` (epoch milliseconds).
|
|
40
|
+
- `expiresAt` is required and may be at most five minutes ahead. A valid published status always wins.
|
|
41
|
+
- `/jar quota on` (the default each session) lets pi-jar resolve the current Anthropic or OpenAI Codex OAuth credentials through Pi's model registry and make a **read-only** request to the provider's quota endpoint when nothing is published.
|
|
42
|
+
- Requests have a 5 s timeout and results (including failures) are cached for 5 minutes. `/jar quota off` cancels pending requests and clears the cache.
|
|
43
|
+
- These provider endpoints are not stable public APIs.
|
|
44
|
+
|
|
45
|
+
## Session entries owned by pi-jar
|
|
46
|
+
|
|
47
|
+
| Custom type | Contents | Replay |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| `pi-jar.task` | versioned to-do events (`write`, `add`, `edit`, `status`, `delete`; legacy `toggle` accepted) | active branch on start, tree navigation and compaction |
|
|
50
|
+
| `pi-jar.goal` | goal events (`set`, `status`, `round`; v1 `set`/`clear` accepted) | active branch |
|
|
51
|
+
| `pi-jar.plan` | plan state (`enabled`, `steps`, `text`, `path`, `title`) | active branch |
|
|
52
|
+
|
|
53
|
+
Hidden context messages (`pi-jar.plan-context`, `pi-jar.plan-reminder`, `pi-jar.goal-context`, `pi-jar.goal-continuation`, `pi-jar.suggest-reminder`) are filtered or deduplicated in the `context` hook, so they never accumulate.
|
|
54
|
+
|
|
55
|
+
## Tools pi-jar registers
|
|
56
|
+
|
|
57
|
+
| Tool | Purpose |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `jar_todo` | branch-aware checklist: `todos` full-list writes (`content`, `status` pending/in_progress/completed, `activeForm`), plus `list`, `add`, `start`, `done`, `open`, `edit`, `delete` |
|
|
60
|
+
| `jar_ask` | structured questions answered in the TUI |
|
|
61
|
+
| `jar_plan_submit` | submit a plan file for review (plan mode only) |
|
|
62
|
+
| `jar_goal` | `get`, `complete` (with evidence, audit phase only), `block` |
|
|
63
|
+
| `jar_suggest` | one next-prompt suggestion shown as composer ghost text |
|
|
64
|
+
| `jar_shell` | background shells: `start` (`command`, `name`, `watch`, `notify`), `list`, `output`, `kill` |
|
|
65
|
+
| `jar_delegate` | up to four parallel subagents (`tasks: [{task, name?, role?}]`, `write?`) |
|
|
66
|
+
| `jar_advisor` | second opinion from the `advisor` role (`question?`, `draft?`) |
|
|
67
|
+
|
|
68
|
+
`jar_shell` events arrive as a visible `pi-jar.shell` custom message that triggers (or queues) an agent turn. `jar_delegate` runs child processes with `PI_JAR_CHILD=1`, which keeps pi-jar in the child from registering `jar_delegate` again, and publishes each running subagent through the role contract above as `pi-jar.role.delegate-<batch>-<n>`. The advisor publishes `pi-jar.role.advisor` while it is consulting, and its `/advisor` and gate answers arrive as visible `pi-jar.advisor` custom messages.
|
|
69
|
+
|
|
70
|
+
## Commands that overlap other packages
|
|
71
|
+
|
|
72
|
+
pi-jar registers `/usage`, `/context` and `/advisor`. Pi keeps both commands when two extensions register the same name and suffixes the later one (for example `/usage:2`), so remove packages whose commands you no longer need (such as a separate usage, context or advisor extension) to keep the plain names on pi-jar.
|
|
73
|
+
|
|
74
|
+
## Working signals and other managers
|
|
75
|
+
|
|
76
|
+
Working wording, icon colors and Ember's moods use only Pi's public agent, turn, UI-prompt and tool-execution events. "Thinking" means active generation, not access to hidden reasoning. Motion stops when animations are off, the run settles, the UI is disabled or the session shuts down.
|
|
77
|
+
|
|
78
|
+
`/jar hub` lists installed extension commands `/tasks` and `/subagents-fleet` when present and opens the one you pick. It never reads their data or replaces their controls.
|
|
79
|
+
|
|
80
|
+
## Editor and footer ownership
|
|
81
|
+
|
|
82
|
+
`/jar composer on` wraps an existing custom editor factory if another extension installed one, or otherwise replaces Pi's editor with a `CustomEditor` subclass that keeps Pi's application keybindings. `/jar composer off` restores only a factory pi-jar still owns and keeps the draft. `/jar ui off` gives the footer back to Pi.
|