@aemonge-dev/pi-stardeck 0.5.0 → 0.6.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/README.md +3 -2
- package/docs/architecture.md +8 -5
- package/licenses/README.md +9 -7
- package/package.json +2 -2
- package/packages/footer/README.md +15 -0
- package/packages/footer/index.ts +37 -0
- package/packages/footer/package.json +32 -0
- package/packages/footer/src/protocol.ts +10 -0
- package/packages/footer/src/quota.ts +26 -0
- package/packages/footer/src/telemetry.ts +59 -0
- package/packages/pi-stardeck/README.md +7 -6
- package/packages/status/package.json +1 -1
- package/src/health.ts +0 -1
- package/src/index.ts +3 -4
- package/licenses/pi-fancy-footer-LICENSE +0 -21
- package/packages/pi-fancy-footer-full-palette/LICENSE +0 -21
- package/packages/pi-fancy-footer-full-palette/LOCAL-CHANGES.md +0 -41
- package/packages/pi-fancy-footer-full-palette/README.md +0 -468
- package/packages/pi-fancy-footer-full-palette/package.json +0 -52
- package/packages/pi-fancy-footer-full-palette/src/api.ts +0 -204
- package/packages/pi-fancy-footer-full-palette/src/config-editor.ts +0 -634
- package/packages/pi-fancy-footer-full-palette/src/config.ts +0 -852
- package/packages/pi-fancy-footer-full-palette/src/data-widgets.ts +0 -259
- package/packages/pi-fancy-footer-full-palette/src/git.ts +0 -130
- package/packages/pi-fancy-footer-full-palette/src/index.ts +0 -479
- package/packages/pi-fancy-footer-full-palette/src/layout.ts +0 -309
- package/packages/pi-fancy-footer-full-palette/src/provider-status.ts +0 -1466
- package/packages/pi-fancy-footer-full-palette/src/render.ts +0 -1061
- package/packages/pi-fancy-footer-full-palette/src/shared.ts +0 -903
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type {
|
|
3
|
-
FooterIconFamily,
|
|
4
|
-
FooterWidgetAlign,
|
|
5
|
-
FooterWidgetColor,
|
|
6
|
-
FooterWidgetFill,
|
|
7
|
-
} from "./shared.ts";
|
|
8
|
-
|
|
9
|
-
export const FANCY_FOOTER_PROTOCOL_VERSION = 1 as const;
|
|
10
|
-
export const FANCY_FOOTER_WIDGET_CHANNEL = "pi-fancy-footer:widget";
|
|
11
|
-
export const FANCY_FOOTER_READY_CHANNEL = "pi-fancy-footer:ready";
|
|
12
|
-
export const FANCY_FOOTER_TELEMETRY_CHANNEL = "pi-stardeck:footer-telemetry/v1";
|
|
13
|
-
export const PI_STATUS_SOURCE_CHANNEL = "pi-stardeck:status-source/v1";
|
|
14
|
-
|
|
15
|
-
export interface FancyFooterTextContent {
|
|
16
|
-
type: "text";
|
|
17
|
-
text: string;
|
|
18
|
-
/** Optional HTTP(S) destination for the complete rendered widget. */
|
|
19
|
-
href?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface FancyFooterDataWidgetIcon {
|
|
23
|
-
glyphs: string | Partial<Record<FooterIconFamily, string>>;
|
|
24
|
-
color?: FooterWidgetColor;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface FancyFooterDataWidgetStyle {
|
|
28
|
-
textColor?: FooterWidgetColor;
|
|
29
|
-
bold?: boolean;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface FancyFooterDataWidgetLayout {
|
|
33
|
-
/**
|
|
34
|
-
* Whether the widget is enabled by default. Opt-in widgets hide when their
|
|
35
|
-
* text is empty.
|
|
36
|
-
*/
|
|
37
|
-
enabled?: boolean;
|
|
38
|
-
row?: number;
|
|
39
|
-
position?: number;
|
|
40
|
-
align?: FooterWidgetAlign;
|
|
41
|
-
fill?: FooterWidgetFill;
|
|
42
|
-
minWidth?: number;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface FancyFooterDataWidget {
|
|
46
|
-
/** Namespaced ID such as `acme.status`. */
|
|
47
|
-
id: string;
|
|
48
|
-
label?: string;
|
|
49
|
-
description?: string;
|
|
50
|
-
content: FancyFooterTextContent;
|
|
51
|
-
icon?: FancyFooterDataWidgetIcon | false;
|
|
52
|
-
style?: FancyFooterDataWidgetStyle;
|
|
53
|
-
layout?: FancyFooterDataWidgetLayout;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export type FancyFooterWidgetMessage =
|
|
57
|
-
| {
|
|
58
|
-
protocol: typeof FANCY_FOOTER_PROTOCOL_VERSION;
|
|
59
|
-
type: "upsert";
|
|
60
|
-
widget: FancyFooterDataWidget;
|
|
61
|
-
}
|
|
62
|
-
| {
|
|
63
|
-
protocol: typeof FANCY_FOOTER_PROTOCOL_VERSION;
|
|
64
|
-
type: "remove";
|
|
65
|
-
id: string;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export interface FancyFooterReadyMessage {
|
|
69
|
-
protocol: typeof FANCY_FOOTER_PROTOCOL_VERSION;
|
|
70
|
-
version: string;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface FancyFooterQuotaWindow {
|
|
74
|
-
label: string;
|
|
75
|
-
percent: number;
|
|
76
|
-
resetAt?: number;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface FancyFooterTelemetryMessage {
|
|
80
|
-
protocol: typeof FANCY_FOOTER_PROTOCOL_VERSION;
|
|
81
|
-
type: "snapshot";
|
|
82
|
-
totalCost: number;
|
|
83
|
-
quotaPercent?: number;
|
|
84
|
-
quotaWindows?: FancyFooterQuotaWindow[];
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export interface FancyFooterStatusSourceMessage {
|
|
88
|
-
protocol: typeof FANCY_FOOTER_PROTOCOL_VERSION;
|
|
89
|
-
type: "snapshot";
|
|
90
|
-
source: "fancy-footer";
|
|
91
|
-
conditions: Array<{
|
|
92
|
-
id: string;
|
|
93
|
-
severity: "warning" | "error";
|
|
94
|
-
summary: string;
|
|
95
|
-
}>;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export interface FancyFooterClient {
|
|
99
|
-
upsert(widget: FancyFooterDataWidget): void;
|
|
100
|
-
remove(id: string): void;
|
|
101
|
-
onReady(handler: (message: FancyFooterReadyMessage) => void): () => void;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
105
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export function parseFancyFooterTelemetry(
|
|
109
|
-
value: unknown,
|
|
110
|
-
): FancyFooterTelemetryMessage | null {
|
|
111
|
-
if (!isRecord(value) || value.protocol !== FANCY_FOOTER_PROTOCOL_VERSION) {
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
if (value.type !== "snapshot") return null;
|
|
115
|
-
const totalCost = Number(value.totalCost);
|
|
116
|
-
if (!Number.isFinite(totalCost) || totalCost < 0) return null;
|
|
117
|
-
if (
|
|
118
|
-
value.quotaPercent !== undefined &&
|
|
119
|
-
(!Number.isFinite(Number(value.quotaPercent)) ||
|
|
120
|
-
Number(value.quotaPercent) < 0 ||
|
|
121
|
-
Number(value.quotaPercent) > 100)
|
|
122
|
-
) {
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
const quotaWindows =
|
|
126
|
-
value.quotaWindows === undefined
|
|
127
|
-
? undefined
|
|
128
|
-
: parseFancyFooterQuotaWindows(value.quotaWindows);
|
|
129
|
-
if (value.quotaWindows !== undefined && quotaWindows === undefined) return null;
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
protocol: FANCY_FOOTER_PROTOCOL_VERSION,
|
|
133
|
-
type: "snapshot",
|
|
134
|
-
totalCost,
|
|
135
|
-
...(value.quotaPercent !== undefined
|
|
136
|
-
? { quotaPercent: Number(value.quotaPercent) }
|
|
137
|
-
: {}),
|
|
138
|
-
...(quotaWindows !== undefined ? { quotaWindows } : {}),
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function parseFancyFooterQuotaWindows(
|
|
143
|
-
value: unknown,
|
|
144
|
-
): FancyFooterQuotaWindow[] | undefined {
|
|
145
|
-
if (!Array.isArray(value) || value.length === 0 || value.length > 2) {
|
|
146
|
-
return undefined;
|
|
147
|
-
}
|
|
148
|
-
const windows: FancyFooterQuotaWindow[] = [];
|
|
149
|
-
for (const entry of value) {
|
|
150
|
-
if (!isRecord(entry)) return undefined;
|
|
151
|
-
const { label } = entry;
|
|
152
|
-
if (typeof label !== "string" || label.length === 0 || label.length > 8) {
|
|
153
|
-
return undefined;
|
|
154
|
-
}
|
|
155
|
-
const percent = Number(entry.percent);
|
|
156
|
-
if (!Number.isFinite(percent) || percent < 0 || percent > 100) return undefined;
|
|
157
|
-
const resetAt = entry.resetAt === undefined ? undefined : Number(entry.resetAt);
|
|
158
|
-
if (resetAt !== undefined && (!Number.isFinite(resetAt) || resetAt <= 0)) {
|
|
159
|
-
return undefined;
|
|
160
|
-
}
|
|
161
|
-
windows.push({ label, percent, ...(resetAt !== undefined ? { resetAt } : {}) });
|
|
162
|
-
}
|
|
163
|
-
return windows;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/** Create a typed client over the same import-free event-bus protocol. */
|
|
167
|
-
export function createFancyFooterClient(pi: ExtensionAPI): FancyFooterClient {
|
|
168
|
-
return {
|
|
169
|
-
upsert: (widget) => {
|
|
170
|
-
const message: FancyFooterWidgetMessage = {
|
|
171
|
-
protocol: FANCY_FOOTER_PROTOCOL_VERSION,
|
|
172
|
-
type: "upsert",
|
|
173
|
-
widget,
|
|
174
|
-
};
|
|
175
|
-
pi.events.emit(FANCY_FOOTER_WIDGET_CHANNEL, message);
|
|
176
|
-
},
|
|
177
|
-
remove: (id) => {
|
|
178
|
-
const message: FancyFooterWidgetMessage = {
|
|
179
|
-
protocol: FANCY_FOOTER_PROTOCOL_VERSION,
|
|
180
|
-
type: "remove",
|
|
181
|
-
id,
|
|
182
|
-
};
|
|
183
|
-
pi.events.emit(FANCY_FOOTER_WIDGET_CHANNEL, message);
|
|
184
|
-
},
|
|
185
|
-
onReady: (handler) =>
|
|
186
|
-
pi.events.on(FANCY_FOOTER_READY_CHANNEL, (raw) => {
|
|
187
|
-
if (
|
|
188
|
-
!isRecord(raw) ||
|
|
189
|
-
raw.protocol !== FANCY_FOOTER_PROTOCOL_VERSION ||
|
|
190
|
-
typeof raw.version !== "string"
|
|
191
|
-
) {
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
handler(raw as unknown as FancyFooterReadyMessage);
|
|
195
|
-
}),
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export type {
|
|
200
|
-
FooterIconFamily,
|
|
201
|
-
FooterWidgetAlign,
|
|
202
|
-
FooterWidgetColor,
|
|
203
|
-
FooterWidgetFill,
|
|
204
|
-
} from "./shared.ts";
|