@henryqw/pi-footer 4.1.1 → 4.1.3
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/README.md +21 -21
- package/extensions/footer.ts +4 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `@henryqw/pi-footer`
|
|
2
2
|
|
|
3
|
-
Keep
|
|
3
|
+
Keep footer identity, model usage, agent-work time, and extension status visible while you work in Pi. Use `/open` to open the current working directory. `/open` uses VS Code by default, or another configured command. You can enable the footer and the open commands independently.
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
@@ -10,16 +10,16 @@ Keep checkout identity, model usage, elapsed agent work, and extension status vi
|
|
|
10
10
|
pi install npm:@henryqw/pi-footer
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
This package requires Pi 1.1.0 or later in the 1.x series.
|
|
14
14
|
|
|
15
|
-
Version 3 replaces `@henryqw/pi-open-in`. If
|
|
15
|
+
Version 3 replaces `@henryqw/pi-open-in`. If it is installed, remove it before you upgrade. This prevents duplicate `/open` and `/set-open-in` commands:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
pi remove npm:@henryqw/pi-open-in
|
|
19
19
|
pi install npm:@henryqw/pi-footer
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
For project-local installs, use `--local` on both commands.
|
|
22
|
+
For project-local installs, use `--local` on both commands. Also remove manually configured paths to the old package. Then restart Pi. The existing open-command config stays at `config/pi-open-in/config.json`. Do not move it.
|
|
23
23
|
|
|
24
24
|
Both entry points load by default. To use `/open` without the custom footer, use Pi's native package resource filter in `settings.json`:
|
|
25
25
|
|
|
@@ -34,7 +34,7 @@ Both entry points load by default. To use `/open` without the custom footer, use
|
|
|
34
34
|
}
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
To use only the footer, select `extensions/footer.ts` instead. You can also use `pi config` to toggle either resource. You do not need package activation config.
|
|
38
38
|
|
|
39
39
|
## Works with
|
|
40
40
|
|
|
@@ -47,11 +47,11 @@ Select `extensions/footer.ts` instead for only the footer, or use `pi config` to
|
|
|
47
47
|
|
|
48
48
|
## Use
|
|
49
49
|
|
|
50
|
-
After
|
|
50
|
+
After installation, start a Pi TUI session. The footer shows checkout, usage, model, thinking, and extension statuses. Run `/open` to open the current working directory in VS Code by default. `/open` also works while the agent is busy.
|
|
51
51
|
|
|
52
52
|
| Surface | Type | Purpose |
|
|
53
53
|
| --- | --- | --- |
|
|
54
|
-
| Footer | ui | Shows
|
|
54
|
+
| Footer | ui | Shows footer identity, usage, model, agent-work time, and extension statuses. |
|
|
55
55
|
| `/open` | command | Opens the current working directory with the configured command. |
|
|
56
56
|
| `/set-open-in <command>` | command | Sets the command used by `/open`. |
|
|
57
57
|
|
|
@@ -63,9 +63,9 @@ pi-harness · clear-field-f8d2 [+2 ~3 ?1 ↑2] · PR #123 · approved Codex #
|
|
|
63
63
|
✓ CG · ● 🐴 ponytail: ⚡ FULL ◷ 12m 34s
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
- The first line shows the repository, branch, Git state, and `pi-pr` pull request status beside the
|
|
67
|
-
- The second line shows cumulative input tokens, output tokens, latest cache-hit rate, and tokens per second for the most recent assistant response. The rate is timed from the
|
|
68
|
-
- The third line shows CodeGraph's icon and `CG` first: `✓ CG` when indexed, `○ CG` when a Git repository has no index, or a dim spinner and elapsed time such as `⠋ CG · indexing 8s` during setup. Non-Git directories show no index badge. Other extension statuses follow, such as `⠋ deps · installing 12s
|
|
66
|
+
- The first line shows the repository, branch, Git state, and `pi-pr` pull request status beside the footer identity. The `pi-multi-codex` quota status, when non-empty, occupies the right side. Linked-worktree branches drop the generated `worktree/` prefix.
|
|
67
|
+
- The second line shows cumulative input tokens, output tokens, latest cache-hit rate, and tokens per second for the most recent assistant response. The rate is timed from the first streamed content of the response to the last. Thus, the rate excludes request latency, time to first token, and provider work after the stream ends (such as the Claude bridge shutdown of Claude Code). A response that arrives without streamed content, or all at once, shows `—`. It also shows estimated cost and context usage. Totals include reported tool usage and finished `pi-subagent` background workflows. The active model and thinking level are right-aligned. Under a virtual model, the physical model and thinking level of the latest successful response follow an arrow, for example `auto • high → gpt-5.6-luna • medium`. This matches Pi's built-in footer.
|
|
68
|
+
- The third line shows CodeGraph's icon and `CG` first: `✓ CG` when indexed, `○ CG` when a Git repository has no index, or a dim spinner and elapsed time such as `⠋ CG · indexing 8s` during setup. Non-Git directories show no index badge. Other extension statuses follow, such as `⠋ deps · installing 12s`. Dependency preparation statuses disappear when work completes. Persistent CodeGraph failures keep their theme-colored `!` icon and meaningful text. During direct `codegraph_explore` calls, `● CG` temporarily replaces the CodeGraph status. The status returns when the call finishes. A middle dot separates statuses. Cumulative agent-work time stays on the right, below the active model.
|
|
69
69
|
|
|
70
70
|
Git badges appear only when action is needed:
|
|
71
71
|
|
|
@@ -78,7 +78,7 @@ Git badges appear only when action is needed:
|
|
|
78
78
|
| `↑2` | Two commits ahead of the upstream branch |
|
|
79
79
|
| `↓1` | One commit behind the upstream branch |
|
|
80
80
|
|
|
81
|
-
`?N` counts porcelain status entries. In `--untracked-files=normal` mode, Git
|
|
81
|
+
`?N` counts porcelain status entries. In `--untracked-files=normal` mode, Git can collapse a whole untracked directory to one entry.
|
|
82
82
|
|
|
83
83
|
Active operations appear first, such as `REBASE 3/7`, `MERGING`, or `CHERRY-PICKING`. Detached HEAD uses the short commit form `@a1b2c3d`.
|
|
84
84
|
|
|
@@ -90,9 +90,9 @@ Unavailable values render as `—` without a misleading percent sign.
|
|
|
90
90
|
|
|
91
91
|
`ultra` renders as a rainbow when the active Pi runtime supplies that thinking level. Unsupported levels never appear.
|
|
92
92
|
|
|
93
|
-
Only the non-empty `pi-multi-codex` quota status occupies the right side of the first line. The `pi-pr` pull-request status stays beside
|
|
93
|
+
Only the non-empty `pi-multi-codex` quota status occupies the right side of the first line. The `pi-pr` pull-request status stays beside footer identity, and CodeGraph index status, setup progress, or tool activity appears separately on the third line.
|
|
94
94
|
|
|
95
|
-
Statuses from other extensions, including Ponytail and `pi-rewind`, share the left side of the third line. They are sorted by key
|
|
95
|
+
Statuses from other extensions, including Ponytail and `pi-rewind`, share the left side of the third line. They are sorted by key. Colors, links, glyphs, and interior spacing are preserved. Leading and trailing whitespace is trimmed, line breaks become spaces, and long statuses can be clipped to fit the footer. Only direct `codegraph_explore` tool calls trigger the `● CG` badge. The footer does not show CodeGraph queries from inside scripted tools.
|
|
96
96
|
|
|
97
97
|
## Config
|
|
98
98
|
|
|
@@ -100,13 +100,13 @@ Package-owned: `~/.pi/agent/config/pi-open-in/config.json` (under `getAgentDir()
|
|
|
100
100
|
|
|
101
101
|
| Name | Description | Values | Default |
|
|
102
102
|
| --- | --- | --- | --- |
|
|
103
|
-
| `command` | Command
|
|
103
|
+
| `command` | Command that `/open` runs. Required when the file exists. | Non-empty string. | `"code"` |
|
|
104
104
|
|
|
105
|
-
A missing file silently uses the default command, `code`. An invalid existing file makes `/open` fail visibly and
|
|
105
|
+
A missing file silently uses the default command, `code`. An invalid existing file makes `/open` fail visibly and stays unchanged. See Limits and recovery. `/open` reads the config on every run. Only `/set-open-in` writes the file, atomically. Reads do not create or write the config home.
|
|
106
106
|
|
|
107
107
|
## API
|
|
108
108
|
|
|
109
|
-
Consumers
|
|
109
|
+
Consumers: use the owner API. Do not read the config file directly. Replace imports from `@henryqw/pi-open-in/open-uri` with `@henryqw/pi-footer/open-uri`:
|
|
110
110
|
|
|
111
111
|
```ts
|
|
112
112
|
import { loadOpenInConfig } from "@henryqw/pi-footer/open-uri";
|
|
@@ -114,7 +114,7 @@ import { loadOpenInConfig } from "@henryqw/pi-footer/open-uri";
|
|
|
114
114
|
const { source, value } = loadOpenInConfig();
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
These exports
|
|
117
|
+
These exports are for package consumers. The commands in Use are the Pi interfaces.
|
|
118
118
|
|
|
119
119
|
| Surface | Type | Purpose |
|
|
120
120
|
| --- | --- | --- |
|
|
@@ -123,18 +123,18 @@ These exports serve package consumers; the commands in Use are the Pi interfaces
|
|
|
123
123
|
| `loadOpenInConfig(agentDir?)` | function | Reads and validates the owner config. |
|
|
124
124
|
| `configuredOpenUri(path)` | function | Returns a safe VS Code URI for a supported command. |
|
|
125
125
|
|
|
126
|
-
`loadOpenInConfig` returns `source` as `"missing"` or `"file"
|
|
126
|
+
`loadOpenInConfig` returns `source` as `"missing"` or `"file"`. `value.command` is validated. Pass an agent directory when needed.
|
|
127
127
|
|
|
128
128
|
`configuredOpenUri(path)` works when the executable is `code`. With `code -n` or `code --new-window`, it adds `windowId=_blank` so the link opens in a new window. It returns `undefined` for other commands or invalid config. `@henryqw/pi-config-store` owns the config home and storage.
|
|
129
129
|
|
|
130
130
|
## Limits and recovery
|
|
131
131
|
|
|
132
|
-
The open command splits on whitespace into an executable and arguments. Tokens cannot contain spaces, and quoting is unsupported. Use a wrapper script for executables in
|
|
132
|
+
The open command splits on whitespace into an executable and arguments. Tokens cannot contain spaces, and quoting is unsupported. Use a wrapper script for executables in paths that contain spaces.
|
|
133
133
|
|
|
134
|
-
An existing config file must be a JSON object with exactly one non-empty string `command` property. Otherwise `/open` fails with a visible error, offers no open URI, and leaves the malformed file unchanged. If the configured command exits
|
|
134
|
+
An existing config file must be a JSON object with exactly one non-empty string `command` property. Otherwise `/open` fails with a visible error, offers no open URI, and leaves the malformed file unchanged. If the configured command exits with an error, Pi reports its error output or exit code. Fix the command and run `/open` again.
|
|
135
135
|
|
|
136
136
|
When the configured executable is `code` and Pi reports hyperlink support, the accent-colored checkout name links to the current path. The link opens a new window for `code -n` or `code --new-window`. A missing config silently uses `code`. Other executables and terminals with hyperlinks disabled render plain text.
|
|
137
137
|
|
|
138
138
|
Pi handles the custom URI in its default fullscreen TUI. Use normal primary click. Regular TUI (`"tuiMode": "regular"` or `--tui-mode regular`) delegates OSC 8 activation to the terminal, so the link works only where the terminal opens custom URI schemes.
|
|
139
139
|
|
|
140
|
-
Ghostty uses `Cmd+click
|
|
140
|
+
Ghostty uses `Cmd+click`, but it possibly does not open custom URI schemes.
|
package/extensions/footer.ts
CHANGED
|
@@ -15,6 +15,8 @@ const THINKING_COLORS = {
|
|
|
15
15
|
const QUOTA_STATUS_KEY = "pi-multi-codex";
|
|
16
16
|
const AGENT_TIME_ENTRY = "pi-footer:agent-work";
|
|
17
17
|
const SUBAGENT_BACKGROUND_RESULT = "subagent-background-result";
|
|
18
|
+
// Shorter windows are bursts (non-streamed fallbacks, one large chunk) or too coarse to time.
|
|
19
|
+
const MIN_TPS_WINDOW_MS = 250;
|
|
18
20
|
/** Pi's VIRTUAL_MODEL_API: catalog entries that route each request to a physical model. */
|
|
19
21
|
const VIRTUAL_MODEL_API = "pi-virtual";
|
|
20
22
|
|
|
@@ -284,9 +286,9 @@ export default function footerExtension(pi: ExtensionAPI): void {
|
|
|
284
286
|
pi.on("message_end", (event) => {
|
|
285
287
|
if (event.message.role !== "assistant") return;
|
|
286
288
|
const output = event.message.usage?.output ?? 0;
|
|
287
|
-
const
|
|
289
|
+
const milliseconds = assistantStartedAt === undefined ? 0 : assistantLastUpdateAt! - assistantStartedAt;
|
|
288
290
|
assistantStartedAt = assistantLastUpdateAt = undefined;
|
|
289
|
-
tps =
|
|
291
|
+
tps = milliseconds >= MIN_TPS_WINDOW_MS ? output / (milliseconds / 1000) : undefined;
|
|
290
292
|
});
|
|
291
293
|
|
|
292
294
|
// Session entries are append-only; the leaf also changes on tree navigation.
|