@aemonge-dev/pi-stardeck 0.0.0-stage → 0.5.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 +239 -2
- package/demo/pi-stardeck.tape +59 -0
- package/docs/architecture.md +103 -0
- package/docs/assets/pi-stardeck.gif +0 -0
- package/docs/development.md +128 -0
- package/licenses/README.md +17 -0
- package/licenses/pi-fancy-footer-LICENSE +21 -0
- package/licenses/pi-vim-LICENSE +21 -0
- package/package.json +81 -4
- package/packages/pi-fancy-footer-full-palette/LICENSE +21 -0
- package/packages/pi-fancy-footer-full-palette/LOCAL-CHANGES.md +41 -0
- package/packages/pi-fancy-footer-full-palette/README.md +468 -0
- package/packages/pi-fancy-footer-full-palette/package.json +52 -0
- package/packages/pi-fancy-footer-full-palette/src/api.ts +204 -0
- package/packages/pi-fancy-footer-full-palette/src/config-editor.ts +634 -0
- package/packages/pi-fancy-footer-full-palette/src/config.ts +852 -0
- package/packages/pi-fancy-footer-full-palette/src/data-widgets.ts +259 -0
- package/packages/pi-fancy-footer-full-palette/src/git.ts +130 -0
- package/packages/pi-fancy-footer-full-palette/src/index.ts +479 -0
- package/packages/pi-fancy-footer-full-palette/src/layout.ts +309 -0
- package/packages/pi-fancy-footer-full-palette/src/provider-status.ts +1466 -0
- package/packages/pi-fancy-footer-full-palette/src/render.ts +1061 -0
- package/packages/pi-fancy-footer-full-palette/src/shared.ts +903 -0
- package/packages/pi-stardeck/README.md +219 -0
- package/packages/pi-stardeck/index.ts +691 -0
- package/packages/pi-stardeck/package.json +32 -0
- package/packages/pi-stardeck/src/activity-age.ts +184 -0
- package/packages/pi-stardeck/src/capabilities.ts +105 -0
- package/packages/pi-stardeck/src/deck.ts +807 -0
- package/packages/pi-stardeck/src/gauge.ts +1323 -0
- package/packages/pi-stardeck/src/git-refresh.ts +5 -0
- package/packages/pi-stardeck/src/process-resources.ts +428 -0
- package/packages/pi-stardeck/src/title-state.ts +195 -0
- package/packages/pi-stardeck/src/title.ts +443 -0
- package/packages/pi-vim-top-border/LICENSE +21 -0
- package/packages/pi-vim-top-border/LOCAL-CHANGES.md +71 -0
- package/packages/pi-vim-top-border/README.md +577 -0
- package/packages/pi-vim-top-border/clipboard-mirror.ts +451 -0
- package/packages/pi-vim-top-border/clipboard-policy.ts +23 -0
- package/packages/pi-vim-top-border/cursor-shape.ts +131 -0
- package/packages/pi-vim-top-border/index.ts +4195 -0
- package/packages/pi-vim-top-border/input-keys.ts +49 -0
- package/packages/pi-vim-top-border/mode-change-command.ts +120 -0
- package/packages/pi-vim-top-border/mode-colors.ts +97 -0
- package/packages/pi-vim-top-border/mode-label.ts +62 -0
- package/packages/pi-vim-top-border/motions.ts +297 -0
- package/packages/pi-vim-top-border/package.json +47 -0
- package/packages/pi-vim-top-border/prompt-external-editor.ts +152 -0
- package/packages/pi-vim-top-border/prompt-rail.ts +334 -0
- package/packages/pi-vim-top-border/prompt-status.ts +131 -0
- package/packages/pi-vim-top-border/settings.ts +287 -0
- package/packages/pi-vim-top-border/text-objects.ts +389 -0
- package/packages/pi-vim-top-border/types.ts +51 -0
- package/packages/pi-vim-top-border/visual.ts +65 -0
- package/packages/pi-vim-top-border/word-boundary-cache.ts +196 -0
- package/packages/status/README.md +398 -0
- package/packages/status/index.ts +1717 -0
- package/packages/status/package.json +33 -0
- package/packages/status/src/active-work.ts +235 -0
- package/packages/status/src/config.ts +218 -0
- package/packages/status/src/diagnostics.ts +238 -0
- package/packages/status/src/goal-block.ts +377 -0
- package/packages/status/src/goal.ts +170 -0
- package/packages/status/src/ledger.ts +101 -0
- package/packages/status/src/openspec.ts +394 -0
- package/packages/status/src/orchestration.ts +237 -0
- package/packages/status/src/publisher.ts +1294 -0
- package/packages/status/src/reducer.ts +190 -0
- package/packages/status/src/runtime-runs.ts +267 -0
- package/packages/status/src/state.ts +178 -0
- package/packages/status/src/title-activity.ts +224 -0
- package/packages/status/src/title-state.ts +218 -0
- package/packages/status/src/turn-cost.ts +63 -0
- package/packages/status/src/types.ts +228 -0
- package/src/deck-surface.ts +46 -0
- package/src/health.ts +228 -0
- package/src/index.ts +28 -0
- package/src/pi-status.ts +334 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# pi-stardeck
|
|
2
|
+
|
|
3
|
+
A dependency-free Pi extension that coordinates the prompt information architecture
|
|
4
|
+
through Pi's supported widget and event APIs.
|
|
5
|
+
|
|
6
|
+
```text
|
|
7
|
+
─ › ─────────────────────────────────────────────────────────────────────
|
|
8
|
+
( 3 › 2 · 00:05'12) working ⟩ checking Stabilize runtime and focus · step 3/5 task 1/2 › stps 3/5
|
|
9
|
+
Stabilize runtime and focus in the cockpit
|
|
10
|
+
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
|
|
11
|
+
[] ~/projects/example main ⟩ clean
|
|
12
|
+
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
|
|
13
|
+
Opus › high ⟩ 42% › 2 10% › $0.10 ⟩ 12% › 375M › 3/3
|
|
14
|
+
─ ─────────────────────────────────────────────────────────────── ‹ ─
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The preferred editor-deck surface keeps two stable semantic rows. The first is a
|
|
18
|
+
left-packed operational strip: runtime capsule, lifecycle, activity, controlled next
|
|
19
|
+
action, and Task/Step progress. The second is a full-width explicit selection canvas
|
|
20
|
+
that wraps to at most two lines. Every slot remains present; zero, idle, unavailable,
|
|
21
|
+
and unselected states are dim instead of appearing or disappearing. Long content may
|
|
22
|
+
wrap responsively, but runtime state never changes the deck topology. Decorative rails
|
|
23
|
+
remain slim and contain no telemetry.
|
|
24
|
+
|
|
25
|
+
The editor deck uses blue for the active runtime capsule, the bold lifecycle anchor,
|
|
26
|
+
and regular-weight explicit selection. Ordinary active activity remains neutral, except
|
|
27
|
+
that `recovering` and its ordinary suggestion are blue together while only the lifecycle
|
|
28
|
+
is bold. Other ordinary suggestions remain green. Incomplete Task/Step progress is
|
|
29
|
+
neutral until each counter completes and stays right-aligned without a major boundary.
|
|
30
|
+
The lifecycle/activity boundary and rails remain purple; minor separators are dim.
|
|
31
|
+
Human-input and validation cues stay yellow, blockers stay red, and every inactive value
|
|
32
|
+
stays dim.
|
|
33
|
+
|
|
34
|
+
The legacy above-editor widget owns only current work identity and preserves the
|
|
35
|
+
` ready ⟩ no focused task` idle row when no work is selected. The leading icon is
|
|
36
|
+
runtime-authoritative: `` while Pi is busy in an active lifecycle and `` while
|
|
37
|
+
settled, waiting, blocked, listening, or aborted. Internal lifecycle states render as
|
|
38
|
+
short readable verbs. The Ramona loop remains exact: `understand`, `work`, `assure`,
|
|
39
|
+
`learn`, and `answer`. Runtime boundaries are `wait`, `blocked`, `ready`, or `stopped`.
|
|
40
|
+
The title has four styled groups: lifecycle, a structured active ancestry, focus, and
|
|
41
|
+
optional focus detail. Each activity-path segment receives the blue minor `›`; the
|
|
42
|
+
violet-pink major `⟩` divides runtime ancestry from the green narrative focus. Human
|
|
43
|
+
prompt text is never converted into focus automatically. OpenSpec may add its exact Task
|
|
44
|
+
after another green `›`. Focus selection prefers an exact OpenSpec Task, then Goal, then
|
|
45
|
+
Session Work. Active turns without a selection use the explicit `OpenSpec › no focus`,
|
|
46
|
+
`no OpenSpec`, or `no focus` state supplied by the status producer; `Direct response` is
|
|
47
|
+
never presented as a focus. Empty states are dim while real focus remains bold semantic
|
|
48
|
+
green.
|
|
49
|
+
|
|
50
|
+
Wide rows render lifecycle → active ancestry → optional focus → optional focus detail,
|
|
51
|
+
for example `assure › checking quality › assuring tests ⟩ Implement global flow`. The
|
|
52
|
+
renderer generates every separator. Empty or rejected paths leave no separator or
|
|
53
|
+
placeholder whitespace. As width falls it tries full labels, compact labels, a collapsed
|
|
54
|
+
`… › deepest` ancestry, and finally compact lifecycle plus the deepest active segment.
|
|
55
|
+
Narrative focus disappears before meaningful active ancestry. Terminal display-cell
|
|
56
|
+
measurement and final truncation remain Unicode- and Nerd-Font-aware.
|
|
57
|
+
|
|
58
|
+
Runtime anchor and lifecycle are bold blue `#076678`; activity ancestry and its minor
|
|
59
|
+
`›` are regular blue; the major `⟩` is purple; focus is bold semantic success green; and
|
|
60
|
+
optional focus hierarchy is regular success green. Dim is reserved for the two empty
|
|
61
|
+
focus fallbacks; muted, text, cyan, yellow, and gray are never used in the title.
|
|
62
|
+
|
|
63
|
+
The extension hides Pi's separate built-in `Working...` loader row with
|
|
64
|
+
`ctx.ui.setWorkingVisible(false)`, including its vertical space. The header therefore
|
|
65
|
+
uses its complete width for lifecycle, bounded activity, and focus. Runtime age is
|
|
66
|
+
published for the bottom prompt rail as an eight-cell chronometer measuring time since
|
|
67
|
+
the most recent observed foreground provider, assistant, or tool event. It stays
|
|
68
|
+
fixed-width as it advances: `00:00'00`, `00:00'45`, `00:12'30`, or `12:34'56`; hour/day
|
|
69
|
+
fallbacks also remain eight cells. Active timing uses the high-contrast deep-cyan
|
|
70
|
+
`accent` color; settled states display dim `00:00'00` rather than repeating the header's
|
|
71
|
+
`wait`, `ready`, or other lifecycle word. A session-scoped ticker publishes only when
|
|
72
|
+
the formatted chronometer changes and is cleared on shutdown. No message content,
|
|
73
|
+
thinking, reasoning, prompts, tool arguments, or child-agent output enters the widget.
|
|
74
|
+
|
|
75
|
+
The additive header protocol projects selection independently from live work:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
selection: {
|
|
79
|
+
source: 'openspec' | 'goal' | 'session-work';
|
|
80
|
+
titles: string[]; // one or two bounded, normalized titles
|
|
81
|
+
color: HeaderColor;
|
|
82
|
+
} | null;
|
|
83
|
+
suggestion: HeaderSuggestion | null; // controlled enum, never generated prose
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Selection priority remains exact OpenSpec Task, Goal, then Session Work. Older
|
|
87
|
+
protocol-1 events may use sanitized non-placeholder work titles as a legacy selection;
|
|
88
|
+
explicit malformed selection is rejected rather than borrowing a fallback. The
|
|
89
|
+
suggestion vocabulary is producer-owned, appears only in waiting, blocked, approval,
|
|
90
|
+
or aborted states, and is bounded to reporting cues such as
|
|
91
|
+
`requesting validation or redirection`, `awaiting continuation`, and
|
|
92
|
+
`requesting redirection`. While work is active, the same slot reports the current
|
|
93
|
+
WHAT: the focused task title with live step progress.
|
|
94
|
+
|
|
95
|
+
The preferred activity contract is a structured path that never stores separators:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
work.activityPath?: Array<{
|
|
99
|
+
id: string; // lowercase letters, digits, and hyphens; at most 48 code points
|
|
100
|
+
label: string; // one line; normalized to at most 48 code points
|
|
101
|
+
compact?: string; // normalized to at most 24 code points
|
|
102
|
+
current?: number;
|
|
103
|
+
total?: number;
|
|
104
|
+
}>; // at most six unique segments; lifecycle is not duplicated here
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
An explicit valid array, including `[]`, takes precedence. A malformed array is rejected
|
|
108
|
+
as a whole and falls back to the legacy allowlisted `work.activity` field. Legacy
|
|
109
|
+
activity is normalized to one internal segment, preserving existing producers until they
|
|
110
|
+
migrate. Progress is bounded to `0..9,999` and appended as `current/total` only when
|
|
111
|
+
both values are valid.
|
|
112
|
+
|
|
113
|
+
The consumer removes ANSI escapes and control characters, normalizes whitespace, rejects
|
|
114
|
+
empty labels and malformed or duplicate IDs, and fails soft. Semantic safety remains a
|
|
115
|
+
producer obligation: labels must be bounded display vocabulary, never prompts, commands,
|
|
116
|
+
paths, secrets, generated paragraphs, or tool output. The consumer cannot infer those
|
|
117
|
+
semantics from arbitrary text. The future global-flow producer selects one primary
|
|
118
|
+
active path; completed, skipped, sibling, and parallel aggregation remain out of scope.
|
|
119
|
+
|
|
120
|
+
The legacy `work.activity` enum remains temporarily supported. Its renderer-owned labels
|
|
121
|
+
convert operation starts such as `inspection` and `mutation` into
|
|
122
|
+
`inspecting project context` and `updating selected files`. Their bounded completion
|
|
123
|
+
transitions render as `finalizing current request`, `reviewing applied changes`, or
|
|
124
|
+
`reviewing check results`; unknown kinds and raw activity text remain omitted.
|
|
125
|
+
|
|
126
|
+
The extension refreshes bounded local Git branch and status data at session start, after
|
|
127
|
+
successful mutating tools, and when the agent settles. Footer row one keeps project
|
|
128
|
+
identity on the left and work scope on the right. The bold PWD is shown in full relative
|
|
129
|
+
to home (`/home/aemonge/projects/example` → `~/projects/example`) and yields ANSI-safely
|
|
130
|
+
only when the terminal cannot preserve both aligned groups. Git branch and state follow
|
|
131
|
+
a blue minor `›`. Outside a repository, one dim responsive `› (no Git)` state fills
|
|
132
|
+
the otherwise missing project slot and yields before core project/work information on
|
|
133
|
+
narrow terminals. Slash-prefixed Git branches collapse the prefix to its initial and cap
|
|
134
|
+
display at 30 cells with `...` (`feat/persist-versioned-prompts-in-duckdb` →
|
|
135
|
+
`f/persist-versioned-prompts...`). The right side shows compact OpenSpec Plan/Task
|
|
136
|
+
progress, or the simple Goal, Focus, or `no OpenSpec` fallback when no OpenSpec
|
|
137
|
+
portfolio is available. The footer reserves a four-cell visual split between alignment
|
|
138
|
+
groups. OpenSpec uses icons instead of repeated labels: task-list `` for Plans and
|
|
139
|
+
notebook `` for Tasks, with minor `›` between them. Their Nerd Font glyphs exactly
|
|
140
|
+
match Starship: ``, ``, ``, ``, and ``. When `DEVBOX_PROJECT_ROOT` is present, the
|
|
141
|
+
PWD begins `[] ~/project`; the boxed Devbox marker precedes the folder icon without
|
|
142
|
+
exposing the variable's value. The top prompt rail may prepend MCP availability to work
|
|
143
|
+
progress as ` healthy/total ⟩ Plans › Tasks`. MCP status comes only from the live
|
|
144
|
+
`pi-mcp-adapter/status/v1` feed; lazy cached or not-yet-connected servers remain
|
|
145
|
+
available, while failed or authentication-blocked servers reduce the numerator. This is
|
|
146
|
+
availability telemetry, not a tool-call counter. Before the first valid snapshot, or
|
|
147
|
+
when status is empty or malformed, the segment remains visible as dim ` 0/0`. The
|
|
148
|
+
entire segment yields before right-aligned work progress is truncated. Neovim LSP
|
|
149
|
+
inventory is intentionally neither collected nor shown because it does not establish an
|
|
150
|
+
agent-usable LSP capability. Plugin and extension inventory is not shown without a
|
|
151
|
+
trustworthy runtime health source. Adjacent left and right segments use the same Gruvbox
|
|
152
|
+
colors as the configured Starship prompts: blue `#076678`, green `#79740e`, bright green
|
|
153
|
+
`#689d6a`, aqua `#427b58`, yellow `#b57614`, orange `#af3a03`, major-separator Gruvbox
|
|
154
|
+
purple `#b16286`, blue-violet `#5c5ca8`, and red `#9d0006`. Project, Git, work-scope,
|
|
155
|
+
model, quota, and local telemetry avoid generic gray; only missing Git and the runtime
|
|
156
|
+
chronometer are deliberately dim. PWD and model identity share the same blue anchor
|
|
157
|
+
color; reasoning retains its own level color. The single footer row keeps PWD and Git on
|
|
158
|
+
the left and model, reasoning, and quota on the right. Other bounded widget snapshots
|
|
159
|
+
feed the prompt rails: mode alone on the left and optional MCP availability plus work
|
|
160
|
+
progress on the right of the top rail; chronometer left and context, compactions,
|
|
161
|
+
memory, CPU, and cost right on the bottom rail. A major separator distinguishes model
|
|
162
|
+
context from process resources. On wide terminals the footer ends with the dedicated
|
|
163
|
+
five-cell avatar tail `⟨ `: a purple left-pointing boundary, violet ladybug, and one
|
|
164
|
+
blank cell to her right. Each rail aligns its own groups independently, so the header is
|
|
165
|
+
never padded for cross-row alignment. CPU is normalized against Pi's available logical
|
|
166
|
+
CPU capacity and capped at 100%, so the number reads as whole-machine share rather than
|
|
167
|
+
one-core units. CPU and RAM are blue normally and independently turn yellow only for
|
|
168
|
+
sustained CPU pressure above 80% or unusually high session memory; one resource warning
|
|
169
|
+
does not recolor its neighbors. Pink and red are never used in these three telemetry
|
|
170
|
+
groups. In the title, lifecycle and bounded activity are blue; the major boundary is
|
|
171
|
+
purple; real focus and optional Task hierarchy are green; empty focus fallbacks and the
|
|
172
|
+
footer runtime age/state are dim. Persistent cache-hit presentation is disabled, while
|
|
173
|
+
Fancy Footer retains its internal cache accounting. Compaction count is hidden at zero.
|
|
174
|
+
The first deck row always begins with the compact runtime capsule
|
|
175
|
+
`( children › subagents · 00:00'00)`. Each zero count and the settled timer remain
|
|
176
|
+
dim in place; a live count or timer changes color without moving neighboring content.
|
|
177
|
+
The active-run aggregate no longer appears in the lower resource row. Final
|
|
178
|
+
narrow-width fitting remains ANSI-aware and removes exposed trailing separators. The
|
|
179
|
+
renderer never shows the main Pi process, historical worker totals, completed-file
|
|
180
|
+
progress, queued subagent placeholders, or runtime identity and output fields.
|
|
181
|
+
Quota is reduced to the most constrained provider-reported percentage with no weekly
|
|
182
|
+
analysis. Cost is Pi's native estimated session cost in USD, rendered without trailing
|
|
183
|
+
fractional zeros; its preceding `⟩` retains the shared purple major-boundary color while
|
|
184
|
+
the value remains blue. No local daily aggregation or currency conversion is performed.
|
|
185
|
+
No center group or gauges are used. The local Fancy Footer fork expands its widget
|
|
186
|
+
protocol to accept these native theme tokens. The narrative lifecycle header begins with
|
|
187
|
+
its active/passive terminal icon; the prompt border keeps only its right-aligned vi-mode
|
|
188
|
+
glyph. Concurrent Git refreshes coalesce without polling.
|
|
189
|
+
|
|
190
|
+
Agent-environment, context, CPU, RAM, and compaction widgets use the same Fancy Footer
|
|
191
|
+
protocol, including producer-requested bold text for the PWD. Every three seconds on
|
|
192
|
+
Linux, the extension discovers only Pi descendants through bounded
|
|
193
|
+
`/proc/<pid>/task/<pid>/children` reads, then reads their `stat` and `status` records
|
|
194
|
+
without shelling out or retaining process names, arguments, or paths. Memory sums
|
|
195
|
+
private anonymous resident pages (`RssAnon`) instead of counting shared file-backed
|
|
196
|
+
pages once per process. Individual status-read failures fall back to that process's RSS;
|
|
197
|
+
unavailable `/proc` falls back honestly to current-process CPU and RSS. Sampling,
|
|
198
|
+
smoothing, publication, timers, and resource widgets are session-scoped and cleaned up
|
|
199
|
+
on shutdown. The local Fancy Footer fork owns cache, quota, and session-cost collection.
|
|
200
|
+
When the footer reports quota windows, the compact telemetry row paints icon-native
|
|
201
|
+
tiles in cost, long-window, coding-window order — ` $5.21 ⟩ 12% ⟩ 62% › 1:45`.
|
|
202
|
+
The flame is the coding window's permanent icon and always carries the clock
|
|
203
|
+
countdown; 80% used turns a tile's accent color into a warning. Without windows the
|
|
204
|
+
slot degrades to the single footer-reported percent, and without telemetry it stays a
|
|
205
|
+
dim dash.
|
|
206
|
+
Unavailable temperature and unsupported environment claims are hidden; environment
|
|
207
|
+
classification defaults honestly to `host` unless an explicit supported marker exists.
|
|
208
|
+
|
|
209
|
+
## Test
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
npm install
|
|
213
|
+
npm run check
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Remove
|
|
217
|
+
|
|
218
|
+
Delete `./packages/pi-stardeck` from `.pi/agent/settings.json`, remove this
|
|
219
|
+
directory, and run `/reload`.
|