@bacnh85/pi-sub 0.1.39 → 0.1.40
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 +15 -0
- package/extensions/index.ts +21 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.40 (2026-09-14)
|
|
4
|
+
|
|
5
|
+
### Tests
|
|
6
|
+
|
|
7
|
+
- Added unit test coverage for the three untested parsers: the OmniRoute
|
|
8
|
+
om-usage free-text report (`parseOmniUsageText` — four windows, section
|
|
9
|
+
switching, out-of-range percentages, disabled/no-cache text), the Command
|
|
10
|
+
Code `/alpha/billing/credits` window mapper (used/cap → remaining%, epoch-ms
|
|
11
|
+
resetAt, over-cap clamp, bad-window bail), and the `.env.local` parser
|
|
12
|
+
(extracted as exported `parseEnvText`; `export ` prefix, quoted values,
|
|
13
|
+
comments, CRLF, `#`-in-value). No behavior changes.
|
|
14
|
+
One edge case differs from the inline loop it replaces: duplicate keys in a
|
|
15
|
+
single .env file now resolve last-wins (dotenv convention) instead of
|
|
16
|
+
first-wins.
|
|
17
|
+
|
|
3
18
|
## 0.1.39 (2026-09-12)
|
|
4
19
|
|
|
5
20
|
### Fixed
|
package/extensions/index.ts
CHANGED
|
@@ -4,6 +4,22 @@ import fs from "node:fs";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
|
|
7
|
+
/** Parse .env-style text into KEY→VALUE entries: `export ` prefix allowed,
|
|
8
|
+
* single/double quotes stripped, comment/blank/non-assignment lines ignored.
|
|
9
|
+
* No inline-comment stripping (a `#` in the value stays part of the value).
|
|
10
|
+
* Exported for tests. */
|
|
11
|
+
export function parseEnvText(text: string): Record<string, string> {
|
|
12
|
+
const out: Record<string, string> = {};
|
|
13
|
+
for (const line of text.split(/\r?\n/)) {
|
|
14
|
+
const m = line.match(/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)\s*$/);
|
|
15
|
+
if (!m) continue;
|
|
16
|
+
let v = m[2].trim();
|
|
17
|
+
if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) v = v.slice(1, -1);
|
|
18
|
+
out[m[1]] = v;
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
|
|
7
23
|
/** Pi config dirs + .env.local/.env discovery (pi-munin convention, stdlib parse). */
|
|
8
24
|
function loadEnvFiles(): void {
|
|
9
25
|
const dirs = process.env.PI_CODING_AGENT_DIR
|
|
@@ -14,12 +30,8 @@ function loadEnvFiles(): void {
|
|
|
14
30
|
for (const file of candidates) {
|
|
15
31
|
try {
|
|
16
32
|
const text = fs.readFileSync(file, "utf8");
|
|
17
|
-
for (const
|
|
18
|
-
|
|
19
|
-
if (!m) continue;
|
|
20
|
-
let v = m[2].trim();
|
|
21
|
-
if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) v = v.slice(1, -1);
|
|
22
|
-
if (process.env[m[1]] === undefined) process.env[m[1]] = v;
|
|
33
|
+
for (const [key, value] of Object.entries(parseEnvText(text))) {
|
|
34
|
+
if (process.env[key] === undefined) process.env[key] = value;
|
|
23
35
|
}
|
|
24
36
|
} catch { /* optional file */ }
|
|
25
37
|
}
|
|
@@ -437,7 +449,8 @@ export function parseOmniUsageText(text: string): {
|
|
|
437
449
|
return out;
|
|
438
450
|
}
|
|
439
451
|
|
|
440
|
-
// ponytail: runnable self-check (
|
|
452
|
+
// ponytail: runnable self-check (pack gate; extensions/test covers the same
|
|
453
|
+
// parser paths plus the adapters the self-check doesn't)
|
|
441
454
|
if (process.env.PI_SUB_SELF_CHECK === "1") {
|
|
442
455
|
const sample = [
|
|
443
456
|
"Personal quota", "Daily", "80% left", "⏱ reset in 15h 0m", "",
|
|
@@ -850,7 +863,7 @@ interface CommandCodeCreditsApiResponse {
|
|
|
850
863
|
|
|
851
864
|
/** Map a Command Code USD window (used/cap in dollars, resetAt in ms) into
|
|
852
865
|
* the shared UsageWindow shape (remaining%, reset labels). */
|
|
853
|
-
function commandCodeWindowToUsageWindow(window: CommandCodeWindowApi | undefined): UsageWindow | undefined {
|
|
866
|
+
export function commandCodeWindowToUsageWindow(window: CommandCodeWindowApi | undefined): UsageWindow | undefined {
|
|
854
867
|
if (!window || typeof window.used !== "number" || typeof window.cap !== "number" || window.cap <= 0) return undefined;
|
|
855
868
|
const usedPct = Math.round((window.used / window.cap) * 100);
|
|
856
869
|
const percent = Math.min(100, usedPct);
|