@beyona/pi-zai-usage 0.3.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.
- package/CHANGELOG.md +177 -0
- package/LICENSE +21 -0
- package/README.md +100 -0
- package/dist/api.d.ts +34 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +39 -0
- package/dist/api.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/usage-lib/api.d.ts +34 -0
- package/dist/usage-lib/api.d.ts.map +1 -0
- package/dist/usage-lib/api.js +74 -0
- package/dist/usage-lib/api.js.map +1 -0
- package/dist/usage-lib/cache.d.ts +22 -0
- package/dist/usage-lib/cache.d.ts.map +1 -0
- package/dist/usage-lib/cache.js +56 -0
- package/dist/usage-lib/cache.js.map +1 -0
- package/dist/usage-lib/color.d.ts +24 -0
- package/dist/usage-lib/color.d.ts.map +1 -0
- package/dist/usage-lib/color.js +38 -0
- package/dist/usage-lib/color.js.map +1 -0
- package/dist/usage-lib/config.d.ts +34 -0
- package/dist/usage-lib/config.d.ts.map +1 -0
- package/dist/usage-lib/config.js +86 -0
- package/dist/usage-lib/config.js.map +1 -0
- package/dist/usage-lib/datetime.d.ts +13 -0
- package/dist/usage-lib/datetime.d.ts.map +1 -0
- package/dist/usage-lib/datetime.js +46 -0
- package/dist/usage-lib/datetime.js.map +1 -0
- package/dist/usage-lib/extension.d.ts +14 -0
- package/dist/usage-lib/extension.d.ts.map +1 -0
- package/dist/usage-lib/extension.js +51 -0
- package/dist/usage-lib/extension.js.map +1 -0
- package/dist/usage-lib/index.d.ts +14 -0
- package/dist/usage-lib/index.d.ts.map +1 -0
- package/dist/usage-lib/index.js +13 -0
- package/dist/usage-lib/index.js.map +1 -0
- package/dist/usage-lib/types.d.ts +58 -0
- package/dist/usage-lib/types.d.ts.map +1 -0
- package/dist/usage-lib/types.js +6 -0
- package/dist/usage-lib/types.js.map +1 -0
- package/package.json +75 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.3.2] - 2026-06-19
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- upgrade usage lib for custom warning values
|
|
15
|
+
|
|
16
|
+
## [0.3.1] - 2026-06-17
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- use correct format for colored values
|
|
21
|
+
|
|
22
|
+
## [0.3.0] - 2026-06-17
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- use warning colors for high quota usage
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **deps-ci**: bump codecov/codecov-action from 6 to 7 (#42)
|
|
31
|
+
- **deps**: update dependencies
|
|
32
|
+
- **deps**: update dependencies (#39)
|
|
33
|
+
- **deps**: update dependencies (#40)
|
|
34
|
+
- **deps-dev**: update dependencies (#41)
|
|
35
|
+
- **deps**: update dependencies (#43)
|
|
36
|
+
- **deps**: update dependencies (#44)
|
|
37
|
+
- **deps**: update dependencies (#45)
|
|
38
|
+
|
|
39
|
+
## [0.2.2] - 2026-05-30
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- use @alexanderfortin/pi-usage-lib shared library (#38)
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- fix ts type issue
|
|
48
|
+
|
|
49
|
+
## [0.2.1] - 2026-05-29
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- **deps**: update dependencies (#34)
|
|
54
|
+
- **deps**: update dependencies (#35)
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
- add UTC default timezone to support sbx sandboxes
|
|
59
|
+
|
|
60
|
+
## [0.2.0] - 2026-05-26
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
|
|
64
|
+
- show error codes in footer instead of raw console errors
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- **deps**: update dependencies (#32)
|
|
69
|
+
- **deps**: update dependencies (#33)
|
|
70
|
+
|
|
71
|
+
## [0.1.14] - 2026-05-18
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
|
|
75
|
+
- remove pinned dependency version
|
|
76
|
+
|
|
77
|
+
## [0.1.13] - 2026-05-18
|
|
78
|
+
|
|
79
|
+
### Fixed
|
|
80
|
+
|
|
81
|
+
- handle empty/malformed API responses from Pi v0.75.0 fetch changes
|
|
82
|
+
|
|
83
|
+
## [0.1.12] - 2026-05-08
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- **deps**: update namespace to @earendil-works
|
|
88
|
+
|
|
89
|
+
## [0.1.11] - 2026-05-04
|
|
90
|
+
|
|
91
|
+
### Fixed
|
|
92
|
+
|
|
93
|
+
- **deps**: bump dependencies
|
|
94
|
+
|
|
95
|
+
## [0.1.10] - 2026-04-26
|
|
96
|
+
|
|
97
|
+
### Fixed
|
|
98
|
+
|
|
99
|
+
- **deps**: update dependencies to latest versions (#10)
|
|
100
|
+
|
|
101
|
+
## [0.1.9] - 2026-04-14
|
|
102
|
+
|
|
103
|
+
### Changed
|
|
104
|
+
|
|
105
|
+
- **deps**: bump @mariozechner/pi-coding-agent (#1)
|
|
106
|
+
- **deps**: update Pi and other deps
|
|
107
|
+
|
|
108
|
+
### Fixed
|
|
109
|
+
|
|
110
|
+
- bump release
|
|
111
|
+
|
|
112
|
+
## [0.1.8] - 2026-04-09
|
|
113
|
+
|
|
114
|
+
### Fixed
|
|
115
|
+
|
|
116
|
+
- correct CHANGELOG format and semantic release configuration
|
|
117
|
+
|
|
118
|
+
## [0.1.7] - 2026-04-09
|
|
119
|
+
|
|
120
|
+
### Fixed
|
|
121
|
+
|
|
122
|
+
- add semantic release automated workflow
|
|
123
|
+
|
|
124
|
+
## [0.1.6] - 2026-04-04
|
|
125
|
+
|
|
126
|
+
### Changed
|
|
127
|
+
|
|
128
|
+
- Manual version bump for NPM publishing
|
|
129
|
+
|
|
130
|
+
## [0.1.3] - 2026-04-04
|
|
131
|
+
|
|
132
|
+
### Changed
|
|
133
|
+
|
|
134
|
+
- remove redundant cleanup for turn_end
|
|
135
|
+
- reduce duplication in set status logic
|
|
136
|
+
- fix readme
|
|
137
|
+
|
|
138
|
+
## [0.1.2] - 2026-04-03
|
|
139
|
+
|
|
140
|
+
### Changed
|
|
141
|
+
|
|
142
|
+
- update README with install instructions
|
|
143
|
+
- cleanup release docs
|
|
144
|
+
|
|
145
|
+
## [0.1.1] - 2026-04-03
|
|
146
|
+
|
|
147
|
+
### Added
|
|
148
|
+
|
|
149
|
+
- Usage tool for checking Z.ai API token usage quota
|
|
150
|
+
- Auto footer display when using Z.ai models
|
|
151
|
+
- Smart caching (30-second cache to avoid excessive API calls)
|
|
152
|
+
- Temporal-based datetime formatting
|
|
153
|
+
- Time tracking (reset time and remaining time display)
|
|
154
|
+
|
|
155
|
+
### Changed
|
|
156
|
+
|
|
157
|
+
- Enabled full OIDC publishing (no NPM_TOKEN required)
|
|
158
|
+
|
|
159
|
+
[unreleased]: https://github.com/shaftoe/pi-zai-usage/compare/v0.3.2...HEAD
|
|
160
|
+
[0.3.2]: https://github.com/shaftoe/pi-zai-usage/compare/v0.3.1...v0.3.2
|
|
161
|
+
[0.3.1]: https://github.com/shaftoe/pi-zai-usage/compare/v0.3.0...v0.3.1
|
|
162
|
+
[0.3.0]: https://github.com/shaftoe/pi-zai-usage/compare/v0.2.2...v0.3.0
|
|
163
|
+
[0.2.2]: https://github.com/shaftoe/pi-zai-usage/compare/v0.2.1...v0.2.2
|
|
164
|
+
[0.2.1]: https://github.com/shaftoe/pi-zai-usage/compare/v0.2.0...v0.2.1
|
|
165
|
+
[0.2.0]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.14...v0.2.0
|
|
166
|
+
[0.1.14]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.13...v0.1.14
|
|
167
|
+
[0.1.13]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.12...v0.1.13
|
|
168
|
+
[0.1.12]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.11...v0.1.12
|
|
169
|
+
[0.1.11]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.10...v0.1.11
|
|
170
|
+
[0.1.10]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.9...v0.1.10
|
|
171
|
+
[0.1.9]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.8...v0.1.9
|
|
172
|
+
[0.1.8]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.7...v0.1.8
|
|
173
|
+
[0.1.7]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.6...v0.1.7
|
|
174
|
+
[0.1.6]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.3...v0.1.6
|
|
175
|
+
[0.1.3]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.2...v0.1.3
|
|
176
|
+
[0.1.2]: https://github.com/shaftoe/pi-zai-usage/compare/v0.1.1...v0.1.2
|
|
177
|
+
[0.1.1]: https://github.com/shaftoe/pi-zai-usage/releases/tag/v0.1.1
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexander Fortin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Pi coding agent Z.ai Usage Extension
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
A [Pi coding agent](https://pi.dev/) extension that monitors [Z.ai subscription](https://z.ai/subscribe) API token usage quota and automatically displays usage in the footer when using the Z.ai provider.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Auto Footer Display**: Automatically shows usage in the footer when using Z.ai models
|
|
12
|
+
- **Smart Caching**: Caches usage data for 30 seconds to avoid excessive API calls
|
|
13
|
+
- **Time Tracking**: Displays remaining time until quota reset
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pi install npm:@beyona/pi-zai-usage
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
or if you prefer to build and keep a source checkout locally, clone your fork and run:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Install dependencies
|
|
25
|
+
bun install
|
|
26
|
+
|
|
27
|
+
# Build the extension
|
|
28
|
+
bun run build
|
|
29
|
+
|
|
30
|
+
# Install the extension
|
|
31
|
+
pi install ./
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Development
|
|
35
|
+
|
|
36
|
+
This project uses modern TypeScript development tooling:
|
|
37
|
+
|
|
38
|
+
- **Bun** - Fast package manager and runtime
|
|
39
|
+
- **TypeScript 6** - Static type checking with strict mode enabled
|
|
40
|
+
- **Biome** - Ultra-fast linter and formatter
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Type check
|
|
44
|
+
bun run typecheck
|
|
45
|
+
|
|
46
|
+
# Lint code
|
|
47
|
+
bun run lint
|
|
48
|
+
|
|
49
|
+
# Auto-fix lint issues
|
|
50
|
+
bun run lint:fix
|
|
51
|
+
|
|
52
|
+
# Format code
|
|
53
|
+
bun run format
|
|
54
|
+
|
|
55
|
+
# Run all checks
|
|
56
|
+
bun run check
|
|
57
|
+
|
|
58
|
+
# Watch mode for development
|
|
59
|
+
bun run dev
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
### Automatic Footer Display
|
|
65
|
+
|
|
66
|
+
When using a Z.ai model (e.g., `glm-4.7`, `glm-5`, `glm-5-flash`), the extension automatically displays the usage in the footer (between brackets the time left for the quota to be reset):
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
Z.ai: 45% (2h 15m 30s)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The footer updates after each AI turn and on model selection changes.
|
|
73
|
+
|
|
74
|
+
## Configuration
|
|
75
|
+
|
|
76
|
+
No configuration needed. The extension automatically:
|
|
77
|
+
- Uses cached data for 30 seconds to avoid excessive API calls
|
|
78
|
+
- Shows/updates status only when Z.ai models are active
|
|
79
|
+
- Clears status when switching to non-Z.ai models
|
|
80
|
+
|
|
81
|
+
## API
|
|
82
|
+
|
|
83
|
+
The extension uses the Z.ai API endpoint: `https://api.z.ai/api/monitor/usage/quota/limit`
|
|
84
|
+
|
|
85
|
+
Make sure you're logged in to Z.ai via Pi (`/login for Z.ai`).
|
|
86
|
+
|
|
87
|
+
## Releasing
|
|
88
|
+
|
|
89
|
+
This project uses automated publishing to NPM via GitHub Actions. The workflow will:
|
|
90
|
+
- Run all CI checks
|
|
91
|
+
- Build the package
|
|
92
|
+
- Publish to NPM with provenance (signed) via [trusted publishing](https://docs.npmjs.com/trusted-publishers)
|
|
93
|
+
|
|
94
|
+
## Redistribution notes
|
|
95
|
+
|
|
96
|
+
This fork vendors the helper code formerly provided by `@alexanderfortin/pi-usage-lib` so the published `@beyona/pi-zai-usage` package has no runtime dependency on that package. The vendored helper code and original extension are MIT-licensed by Alexander Fortin.
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Z.ai Usage Checker - Pi Extension
|
|
3
|
+
* Provider-specific API interaction using shared library primitives
|
|
4
|
+
*/
|
|
5
|
+
import type { ModelRegistry } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import { UsageError } from "./usage-lib";
|
|
7
|
+
export interface ZaiUsageResponse {
|
|
8
|
+
data: {
|
|
9
|
+
limits: Array<{
|
|
10
|
+
type: string;
|
|
11
|
+
percentage: number;
|
|
12
|
+
nextResetTime?: number;
|
|
13
|
+
}>;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface ZaiApiError {
|
|
17
|
+
code: number;
|
|
18
|
+
msg: string;
|
|
19
|
+
success: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface ZaiUsageData {
|
|
22
|
+
percentage: number;
|
|
23
|
+
resetTime?: string;
|
|
24
|
+
timeRemaining?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fetch Z.ai usage from the API
|
|
28
|
+
*
|
|
29
|
+
* Uses shared library primitives (buildAuthHeaders, safeFetch, safeParseJson)
|
|
30
|
+
* for sandbox-aware auth, error handling, and JSON parsing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getZaiUsage(modelRegistry: Pick<ModelRegistry, "getApiKeyForProvider">): Promise<ZaiUsageData>;
|
|
33
|
+
export { UsageError };
|
|
34
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAML,UAAU,EACX,MAAM,aAAa,CAAA;AAIpB,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE;QACJ,MAAM,EAAE,KAAK,CAAC;YACZ,IAAI,EAAE,MAAM,CAAA;YACZ,UAAU,EAAE,MAAM,CAAA;YAClB,aAAa,CAAC,EAAE,MAAM,CAAA;SACvB,CAAC,CAAA;KACH,CAAA;CACF;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAID;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,sBAAsB,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,CA+BvB;AAGD,OAAO,EAAE,UAAU,EAAE,CAAA"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Z.ai Usage Checker - Pi Extension
|
|
3
|
+
* Provider-specific API interaction using shared library primitives
|
|
4
|
+
*/
|
|
5
|
+
import { buildAuthHeaders, formatInstantFromEpochMs, formatTimeRemainingFromEpochMs, safeFetch, safeParseJson, UsageError, } from "./usage-lib";
|
|
6
|
+
const ZAI_USAGE_API_URL = "https://api.z.ai/api/monitor/usage/quota/limit";
|
|
7
|
+
/**
|
|
8
|
+
* Fetch Z.ai usage from the API
|
|
9
|
+
*
|
|
10
|
+
* Uses shared library primitives (buildAuthHeaders, safeFetch, safeParseJson)
|
|
11
|
+
* for sandbox-aware auth, error handling, and JSON parsing.
|
|
12
|
+
*/
|
|
13
|
+
export async function getZaiUsage(modelRegistry) {
|
|
14
|
+
const headers = await buildAuthHeaders(modelRegistry, "zai");
|
|
15
|
+
const response = await safeFetch(ZAI_USAGE_API_URL, { headers });
|
|
16
|
+
const parsed = await safeParseJson(response);
|
|
17
|
+
// Z.ai API can return HTTP 200 with an error body
|
|
18
|
+
// e.g. {"code":401,"msg":"token expired or incorrect","success":false}
|
|
19
|
+
const apiError = parsed;
|
|
20
|
+
if (typeof apiError.success === "boolean" && !apiError.success && apiError.msg) {
|
|
21
|
+
throw new UsageError(`Z.ai API error: ${apiError.msg}`, `api${apiError.code ?? "unknown"}`);
|
|
22
|
+
}
|
|
23
|
+
const data = parsed;
|
|
24
|
+
const tokensLimit = data.data?.limits?.find((limit) => limit.type === "TOKENS_LIMIT");
|
|
25
|
+
if (!tokensLimit) {
|
|
26
|
+
throw new UsageError("TOKENS_LIMIT not found in API response", "nolimit");
|
|
27
|
+
}
|
|
28
|
+
const result = {
|
|
29
|
+
percentage: tokensLimit.percentage,
|
|
30
|
+
};
|
|
31
|
+
if (tokensLimit.nextResetTime) {
|
|
32
|
+
result.resetTime = formatInstantFromEpochMs(tokensLimit.nextResetTime);
|
|
33
|
+
result.timeRemaining = formatTimeRemainingFromEpochMs(tokensLimit.nextResetTime);
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
// Re-export UsageError for consumers that need it
|
|
38
|
+
export { UsageError };
|
|
39
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,8BAA8B,EAC9B,SAAS,EACT,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAA;AA0BpB,MAAM,iBAAiB,GAAG,gDAAgD,CAAA;AAE1E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,aAA0D;IAE1D,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;IAE5D,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;IAEhE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAA;IAE5C,kDAAkD;IAClD,uEAAuE;IACvE,MAAM,QAAQ,GAAG,MAAqB,CAAA;IACtC,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC;QAC/E,MAAM,IAAI,UAAU,CAAC,mBAAmB,QAAQ,CAAC,GAAG,EAAE,EAAE,MAAM,QAAQ,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,CAAA;IAC7F,CAAC;IAED,MAAM,IAAI,GAAG,MAA0B,CAAA;IACvC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,CAAA;IAErF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,UAAU,CAAC,wCAAwC,EAAE,SAAS,CAAC,CAAA;IAC3E,CAAC;IAED,MAAM,MAAM,GAAiB;QAC3B,UAAU,EAAE,WAAW,CAAC,UAAU;KACnC,CAAA;IAED,IAAI,WAAW,CAAC,aAAa,EAAE,CAAC;QAC9B,MAAM,CAAC,SAAS,GAAG,wBAAwB,CAAC,WAAW,CAAC,aAAa,CAAC,CAAA;QACtE,MAAM,CAAC,aAAa,GAAG,8BAA8B,CAAC,WAAW,CAAC,aAAa,CAAC,CAAA;IAClF,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,kDAAkD;AAClD,OAAO,EAAE,UAAU,EAAE,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Z.ai Usage Checker - Pi Extension
|
|
3
|
+
*
|
|
4
|
+
* Uses createUsageExtension from the shared library to handle all
|
|
5
|
+
* event registration, provider matching, caching, and footer lifecycle.
|
|
6
|
+
*/
|
|
7
|
+
import { type ZaiUsageData } from "./api";
|
|
8
|
+
import { createUsageExtension, type Theme } from "./usage-lib";
|
|
9
|
+
/** Render Z.ai usage data into a themed footer string */
|
|
10
|
+
export declare function renderZaiStatus(data: ZaiUsageData, theme: Theme): string;
|
|
11
|
+
declare const extension: ReturnType<typeof createUsageExtension<ZaiUsageData>>;
|
|
12
|
+
export default extension;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,EAAsB,oBAAoB,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAA;AAElF,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAOxE;AAED,QAAA,MAAM,SAAS,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,YAAY,CAAC,CAOjE,CAAA;AAEJ,eAAe,SAAS,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Z.ai Usage Checker - Pi Extension
|
|
3
|
+
*
|
|
4
|
+
* Uses createUsageExtension from the shared library to handle all
|
|
5
|
+
* event registration, provider matching, caching, and footer lifecycle.
|
|
6
|
+
*/
|
|
7
|
+
import { getZaiUsage } from "./api";
|
|
8
|
+
import { colorForPercentage, createUsageExtension } from "./usage-lib";
|
|
9
|
+
/** Render Z.ai usage data into a themed footer string */
|
|
10
|
+
export function renderZaiStatus(data, theme) {
|
|
11
|
+
const displayPercentage = Math.round(data.percentage * 10) / 10;
|
|
12
|
+
let status = `${theme.fg("muted", "Z.ai:")}${colorForPercentage(displayPercentage, theme)(`${displayPercentage}%`)}`;
|
|
13
|
+
if (data.resetTime && data.timeRemaining) {
|
|
14
|
+
status += ` ${theme.fg("dim", `(${data.timeRemaining})`)}`;
|
|
15
|
+
}
|
|
16
|
+
return status;
|
|
17
|
+
}
|
|
18
|
+
const extension = createUsageExtension({
|
|
19
|
+
providerPrefix: "zai",
|
|
20
|
+
statusKey: "zai-usage",
|
|
21
|
+
label: "Z.ai",
|
|
22
|
+
fetchUsage: getZaiUsage,
|
|
23
|
+
renderStatus: renderZaiStatus,
|
|
24
|
+
});
|
|
25
|
+
export default extension;
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAqB,MAAM,OAAO,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAc,MAAM,aAAa,CAAA;AAElF,yDAAyD;AACzD,MAAM,UAAU,eAAe,CAAC,IAAkB,EAAE,KAAY;IAC9D,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,EAAE,CAAA;IAC/D,IAAI,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,GAAG,iBAAiB,GAAG,CAAC,EAAE,CAAA;IACpH,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACzC,MAAM,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,aAAa,GAAG,CAAC,EAAE,CAAA;IAC5D,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,SAAS,GACb,oBAAoB,CAAe;IACjC,cAAc,EAAE,KAAK;IACrB,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,MAAM;IACb,UAAU,EAAE,WAAW;IACvB,YAAY,EAAE,eAAe;CAC9B,CAAC,CAAA;AAEJ,eAAe,SAAS,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* API utilities: sandbox-aware auth, safe fetch, structured errors.
|
|
4
|
+
*/
|
|
5
|
+
import type { ModelRegistry } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
/** Error thrown by API interactions; carries a short code for footer display */
|
|
7
|
+
export declare class UsageError extends Error {
|
|
8
|
+
readonly code: string;
|
|
9
|
+
readonly name = "UsageError";
|
|
10
|
+
constructor(message: string, code: string);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build authenticated headers using a 3-way sandbox-aware strategy:
|
|
14
|
+
*
|
|
15
|
+
* 1. Real key present → send "Authorization: Bearer <key>"
|
|
16
|
+
* 2. Key is "proxy-managed" sentinel → don't set auth (sandbox proxy handles it)
|
|
17
|
+
* 3. No key → don't set auth (API returns 401, shown as error)
|
|
18
|
+
*
|
|
19
|
+
* Also sets Accept-Encoding: identity to work around Pi v0.75.0's
|
|
20
|
+
* undici EnvHttpProxyAgent gzip decompression issue.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildAuthHeaders(modelRegistry: Pick<ModelRegistry, "getApiKeyForProvider">, providerName: string, extra?: Record<string, string>): Promise<Record<string, string>>;
|
|
23
|
+
/**
|
|
24
|
+
* Fetch with error wrapping:
|
|
25
|
+
* - Network errors (DNS, timeout, proxy) → UsageError("fetch")
|
|
26
|
+
* - HTTP errors (4xx, 5xx) → UsageError("http{status}")
|
|
27
|
+
*/
|
|
28
|
+
export declare function safeFetch(url: string, init?: RequestInit): Promise<Response>;
|
|
29
|
+
/**
|
|
30
|
+
* Parse JSON with error handling:
|
|
31
|
+
* - Empty/malformed body → UsageError("badjson")
|
|
32
|
+
*/
|
|
33
|
+
export declare function safeParseJson<T = unknown>(response: Response): Promise<T>;
|
|
34
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/usage-lib/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAQpE,gFAAgF;AAChF,qBAAa,UAAW,SAAQ,KAAK;aAIjB,IAAI,EAAE,MAAM;IAH9B,SAAkB,IAAI,gBAAe;gBAEnC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM;CAI/B;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,sBAAsB,CAAC,EAC1D,YAAY,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAajC;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAclF;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAO/E"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* API utilities: sandbox-aware auth, safe fetch, structured errors.
|
|
4
|
+
*/
|
|
5
|
+
/** Sentinel value injected by Docker Sandbox proxy when an env var is
|
|
6
|
+
* proxy-managed (listed under environment.proxyManaged in spec.yaml).
|
|
7
|
+
* When the API key reads as this value, the proxy will inject the real
|
|
8
|
+
* Authorization header, so we should not set it ourselves. */
|
|
9
|
+
const PROXY_MANAGED_SENTINEL = "proxy-managed";
|
|
10
|
+
/** Error thrown by API interactions; carries a short code for footer display */
|
|
11
|
+
export class UsageError extends Error {
|
|
12
|
+
code;
|
|
13
|
+
name = "UsageError";
|
|
14
|
+
constructor(message, code) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.code = code;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build authenticated headers using a 3-way sandbox-aware strategy:
|
|
21
|
+
*
|
|
22
|
+
* 1. Real key present → send "Authorization: Bearer <key>"
|
|
23
|
+
* 2. Key is "proxy-managed" sentinel → don't set auth (sandbox proxy handles it)
|
|
24
|
+
* 3. No key → don't set auth (API returns 401, shown as error)
|
|
25
|
+
*
|
|
26
|
+
* Also sets Accept-Encoding: identity to work around Pi v0.75.0's
|
|
27
|
+
* undici EnvHttpProxyAgent gzip decompression issue.
|
|
28
|
+
*/
|
|
29
|
+
export async function buildAuthHeaders(modelRegistry, providerName, extra) {
|
|
30
|
+
const apiKey = await modelRegistry.getApiKeyForProvider(providerName);
|
|
31
|
+
const headers = {
|
|
32
|
+
// Prevent gzip encoding: Pi v0.75.0 routes fetch() through undici's
|
|
33
|
+
// EnvHttpProxyAgent which fails to decompress gzip responses, causing
|
|
34
|
+
// response.json() to see garbled bytes and throw SyntaxError.
|
|
35
|
+
"Accept-Encoding": "identity",
|
|
36
|
+
...extra,
|
|
37
|
+
};
|
|
38
|
+
if (apiKey && apiKey !== PROXY_MANAGED_SENTINEL) {
|
|
39
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
40
|
+
}
|
|
41
|
+
return headers;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Fetch with error wrapping:
|
|
45
|
+
* - Network errors (DNS, timeout, proxy) → UsageError("fetch")
|
|
46
|
+
* - HTTP errors (4xx, 5xx) → UsageError("http{status}")
|
|
47
|
+
*/
|
|
48
|
+
export async function safeFetch(url, init) {
|
|
49
|
+
let response;
|
|
50
|
+
try {
|
|
51
|
+
response = await fetch(url, init);
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
throw new UsageError(`Network error: ${e instanceof Error ? e.message : String(e)}`, "fetch");
|
|
55
|
+
}
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
throw new UsageError(`API request failed with status ${response.status}`, `http${response.status}`);
|
|
58
|
+
}
|
|
59
|
+
return response;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Parse JSON with error handling:
|
|
63
|
+
* - Empty/malformed body → UsageError("badjson")
|
|
64
|
+
*/
|
|
65
|
+
export async function safeParseJson(response) {
|
|
66
|
+
try {
|
|
67
|
+
return (await response.json());
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
const message = e instanceof SyntaxError ? "empty or malformed response" : String(e);
|
|
71
|
+
throw new UsageError(`API returned invalid JSON (${message})`, "badjson");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/usage-lib/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;8DAG8D;AAC9D,MAAM,sBAAsB,GAAG,eAAe,CAAA;AAE9C,gFAAgF;AAChF,MAAM,OAAO,UAAW,SAAQ,KAAK;IAIjB;IAHA,IAAI,GAAG,YAAY,CAAA;IACrC,YACE,OAAe,EACC,IAAY;QAE5B,KAAK,CAAC,OAAO,CAAC,CAAA;QAFE,SAAI,GAAJ,IAAI,CAAQ;IAG9B,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,aAA0D,EAC1D,YAAoB,EACpB,KAA8B;IAE9B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAA;IACrE,MAAM,OAAO,GAA2B;QACtC,oEAAoE;QACpE,sEAAsE;QACtE,8DAA8D;QAC9D,iBAAiB,EAAE,UAAU;QAC7B,GAAG,KAAK;KACT,CAAA;IACD,IAAI,MAAM,IAAI,MAAM,KAAK,sBAAsB,EAAE,CAAC;QAChD,OAAO,CAAC,aAAa,GAAG,UAAU,MAAM,EAAE,CAAA;IAC5C,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,IAAkB;IAC7D,IAAI,QAAkB,CAAA;IACtB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACnC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC/F,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,UAAU,CAClB,kCAAkC,QAAQ,CAAC,MAAM,EAAE,EACnD,OAAO,QAAQ,CAAC,MAAM,EAAE,CACzB,CAAA;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAc,QAAkB;IACjE,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAA;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,CAAC,YAAY,WAAW,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACpF,MAAM,IAAI,UAAU,CAAC,8BAA8B,OAAO,GAAG,EAAE,SAAS,CAAC,CAAA;IAC3E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* Generic usage cache with themed footer rendering.
|
|
4
|
+
*/
|
|
5
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import type { FetchUsageFn, RenderErrorFn, RenderStatusFn } from "./types";
|
|
7
|
+
/** Generic cache for usage data with cooldown and themed footer rendering */
|
|
8
|
+
export declare class UsageCache<TData> {
|
|
9
|
+
private readonly statusKey;
|
|
10
|
+
private readonly fetchUsage;
|
|
11
|
+
private readonly renderStatus;
|
|
12
|
+
private readonly cooldownMs;
|
|
13
|
+
private lastData;
|
|
14
|
+
private lastFetchTime;
|
|
15
|
+
private readonly renderError;
|
|
16
|
+
constructor(statusKey: string, label: string, fetchUsage: FetchUsageFn<TData>, renderStatus: RenderStatusFn<TData>, renderError: RenderErrorFn | undefined, cooldownMs?: number);
|
|
17
|
+
/** Update footer status from API or cache */
|
|
18
|
+
updateStatus(ctx: ExtensionContext): Promise<void>;
|
|
19
|
+
/** Clear footer status */
|
|
20
|
+
clear(ctx: ExtensionContext): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/usage-lib/cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAGvE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAS,MAAM,SAAS,CAAA;AAUjF,6EAA6E;AAC7E,qBAAa,UAAU,CAAC,KAAK;IAMzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAV7B,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAe;gBAGxB,SAAS,EAAE,MAAM,EAClC,KAAK,EAAE,MAAM,EACI,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC,EAC/B,YAAY,EAAE,cAAc,CAAC,KAAK,CAAC,EACpD,WAAW,EAAE,aAAa,GAAG,SAAS,EACrB,UAAU,SAAS;IAMtC,6CAA6C;IACvC,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBxD,0BAA0B;IAC1B,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;CAGnC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* Generic usage cache with themed footer rendering.
|
|
4
|
+
*/
|
|
5
|
+
import { Temporal } from "temporal-polyfill";
|
|
6
|
+
import { UsageError } from "./api";
|
|
7
|
+
/** Build the default error renderer for a given label */
|
|
8
|
+
function defaultRenderError(label) {
|
|
9
|
+
return (error, theme) => {
|
|
10
|
+
const code = error instanceof UsageError ? error.code : "fetch";
|
|
11
|
+
return theme.fg("muted", `${label}:`) + theme.fg("error", `<err:${code}>`);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Generic cache for usage data with cooldown and themed footer rendering */
|
|
15
|
+
export class UsageCache {
|
|
16
|
+
statusKey;
|
|
17
|
+
fetchUsage;
|
|
18
|
+
renderStatus;
|
|
19
|
+
cooldownMs;
|
|
20
|
+
lastData = null;
|
|
21
|
+
lastFetchTime = 0;
|
|
22
|
+
renderError;
|
|
23
|
+
constructor(statusKey, label, fetchUsage, renderStatus, renderError, cooldownMs = 30_000) {
|
|
24
|
+
this.statusKey = statusKey;
|
|
25
|
+
this.fetchUsage = fetchUsage;
|
|
26
|
+
this.renderStatus = renderStatus;
|
|
27
|
+
this.cooldownMs = cooldownMs;
|
|
28
|
+
// Use default error rendering
|
|
29
|
+
this.renderError = renderError ?? defaultRenderError(label);
|
|
30
|
+
}
|
|
31
|
+
/** Update footer status from API or cache */
|
|
32
|
+
async updateStatus(ctx) {
|
|
33
|
+
try {
|
|
34
|
+
const now = Temporal.Now.instant().epochMilliseconds;
|
|
35
|
+
// Use cached data if still fresh
|
|
36
|
+
if (this.lastData && now - this.lastFetchTime < this.cooldownMs) {
|
|
37
|
+
ctx.ui.setStatus(this.statusKey, this.renderStatus(this.lastData, ctx.ui.theme));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const data = await this.fetchUsage(ctx.modelRegistry);
|
|
41
|
+
this.lastData = data;
|
|
42
|
+
this.lastFetchTime = now;
|
|
43
|
+
ctx.ui.setStatus(this.statusKey, this.renderStatus(data, ctx.ui.theme));
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
// Show error code in footer (no console.error)
|
|
47
|
+
const rendered = this.renderError(error, ctx.ui.theme);
|
|
48
|
+
ctx.ui.setStatus(this.statusKey, rendered); // undefined → clears
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Clear footer status */
|
|
52
|
+
clear(ctx) {
|
|
53
|
+
ctx.ui.setStatus(this.statusKey, undefined);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/usage-lib/cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAGlC,yDAAyD;AACzD,SAAS,kBAAkB,CAAC,KAAa;IACvC,OAAO,CAAC,KAAc,EAAE,KAAY,EAAU,EAAE;QAC9C,MAAM,IAAI,GAAG,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAA;QAC/D,OAAO,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,IAAI,GAAG,CAAC,CAAA;IAC5E,CAAC,CAAA;AACH,CAAC;AAED,6EAA6E;AAC7E,MAAM,OAAO,UAAU;IAMF;IAEA;IACA;IAEA;IAVX,QAAQ,GAAiB,IAAI,CAAA;IAC7B,aAAa,GAAG,CAAC,CAAA;IACR,WAAW,CAAe;IAE3C,YACmB,SAAiB,EAClC,KAAa,EACI,UAA+B,EAC/B,YAAmC,EACpD,WAAsC,EACrB,aAAa,MAAM;QALnB,cAAS,GAAT,SAAS,CAAQ;QAEjB,eAAU,GAAV,UAAU,CAAqB;QAC/B,iBAAY,GAAZ,YAAY,CAAuB;QAEnC,eAAU,GAAV,UAAU,CAAS;QAEpC,8BAA8B;QAC9B,IAAI,CAAC,WAAW,GAAG,WAAW,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC7D,CAAC;IAED,6CAA6C;IAC7C,KAAK,CAAC,YAAY,CAAC,GAAqB;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,iBAAiB,CAAA;YAEpD,iCAAiC;YACjC,IAAI,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChE,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;gBAChF,OAAM;YACR,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;YACrD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;YACpB,IAAI,CAAC,aAAa,GAAG,GAAG,CAAA;YAExB,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;QACzE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,+CAA+C;YAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;YACtD,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA,CAAC,qBAAqB;QAClE,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,KAAK,CAAC,GAAqB;QACzB,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAC7C,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* Color threshold helpers for usage display.
|
|
4
|
+
*/
|
|
5
|
+
import type { ColorThresholds, Theme } from "./types";
|
|
6
|
+
/**
|
|
7
|
+
* Get the appropriate TUI color function for a percentage-based usage value.
|
|
8
|
+
*
|
|
9
|
+
* - accent (default) when percentage ≤ warning threshold
|
|
10
|
+
* - warning when percentage > warning threshold
|
|
11
|
+
* - error when percentage ≥ critical threshold
|
|
12
|
+
*/
|
|
13
|
+
export declare function colorForPercentage(percentage: number, theme: Theme, thresholds?: ColorThresholds): (text: string) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Get the appropriate TUI color function for a credit / monetary balance value.
|
|
16
|
+
*
|
|
17
|
+
* - accent (default) when credit ≥ warning threshold
|
|
18
|
+
* - warning when credit < warning threshold
|
|
19
|
+
* - error when credit ≤ critical threshold
|
|
20
|
+
*/
|
|
21
|
+
export declare function colorForCredit(credit: number, theme: Theme, thresholds?: ColorThresholds): (text: string) => string;
|
|
22
|
+
/** Default color thresholds — re-exported for convenience. */
|
|
23
|
+
export { DEFAULT_COLOR_THRESHOLDS } from "./config";
|
|
24
|
+
//# sourceMappingURL=color.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/usage-lib/color.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAErD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,KAAK,EACZ,UAAU,CAAC,EAAE,eAAe,GAC3B,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAK1B;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,UAAU,CAAC,EAAE,eAAe,GAC3B,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAK1B;AAED,8DAA8D;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* Color threshold helpers for usage display.
|
|
4
|
+
*/
|
|
5
|
+
import { loadColorThresholds } from "./config";
|
|
6
|
+
/**
|
|
7
|
+
* Get the appropriate TUI color function for a percentage-based usage value.
|
|
8
|
+
*
|
|
9
|
+
* - accent (default) when percentage ≤ warning threshold
|
|
10
|
+
* - warning when percentage > warning threshold
|
|
11
|
+
* - error when percentage ≥ critical threshold
|
|
12
|
+
*/
|
|
13
|
+
export function colorForPercentage(percentage, theme, thresholds) {
|
|
14
|
+
const t = thresholds ?? loadColorThresholds();
|
|
15
|
+
if (percentage >= t.percentage.critical)
|
|
16
|
+
return (s) => theme.fg("error", s);
|
|
17
|
+
if (percentage > t.percentage.warning)
|
|
18
|
+
return (s) => theme.fg("warning", s);
|
|
19
|
+
return (s) => theme.fg("accent", s);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get the appropriate TUI color function for a credit / monetary balance value.
|
|
23
|
+
*
|
|
24
|
+
* - accent (default) when credit ≥ warning threshold
|
|
25
|
+
* - warning when credit < warning threshold
|
|
26
|
+
* - error when credit ≤ critical threshold
|
|
27
|
+
*/
|
|
28
|
+
export function colorForCredit(credit, theme, thresholds) {
|
|
29
|
+
const t = thresholds ?? loadColorThresholds();
|
|
30
|
+
if (credit <= t.credit.critical)
|
|
31
|
+
return (s) => theme.fg("error", s);
|
|
32
|
+
if (credit < t.credit.warning)
|
|
33
|
+
return (s) => theme.fg("warning", s);
|
|
34
|
+
return (s) => theme.fg("accent", s);
|
|
35
|
+
}
|
|
36
|
+
/** Default color thresholds — re-exported for convenience. */
|
|
37
|
+
export { DEFAULT_COLOR_THRESHOLDS } from "./config";
|
|
38
|
+
//# sourceMappingURL=color.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/usage-lib/color.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAG9C;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAkB,EAClB,KAAY,EACZ,UAA4B;IAE5B,MAAM,CAAC,GAAG,UAAU,IAAI,mBAAmB,EAAE,CAAA;IAC7C,IAAI,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ;QAAE,OAAO,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IACnF,IAAI,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO;QAAE,OAAO,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;IACnF,OAAO,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,KAAY,EACZ,UAA4B;IAE5B,MAAM,CAAC,GAAG,UAAU,IAAI,mBAAmB,EAAE,CAAA;IAC7C,IAAI,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IAC3E,IAAI,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;IAC3E,OAAO,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;AAC7C,CAAC;AAED,8DAA8D;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* User configuration management for color thresholds.
|
|
4
|
+
*/
|
|
5
|
+
import type { ColorThresholds } from "./types";
|
|
6
|
+
/** Default color thresholds used when no user overrides are present. */
|
|
7
|
+
export declare const DEFAULT_COLOR_THRESHOLDS: ColorThresholds;
|
|
8
|
+
/** Filename for user-managed settings, relative to the home directory. */
|
|
9
|
+
export declare const SETTINGS_RELATIVE_PATH = ".pi/agent/usage-lib.json";
|
|
10
|
+
/** Resolve the absolute path to the user settings file. */
|
|
11
|
+
export declare function getSettingsFilePath(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Merge a *partial* set of user-provided thresholds into the defaults.
|
|
14
|
+
*
|
|
15
|
+
* Only known, numeric keys are applied — everything else (unknown keys,
|
|
16
|
+
* non-numeric values) is ignored so a malformed file cannot break rendering.
|
|
17
|
+
*/
|
|
18
|
+
export declare function mergeThresholds(defaults: ColorThresholds, overrides: unknown): ColorThresholds;
|
|
19
|
+
/**
|
|
20
|
+
* Load color thresholds from `~/.pi/agent/usage-lib.json`, merged with defaults.
|
|
21
|
+
*
|
|
22
|
+
* The file is read **once** per process and cached — subsequent calls return
|
|
23
|
+
* the cached object without touching the filesystem.
|
|
24
|
+
*
|
|
25
|
+
* Returns the built-in defaults if the file is missing, unreadable, or
|
|
26
|
+
* contains invalid JSON.
|
|
27
|
+
*/
|
|
28
|
+
export declare function loadColorThresholds(): ColorThresholds;
|
|
29
|
+
/**
|
|
30
|
+
* Reset the internal cache so the next `loadColorThresholds()` call re-reads
|
|
31
|
+
* the settings file. Primarily useful for testing.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resetThresholdsCache(): void;
|
|
34
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/usage-lib/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,EAAE,eAG7B,CAAA;AAEV,0EAA0E;AAC1E,eAAO,MAAM,sBAAsB,6BAA6B,CAAA;AAEhE,2DAA2D;AAC3D,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,GAAG,eAAe,CAe9F;AASD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,eAAe,CAwBrD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* User configuration management for color thresholds.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
/** Default color thresholds used when no user overrides are present. */
|
|
9
|
+
export const DEFAULT_COLOR_THRESHOLDS = {
|
|
10
|
+
percentage: { warning: 80, critical: 90 },
|
|
11
|
+
credit: { warning: 5, critical: 1 },
|
|
12
|
+
};
|
|
13
|
+
/** Filename for user-managed settings, relative to the home directory. */
|
|
14
|
+
export const SETTINGS_RELATIVE_PATH = ".pi/agent/usage-lib.json";
|
|
15
|
+
/** Resolve the absolute path to the user settings file. */
|
|
16
|
+
export function getSettingsFilePath() {
|
|
17
|
+
return join(homedir(), SETTINGS_RELATIVE_PATH);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Merge a *partial* set of user-provided thresholds into the defaults.
|
|
21
|
+
*
|
|
22
|
+
* Only known, numeric keys are applied — everything else (unknown keys,
|
|
23
|
+
* non-numeric values) is ignored so a malformed file cannot break rendering.
|
|
24
|
+
*/
|
|
25
|
+
export function mergeThresholds(defaults, overrides) {
|
|
26
|
+
const o = (overrides ?? {});
|
|
27
|
+
const pct = o.percentage;
|
|
28
|
+
const credit = o.credit;
|
|
29
|
+
return {
|
|
30
|
+
percentage: {
|
|
31
|
+
warning: pickNumber(pct?.warning, defaults.percentage.warning),
|
|
32
|
+
critical: pickNumber(pct?.critical, defaults.percentage.critical),
|
|
33
|
+
},
|
|
34
|
+
credit: {
|
|
35
|
+
warning: pickNumber(credit?.warning, defaults.credit.warning),
|
|
36
|
+
critical: pickNumber(credit?.critical, defaults.credit.critical),
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Return the value if it is a finite number, otherwise the fallback. */
|
|
41
|
+
function pickNumber(value, fallback) {
|
|
42
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
43
|
+
}
|
|
44
|
+
let cachedThresholds = null;
|
|
45
|
+
/**
|
|
46
|
+
* Load color thresholds from `~/.pi/agent/usage-lib.json`, merged with defaults.
|
|
47
|
+
*
|
|
48
|
+
* The file is read **once** per process and cached — subsequent calls return
|
|
49
|
+
* the cached object without touching the filesystem.
|
|
50
|
+
*
|
|
51
|
+
* Returns the built-in defaults if the file is missing, unreadable, or
|
|
52
|
+
* contains invalid JSON.
|
|
53
|
+
*/
|
|
54
|
+
export function loadColorThresholds() {
|
|
55
|
+
if (cachedThresholds)
|
|
56
|
+
return cachedThresholds;
|
|
57
|
+
let fileContent;
|
|
58
|
+
try {
|
|
59
|
+
fileContent = readFileSync(getSettingsFilePath(), "utf-8");
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// File missing or unreadable — use defaults
|
|
63
|
+
cachedThresholds = { ...DEFAULT_COLOR_THRESHOLDS };
|
|
64
|
+
return cachedThresholds;
|
|
65
|
+
}
|
|
66
|
+
let parsed;
|
|
67
|
+
try {
|
|
68
|
+
parsed = JSON.parse(fileContent);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Invalid JSON — use defaults
|
|
72
|
+
cachedThresholds = { ...DEFAULT_COLOR_THRESHOLDS };
|
|
73
|
+
return cachedThresholds;
|
|
74
|
+
}
|
|
75
|
+
const thresholds = parsed?.thresholds;
|
|
76
|
+
cachedThresholds = mergeThresholds(DEFAULT_COLOR_THRESHOLDS, thresholds);
|
|
77
|
+
return cachedThresholds;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Reset the internal cache so the next `loadColorThresholds()` call re-reads
|
|
81
|
+
* the settings file. Primarily useful for testing.
|
|
82
|
+
*/
|
|
83
|
+
export function resetThresholdsCache() {
|
|
84
|
+
cachedThresholds = null;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/usage-lib/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,wEAAwE;AACxE,MAAM,CAAC,MAAM,wBAAwB,GAAoB;IACvD,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACzC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;CAC3B,CAAA;AAEV,0EAA0E;AAC1E,MAAM,CAAC,MAAM,sBAAsB,GAAG,0BAA0B,CAAA;AAEhE,2DAA2D;AAC3D,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,sBAAsB,CAAC,CAAA;AAChD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,QAAyB,EAAE,SAAkB;IAC3E,MAAM,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAA4B,CAAA;IACtD,MAAM,GAAG,GAAG,CAAC,CAAC,UAAiD,CAAA;IAC/D,MAAM,MAAM,GAAG,CAAC,CAAC,MAA6C,CAAA;IAE9D,OAAO;QACL,UAAU,EAAE;YACV,OAAO,EAAE,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;YAC9D,QAAQ,EAAE,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;SAClE;QACD,MAAM,EAAE;YACN,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;YAC7D,QAAQ,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC;SACjE;KACF,CAAA;AACH,CAAC;AAED,yEAAyE;AACzE,SAAS,UAAU,CAAC,KAAc,EAAE,QAAgB;IAClD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC/E,CAAC;AAED,IAAI,gBAAgB,GAA2B,IAAI,CAAA;AAEnD;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,gBAAgB;QAAE,OAAO,gBAAgB,CAAA;IAE7C,IAAI,WAAmB,CAAA;IACvB,IAAI,CAAC;QACH,WAAW,GAAG,YAAY,CAAC,mBAAmB,EAAE,EAAE,OAAO,CAAC,CAAA;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,4CAA4C;QAC5C,gBAAgB,GAAG,EAAE,GAAG,wBAAwB,EAAE,CAAA;QAClD,OAAO,gBAAgB,CAAA;IACzB,CAAC;IAED,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;QAC9B,gBAAgB,GAAG,EAAE,GAAG,wBAAwB,EAAE,CAAA;QAClD,OAAO,gBAAgB,CAAA;IACzB,CAAC;IAED,MAAM,UAAU,GAAI,MAAyC,EAAE,UAAU,CAAA;IACzE,gBAAgB,GAAG,eAAe,CAAC,wBAAwB,EAAE,UAAU,CAAC,CAAA;IACxE,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,gBAAgB,GAAG,IAAI,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* Date/time formatting utilities using Temporal.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Format an instant (epoch milliseconds) as a localized date/time string
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatInstantFromEpochMs(ms: number): string;
|
|
9
|
+
/**
|
|
10
|
+
* Format the remaining time from an instant (epoch milliseconds) to now
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatTimeRemainingFromEpochMs(ms: number): string;
|
|
13
|
+
//# sourceMappingURL=datetime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datetime.d.ts","sourceRoot":"","sources":["../../src/usage-lib/datetime.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAa3D;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAuBjE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* Date/time formatting utilities using Temporal.
|
|
4
|
+
*/
|
|
5
|
+
import { Temporal } from "temporal-polyfill";
|
|
6
|
+
/**
|
|
7
|
+
* Format an instant (epoch milliseconds) as a localized date/time string
|
|
8
|
+
*/
|
|
9
|
+
export function formatInstantFromEpochMs(ms) {
|
|
10
|
+
const instant = Temporal.Instant.fromEpochMilliseconds(ms);
|
|
11
|
+
const zonedDateTime = instant.toZonedDateTimeISO(Temporal.Now.timeZoneId() ?? "UTC");
|
|
12
|
+
return zonedDateTime.toLocaleString(undefined, {
|
|
13
|
+
weekday: "short",
|
|
14
|
+
day: "2-digit",
|
|
15
|
+
month: "short",
|
|
16
|
+
year: "numeric",
|
|
17
|
+
hour: "2-digit",
|
|
18
|
+
minute: "2-digit",
|
|
19
|
+
second: "2-digit",
|
|
20
|
+
timeZoneName: "short",
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Format the remaining time from an instant (epoch milliseconds) to now
|
|
25
|
+
*/
|
|
26
|
+
export function formatTimeRemainingFromEpochMs(ms) {
|
|
27
|
+
const now = Temporal.Now.instant();
|
|
28
|
+
const target = Temporal.Instant.fromEpochMilliseconds(ms);
|
|
29
|
+
// If the target time is in the past, return zero
|
|
30
|
+
if (target.epochMilliseconds < now.epochMilliseconds) {
|
|
31
|
+
return "0h 0m 0s";
|
|
32
|
+
}
|
|
33
|
+
const duration = target.since(now);
|
|
34
|
+
const totalSeconds = Math.round(Math.abs(duration.seconds));
|
|
35
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
36
|
+
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
37
|
+
const seconds = totalSeconds % 60;
|
|
38
|
+
if (hours > 0) {
|
|
39
|
+
return `${hours}h ${minutes}m ${seconds}s`;
|
|
40
|
+
}
|
|
41
|
+
if (minutes > 0) {
|
|
42
|
+
return `${minutes}m ${seconds}s`;
|
|
43
|
+
}
|
|
44
|
+
return `${seconds}s`;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=datetime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datetime.js","sourceRoot":"","sources":["../../src/usage-lib/datetime.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE5C;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,EAAU;IACjD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAA;IAC1D,MAAM,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,KAAK,CAAC,CAAA;IACpF,OAAO,aAAa,CAAC,cAAc,CAAC,SAAS,EAAE;QAC7C,OAAO,EAAE,OAAO;QAChB,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,SAAS;QACjB,YAAY,EAAE,OAAO;KACtB,CAAC,CAAA;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,8BAA8B,CAAC,EAAU;IACvD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;IAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAA;IAEzD,iDAAiD;IACjD,IAAI,MAAM,CAAC,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,EAAE,CAAC;QACrD,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAElC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IACtD,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAA;IAEjC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,GAAG,KAAK,KAAK,OAAO,KAAK,OAAO,GAAG,CAAA;IAC5C,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,CAAA;IAClC,CAAC;IACD,OAAO,GAAG,OAAO,GAAG,CAAA;AACtB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* Factory for usage-monitoring Pi extensions.
|
|
4
|
+
*/
|
|
5
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import type { UsageExtensionConfig } from "./types";
|
|
7
|
+
/**
|
|
8
|
+
* Create a Pi usage extension from a configuration object.
|
|
9
|
+
*
|
|
10
|
+
* Handles all boilerplate: event registration, provider matching,
|
|
11
|
+
* cache management, and footer lifecycle.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createUsageExtension<TData>(config: UsageExtensionConfig<TData>): (pi: ExtensionAPI) => void;
|
|
14
|
+
//# sourceMappingURL=extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../src/usage-lib/extension.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAA;AAErF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAYnD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,oBAAoB,CAAC,KAAK,CAAC,IAGnD,IAAI,YAAY,UAsC3C"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* Factory for usage-monitoring Pi extensions.
|
|
4
|
+
*/
|
|
5
|
+
import { UsageCache } from "./cache";
|
|
6
|
+
/** Check if a provider name matches the given prefix (case-insensitive) */
|
|
7
|
+
function isProviderMatch(provider, prefix) {
|
|
8
|
+
return provider?.toLowerCase().startsWith(prefix) ?? false;
|
|
9
|
+
}
|
|
10
|
+
/** Check if the current model's provider matches the given prefix */
|
|
11
|
+
function isCurrentProvider(ctx, prefix) {
|
|
12
|
+
return isProviderMatch(ctx.model?.provider, prefix);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a Pi usage extension from a configuration object.
|
|
16
|
+
*
|
|
17
|
+
* Handles all boilerplate: event registration, provider matching,
|
|
18
|
+
* cache management, and footer lifecycle.
|
|
19
|
+
*/
|
|
20
|
+
export function createUsageExtension(config) {
|
|
21
|
+
const { providerPrefix, statusKey, label, cooldownMs = 30_000 } = config;
|
|
22
|
+
return function extension(pi) {
|
|
23
|
+
const cache = new UsageCache(statusKey, label, config.fetchUsage, config.renderStatus, config.renderError, cooldownMs);
|
|
24
|
+
// Show footer at session start (only when using matching model)
|
|
25
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
26
|
+
if (isCurrentProvider(ctx, providerPrefix)) {
|
|
27
|
+
await cache.updateStatus(ctx);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
// Update footer on model select
|
|
31
|
+
pi.on("model_select", async (event, ctx) => {
|
|
32
|
+
if (isProviderMatch(event.model.provider, providerPrefix)) {
|
|
33
|
+
await cache.updateStatus(ctx);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
cache.clear(ctx);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// Update footer after each turn
|
|
40
|
+
pi.on("turn_end", async (_event, ctx) => {
|
|
41
|
+
if (isCurrentProvider(ctx, providerPrefix)) {
|
|
42
|
+
await cache.updateStatus(ctx);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// Clear footer on session shutdown
|
|
46
|
+
pi.on("session_shutdown", async (_event, ctx) => {
|
|
47
|
+
cache.clear(ctx);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../src/usage-lib/extension.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGpC,2EAA2E;AAC3E,SAAS,eAAe,CAAC,QAA4B,EAAE,MAAc;IACnE,OAAO,QAAQ,EAAE,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,CAAA;AAC5D,CAAC;AAED,qEAAqE;AACrE,SAAS,iBAAiB,CAAC,GAAqB,EAAE,MAAc;IAC9D,OAAO,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;AACrD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAQ,MAAmC;IAC7E,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,GAAG,MAAM,CAAA;IAExE,OAAO,SAAS,SAAS,CAAC,EAAgB;QACxC,MAAM,KAAK,GAAG,IAAI,UAAU,CAC1B,SAAS,EACT,KAAK,EACL,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,WAAW,EAClB,UAAU,CACX,CAAA;QAED,gEAAgE;QAChE,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YAC3C,IAAI,iBAAiB,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC3C,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,gCAAgC;QAChC,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACzC,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC1D,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;YAC/B,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAClB,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,gCAAgC;QAChC,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACtC,IAAI,iBAAiB,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC3C,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,mCAAmC;QACnC,EAAE,CAAC,EAAE,CAAC,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YAC9C,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAClB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored usage helper public API.
|
|
3
|
+
*
|
|
4
|
+
* Source adapted from @alexanderfortin/pi-usage-lib under the MIT license so
|
|
5
|
+
* @beyona/pi-zai-usage can be redistributed without that runtime dependency.
|
|
6
|
+
*/
|
|
7
|
+
export { buildAuthHeaders, safeFetch, safeParseJson, UsageError } from "./api";
|
|
8
|
+
export { UsageCache } from "./cache";
|
|
9
|
+
export { colorForCredit, colorForPercentage } from "./color";
|
|
10
|
+
export { DEFAULT_COLOR_THRESHOLDS, getSettingsFilePath, loadColorThresholds, mergeThresholds, resetThresholdsCache, } from "./config";
|
|
11
|
+
export { formatInstantFromEpochMs, formatTimeRemainingFromEpochMs } from "./datetime";
|
|
12
|
+
export { createUsageExtension } from "./extension";
|
|
13
|
+
export type { ColorThresholds, FetchUsageFn, RenderErrorFn, RenderStatusFn, Theme, UsageExtensionConfig, } from "./types";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/usage-lib/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAC5D,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,GACrB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,wBAAwB,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAA;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAElD,YAAY,EACV,eAAe,EACf,YAAY,EACZ,aAAa,EACb,cAAc,EACd,KAAK,EACL,oBAAoB,GACrB,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored usage helper public API.
|
|
3
|
+
*
|
|
4
|
+
* Source adapted from @alexanderfortin/pi-usage-lib under the MIT license so
|
|
5
|
+
* @beyona/pi-zai-usage can be redistributed without that runtime dependency.
|
|
6
|
+
*/
|
|
7
|
+
export { buildAuthHeaders, safeFetch, safeParseJson, UsageError } from "./api";
|
|
8
|
+
export { UsageCache } from "./cache";
|
|
9
|
+
export { colorForCredit, colorForPercentage } from "./color";
|
|
10
|
+
export { DEFAULT_COLOR_THRESHOLDS, getSettingsFilePath, loadColorThresholds, mergeThresholds, resetThresholdsCache, } from "./config";
|
|
11
|
+
export { formatInstantFromEpochMs, formatTimeRemainingFromEpochMs } from "./datetime";
|
|
12
|
+
export { createUsageExtension } from "./extension";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/usage-lib/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAC5D,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,GACrB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,wBAAwB,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAA;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from @alexanderfortin/pi-usage-lib (MIT).
|
|
3
|
+
* Shared public API types for usage monitoring helpers.
|
|
4
|
+
*/
|
|
5
|
+
import type { ExtensionContext, ModelRegistry } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
/** Theme helper — matches ctx.ui.theme */
|
|
7
|
+
export type Theme = ExtensionContext["ui"]["theme"];
|
|
8
|
+
/**
|
|
9
|
+
* Color thresholds for usage display.
|
|
10
|
+
*
|
|
11
|
+
* Users can override any subset of these values via the
|
|
12
|
+
* `~/.pi/agent/usage-lib.json` settings file.
|
|
13
|
+
*/
|
|
14
|
+
export interface ColorThresholds {
|
|
15
|
+
/** Percentage-based usage thresholds (0–100) */
|
|
16
|
+
percentage: {
|
|
17
|
+
/** Above this % → **warning** color (default: 80) */
|
|
18
|
+
warning: number;
|
|
19
|
+
/** At or above this % → **critical** color (default: 90) */
|
|
20
|
+
critical: number;
|
|
21
|
+
};
|
|
22
|
+
/** Credit / monetary balance thresholds (in USD) */
|
|
23
|
+
credit: {
|
|
24
|
+
/** Below this → **warning** color (default: 5) */
|
|
25
|
+
warning: number;
|
|
26
|
+
/** At or below this → **critical** color (default: 1) */
|
|
27
|
+
critical: number;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Fetch function signature */
|
|
31
|
+
export type FetchUsageFn<TData> = (modelRegistry: Pick<ModelRegistry, "getApiKeyForProvider">) => Promise<TData>;
|
|
32
|
+
/** Render usage data into a themed footer string */
|
|
33
|
+
export type RenderStatusFn<TData> = (data: TData, theme: Theme) => string;
|
|
34
|
+
/** Render an error into a themed footer string. Return undefined to clear the footer. */
|
|
35
|
+
export type RenderErrorFn = (error: unknown, theme: Theme) => string | undefined;
|
|
36
|
+
/** Configuration to define a usage extension */
|
|
37
|
+
export interface UsageExtensionConfig<TData> {
|
|
38
|
+
/** Provider name prefix for matching (e.g. "zai", "deepseek") */
|
|
39
|
+
providerPrefix: string;
|
|
40
|
+
/** Status key for ctx.ui.setStatus() (e.g. "zai-usage") */
|
|
41
|
+
statusKey: string;
|
|
42
|
+
/** Display label for footer prefix (e.g. "MyProvider") */
|
|
43
|
+
label: string;
|
|
44
|
+
/** Cache cooldown in ms (default: 30_000) */
|
|
45
|
+
cooldownMs?: number;
|
|
46
|
+
/** Fetch usage data from the provider API */
|
|
47
|
+
fetchUsage: FetchUsageFn<TData>;
|
|
48
|
+
/** Render usage data into a themed footer string */
|
|
49
|
+
renderStatus: RenderStatusFn<TData>;
|
|
50
|
+
/**
|
|
51
|
+
* Render an error into a themed footer string.
|
|
52
|
+
* Default: shows themed `<err:code>` using UsageError.code,
|
|
53
|
+
* falling back to "fetch" for unknown errors.
|
|
54
|
+
* Return undefined to clear the footer instead.
|
|
55
|
+
*/
|
|
56
|
+
renderError?: RenderErrorFn;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/usage-lib/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAEtF,0CAA0C;AAC1C,MAAM,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAA;AAEnD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,UAAU,EAAE;QACV,qDAAqD;QACrD,OAAO,EAAE,MAAM,CAAA;QACf,4DAA4D;QAC5D,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,oDAAoD;IACpD,MAAM,EAAE;QACN,kDAAkD;QAClD,OAAO,EAAE,MAAM,CAAA;QACf,yDAAyD;QACzD,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED,+BAA+B;AAC/B,MAAM,MAAM,YAAY,CAAC,KAAK,IAAI,CAChC,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,sBAAsB,CAAC,KACvD,OAAO,CAAC,KAAK,CAAC,CAAA;AAEnB,oDAAoD;AACpD,MAAM,MAAM,cAAc,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,CAAA;AAEzE,yFAAyF;AACzF,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,GAAG,SAAS,CAAA;AAEhF,gDAAgD;AAChD,MAAM,WAAW,oBAAoB,CAAC,KAAK;IACzC,iEAAiE;IACjE,cAAc,EAAE,MAAM,CAAA;IAEtB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAA;IAEjB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAA;IAEb,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,6CAA6C;IAC7C,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAE/B,oDAAoD;IACpD,YAAY,EAAE,cAAc,CAAC,KAAK,CAAC,CAAA;IAEnC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,aAAa,CAAA;CAC5B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/usage-lib/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@beyona/pi-zai-usage",
|
|
3
|
+
"version": "0.3.2",
|
|
4
|
+
"description": "Pi extension for monitoring Z.ai API token usage quota",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"dev": "bun --watch src/index.ts",
|
|
16
|
+
"build": "bun run typecheck && bun run build:tsc",
|
|
17
|
+
"build:tsc": "tsc",
|
|
18
|
+
"typecheck": "tsc --noEmit --project tsconfig.test.json",
|
|
19
|
+
"lint": "biome check src/ tests/",
|
|
20
|
+
"lint:fix": "biome check --write src/ tests/",
|
|
21
|
+
"format": "biome format --write src/",
|
|
22
|
+
"check": "bun run typecheck && bun run lint",
|
|
23
|
+
"test": "bun test",
|
|
24
|
+
"test:coverage": "bun test --coverage --coverage-reporter=lcov",
|
|
25
|
+
"release": "semantic-release",
|
|
26
|
+
"release:dry-run": "semantic-release --dry-run"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"temporal-polyfill": "^1.0.1"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@alexanderfortin/semantic-release-keep-a-changelog": "^0.4.4",
|
|
33
|
+
"@biomejs/biome": "^2.5.1",
|
|
34
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
35
|
+
"@semantic-release/exec": "^7.1.0",
|
|
36
|
+
"@semantic-release/git": "^10.0.1",
|
|
37
|
+
"@semantic-release/github": "^12.0.8",
|
|
38
|
+
"@semantic-release/npm": "^13.1.5",
|
|
39
|
+
"@types/bun": "^1.3.14",
|
|
40
|
+
"semantic-release": "^25.0.5",
|
|
41
|
+
"typescript": "^6.0.3"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@earendil-works/pi-coding-agent": "^0.80.2",
|
|
45
|
+
"@earendil-works/pi-tui": "^0.80.2"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"package.json",
|
|
53
|
+
"README.md",
|
|
54
|
+
"CHANGELOG.md",
|
|
55
|
+
"LICENSE"
|
|
56
|
+
],
|
|
57
|
+
"keywords": [
|
|
58
|
+
"pi-package",
|
|
59
|
+
"pi-extension",
|
|
60
|
+
"zai",
|
|
61
|
+
"Z.ai",
|
|
62
|
+
"usage-monitoring",
|
|
63
|
+
"api-quota"
|
|
64
|
+
],
|
|
65
|
+
"pi": {
|
|
66
|
+
"extensions": [
|
|
67
|
+
"./dist/index.js"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"author": "Alexander Fortin",
|
|
71
|
+
"contributors": [
|
|
72
|
+
"beyona"
|
|
73
|
+
],
|
|
74
|
+
"license": "MIT"
|
|
75
|
+
}
|