@spences10/pi-footer 0.0.1 → 0.0.2

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.
Files changed (47) hide show
  1. package/README.md +16 -0
  2. package/dist/commands/footer-command.d.ts +3 -0
  3. package/dist/commands/footer-command.js +124 -0
  4. package/dist/commands/footer-command.js.map +1 -0
  5. package/dist/config.d.ts +4 -0
  6. package/dist/config.js +44 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/extension/install.d.ts +3 -0
  9. package/dist/extension/install.js +16 -0
  10. package/dist/extension/install.js.map +1 -0
  11. package/dist/index.d.ts +7 -5
  12. package/dist/index.js +12 -264
  13. package/dist/index.js.map +1 -1
  14. package/dist/model/footer-model.d.ts +20 -0
  15. package/dist/model/footer-model.js +94 -0
  16. package/dist/model/footer-model.js.map +1 -0
  17. package/dist/model/git.d.ts +10 -0
  18. package/dist/model/git.js +64 -0
  19. package/dist/model/git.js.map +1 -0
  20. package/dist/model/thinking.d.ts +4 -0
  21. package/dist/model/thinking.js +34 -0
  22. package/dist/model/thinking.js.map +1 -0
  23. package/dist/presets/types.d.ts +20 -0
  24. package/dist/presets/types.js +49 -0
  25. package/dist/presets/types.js.map +1 -0
  26. package/dist/reference/research.d.ts +6 -0
  27. package/dist/reference/research.js +50 -0
  28. package/dist/reference/research.js.map +1 -0
  29. package/dist/render/footer-lines.d.ts +4 -0
  30. package/dist/render/footer-lines.js +117 -0
  31. package/dist/render/footer-lines.js.map +1 -0
  32. package/dist/render/preview.d.ts +6 -0
  33. package/dist/render/preview.js +34 -0
  34. package/dist/render/preview.js.map +1 -0
  35. package/dist/render/status-line.d.ts +3 -0
  36. package/dist/render/status-line.js +32 -0
  37. package/dist/render/status-line.js.map +1 -0
  38. package/dist/test-utils.d.ts +5 -0
  39. package/dist/test-utils.js +46 -0
  40. package/dist/test-utils.js.map +1 -0
  41. package/dist/theme/tokens.d.ts +16 -0
  42. package/dist/theme/tokens.js +26 -0
  43. package/dist/theme/tokens.js.map +1 -0
  44. package/dist/utils/text.d.ts +3 -0
  45. package/dist/utils/text.js +23 -0
  46. package/dist/utils/text.js.map +1 -0
  47. package/package.json +6 -6
package/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # @spences10/pi-footer
2
2
 
3
+ [![built with Vite+](https://img.shields.io/badge/built%20with-Vite+-646CFF?logo=vite&logoColor=white)](https://viteplus.dev)
4
+ [![tested with Vitest](https://img.shields.io/badge/tested%20with-Vitest-6E9F18?logo=vitest&logoColor=white)](https://vitest.dev)
5
+ [![npm version](https://img.shields.io/npm/v/@spences10/pi-footer?color=CB3837&logo=npm&logoColor=white)](https://www.npmjs.com/package/@spences10/pi-footer)
6
+ [![license](https://img.shields.io/npm/l/@spences10/pi-footer)](https://www.npmjs.com/package/@spences10/pi-footer)
7
+
3
8
  Configurable Pi footer/statusline extension.
4
9
 
5
10
  It owns `ctx.ui.setFooter(...)` and renders core Pi session data plus
@@ -16,3 +21,14 @@ extension statuses published by other extensions with
16
21
  - `minimal` — compact cwd/model/context footer.
17
22
  - `power` — fuller status-forward layout.
18
23
  - `git-heavy` — emphasizes cwd/git/status widgets.
24
+
25
+ ## Development
26
+
27
+ Package scripts build transitive workspace dependencies first, then
28
+ run local tools through Vite+ with `vp exec`.
29
+
30
+ ```bash
31
+ pnpm --filter @spences10/pi-footer run check
32
+ pnpm --filter @spences10/pi-footer run test
33
+ pnpm --filter @spences10/pi-footer run build
34
+ ```
@@ -0,0 +1,3 @@
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ import { type FooterState } from '../presets/types.js';
3
+ export declare function register_footer_command(pi: ExtensionAPI, state: FooterState): void;
@@ -0,0 +1,124 @@
1
+ import { show_settings_modal } from '@spences10/pi-tui-modal';
2
+ import { save_footer_state } from '../config.js';
3
+ import { install_footer } from '../extension/install.js';
4
+ import { FOOTER_DENSITIES, FOOTER_PRESETS, FOOTER_TONES, FOOTER_WIDGETS, STATUS_LABEL_MODES, } from '../presets/types.js';
5
+ import { FOOTER_RESEARCH_REFERENCES } from '../reference/research.js';
6
+ export function register_footer_command(pi, state) {
7
+ pi.registerCommand('footer', {
8
+ description: 'Configure the Pi footer',
9
+ handler: async (_args, ctx) => configure_footer(ctx, state),
10
+ });
11
+ }
12
+ async function configure_footer(ctx, state) {
13
+ await show_settings_modal(ctx, {
14
+ title: 'Footer settings',
15
+ subtitle: 'Changes apply live and persist to ~/.pi/agent/extensions/pi-footer.json.',
16
+ footer: 'enter cycles values • esc close',
17
+ items: get_footer_settings(state),
18
+ enable_search: true,
19
+ detail: (item) => get_setting_detail(item.id),
20
+ metadata: (item) => get_setting_metadata(item?.id, state),
21
+ on_change: (id, new_value) => {
22
+ apply_footer_setting(state, id, new_value);
23
+ save_footer_state(state);
24
+ install_footer(ctx, state);
25
+ return false;
26
+ },
27
+ });
28
+ }
29
+ function get_footer_settings(state) {
30
+ return [
31
+ {
32
+ id: 'preset',
33
+ label: 'Preset',
34
+ description: 'Overall footer layout',
35
+ currentValue: state.preset,
36
+ values: [...FOOTER_PRESETS],
37
+ },
38
+ {
39
+ id: 'density',
40
+ label: 'Density',
41
+ description: 'How many footer rows to use',
42
+ currentValue: state.density,
43
+ values: [...FOOTER_DENSITIES],
44
+ },
45
+ {
46
+ id: 'tone',
47
+ label: 'Tone',
48
+ description: 'Footer color treatment from the active Pi theme',
49
+ currentValue: state.tone,
50
+ values: [...FOOTER_TONES],
51
+ },
52
+ {
53
+ id: 'status-labels',
54
+ label: 'Status labels',
55
+ description: 'How extension statuses are labelled',
56
+ currentValue: state.status_label_mode,
57
+ values: [...STATUS_LABEL_MODES],
58
+ },
59
+ ...FOOTER_WIDGETS.map((widget) => ({
60
+ id: `widget:${widget}`,
61
+ label: `Widget: ${widget}`,
62
+ description: 'Show or hide this footer building block',
63
+ currentValue: state.widgets[widget] ? 'on' : 'off',
64
+ values: ['on', 'off'],
65
+ })),
66
+ ];
67
+ }
68
+ function apply_footer_setting(state, id, new_value) {
69
+ if (id === 'preset' &&
70
+ FOOTER_PRESETS.includes(new_value)) {
71
+ state.preset = new_value;
72
+ }
73
+ if (id === 'density' &&
74
+ FOOTER_DENSITIES.includes(new_value)) {
75
+ state.density = new_value;
76
+ }
77
+ if (id === 'tone' &&
78
+ FOOTER_TONES.includes(new_value)) {
79
+ state.tone = new_value;
80
+ }
81
+ if (id === 'status-labels' &&
82
+ STATUS_LABEL_MODES.includes(new_value)) {
83
+ state.status_label_mode = new_value;
84
+ }
85
+ if (id.startsWith('widget:')) {
86
+ const widget = id.slice('widget:'.length);
87
+ if (FOOTER_WIDGETS.includes(widget))
88
+ state.widgets[widget] = new_value === 'on';
89
+ }
90
+ }
91
+ function get_setting_detail(id) {
92
+ if (id === 'preset')
93
+ return 'Presets are starter arrangements; widget toggles decide exact content.';
94
+ if (id === 'density')
95
+ return 'Compact is one row, comfortable is normal 2–3 rows, expanded adds diagnostic/footer mode detail.';
96
+ if (id === 'tone')
97
+ return 'Muted uses dim theme color, balanced uses plain terminal foreground, bright uses theme accent.';
98
+ if (id === 'status-labels')
99
+ return 'Smart avoids doubled labels such as mcp:MCP 6/6 connected.';
100
+ if (id.startsWith('widget:'))
101
+ return 'Widgets are composable footer building blocks you can show or hide.';
102
+ }
103
+ function get_setting_metadata(id, state) {
104
+ const lines = [
105
+ `Current preset: ${state.preset}`,
106
+ `Density: ${state.density}`,
107
+ `Tone: ${state.tone}`,
108
+ `Status labels: ${state.status_label_mode}`,
109
+ ];
110
+ if (id?.startsWith('widget:')) {
111
+ lines.push('', 'Enabled widgets:');
112
+ for (const widget of FOOTER_WIDGETS.filter((widget) => state.widgets[widget])) {
113
+ lines.push(`• ${widget}`);
114
+ }
115
+ }
116
+ if (id === 'preset') {
117
+ lines.push('', 'Research references to fold in:');
118
+ for (const reference of FOOTER_RESEARCH_REFERENCES.slice(0, 4)) {
119
+ lines.push(`• ${reference.name}: ${reference.takeaways[0]}`);
120
+ }
121
+ }
122
+ return lines;
123
+ }
124
+ //# sourceMappingURL=footer-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"footer-command.js","sourceRoot":"","sources":["../../src/commands/footer-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type FooterState } from './presets/types.js';
2
+ export declare function load_footer_state(): FooterState;
3
+ export declare function save_footer_state(state: FooterState): void;
4
+ export declare function normalize_footer_state(state: Partial<FooterState>): FooterState;
package/dist/config.js ADDED
@@ -0,0 +1,44 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { DEFAULT_FOOTER_STATE, DEFAULT_FOOTER_WIDGETS, FOOTER_DENSITIES, FOOTER_PRESETS, FOOTER_TONES, FOOTER_WIDGETS, STATUS_LABEL_MODES, } from './presets/types.js';
4
+ const CONFIG_PATH = join(process.env.PI_HOME ??
5
+ join(process.env.HOME ?? '.', '.pi', 'agent'), 'extensions', 'pi-footer.json');
6
+ export function load_footer_state() {
7
+ if (!existsSync(CONFIG_PATH))
8
+ return clone_default_state();
9
+ try {
10
+ const parsed = JSON.parse(readFileSync(CONFIG_PATH, 'utf8'));
11
+ return normalize_footer_state(parsed);
12
+ }
13
+ catch {
14
+ return clone_default_state();
15
+ }
16
+ }
17
+ export function save_footer_state(state) {
18
+ mkdirSync(dirname(CONFIG_PATH), { recursive: true });
19
+ writeFileSync(CONFIG_PATH, `${JSON.stringify(state, null, '\t')}\n`);
20
+ }
21
+ export function normalize_footer_state(state) {
22
+ return {
23
+ preset: FOOTER_PRESETS.includes(state.preset)
24
+ ? state.preset
25
+ : DEFAULT_FOOTER_STATE.preset,
26
+ density: FOOTER_DENSITIES.includes(state.density)
27
+ ? state.density
28
+ : DEFAULT_FOOTER_STATE.density,
29
+ status_label_mode: STATUS_LABEL_MODES.includes(state.status_label_mode)
30
+ ? state.status_label_mode
31
+ : DEFAULT_FOOTER_STATE.status_label_mode,
32
+ tone: FOOTER_TONES.includes(state.tone)
33
+ ? state.tone
34
+ : DEFAULT_FOOTER_STATE.tone,
35
+ widgets: {
36
+ ...DEFAULT_FOOTER_WIDGETS,
37
+ ...Object.fromEntries(Object.entries(state.widgets ?? {}).filter(([key]) => FOOTER_WIDGETS.includes(key))),
38
+ },
39
+ };
40
+ }
41
+ function clone_default_state() {
42
+ return normalize_footer_state(DEFAULT_FOOTER_STATE);
43
+ }
44
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,UAAU,EACV,SAAS,EACT,YAAY,EACZ,aAAa,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACN,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,kBAAkB,GAElB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,GAAG,IAAI,CACvB,OAAO,CAAC,GAAG,CAAC,OAAO;IAClB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,EAC9C,YAAY,EACZ,gBAAgB,CAChB,CAAC;AAEF,MAAM,UAAU,iBAAiB;IAChC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,mBAAmB,EAAE,CAAC;IAC3D,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CACxB,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CACT,CAAC;QAC1B,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,mBAAmB,EAAE,CAAC;IAC9B,CAAC;AACF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAkB;IACnD,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,aAAa,CACZ,WAAW,EACX,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CACxC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACrC,KAA2B;IAE3B,OAAO;QACN,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAe,CAAC;YACrD,CAAC,CAAC,KAAK,CAAC,MAAO;YACf,CAAC,CAAC,oBAAoB,CAAC,MAAM;QAC9B,OAAO,EAAE,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAgB,CAAC;YACzD,CAAC,CAAC,KAAK,CAAC,OAAQ;YAChB,CAAC,CAAC,oBAAoB,CAAC,OAAO;QAC/B,iBAAiB,EAAE,kBAAkB,CAAC,QAAQ,CAC7C,KAAK,CAAC,iBAA0B,CAChC;YACA,CAAC,CAAC,KAAK,CAAC,iBAAkB;YAC1B,CAAC,CAAC,oBAAoB,CAAC,iBAAiB;QACzC,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAa,CAAC;YAC/C,CAAC,CAAC,KAAK,CAAC,IAAK;YACb,CAAC,CAAC,oBAAoB,CAAC,IAAI;QAC5B,OAAO,EAAE;YACR,GAAG,sBAAsB;YACzB,GAAG,MAAM,CAAC,WAAW,CACpB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CACpD,cAAc,CAAC,QAAQ,CAAC,GAAY,CAAC,CACrC,CACD;SACD;KACD,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB;IAC3B,OAAO,sBAAsB,CAAC,oBAAoB,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ExtensionContext } from '@earendil-works/pi-coding-agent';
2
+ import type { FooterState } from '../presets/types.js';
3
+ export declare function install_footer(ctx: ExtensionContext, state: FooterState): void;
@@ -0,0 +1,16 @@
1
+ import { render_footer_lines } from '../render/footer-lines.js';
2
+ export function install_footer(ctx, state) {
3
+ if (!ctx.hasUI)
4
+ return;
5
+ ctx.ui.setFooter((tui, theme, footer_data) => {
6
+ const unsubscribe = footer_data.onBranchChange(() => tui.requestRender());
7
+ return {
8
+ dispose: unsubscribe,
9
+ invalidate() { },
10
+ render(width) {
11
+ return render_footer_lines(ctx, theme, footer_data, state, width);
12
+ },
13
+ };
14
+ });
15
+ }
16
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/extension/install.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,MAAM,UAAU,cAAc,CAC7B,GAAqB,EACrB,KAAkB;IAElB,IAAI,CAAC,GAAG,CAAC,KAAK;QAAE,OAAO;IACvB,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;QAC5C,MAAM,WAAW,GAAG,WAAW,CAAC,cAAc,CAAC,GAAG,EAAE,CACnD,GAAG,CAAC,aAAa,EAAE,CACnB,CAAC;QACF,OAAO;YACN,OAAO,EAAE,WAAW;YACpB,UAAU,KAAI,CAAC;YACf,MAAM,CAAC,KAAa;gBACnB,OAAO,mBAAmB,CACzB,GAAG,EACH,KAAK,EACL,WAAW,EACX,KAAK,EACL,KAAK,CACL,CAAC;YACH,CAAC;SACD,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { type ModelThinkingLevel } from '@earendil-works/pi-ai';
2
- import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';
3
- export declare function render_footer_status_line(theme: ExtensionContext['ui']['theme'], width: number, left_items: string[], right_item?: string): string | undefined;
4
- export declare function get_default_footer_thinking_level(model: ExtensionContext['model']): ModelThinkingLevel;
5
- export declare function get_current_thinking_level(ctx: Pick<ExtensionContext, 'model' | 'sessionManager'>): ModelThinkingLevel;
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ export { get_current_thinking_level, get_default_footer_thinking_level, } from './model/thinking.js';
3
+ export { FOOTER_DENSITIES, FOOTER_PRESETS, FOOTER_TONES, FOOTER_WIDGETS, type FooterDensity, type FooterPreset, type FooterTone, type FooterWidget, } from './presets/types.js';
4
+ export { FOOTER_RESEARCH_REFERENCES } from './reference/research.js';
5
+ export { render_footer_lines } from './render/footer-lines.js';
6
+ export { render_footer_status_line } from './render/status-line.js';
7
+ export { FOOTER_COLORS, type FooterTheme } from './theme/tokens.js';
6
8
  export default function footer_extension(pi: ExtensionAPI): void;
package/dist/index.js CHANGED
@@ -1,269 +1,17 @@
1
- import { clampThinkingLevel, getSupportedThinkingLevels, } from '@earendil-works/pi-ai';
2
- import { truncateToWidth, visibleWidth, } from '@earendil-works/pi-tui';
3
- import { show_picker_modal } from '@spences10/pi-tui-modal';
4
- const PRESETS = ['minimal', 'default', 'power', 'git-heavy'];
5
- const state = {
6
- preset: 'default',
7
- };
8
- function sanitize_status_text(text) {
9
- return text
10
- .replace(/[\r\n\t]/g, ' ')
11
- .replace(/ +/g, ' ')
12
- .trim();
13
- }
14
- function format_token_count(count) {
15
- if (count < 1000)
16
- return count.toString();
17
- if (count < 10000)
18
- return `${(count / 1000).toFixed(1)}k`;
19
- if (count < 1000000)
20
- return `${Math.round(count / 1000)}k`;
21
- if (count < 10000000)
22
- return `${(count / 1000000).toFixed(1)}M`;
23
- return `${Math.round(count / 1000000)}M`;
24
- }
25
- export function render_footer_status_line(theme, width, left_items, right_item) {
26
- const left = sanitize_status_text(left_items.join(' '));
27
- const right = right_item ? sanitize_status_text(right_item) : '';
28
- if (!left && !right)
29
- return undefined;
30
- if (!right) {
31
- return truncateToWidth(theme.fg('dim', left), width, theme.fg('dim', '...'));
32
- }
33
- if (!left) {
34
- const themed_right = theme.fg('dim', right);
35
- const right_width = visibleWidth(themed_right);
36
- return right_width >= width
37
- ? truncateToWidth(themed_right, width, theme.fg('dim', '...'))
38
- : `${' '.repeat(width - right_width)}${themed_right}`;
39
- }
40
- const right_width = visibleWidth(right);
41
- if (right_width >= width) {
42
- return truncateToWidth(theme.fg('dim', right), width, theme.fg('dim', '...'));
43
- }
44
- const min_gap = 1;
45
- const available_left = Math.max(0, width - right_width - min_gap);
46
- const truncated_left = truncateToWidth(left, available_left, '...');
47
- const left_width = visibleWidth(truncated_left);
48
- const gap = Math.max(min_gap, width - left_width - right_width);
49
- return (theme.fg('dim', truncated_left) +
50
- ' '.repeat(gap) +
51
- theme.fg('dim', right));
52
- }
53
- const VALID_THINKING_LEVELS = new Set([
54
- 'off',
55
- 'minimal',
56
- 'low',
57
- 'medium',
58
- 'high',
59
- 'xhigh',
60
- ]);
61
- function is_model_thinking_level(level) {
62
- return VALID_THINKING_LEVELS.has(level);
63
- }
64
- export function get_default_footer_thinking_level(model) {
65
- if (!model?.reasoning)
66
- return 'off';
67
- return clampThinkingLevel(model, 'medium');
68
- }
69
- export function get_current_thinking_level(ctx) {
70
- const entries = ctx.sessionManager.getEntries();
71
- for (let i = entries.length - 1; i >= 0; i--) {
72
- const entry = entries[i];
73
- if (entry.type === 'thinking_level_change' &&
74
- typeof entry.thinkingLevel === 'string' &&
75
- is_model_thinking_level(entry.thinkingLevel)) {
76
- if (!ctx.model?.reasoning)
77
- return 'off';
78
- return getSupportedThinkingLevels(ctx.model).includes(entry.thinkingLevel)
79
- ? entry.thinkingLevel
80
- : clampThinkingLevel(ctx.model, entry.thinkingLevel);
81
- }
82
- }
83
- return get_default_footer_thinking_level(ctx.model);
84
- }
85
- function build_footer_model(ctx, footer_data, theme) {
86
- let total_input = 0;
87
- let total_output = 0;
88
- let total_cache_read = 0;
89
- let total_cache_write = 0;
90
- let total_cost = 0;
91
- for (const entry of ctx.sessionManager.getEntries()) {
92
- if (entry.type === 'message' &&
93
- entry.message.role === 'assistant') {
94
- total_input += entry.message.usage.input;
95
- total_output += entry.message.usage.output;
96
- total_cache_read += entry.message.usage.cacheRead;
97
- total_cache_write += entry.message.usage.cacheWrite;
98
- total_cost += entry.message.usage.cost.total;
99
- }
100
- }
101
- const context_usage = ctx.getContextUsage();
102
- const context_window = context_usage?.contextWindow ?? ctx.model?.contextWindow ?? 0;
103
- const context_percent_value = context_usage?.percent ?? 0;
104
- const context_percent = context_usage?.percent !== null
105
- ? context_percent_value.toFixed(1)
106
- : '?';
107
- let pwd = ctx.cwd;
108
- const home = process.env.HOME || process.env.USERPROFILE;
109
- if (home && pwd.startsWith(home)) {
110
- pwd = `~${pwd.slice(home.length)}`;
111
- }
112
- const branch = footer_data.getGitBranch();
113
- if (branch) {
114
- pwd = `${pwd} (${branch})`;
115
- }
116
- const session_name = ctx.sessionManager.getSessionName();
117
- if (session_name) {
118
- pwd = `${pwd} • ${session_name}`;
119
- }
120
- const stats_parts = [];
121
- if (total_input)
122
- stats_parts.push(`↑${format_token_count(total_input)}`);
123
- if (total_output)
124
- stats_parts.push(`↓${format_token_count(total_output)}`);
125
- if (total_cache_read)
126
- stats_parts.push(`R${format_token_count(total_cache_read)}`);
127
- if (total_cache_write)
128
- stats_parts.push(`W${format_token_count(total_cache_write)}`);
129
- const using_subscription = ctx.model
130
- ? ctx.modelRegistry.isUsingOAuth(ctx.model)
131
- : false;
132
- if (total_cost || using_subscription) {
133
- stats_parts.push(`$${total_cost.toFixed(3)}${using_subscription ? ' (sub)' : ''}`);
134
- }
135
- const context_percent_display = context_percent === '?'
136
- ? `?/${format_token_count(context_window)}`
137
- : `${context_percent}%/${format_token_count(context_window)}`;
138
- let context_percent_str = context_percent_display;
139
- if (context_percent_value > 90) {
140
- context_percent_str = theme.fg('error', context_percent_display);
141
- }
142
- else if (context_percent_value > 70) {
143
- context_percent_str = theme.fg('warning', context_percent_display);
144
- }
145
- stats_parts.push(context_percent_str);
146
- const model_name = ctx.model?.id || 'no-model';
147
- const thinking_level = get_current_thinking_level(ctx);
148
- let model_text = model_name;
149
- if (ctx.model?.reasoning) {
150
- model_text =
151
- thinking_level === 'off'
152
- ? `${model_name} • thinking off`
153
- : `${model_name} • ${thinking_level}`;
154
- }
155
- if (footer_data.getAvailableProviderCount() > 1 && ctx.model) {
156
- model_text = `(${ctx.model.provider}) ${model_text}`;
157
- }
158
- const statuses = new Map(footer_data.getExtensionStatuses());
159
- const preset_status = statuses.get('preset');
160
- statuses.delete('preset');
161
- return {
162
- pwd,
163
- stats_parts,
164
- model_text,
165
- statuses,
166
- preset_status,
167
- };
168
- }
169
- function render_stats_line(model, theme, width) {
170
- let stats_left = model.stats_parts.join(' ');
171
- let stats_left_width = visibleWidth(stats_left);
172
- if (stats_left_width > width) {
173
- stats_left = truncateToWidth(stats_left, width, '...');
174
- stats_left_width = visibleWidth(stats_left);
175
- }
176
- let right_side = model.model_text;
177
- if (stats_left_width + 2 + visibleWidth(right_side) > width) {
178
- right_side = right_side.replace(/^\([^)]*\) /, '');
179
- }
180
- const right_side_width = visibleWidth(right_side);
181
- const total_needed = stats_left_width + 2 + right_side_width;
182
- let stats_line;
183
- if (total_needed <= width) {
184
- const padding = ' '.repeat(width - stats_left_width - right_side_width);
185
- stats_line = stats_left + padding + right_side;
186
- }
187
- else {
188
- const available_for_right = width - stats_left_width - 2;
189
- if (available_for_right > 0) {
190
- const truncated_right = truncateToWidth(right_side, available_for_right, '');
191
- const truncated_right_width = visibleWidth(truncated_right);
192
- const padding = ' '.repeat(Math.max(0, width - stats_left_width - truncated_right_width));
193
- stats_line = stats_left + padding + truncated_right;
194
- }
195
- else {
196
- stats_line = stats_left;
197
- }
198
- }
199
- const dim_stats_left = theme.fg('dim', stats_left);
200
- const remainder = stats_line.slice(stats_left.length);
201
- return dim_stats_left + theme.fg('dim', remainder);
202
- }
203
- function render_statuses(model, theme, width) {
204
- const other_statuses = Array.from(model.statuses.entries())
205
- .sort(([a], [b]) => a.localeCompare(b))
206
- .map(([key, text]) => `${key}:${sanitize_status_text(text)}`);
207
- return render_footer_status_line(theme, width, other_statuses, model.preset_status);
208
- }
209
- function render_footer_lines(ctx, theme, footer_data, width) {
210
- const model = build_footer_model(ctx, footer_data, theme);
211
- const lines = [];
212
- if (state.preset === 'minimal') {
213
- lines.push(render_footer_status_line(theme, width, [model.pwd], model.model_text) ?? '');
214
- return lines.filter(Boolean);
215
- }
216
- lines.push(truncateToWidth(theme.fg('dim', model.pwd), width, theme.fg('dim', '...')));
217
- lines.push(render_stats_line(model, theme, width));
218
- const status_line = render_statuses(model, theme, width);
219
- if (status_line)
220
- lines.push(status_line);
221
- if (state.preset === 'power') {
222
- const footer_mode = theme.fg('dim', `footer:${state.preset}`);
223
- lines.push(truncateToWidth(footer_mode, width, theme.fg('dim', '...')));
224
- }
225
- return lines;
226
- }
227
- function install_footer(ctx) {
228
- if (!ctx.hasUI)
229
- return;
230
- ctx.ui.setFooter((tui, theme, footer_data) => {
231
- const unsubscribe = footer_data.onBranchChange(() => tui.requestRender());
232
- return {
233
- dispose: unsubscribe,
234
- invalidate() { },
235
- render(width) {
236
- return render_footer_lines(ctx, theme, footer_data, width);
237
- },
238
- };
239
- });
240
- }
1
+ import { register_footer_command } from './commands/footer-command.js';
2
+ import { load_footer_state } from './config.js';
3
+ import { install_footer } from './extension/install.js';
4
+ export { get_current_thinking_level, get_default_footer_thinking_level, } from './model/thinking.js';
5
+ export { FOOTER_DENSITIES, FOOTER_PRESETS, FOOTER_TONES, FOOTER_WIDGETS, } from './presets/types.js';
6
+ export { FOOTER_RESEARCH_REFERENCES } from './reference/research.js';
7
+ export { render_footer_lines } from './render/footer-lines.js';
8
+ export { render_footer_status_line } from './render/status-line.js';
9
+ export { FOOTER_COLORS } from './theme/tokens.js';
10
+ const state = load_footer_state();
241
11
  export default function footer_extension(pi) {
242
- pi.registerCommand('footer', {
243
- description: 'Configure the Pi footer',
244
- handler: async (_args, ctx) => {
245
- const selected = await show_picker_modal(ctx, {
246
- title: 'Footer preset',
247
- items: PRESETS.map((preset) => ({
248
- value: preset,
249
- label: preset,
250
- description: preset === state.preset
251
- ? 'Current footer preset'
252
- : undefined,
253
- })),
254
- initial_index: PRESETS.indexOf(state.preset),
255
- });
256
- if (!selected)
257
- return;
258
- if (PRESETS.includes(selected)) {
259
- state.preset = selected;
260
- install_footer(ctx);
261
- ctx.ui.notify(`Footer preset: ${state.preset}`, 'info');
262
- }
263
- },
264
- });
12
+ register_footer_command(pi, state);
265
13
  pi.on('session_start', async (_event, ctx) => {
266
- install_footer(ctx);
14
+ install_footer(ctx, state);
267
15
  });
268
16
  pi.on('session_shutdown', async (_event, ctx) => {
269
17
  ctx.ui.setFooter(undefined);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EACN,0BAA0B,EAC1B,iCAAiC,GACjC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,cAAc,GAKd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAoB,MAAM,mBAAmB,CAAC;AAEpE,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;AAElC,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAgB;IACxD,uBAAuB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAEnC,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QAC5C,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QAC/C,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { ExtensionContext, ReadonlyFooterDataProvider } from '@earendil-works/pi-coding-agent';
2
+ import { type FooterTheme } from '../theme/tokens.js';
3
+ import { type GitSummary } from './git.js';
4
+ export interface FooterModel {
5
+ cwd: string;
6
+ path_text: string;
7
+ git: GitSummary;
8
+ git_text?: string;
9
+ session_text?: string;
10
+ token_parts: string[];
11
+ cost_text?: string;
12
+ context_text: string;
13
+ model_name: string;
14
+ provider?: string;
15
+ thinking_text?: string;
16
+ model_text: string;
17
+ statuses: Map<string, string>;
18
+ preset_status?: string;
19
+ }
20
+ export declare function build_footer_model(ctx: ExtensionContext, footer_data: ReadonlyFooterDataProvider, theme: FooterTheme): FooterModel;