pi-cockpit 0.24.4 → 0.24.5
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/package.json +88 -88
- package/src/usage/core.ts +16 -0
- package/src/usage/extension.ts +22 -2
package/package.json
CHANGED
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "pi-cockpit",
|
|
3
|
-
"version": "0.24.
|
|
4
|
-
"description": "Responsive Maestro operations sidebar, fallback status widgets, and footer for Pi.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"engines": {
|
|
7
|
-
"node": ">=22.19.0"
|
|
8
|
-
},
|
|
9
|
-
"keywords": [
|
|
10
|
-
"pi-package",
|
|
11
|
-
"pi",
|
|
12
|
-
"pi-extension",
|
|
13
|
-
"tui",
|
|
14
|
-
"teammate",
|
|
15
|
-
"todo"
|
|
16
|
-
],
|
|
17
|
-
"license": "MIT",
|
|
18
|
-
"files": [
|
|
19
|
-
"src/",
|
|
20
|
-
"themes/",
|
|
21
|
-
"README.md"
|
|
22
|
-
],
|
|
23
|
-
"scripts": {
|
|
24
|
-
"test": "node --test --experimental-transform-types tests/config.test.ts tests/public-events.test.ts tests/ui-ownership-runtime.test.ts tests/maestro-store.test.ts tests/split-pane.test.ts tests/editor-bottom.test.ts tests/sidebar-render.test.ts tests/sidebar-controller.test.ts tests/viewport-stability.test.ts tests/terminal-emulator.test.ts tests/compaction-style.test.ts tests/quiet-tools.test.ts tests/native-host.test.ts tests/native-host-entry.test.ts tests/native-host-quiet.test.ts tests/edit-guard.test.ts tests/agents-store.test.ts tests/endpoint-store.test.ts tests/session-ui-state.test.ts tests/session-tabs.test.ts tests/agent-bar.test.ts tests/supervision-store.test.ts tests/bash-bg-store.test.ts tests/bash-bg-widget.test.ts tests/bash-bg-overlay.test.ts tests/todo-overlay.test.ts tests/agent-overlay.test.ts tests/todo-store.test.ts tests/render.test.ts tests/agent-scroll.test.ts tests/session-bar.test.ts tests/session-detail.test.ts tests/footer.test.ts tests/extension-status.test.ts tests/teammate-message.test.ts tests/input-routing.test.ts tests/input-history-store.test.ts tests/unified-editor.test.ts tests/integration-contract.test.ts tests/stack-widget.test.ts tests/zen-render.test.ts tests/zen-browse.test.ts tests/zen-sheet.test.ts tests/settings-view.test.ts tests/thinking-fold.test.ts tests/thinking-timer.test.ts tests/tick-policy.test.ts tests/ambient.test.ts tests/viewport.test.ts tests/theme-picker.test.ts tests/model-picker.test.ts tests/title-gen.test.ts tests/title-llm.test.ts tests/settings-registry.test.ts tests/settings-coordinator.test.ts tests/settings-locale.test.ts tests/tui-i18n.test.ts tests/settings-shell.test.ts tests/settings-cockpit-provider.test.ts tests/settings-cross-package.test.ts tests/ui-primitives.test.ts tests/settings-shell-secret.test.ts tests/settings-shell-listcrud.test.ts tests/capturing-overlay.test.ts tests/claude-editor.test.ts tests/fullscreen-controller.test.ts tests/transcript-selection.test.ts tests/terminal-cleanup.test.ts tests/terminal-capability.test.ts tests/usage-core.test.ts tests/usage-extension.test.ts tests/usage-history.test.ts tests/usage-sparkline.test.ts tests/patch-health.test.ts",
|
|
25
|
-
"typecheck": "tsc --noEmit",
|
|
26
|
-
"prepack": "node ../../scripts/bundle-settings-core.mjs",
|
|
27
|
-
"postpack": "node ../../scripts/bundle-settings-core.mjs --clean"
|
|
28
|
-
},
|
|
29
|
-
"pi": {
|
|
30
|
-
"extensions": [
|
|
31
|
-
"./src/extension/index.ts"
|
|
32
|
-
],
|
|
33
|
-
"themes": [
|
|
34
|
-
"./themes"
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"pi-maestro-settings-core": "0.2.3",
|
|
39
|
-
"proper-lockfile": "4.1.2"
|
|
40
|
-
},
|
|
41
|
-
"bundledDependencies": [
|
|
42
|
-
"pi-maestro-settings-core"
|
|
43
|
-
],
|
|
44
|
-
"peerDependencies": {
|
|
45
|
-
"@earendil-works/pi-agent-core": "*",
|
|
46
|
-
"@earendil-works/pi-ai": "*",
|
|
47
|
-
"@earendil-works/pi-coding-agent": "*",
|
|
48
|
-
"@earendil-works/pi-tui": "*",
|
|
49
|
-
"pi-maestro-teammate": "^2.8.1",
|
|
50
|
-
"typebox": "*"
|
|
51
|
-
},
|
|
52
|
-
"peerDependenciesMeta": {
|
|
53
|
-
"@earendil-works/pi-agent-core": {
|
|
54
|
-
"optional": true
|
|
55
|
-
},
|
|
56
|
-
"@earendil-works/pi-ai": {
|
|
57
|
-
"optional": true
|
|
58
|
-
},
|
|
59
|
-
"@earendil-works/pi-coding-agent": {
|
|
60
|
-
"optional": true
|
|
61
|
-
},
|
|
62
|
-
"@earendil-works/pi-tui": {
|
|
63
|
-
"optional": true
|
|
64
|
-
},
|
|
65
|
-
"pi-maestro-teammate": {
|
|
66
|
-
"optional": true
|
|
67
|
-
},
|
|
68
|
-
"typebox": {
|
|
69
|
-
"optional": true
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
"devDependencies": {
|
|
73
|
-
"@earendil-works/pi-agent-core": "0.99.0",
|
|
74
|
-
"@earendil-works/pi-ai": "0.99.0",
|
|
75
|
-
"@earendil-works/pi-coding-agent": "0.99.0",
|
|
76
|
-
"@earendil-works/pi-tui": "0.99.0",
|
|
77
|
-
"@types/node": "^22.0.0",
|
|
78
|
-
"pi-maestro-teammate": "2.
|
|
79
|
-
"typebox": "1.3.27",
|
|
80
|
-
"typescript": "^5.5.0"
|
|
81
|
-
},
|
|
82
|
-
"main": "./src/index.ts",
|
|
83
|
-
"exports": {
|
|
84
|
-
".": "./src/index.ts",
|
|
85
|
-
"./v1/events": "./src/public/v1/events.ts",
|
|
86
|
-
"./src/*": "./src/*"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-cockpit",
|
|
3
|
+
"version": "0.24.5",
|
|
4
|
+
"description": "Responsive Maestro operations sidebar, fallback status widgets, and footer for Pi.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22.19.0"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"pi-package",
|
|
11
|
+
"pi",
|
|
12
|
+
"pi-extension",
|
|
13
|
+
"tui",
|
|
14
|
+
"teammate",
|
|
15
|
+
"todo"
|
|
16
|
+
],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"files": [
|
|
19
|
+
"src/",
|
|
20
|
+
"themes/",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"test": "node --test --experimental-transform-types tests/config.test.ts tests/public-events.test.ts tests/ui-ownership-runtime.test.ts tests/maestro-store.test.ts tests/split-pane.test.ts tests/editor-bottom.test.ts tests/sidebar-render.test.ts tests/sidebar-controller.test.ts tests/viewport-stability.test.ts tests/terminal-emulator.test.ts tests/compaction-style.test.ts tests/quiet-tools.test.ts tests/native-host.test.ts tests/native-host-entry.test.ts tests/native-host-quiet.test.ts tests/edit-guard.test.ts tests/agents-store.test.ts tests/endpoint-store.test.ts tests/session-ui-state.test.ts tests/session-tabs.test.ts tests/agent-bar.test.ts tests/supervision-store.test.ts tests/bash-bg-store.test.ts tests/bash-bg-widget.test.ts tests/bash-bg-overlay.test.ts tests/todo-overlay.test.ts tests/agent-overlay.test.ts tests/todo-store.test.ts tests/render.test.ts tests/agent-scroll.test.ts tests/session-bar.test.ts tests/session-detail.test.ts tests/footer.test.ts tests/extension-status.test.ts tests/teammate-message.test.ts tests/input-routing.test.ts tests/input-history-store.test.ts tests/unified-editor.test.ts tests/integration-contract.test.ts tests/stack-widget.test.ts tests/zen-render.test.ts tests/zen-browse.test.ts tests/zen-sheet.test.ts tests/settings-view.test.ts tests/thinking-fold.test.ts tests/thinking-timer.test.ts tests/tick-policy.test.ts tests/ambient.test.ts tests/viewport.test.ts tests/theme-picker.test.ts tests/model-picker.test.ts tests/title-gen.test.ts tests/title-llm.test.ts tests/settings-registry.test.ts tests/settings-coordinator.test.ts tests/settings-locale.test.ts tests/tui-i18n.test.ts tests/settings-shell.test.ts tests/settings-cockpit-provider.test.ts tests/settings-cross-package.test.ts tests/ui-primitives.test.ts tests/settings-shell-secret.test.ts tests/settings-shell-listcrud.test.ts tests/capturing-overlay.test.ts tests/claude-editor.test.ts tests/fullscreen-controller.test.ts tests/transcript-selection.test.ts tests/terminal-cleanup.test.ts tests/terminal-capability.test.ts tests/usage-core.test.ts tests/usage-extension.test.ts tests/usage-history.test.ts tests/usage-sparkline.test.ts tests/patch-health.test.ts",
|
|
25
|
+
"typecheck": "tsc --noEmit",
|
|
26
|
+
"prepack": "node ../../scripts/bundle-settings-core.mjs",
|
|
27
|
+
"postpack": "node ../../scripts/bundle-settings-core.mjs --clean"
|
|
28
|
+
},
|
|
29
|
+
"pi": {
|
|
30
|
+
"extensions": [
|
|
31
|
+
"./src/extension/index.ts"
|
|
32
|
+
],
|
|
33
|
+
"themes": [
|
|
34
|
+
"./themes"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"pi-maestro-settings-core": "0.2.3",
|
|
39
|
+
"proper-lockfile": "4.1.2"
|
|
40
|
+
},
|
|
41
|
+
"bundledDependencies": [
|
|
42
|
+
"pi-maestro-settings-core"
|
|
43
|
+
],
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@earendil-works/pi-agent-core": "*",
|
|
46
|
+
"@earendil-works/pi-ai": "*",
|
|
47
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
48
|
+
"@earendil-works/pi-tui": "*",
|
|
49
|
+
"pi-maestro-teammate": "^2.8.1",
|
|
50
|
+
"typebox": "*"
|
|
51
|
+
},
|
|
52
|
+
"peerDependenciesMeta": {
|
|
53
|
+
"@earendil-works/pi-agent-core": {
|
|
54
|
+
"optional": true
|
|
55
|
+
},
|
|
56
|
+
"@earendil-works/pi-ai": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"@earendil-works/pi-coding-agent": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"@earendil-works/pi-tui": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
65
|
+
"pi-maestro-teammate": {
|
|
66
|
+
"optional": true
|
|
67
|
+
},
|
|
68
|
+
"typebox": {
|
|
69
|
+
"optional": true
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@earendil-works/pi-agent-core": "0.99.0",
|
|
74
|
+
"@earendil-works/pi-ai": "0.99.0",
|
|
75
|
+
"@earendil-works/pi-coding-agent": "0.99.0",
|
|
76
|
+
"@earendil-works/pi-tui": "0.99.0",
|
|
77
|
+
"@types/node": "^22.0.0",
|
|
78
|
+
"pi-maestro-teammate": "2.10.1",
|
|
79
|
+
"typebox": "1.3.27",
|
|
80
|
+
"typescript": "^5.5.0"
|
|
81
|
+
},
|
|
82
|
+
"main": "./src/index.ts",
|
|
83
|
+
"exports": {
|
|
84
|
+
".": "./src/index.ts",
|
|
85
|
+
"./v1/events": "./src/public/v1/events.ts",
|
|
86
|
+
"./src/*": "./src/*"
|
|
87
|
+
}
|
|
88
|
+
}
|
package/src/usage/core.ts
CHANGED
|
@@ -3,6 +3,7 @@ import * as os from "node:os";
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
|
|
5
5
|
export type ProviderKey =
|
|
6
|
+
| "chatgpt"
|
|
6
7
|
| "codex"
|
|
7
8
|
| "claude"
|
|
8
9
|
| "zai"
|
|
@@ -15,6 +16,7 @@ export type ProviderKey =
|
|
|
15
16
|
| "moonshot"
|
|
16
17
|
| "moonshot-cn";
|
|
17
18
|
export type PiProviderId =
|
|
19
|
+
| "openai"
|
|
18
20
|
| "openai-codex"
|
|
19
21
|
| "anthropic"
|
|
20
22
|
| "zai"
|
|
@@ -570,6 +572,16 @@ function readCodexAccountId(token: string): string | undefined {
|
|
|
570
572
|
}
|
|
571
573
|
}
|
|
572
574
|
|
|
575
|
+
export function getChatGPTUsage(): UsageData {
|
|
576
|
+
// Pi's direct-login grant is not a Codex/WHAM credential.
|
|
577
|
+
return {
|
|
578
|
+
session: 0,
|
|
579
|
+
weekly: 0,
|
|
580
|
+
quotaHidden: true,
|
|
581
|
+
notice: "Subscription quota is not exposed by Pi; check https://chatgpt.com/settings/usage",
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
|
|
573
585
|
export async function fetchCodexUsage(token: string, config: RequestConfig = {}): Promise<UsageData> {
|
|
574
586
|
const headers: Record<string, string> = { Authorization: `Bearer ${token}` };
|
|
575
587
|
// Without account routing, WHAM can return a different account's quota.
|
|
@@ -1183,6 +1195,7 @@ export function detectProvider(
|
|
|
1183
1195
|
): ProviderKey | null {
|
|
1184
1196
|
if (!model || typeof model === "string") return null;
|
|
1185
1197
|
switch ((model.provider || "").toLowerCase()) {
|
|
1198
|
+
case "openai": return "chatgpt";
|
|
1186
1199
|
case "openai-codex": return "codex";
|
|
1187
1200
|
case "anthropic": return "claude";
|
|
1188
1201
|
case "zai": return "zai";
|
|
@@ -1200,6 +1213,7 @@ export function detectProvider(
|
|
|
1200
1213
|
|
|
1201
1214
|
export function providerToPiProviderId(provider: ProviderKey): PiProviderId {
|
|
1202
1215
|
switch (provider) {
|
|
1216
|
+
case "chatgpt": return "openai";
|
|
1203
1217
|
case "codex": return "openai-codex";
|
|
1204
1218
|
case "claude": return "anthropic";
|
|
1205
1219
|
case "zai": return "zai";
|
|
@@ -1231,6 +1245,7 @@ export async function fetchAllUsages(
|
|
|
1231
1245
|
): Promise<UsageByProvider> {
|
|
1232
1246
|
const endpoints = config.endpoints ?? resolveUsageEndpoints(config.env);
|
|
1233
1247
|
const results: UsageByProvider = {
|
|
1248
|
+
chatgpt: null,
|
|
1234
1249
|
codex: null,
|
|
1235
1250
|
claude: null,
|
|
1236
1251
|
zai: null,
|
|
@@ -1253,6 +1268,7 @@ export async function fetchAllUsages(
|
|
|
1253
1268
|
}));
|
|
1254
1269
|
};
|
|
1255
1270
|
|
|
1271
|
+
if (tokens.chatgpt) results.chatgpt = getChatGPTUsage();
|
|
1256
1272
|
if (tokens.codex) assign("codex", fetchCodexUsage(tokens.codex, config));
|
|
1257
1273
|
if (tokens.claude) {
|
|
1258
1274
|
assign("claude", fetchClaudeUsageWithFallback(tokens.claude, {
|
package/src/usage/extension.ts
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
fetchAllUsages,
|
|
45
45
|
fetchClaudeUsageWithFallback,
|
|
46
46
|
fetchCodexUsage,
|
|
47
|
+
getChatGPTUsage,
|
|
47
48
|
fetchDeepSeekBalance,
|
|
48
49
|
fetchKimiUsage,
|
|
49
50
|
fetchMiniMaxUsage,
|
|
@@ -65,6 +66,7 @@ import { type CockpitConfig, DEFAULT_CONFIG } from "../types.ts";
|
|
|
65
66
|
const EXTENSION_ID = "pi-cockpit:usage-bars";
|
|
66
67
|
const USAGE_UPDATE_EVENT = `${EXTENSION_ID}:update`;
|
|
67
68
|
const PROVIDERS: readonly ProviderKey[] = [
|
|
69
|
+
"chatgpt",
|
|
68
70
|
"codex",
|
|
69
71
|
"claude",
|
|
70
72
|
"zai",
|
|
@@ -79,6 +81,7 @@ const PROVIDERS: readonly ProviderKey[] = [
|
|
|
79
81
|
];
|
|
80
82
|
|
|
81
83
|
const PROVIDER_LABELS: Record<ProviderKey, string> = {
|
|
84
|
+
chatgpt: "ChatGPT (official)",
|
|
82
85
|
codex: "Codex",
|
|
83
86
|
claude: "Claude",
|
|
84
87
|
zai: "ZAI Coding Plan (Global)",
|
|
@@ -624,6 +627,7 @@ export function createUsageSubsystem(options: CreateUsageSubsystemOptions): Usag
|
|
|
624
627
|
|
|
625
628
|
const endpoints = resolveUsageEndpoints();
|
|
626
629
|
const state: UsageState = {
|
|
630
|
+
chatgpt: null,
|
|
627
631
|
codex: null,
|
|
628
632
|
claude: null,
|
|
629
633
|
zai: null,
|
|
@@ -731,7 +735,7 @@ export function createUsageSubsystem(options: CreateUsageSubsystemOptions): Usag
|
|
|
731
735
|
return false;
|
|
732
736
|
}
|
|
733
737
|
|
|
734
|
-
function
|
|
738
|
+
function isSubscriptionAuth(source: string | undefined): boolean {
|
|
735
739
|
// Pi 0.84 exposes AuthResult.source as a human-readable label rather than a
|
|
736
740
|
// credential-type discriminator. Keep the compatibility assumption in one
|
|
737
741
|
// place until ModelRegistry exposes the resolved credential type directly.
|
|
@@ -746,7 +750,7 @@ export function createUsageSubsystem(options: CreateUsageSubsystemOptions): Usag
|
|
|
746
750
|
|
|
747
751
|
try {
|
|
748
752
|
const resolved = await ctx.modelRegistry.getProviderAuth(providerId);
|
|
749
|
-
if (provider === "claude" && !
|
|
753
|
+
if ((provider === "claude" || provider === "chatgpt") && !isSubscriptionAuth(resolved?.source)) return {};
|
|
750
754
|
const token = resolved?.auth.apiKey;
|
|
751
755
|
if (token) return { token };
|
|
752
756
|
// Some OAuth flows (e.g. kimi-coding) expose the token only as a Bearer
|
|
@@ -778,6 +782,7 @@ export function createUsageSubsystem(options: CreateUsageSubsystemOptions): Usag
|
|
|
778
782
|
return;
|
|
779
783
|
}
|
|
780
784
|
|
|
785
|
+
if (provider === "chatgpt") state.chatgpt = getChatGPTUsage();
|
|
781
786
|
if (provider === "codex") state.codex = await fetchCodexUsage(credential.token, { signal });
|
|
782
787
|
if (provider === "claude") state.claude = await fetchClaudeUsageWithFallback(credential.token, { signal });
|
|
783
788
|
if (provider === "zai") state.zai = await fetchZaiUsage(credential.token, "zai", { endpoints, signal });
|
|
@@ -886,6 +891,20 @@ export function createUsageSubsystem(options: CreateUsageSubsystemOptions): Usag
|
|
|
886
891
|
pollTimer.unref?.();
|
|
887
892
|
}
|
|
888
893
|
|
|
894
|
+
const unsubscribeAccountChanged = pi.events.on("pi:account-changed", (payload: unknown) => {
|
|
895
|
+
if (!payload || typeof payload !== "object" || !("providerId" in payload) ||
|
|
896
|
+
typeof payload.providerId !== "string") return;
|
|
897
|
+
const provider = detectProvider({ provider: payload.providerId });
|
|
898
|
+
if (!provider) return;
|
|
899
|
+
state[provider] = null;
|
|
900
|
+
delete state.available[provider];
|
|
901
|
+
if (provider === state.activeProvider) {
|
|
902
|
+
providerPollController?.abort();
|
|
903
|
+
onStatusChange();
|
|
904
|
+
if (!isManualRefresh()) void poll();
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
|
|
889
908
|
return {
|
|
890
909
|
async start(ctx) {
|
|
891
910
|
currentContext = ctx;
|
|
@@ -983,6 +1002,7 @@ export function createUsageSubsystem(options: CreateUsageSubsystemOptions): Usag
|
|
|
983
1002
|
},
|
|
984
1003
|
|
|
985
1004
|
dispose() {
|
|
1005
|
+
unsubscribeAccountChanged();
|
|
986
1006
|
providerPollController?.abort();
|
|
987
1007
|
providerPollController = undefined;
|
|
988
1008
|
sessionController?.abort();
|