codiedev 0.9.58 → 0.9.59
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/assets/tui-brand-plugin.tsx +14 -2
- package/dist/codieUsage.d.ts +7 -0
- package/dist/codieUsage.js +46 -0
- package/package.json +1 -1
|
@@ -31,6 +31,7 @@ const MARK = [
|
|
|
31
31
|
const REFRESH_MS = 30_000
|
|
32
32
|
|
|
33
33
|
const [usageLine, setUsageLine] = createSignal("")
|
|
34
|
+
const [usageTone, setUsageTone] = createSignal("normal")
|
|
34
35
|
|
|
35
36
|
async function startUsagePolling() {
|
|
36
37
|
let usage: any
|
|
@@ -56,7 +57,11 @@ async function startUsagePolling() {
|
|
|
56
57
|
})
|
|
57
58
|
// A failed poll leaves the last good line up rather than blanking it:
|
|
58
59
|
// a number that stopped updating beats a number that vanished.
|
|
59
|
-
if (snapshot)
|
|
60
|
+
if (snapshot) {
|
|
61
|
+
setUsageLine(usage.formatUsageLine(snapshot))
|
|
62
|
+
// Older installs of the usage module have no tone; stay muted there.
|
|
63
|
+
if (typeof usage.usageTone === "function") setUsageTone(usage.usageTone(snapshot))
|
|
64
|
+
}
|
|
60
65
|
} catch {}
|
|
61
66
|
}
|
|
62
67
|
void poll()
|
|
@@ -69,7 +74,14 @@ void startUsagePolling().catch(() => {})
|
|
|
69
74
|
|
|
70
75
|
function StatusLine(props: { theme: any }) {
|
|
71
76
|
return (
|
|
72
|
-
<text
|
|
77
|
+
<text
|
|
78
|
+
fg={usageTone() === "critical"
|
|
79
|
+
? (props.theme.error ?? props.theme.textMuted)
|
|
80
|
+
: usageTone() === "warn"
|
|
81
|
+
? (props.theme.warning ?? props.theme.textMuted)
|
|
82
|
+
: props.theme.textMuted}
|
|
83
|
+
selectable={false}
|
|
84
|
+
>
|
|
73
85
|
{usageLine()}
|
|
74
86
|
</text>
|
|
75
87
|
)
|
package/dist/codieUsage.d.ts
CHANGED
|
@@ -39,6 +39,13 @@ export interface CodieUsage {
|
|
|
39
39
|
* Returns "" when there is nothing honest to say.
|
|
40
40
|
*/
|
|
41
41
|
export declare function formatUsageLine(usage: CodieUsage | null | undefined): string;
|
|
42
|
+
export type UsageTone = "normal" | "warn" | "critical";
|
|
43
|
+
/**
|
|
44
|
+
* How urgently the status line should read, from the limit that will stop
|
|
45
|
+
* this developer first: their own cap, or the shared pool when they have no
|
|
46
|
+
* cap or the pool runs out sooner. 75% warns, 90% is critical.
|
|
47
|
+
*/
|
|
48
|
+
export declare function usageTone(usage: CodieUsage | null | undefined): UsageTone;
|
|
42
49
|
/**
|
|
43
50
|
* What this session just cost. Returns "" when the session billed nothing,
|
|
44
51
|
* because a developer who spent nothing does not need to be told a number.
|
package/dist/codieUsage.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// delay, or break a coding session. No snapshot means no line.
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.formatUsageLine = formatUsageLine;
|
|
12
|
+
exports.usageTone = usageTone;
|
|
12
13
|
exports.formatSessionCostLine = formatSessionCostLine;
|
|
13
14
|
exports.fetchCodieUsage = fetchCodieUsage;
|
|
14
15
|
const USAGE_TIMEOUT_MS = 4000;
|
|
@@ -51,6 +52,16 @@ function formatUsageLine(usage) {
|
|
|
51
52
|
const share = percent(budget.userSpentUsd, budget.userBudgetUsd);
|
|
52
53
|
if (share)
|
|
53
54
|
segments.push(share);
|
|
55
|
+
// A personal cap does not help once the shared pool is nearly gone: say
|
|
56
|
+
// so when the pool is running low and will stop this developer before
|
|
57
|
+
// their own cap does.
|
|
58
|
+
if (poolBindsFirst(budget) && typeof budget.companyBudgetUsd === "number"
|
|
59
|
+
&& budget.companyBudgetUsd > 0
|
|
60
|
+
&& budget.companySpentUsd / budget.companyBudgetUsd >= 0.75) {
|
|
61
|
+
const share = percent(budget.companySpentUsd, budget.companyBudgetUsd);
|
|
62
|
+
if (share)
|
|
63
|
+
segments.push(`team pool ${share}`);
|
|
64
|
+
}
|
|
54
65
|
}
|
|
55
66
|
else {
|
|
56
67
|
segments.push(money(budget.userSpentUsd));
|
|
@@ -62,6 +73,10 @@ function formatUsageLine(usage) {
|
|
|
62
73
|
segments.push(`team ${share}`);
|
|
63
74
|
}
|
|
64
75
|
}
|
|
76
|
+
if (typeof budget.companyBudgetUsd === "number" && budget.companyBudgetUsd > 0
|
|
77
|
+
&& budget.companySpentUsd >= budget.companyBudgetUsd) {
|
|
78
|
+
segments.push("team pool used up");
|
|
79
|
+
}
|
|
65
80
|
if (inFlight.requests > 0)
|
|
66
81
|
segments.push(`${inFlight.requests} in flight`);
|
|
67
82
|
// Stale holds cap a budget while doing no work. Naming them is the
|
|
@@ -70,6 +85,37 @@ function formatUsageLine(usage) {
|
|
|
70
85
|
segments.push(`${money(inFlight.staleHeldUsd)} held stale`);
|
|
71
86
|
return segments.join(" · ");
|
|
72
87
|
}
|
|
88
|
+
function poolBindsFirst(budget) {
|
|
89
|
+
if (typeof budget.companyBudgetUsd !== "number" || typeof budget.userBudgetUsd !== "number")
|
|
90
|
+
return false;
|
|
91
|
+
const poolLeft = Math.max(0, budget.companyBudgetUsd - budget.companySpentUsd);
|
|
92
|
+
const userLeft = Math.max(0, budget.userBudgetUsd - budget.userSpentUsd);
|
|
93
|
+
return budget.userBudgetUsd > 0 && poolLeft < userLeft;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* How urgently the status line should read, from the limit that will stop
|
|
97
|
+
* this developer first: their own cap, or the shared pool when they have no
|
|
98
|
+
* cap or the pool runs out sooner. 75% warns, 90% is critical.
|
|
99
|
+
*/
|
|
100
|
+
function usageTone(usage) {
|
|
101
|
+
if (!usage || !usage.enabled)
|
|
102
|
+
return "normal";
|
|
103
|
+
const { budget } = usage;
|
|
104
|
+
const ratios = [];
|
|
105
|
+
if (typeof budget.userBudgetUsd === "number" && budget.userBudgetUsd > 0) {
|
|
106
|
+
ratios.push(budget.userSpentUsd / budget.userBudgetUsd);
|
|
107
|
+
}
|
|
108
|
+
if (typeof budget.companyBudgetUsd === "number" && budget.companyBudgetUsd > 0
|
|
109
|
+
&& (typeof budget.userBudgetUsd !== "number" || poolBindsFirst(budget))) {
|
|
110
|
+
ratios.push(budget.companySpentUsd / budget.companyBudgetUsd);
|
|
111
|
+
}
|
|
112
|
+
const worst = ratios.length ? Math.max(...ratios) : 0;
|
|
113
|
+
if (worst >= 0.9)
|
|
114
|
+
return "critical";
|
|
115
|
+
if (worst >= 0.75)
|
|
116
|
+
return "warn";
|
|
117
|
+
return "normal";
|
|
118
|
+
}
|
|
73
119
|
function tokens(total) {
|
|
74
120
|
// Rounded by arithmetic, not toFixed: 2.55 is not exactly representable, so
|
|
75
121
|
// toFixed(1) rounds it down and the same count can read two ways.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codiedev",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.59",
|
|
4
4
|
"description": "Connect Claude Code, Codex, Cursor, OpenCode, or VS Code Copilot to Codiedev for team session capture and artifact collaboration — and run the governed Codie harness",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codiedev": "dist/cli.js",
|