estela 0.1.39 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -0
- package/dist/billing/assign.d.ts +45 -0
- package/dist/billing/assign.d.ts.map +1 -0
- package/dist/billing/assign.js +159 -0
- package/dist/billing/assign.js.map +1 -0
- package/dist/billing/assign.test.d.ts +2 -0
- package/dist/billing/assign.test.d.ts.map +1 -0
- package/dist/billing/assign.test.js +153 -0
- package/dist/billing/assign.test.js.map +1 -0
- package/dist/bin.js +23 -1
- package/dist/bin.js.map +1 -1
- package/dist/cli-import-recover.test.d.ts +2 -0
- package/dist/cli-import-recover.test.d.ts.map +1 -0
- package/dist/cli-import-recover.test.js +191 -0
- package/dist/cli-import-recover.test.js.map +1 -0
- package/dist/cli-quota.test.d.ts +2 -0
- package/dist/cli-quota.test.d.ts.map +1 -0
- package/dist/cli-quota.test.js +281 -0
- package/dist/cli-quota.test.js.map +1 -0
- package/dist/cli-statusline.test.d.ts +2 -0
- package/dist/cli-statusline.test.d.ts.map +1 -0
- package/dist/cli-statusline.test.js +333 -0
- package/dist/cli-statusline.test.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +350 -49
- package/dist/cli.js.map +1 -1
- package/dist/db/store.d.ts +12 -1
- package/dist/db/store.d.ts.map +1 -1
- package/dist/db/store.js +52 -0
- package/dist/db/store.js.map +1 -1
- package/dist/demo.d.ts.map +1 -1
- package/dist/demo.js +53 -0
- package/dist/demo.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +68 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/metrics/quota.d.ts +226 -0
- package/dist/metrics/quota.d.ts.map +1 -0
- package/dist/metrics/quota.js +291 -0
- package/dist/metrics/quota.js.map +1 -0
- package/dist/metrics/quota.test.d.ts +2 -0
- package/dist/metrics/quota.test.d.ts.map +1 -0
- package/dist/metrics/quota.test.js +325 -0
- package/dist/metrics/quota.test.js.map +1 -0
- package/dist/project-of.d.ts +52 -0
- package/dist/project-of.d.ts.map +1 -0
- package/dist/project-of.js +124 -0
- package/dist/project-of.js.map +1 -0
- package/dist/project-of.test.d.ts +2 -0
- package/dist/project-of.test.d.ts.map +1 -0
- package/dist/project-of.test.js +203 -0
- package/dist/project-of.test.js.map +1 -0
- package/dist/quota.d.ts +27 -0
- package/dist/quota.d.ts.map +1 -0
- package/dist/quota.js +79 -0
- package/dist/quota.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +17 -26
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +37 -0
- package/dist/server.test.js.map +1 -1
- package/dist/statusline-cache.d.ts +35 -0
- package/dist/statusline-cache.d.ts.map +1 -0
- package/dist/statusline-cache.js +57 -0
- package/dist/statusline-cache.js.map +1 -0
- package/dist/statusline-install.d.ts +52 -0
- package/dist/statusline-install.d.ts.map +1 -0
- package/dist/statusline-install.js +115 -0
- package/dist/statusline-install.js.map +1 -0
- package/dist/statusline-run.d.ts +8 -0
- package/dist/statusline-run.d.ts.map +1 -0
- package/dist/statusline-run.js +256 -0
- package/dist/statusline-run.js.map +1 -0
- package/dist/statusline.d.ts +71 -0
- package/dist/statusline.d.ts.map +1 -0
- package/dist/statusline.js +139 -0
- package/dist/statusline.js.map +1 -0
- package/dist/statusline.test.d.ts +2 -0
- package/dist/statusline.test.d.ts.map +1 -0
- package/dist/statusline.test.js +197 -0
- package/dist/statusline.test.js.map +1 -0
- package/dist/watchers/claude.d.ts +11 -1
- package/dist/watchers/claude.d.ts.map +1 -1
- package/dist/watchers/claude.js +32 -15
- package/dist/watchers/claude.js.map +1 -1
- package/package.json +1 -1
- package/web/app.css +36 -0
- package/web/app.js +61 -1
- package/web/i18n.js +28 -0
- package/web/index.html +4 -1
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
7
|
+
const node_test_1 = require("node:test");
|
|
8
|
+
const index_js_1 = require("./i18n/index.js");
|
|
9
|
+
const statusline_install_js_1 = require("./statusline-install.js");
|
|
10
|
+
const statusline_js_1 = require("./statusline.js");
|
|
11
|
+
/**
|
|
12
|
+
* La status line, sin disco: entrada, composición, color y recorte; y el
|
|
13
|
+
* fichero de Claude Code, sobre texto. Lo que no puede pasar nunca: enseñar un
|
|
14
|
+
* límite que Claude Code no mandó, quitar "estela", o pisar la configuración
|
|
15
|
+
* de alguien.
|
|
16
|
+
*/
|
|
17
|
+
const DATA = {
|
|
18
|
+
project: { name: "brightside-portal", client: "Brightside Health" },
|
|
19
|
+
todaySeconds: 2 * 3600 + 14 * 60, projectShare: 0.21, sevenDay: 38, fiveHour: 62,
|
|
20
|
+
};
|
|
21
|
+
const plain = (d, columns) => {
|
|
22
|
+
(0, index_js_1.setLang)("es");
|
|
23
|
+
return (0, statusline_js_1.renderStatus)(d, { color: false, ...(columns ? { columns } : {}) });
|
|
24
|
+
};
|
|
25
|
+
// ── Entrada ─────────────────────────────────────────────────────────────
|
|
26
|
+
(0, node_test_1.test)("entrada con rate_limits: los dos porcentajes, tal cual llegan", () => {
|
|
27
|
+
const i = (0, statusline_js_1.parseStatusInput)(JSON.stringify({
|
|
28
|
+
workspace: { current_dir: "/a/sub", project_dir: "/a" }, transcript_path: "/t.jsonl",
|
|
29
|
+
rate_limits: { five_hour: { used_percentage: 62.4, resets_at: 1 }, seven_day: { used_percentage: 38 } },
|
|
30
|
+
}));
|
|
31
|
+
strict_1.default.deepEqual(i, { dir: "/a", transcriptPath: "/t.jsonl", fiveHour: 62.4, sevenDay: 38,
|
|
32
|
+
fiveHourResetsAt: new Date(1000) });
|
|
33
|
+
});
|
|
34
|
+
(0, node_test_1.test)("entrada sin rate_limits (API key, versiones viejas): nada de límites", () => {
|
|
35
|
+
const i = (0, statusline_js_1.parseStatusInput)(JSON.stringify({ workspace: { current_dir: "/a" } }));
|
|
36
|
+
strict_1.default.equal(i.fiveHour, null);
|
|
37
|
+
strict_1.default.equal(i.sevenDay, null);
|
|
38
|
+
strict_1.default.equal(i.dir, "/a", "sin project_dir, el current_dir");
|
|
39
|
+
const line = plain({ ...DATA, fiveHour: null, sevenDay: null });
|
|
40
|
+
strict_1.default.doesNotMatch(line, /semana|5 h/);
|
|
41
|
+
});
|
|
42
|
+
(0, node_test_1.test)("un JSON roto o que no es un objeto lanza, para que quien llama imprima estela", () => {
|
|
43
|
+
strict_1.default.throws(() => (0, statusline_js_1.parseStatusInput)("esto no es json"));
|
|
44
|
+
strict_1.default.throws(() => (0, statusline_js_1.parseStatusInput)("[1,2]"));
|
|
45
|
+
strict_1.default.throws(() => (0, statusline_js_1.parseStatusInput)("null"));
|
|
46
|
+
});
|
|
47
|
+
// ── Composición ─────────────────────────────────────────────────────────
|
|
48
|
+
(0, node_test_1.test)("orden visual: estela · cliente › proyecto · hoy · este proyecto · semana · 5 h", () => {
|
|
49
|
+
strict_1.default.equal(plain(DATA), "estela · Brightside Health › brightside-portal · hoy 2h14 · este proyecto 21 % · semana 38 % · 5 h 62 %");
|
|
50
|
+
(0, index_js_1.setLang)("en");
|
|
51
|
+
strict_1.default.equal((0, statusline_js_1.stripAnsi)((0, statusline_js_1.renderStatus)(DATA, { color: false })), "estela · Brightside Health › brightside-portal · today 2h14 · this project 21% · week 38% · 5h 62%");
|
|
52
|
+
(0, index_js_1.setLang)("es");
|
|
53
|
+
});
|
|
54
|
+
(0, node_test_1.test)("sin cliente, el nombre es el proyecto; sin proyecto, el aviso de setup", () => {
|
|
55
|
+
strict_1.default.match(plain({ ...DATA, project: { name: "ledger-cli", client: null } }), /^estela · ledger-cli · hoy/);
|
|
56
|
+
strict_1.default.equal(plain({ ...DATA, project: null, unassignedRoot: "web" }), "estela · web (sin proyecto) · estela setup");
|
|
57
|
+
strict_1.default.equal(plain({ ...DATA, project: null, unassignedRoot: null }), "estela · sin proyecto", "fuera de git, sin pista");
|
|
58
|
+
});
|
|
59
|
+
(0, node_test_1.test)("sin proyecto, al recortar: primero la pista, luego el nombre de la raíz con …", () => {
|
|
60
|
+
const d = { ...DATA, project: null, unassignedRoot: "facturacion-clientes" };
|
|
61
|
+
const anchos = [60, 45, 40, 30, 24, 10];
|
|
62
|
+
const lineas = anchos.map((w) => plain(d, w));
|
|
63
|
+
strict_1.default.deepEqual(lineas, [
|
|
64
|
+
"estela · facturacion-clientes (sin proyecto) · estela setup",
|
|
65
|
+
"estela · facturacion-clientes (sin proyecto)",
|
|
66
|
+
"estela · facturacion-cli… (sin proyecto)",
|
|
67
|
+
"estela · factu… (sin proyecto)",
|
|
68
|
+
"estela",
|
|
69
|
+
"estela",
|
|
70
|
+
]);
|
|
71
|
+
lineas.forEach((l, i) => strict_1.default.ok(l.length <= anchos[i], `${anchos[i]}: ${l}`));
|
|
72
|
+
strict_1.default.equal(plain({ ...d, unassignedRoot: null }, 10), "estela");
|
|
73
|
+
(0, index_js_1.setLang)("en");
|
|
74
|
+
strict_1.default.equal((0, statusline_js_1.stripAnsi)((0, statusline_js_1.renderStatus)(d, { color: false })), "estela · facturacion-clientes (no project) · estela setup");
|
|
75
|
+
(0, index_js_1.setLang)("es");
|
|
76
|
+
});
|
|
77
|
+
(0, node_test_1.test)("sin consumo esta semana no se inventa un 0 %", () => {
|
|
78
|
+
strict_1.default.doesNotMatch(plain({ ...DATA, projectShare: null }), /este proyecto/);
|
|
79
|
+
strict_1.default.match(plain({ ...DATA, projectShare: 0 }), /este proyecto 0 %/);
|
|
80
|
+
});
|
|
81
|
+
(0, node_test_1.test)("nunca cuenta atrás ni 'te queda': ni con los límites al 100 %", () => {
|
|
82
|
+
const line = plain({ ...DATA, fiveHour: 100, sevenDay: 99.6 });
|
|
83
|
+
strict_1.default.match(line, /semana 100 % · 5 h 100 %/);
|
|
84
|
+
strict_1.default.doesNotMatch(line, /queda|reinicia|resets|left|:\d\d/i);
|
|
85
|
+
});
|
|
86
|
+
(0, node_test_1.test)("duración corta", () => {
|
|
87
|
+
strict_1.default.equal((0, statusline_js_1.compactDuration)(45 * 60), "45m");
|
|
88
|
+
strict_1.default.equal((0, statusline_js_1.compactDuration)(3 * 3600), "3h");
|
|
89
|
+
strict_1.default.equal((0, statusline_js_1.compactDuration)(2 * 3600 + 5 * 60), "2h05");
|
|
90
|
+
strict_1.default.equal((0, statusline_js_1.compactDuration)(0), "0m");
|
|
91
|
+
});
|
|
92
|
+
// ── Color ───────────────────────────────────────────────────────────────
|
|
93
|
+
(0, node_test_1.test)("estela en #46C0A7, el resto en gris, y la 5 h en ámbar desde el 80 %", () => {
|
|
94
|
+
(0, index_js_1.setLang)("es");
|
|
95
|
+
const jade = "\x1b[38;2;70;192;167m", amber = "\x1b[38;2;221;168;90m";
|
|
96
|
+
const normal = (0, statusline_js_1.renderStatus)({ ...DATA, fiveHour: 79.4 });
|
|
97
|
+
strict_1.default.ok(normal.startsWith(`${jade}estela`));
|
|
98
|
+
strict_1.default.ok(!normal.includes(amber), "79 %: aún no");
|
|
99
|
+
const alto = (0, statusline_js_1.renderStatus)({ ...DATA, fiveHour: 80 });
|
|
100
|
+
strict_1.default.ok(alto.includes(`${amber}5 h 80 %`));
|
|
101
|
+
// La semana no se pinta de ámbar: solo la 5 h, como se pidió.
|
|
102
|
+
strict_1.default.ok(!(0, statusline_js_1.renderStatus)({ ...DATA, sevenDay: 95, fiveHour: 10 }).includes(amber));
|
|
103
|
+
});
|
|
104
|
+
(0, node_test_1.test)("--no-color: ni un código ANSI", () => {
|
|
105
|
+
strict_1.default.doesNotMatch((0, statusline_js_1.renderStatus)(DATA, { color: false }), /\x1b\[/);
|
|
106
|
+
});
|
|
107
|
+
// ── Recorte por COLUMNS ─────────────────────────────────────────────────
|
|
108
|
+
(0, node_test_1.test)("recorte: 5 h → semana → solo cliente → nombre con … → este proyecto → hoy; estela nunca", () => {
|
|
109
|
+
const anchos = [200, 98, 85, 75, 60, 45, 30, 20, 12, 3];
|
|
110
|
+
const lineas = anchos.map((w) => plain(DATA, w));
|
|
111
|
+
for (const [i, w] of anchos.entries()) {
|
|
112
|
+
strict_1.default.ok(lineas[i].length <= w || lineas[i] === "estela", `${w}: ${lineas[i]}`);
|
|
113
|
+
strict_1.default.ok(lineas[i].startsWith("estela"), "estela no se quita nunca");
|
|
114
|
+
}
|
|
115
|
+
strict_1.default.deepEqual(lineas.slice(1), [
|
|
116
|
+
"estela · Brightside Health › brightside-portal · hoy 2h14 · este proyecto 21 % · semana 38 %",
|
|
117
|
+
"estela · Brightside Health › brightside-portal · hoy 2h14 · este proyecto 21 %",
|
|
118
|
+
"estela · Brightside Health · hoy 2h14 · este proyecto 21 %",
|
|
119
|
+
"estela · Brightside Health · hoy 2h14 · este proyecto 21 %",
|
|
120
|
+
// El nombre se acorta antes de quitar "este proyecto", pero no por debajo
|
|
121
|
+
// de 6 caracteres: "Br…" no dice de qué proyecto es.
|
|
122
|
+
"estela · Brightside Health · hoy 2h14",
|
|
123
|
+
"estela · Brightsid… · hoy 2h14",
|
|
124
|
+
"estela · Brightside…",
|
|
125
|
+
"estela · Br…",
|
|
126
|
+
"estela",
|
|
127
|
+
]);
|
|
128
|
+
});
|
|
129
|
+
(0, node_test_1.test)("sin COLUMNS no se recorta nada", () => {
|
|
130
|
+
(0, index_js_1.setLang)("es");
|
|
131
|
+
strict_1.default.equal((0, statusline_js_1.stripAnsi)((0, statusline_js_1.renderStatus)(DATA, { color: false, columns: null })), plain(DATA));
|
|
132
|
+
});
|
|
133
|
+
// ── install / uninstall ─────────────────────────────────────────────────
|
|
134
|
+
(0, node_test_1.test)("install fusiona: el resto del fichero queda igual", () => {
|
|
135
|
+
const antes = JSON.stringify({ model: "opus", permissions: { allow: ["Bash(ls)"] }, hooks: { Stop: [] } });
|
|
136
|
+
const r = (0, statusline_install_js_1.planInstall)(antes);
|
|
137
|
+
strict_1.default.equal(r.status, "installed");
|
|
138
|
+
if (r.status !== "installed")
|
|
139
|
+
return;
|
|
140
|
+
const despues = JSON.parse(r.text);
|
|
141
|
+
strict_1.default.deepEqual(despues["permissions"], { allow: ["Bash(ls)"] });
|
|
142
|
+
strict_1.default.deepEqual(despues["hooks"], { Stop: [] });
|
|
143
|
+
strict_1.default.equal(despues["model"], "opus");
|
|
144
|
+
strict_1.default.deepEqual(despues["statusLine"], { type: "command", command: "estela statusline", padding: 0 });
|
|
145
|
+
strict_1.default.deepEqual(Object.keys(despues), ["model", "permissions", "hooks", "statusLine"], "mismo orden de claves");
|
|
146
|
+
});
|
|
147
|
+
(0, node_test_1.test)("install sin fichero lo crea; con un JSON roto no toca nada", () => {
|
|
148
|
+
strict_1.default.equal((0, statusline_install_js_1.planInstall)(null).status, "installed");
|
|
149
|
+
strict_1.default.equal((0, statusline_install_js_1.planInstall)("{ roto").status, "invalid");
|
|
150
|
+
strict_1.default.equal((0, statusline_install_js_1.planInstall)("[]").status, "invalid");
|
|
151
|
+
});
|
|
152
|
+
(0, node_test_1.test)("install no pisa otra status line: conflicto, --force la sustituye, --append la encadena", () => {
|
|
153
|
+
const ajena = JSON.stringify({ statusLine: { type: "command", command: "~/bin/mi linea 'x'" } });
|
|
154
|
+
const c = (0, statusline_install_js_1.planInstall)(ajena);
|
|
155
|
+
strict_1.default.deepEqual(c, { status: "conflict", existing: "~/bin/mi linea 'x'" });
|
|
156
|
+
const f = (0, statusline_install_js_1.planInstall)(ajena, { force: true });
|
|
157
|
+
strict_1.default.equal(f.status, "replaced");
|
|
158
|
+
const a = (0, statusline_install_js_1.planInstall)(ajena, { append: true });
|
|
159
|
+
strict_1.default.equal(a.status, "chained");
|
|
160
|
+
if (a.status !== "chained")
|
|
161
|
+
return;
|
|
162
|
+
const cmd = JSON.parse(a.text).statusLine.command;
|
|
163
|
+
strict_1.default.equal(cmd, `estela statusline --append ${(0, statusline_install_js_1.shellQuote)("~/bin/mi linea 'x'")}`);
|
|
164
|
+
strict_1.default.equal((0, statusline_install_js_1.appendedCommand)(cmd), "~/bin/mi linea 'x'", "la comilla de dentro sobrevive");
|
|
165
|
+
});
|
|
166
|
+
(0, node_test_1.test)("install dos veces no cambia nada", () => {
|
|
167
|
+
const r = (0, statusline_install_js_1.planInstall)(null);
|
|
168
|
+
if (r.status !== "installed")
|
|
169
|
+
throw new Error();
|
|
170
|
+
strict_1.default.equal((0, statusline_install_js_1.planInstall)(r.text).status, "already");
|
|
171
|
+
});
|
|
172
|
+
(0, node_test_1.test)("uninstall quita la nuestra, devuelve la encadenada y no toca una ajena", () => {
|
|
173
|
+
const sola = (0, statusline_install_js_1.planInstall)(JSON.stringify({ model: "opus" }));
|
|
174
|
+
if (sola.status !== "installed")
|
|
175
|
+
throw new Error();
|
|
176
|
+
const q = (0, statusline_install_js_1.planUninstall)(sola.text);
|
|
177
|
+
strict_1.default.equal(q.status, "removed");
|
|
178
|
+
if (q.status === "removed")
|
|
179
|
+
strict_1.default.deepEqual(JSON.parse(q.text), { model: "opus" });
|
|
180
|
+
const enc = (0, statusline_install_js_1.planInstall)(JSON.stringify({ statusLine: { type: "command", command: "otra" } }), { append: true });
|
|
181
|
+
if (enc.status !== "chained")
|
|
182
|
+
throw new Error();
|
|
183
|
+
const r = (0, statusline_install_js_1.planUninstall)(enc.text);
|
|
184
|
+
strict_1.default.equal(r.status, "restored");
|
|
185
|
+
if (r.status === "restored")
|
|
186
|
+
strict_1.default.deepEqual(JSON.parse(r.text), { statusLine: { type: "command", command: "otra" } });
|
|
187
|
+
strict_1.default.equal((0, statusline_install_js_1.planUninstall)(JSON.stringify({ statusLine: { type: "command", command: "otra" } })).status, "foreign");
|
|
188
|
+
strict_1.default.equal((0, statusline_install_js_1.planUninstall)(JSON.stringify({})).status, "absent");
|
|
189
|
+
});
|
|
190
|
+
(0, node_test_1.test)("reconoce la nuestra también con ruta absoluta o en Windows", () => {
|
|
191
|
+
strict_1.default.ok((0, statusline_install_js_1.isOurs)("estela statusline"));
|
|
192
|
+
strict_1.default.ok((0, statusline_install_js_1.isOurs)("/usr/local/bin/estela statusline --no-color"));
|
|
193
|
+
strict_1.default.ok((0, statusline_install_js_1.isOurs)("C:\\npm\\estela.cmd statusline"));
|
|
194
|
+
strict_1.default.ok(!(0, statusline_install_js_1.isOurs)("ccstatusline"));
|
|
195
|
+
strict_1.default.ok(!(0, statusline_install_js_1.isOurs)("estelar statusline"));
|
|
196
|
+
});
|
|
197
|
+
//# sourceMappingURL=statusline.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statusline.test.js","sourceRoot":"","sources":["../src/statusline.test.ts"],"names":[],"mappings":";;;;;AAAA,gEAAwC;AACxC,yCAAiC;AAEjC,8CAA0C;AAC1C,mEAEiC;AACjC,mDAA8G;AAE9G;;;;;GAKG;AAEH,MAAM,IAAI,GAAe;IACvB,OAAO,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,mBAAmB,EAAE;IACnE,YAAY,EAAE,CAAC,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;CACjF,CAAC;AAEF,MAAM,KAAK,GAAG,CAAC,CAAa,EAAE,OAAgB,EAAE,EAAE;IAChD,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;IACd,OAAO,IAAA,4BAAY,EAAC,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC,CAAC;AAEF,2EAA2E;AAE3E,IAAA,gBAAI,EAAC,+DAA+D,EAAE,GAAG,EAAE;IACzE,MAAM,CAAC,GAAG,IAAA,gCAAgB,EAAC,IAAI,CAAC,SAAS,CAAC;QACxC,SAAS,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,eAAe,EAAE,UAAU;QACpF,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,EAAE;KACxG,CAAC,CAAC,CAAC;IACJ,gBAAM,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QACvF,gBAAgB,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,sEAAsE,EAAE,GAAG,EAAE;IAChF,MAAM,CAAC,GAAG,IAAA,gCAAgB,EAAC,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACjF,gBAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC/B,gBAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC/B,gBAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,iCAAiC,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,gBAAM,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,+EAA+E,EAAE,GAAG,EAAE;IACzF,gBAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,gCAAgB,EAAC,iBAAiB,CAAC,CAAC,CAAC;IACzD,gBAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,gCAAgB,EAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,gBAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,gCAAgB,EAAC,MAAM,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,2EAA2E;AAE3E,IAAA,gBAAI,EAAC,gFAAgF,EAAE,GAAG,EAAE;IAC1F,gBAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EACtB,yGAAyG,CAAC,CAAC;IAC7G,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;IACd,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAS,EAAC,IAAA,4BAAY,EAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,EAC1D,oGAAoG,CAAC,CAAC;IACxG,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,wEAAwE,EAAE,GAAG,EAAE;IAClF,gBAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,4BAA4B,CAAC,CAAC;IAC9G,gBAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,4CAA4C,CAAC,CAAC;IACrH,gBAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,EAAE,uBAAuB,EAAE,yBAAyB,CAAC,CAAC;AAC5H,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,+EAA+E,EAAE,GAAG,EAAE;IACzF,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,sBAAsB,EAAE,CAAC;IAC7E,MAAM,MAAM,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9C,gBAAM,CAAC,SAAS,CAAC,MAAM,EAAE;QACvB,6DAA6D;QAC7D,8CAA8C;QAC9C,0CAA0C;QAC1C,gCAAgC;QAChC,QAAQ;QACR,QAAQ;KACT,CAAC,CAAC;IACH,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,gBAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAE,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,gBAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClE,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;IACd,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAS,EAAC,IAAA,4BAAY,EAAC,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,2DAA2D,CAAC,CAAC;IACxH,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,8CAA8C,EAAE,GAAG,EAAE;IACxD,gBAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC;IAC7E,gBAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,EAAE,mBAAmB,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,+DAA+D,EAAE,GAAG,EAAE;IACzE,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,gBAAM,CAAC,KAAK,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;IAC/C,gBAAM,CAAC,YAAY,CAAC,IAAI,EAAE,mCAAmC,CAAC,CAAC;AACjE,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC1B,gBAAM,CAAC,KAAK,CAAC,IAAA,+BAAe,EAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9C,gBAAM,CAAC,KAAK,CAAC,IAAA,+BAAe,EAAC,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,gBAAM,CAAC,KAAK,CAAC,IAAA,+BAAe,EAAC,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzD,gBAAM,CAAC,KAAK,CAAC,IAAA,+BAAe,EAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,2EAA2E;AAE3E,IAAA,gBAAI,EAAC,sEAAsE,EAAE,GAAG,EAAE;IAChF,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;IACd,MAAM,IAAI,GAAG,uBAAuB,EAAE,KAAK,GAAG,uBAAuB,CAAC;IACtE,MAAM,MAAM,GAAG,IAAA,4BAAY,EAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC;IAC9C,gBAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,IAAA,4BAAY,EAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IACrD,gBAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC;IAC7C,8DAA8D;IAC9D,gBAAM,CAAC,EAAE,CAAC,CAAC,IAAA,4BAAY,EAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACpF,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,+BAA+B,EAAE,GAAG,EAAE;IACzC,gBAAM,CAAC,YAAY,CAAC,IAAA,4BAAY,EAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,2EAA2E;AAE3E,IAAA,gBAAI,EAAC,yFAAyF,EAAE,GAAG,EAAE;IACnG,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACjD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACtC,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,GAAG,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClF,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,0BAA0B,CAAC,CAAC;IACzE,CAAC;IACD,gBAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QAChC,8FAA8F;QAC9F,gFAAgF;QAChF,4DAA4D;QAC5D,4DAA4D;QAC5D,0EAA0E;QAC1E,qDAAqD;QACrD,uCAAuC;QACvC,gCAAgC;QAChC,sBAAsB;QACtB,cAAc;QACd,QAAQ;KACT,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,gCAAgC,EAAE,GAAG,EAAE;IAC1C,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;IACd,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAS,EAAC,IAAA,4BAAY,EAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5F,CAAC,CAAC,CAAC;AAEH,2EAA2E;AAE3E,IAAA,gBAAI,EAAC,mDAAmD,EAAE,GAAG,EAAE;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3G,MAAM,CAAC,GAAG,IAAA,mCAAW,EAAC,KAAK,CAAC,CAAC;IAC7B,gBAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAA4B,CAAC;IAC9D,gBAAM,CAAC,SAAS,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAClE,gBAAM,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACjD,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IACvC,gBAAM,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACvG,gBAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,uBAAuB,CAAC,CAAC;AACnH,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,4DAA4D,EAAE,GAAG,EAAE;IACtE,gBAAM,CAAC,KAAK,CAAC,IAAA,mCAAW,EAAC,IAAI,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpD,gBAAM,CAAC,KAAK,CAAC,IAAA,mCAAW,EAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtD,gBAAM,CAAC,KAAK,CAAC,IAAA,mCAAW,EAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,yFAAyF,EAAE,GAAG,EAAE;IACnG,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,EAAE,EAAE,CAAC,CAAC;IACjG,MAAM,CAAC,GAAG,IAAA,mCAAW,EAAC,KAAK,CAAC,CAAC;IAC7B,gBAAM,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAE5E,MAAM,CAAC,GAAG,IAAA,mCAAW,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,gBAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAEnC,MAAM,CAAC,GAAG,IAAA,mCAAW,EAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,gBAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO;IACnC,MAAM,GAAG,GAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAyC,CAAC,UAAU,CAAC,OAAO,CAAC;IAC3F,gBAAM,CAAC,KAAK,CAAC,GAAG,EAAE,8BAA8B,IAAA,kCAAU,EAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;IACpF,gBAAM,CAAC,KAAK,CAAC,IAAA,uCAAe,EAAC,GAAG,CAAC,EAAE,oBAAoB,EAAE,gCAAgC,CAAC,CAAC;AAC7F,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,kCAAkC,EAAE,GAAG,EAAE;IAC5C,MAAM,CAAC,GAAG,IAAA,mCAAW,EAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW;QAAE,MAAM,IAAI,KAAK,EAAE,CAAC;IAChD,gBAAM,CAAC,KAAK,CAAC,IAAA,mCAAW,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,wEAAwE,EAAE,GAAG,EAAE;IAClF,MAAM,IAAI,GAAG,IAAA,mCAAW,EAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW;QAAE,MAAM,IAAI,KAAK,EAAE,CAAC;IACnD,MAAM,CAAC,GAAG,IAAA,qCAAa,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,gBAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;QAAE,gBAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAEpF,MAAM,GAAG,GAAG,IAAA,mCAAW,EAAC,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAChH,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,EAAE,CAAC;IAChD,MAAM,CAAC,GAAG,IAAA,qCAAa,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,gBAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU;QAAE,gBAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAExH,gBAAM,CAAC,KAAK,CAAC,IAAA,qCAAa,EAAC,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpH,gBAAM,CAAC,KAAK,CAAC,IAAA,qCAAa,EAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,4DAA4D,EAAE,GAAG,EAAE;IACtE,gBAAM,CAAC,EAAE,CAAC,IAAA,8BAAM,EAAC,mBAAmB,CAAC,CAAC,CAAC;IACvC,gBAAM,CAAC,EAAE,CAAC,IAAA,8BAAM,EAAC,6CAA6C,CAAC,CAAC,CAAC;IACjE,gBAAM,CAAC,EAAE,CAAC,IAAA,8BAAM,EAAC,gCAAgC,CAAC,CAAC,CAAC;IACpD,gBAAM,CAAC,EAAE,CAAC,CAAC,IAAA,8BAAM,EAAC,cAAc,CAAC,CAAC,CAAC;IACnC,gBAAM,CAAC,EAAE,CAAC,CAAC,IAAA,8BAAM,EAAC,oBAAoB,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC"}
|
|
@@ -12,6 +12,13 @@ export interface ScanResult {
|
|
|
12
12
|
readonly report: ParseReport;
|
|
13
13
|
}
|
|
14
14
|
export declare function scanClaudeCode(options?: ScanOptions): Promise<ScanResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Una línea del transcript: un turno, `"other"` si es de otro tipo (maquinaria
|
|
17
|
+
* interna que se ignora), `"malformed"` si no se entiende, o null si está en
|
|
18
|
+
* blanco. Es lo que usan tanto el escaneo completo como `estela statusline`,
|
|
19
|
+
* que lee solo las líneas nuevas: los dos tienen que entender lo mismo.
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseTranscriptLine(line: string): AgentTurn | "other" | "malformed" | null;
|
|
15
22
|
/**
|
|
16
23
|
* Devuelve al repositorio de origen los turnos ocurridos en un scratchpad.
|
|
17
24
|
*
|
|
@@ -30,5 +37,8 @@ export declare function scanClaudeCode(options?: ScanOptions): Promise<ScanResul
|
|
|
30
37
|
* es generar ese mismo identificador para cada repositorio conocido y ver cuál
|
|
31
38
|
* coincide.
|
|
32
39
|
*/
|
|
33
|
-
export declare function resolveScratchpads(turns: readonly AgentTurn[]
|
|
40
|
+
export declare function resolveScratchpads(turns: readonly AgentTurn[],
|
|
41
|
+
/** Repositorios ya conocidos, para cuando el lote no trae la ruta real (la status line lee pocas líneas). */
|
|
42
|
+
knownRepos?: readonly string[]): AgentTurn[];
|
|
43
|
+
export declare function isScratchpad(path: string): boolean;
|
|
34
44
|
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/watchers/claude.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAc,MAAM,gBAAgB,CAAC;AAqCzE,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,mEAAmE;IACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/watchers/claude.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAc,MAAM,gBAAgB,CAAC;AAqCzE,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,mEAAmE;IACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CA6DnF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,IAAI,CAW1F;AA2DD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,SAAS,EAAE;AAC3B,6GAA6G;AAC7G,UAAU,GAAE,SAAS,MAAM,EAAO,GACjC,SAAS,EAAE,CAeb;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD"}
|
package/dist/watchers/claude.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.scanClaudeCode = scanClaudeCode;
|
|
4
|
+
exports.parseTranscriptLine = parseTranscriptLine;
|
|
4
5
|
exports.resolveScratchpads = resolveScratchpads;
|
|
6
|
+
exports.isScratchpad = isScratchpad;
|
|
5
7
|
const node_fs_1 = require("node:fs");
|
|
6
8
|
const promises_1 = require("node:fs/promises");
|
|
7
9
|
const node_os_1 = require("node:os");
|
|
@@ -38,27 +40,19 @@ async function scanClaudeCode(options = {}) {
|
|
|
38
40
|
let malformedRecords = 0;
|
|
39
41
|
for (const file of files) {
|
|
40
42
|
for await (const line of readLines(file)) {
|
|
41
|
-
|
|
43
|
+
const parsed = parseTranscriptLine(line);
|
|
44
|
+
if (parsed === null)
|
|
42
45
|
continue;
|
|
43
46
|
recordsSeen++;
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
raw = JSON.parse(line);
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
// Una línea a medio escribir mientras la sesión está viva es normal.
|
|
50
|
-
malformedRecords++;
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
if (raw.type !== "assistant") {
|
|
47
|
+
if (parsed === "other") {
|
|
54
48
|
unknownRecords++;
|
|
55
49
|
continue;
|
|
56
50
|
}
|
|
57
|
-
|
|
58
|
-
if (!turn) {
|
|
51
|
+
if (parsed === "malformed") {
|
|
59
52
|
malformedRecords++;
|
|
60
53
|
continue;
|
|
61
54
|
}
|
|
55
|
+
const turn = parsed;
|
|
62
56
|
if (seenTurnIds.has(turn.turnId)) {
|
|
63
57
|
duplicatesDropped++;
|
|
64
58
|
continue;
|
|
@@ -95,6 +89,27 @@ async function scanClaudeCode(options = {}) {
|
|
|
95
89
|
},
|
|
96
90
|
};
|
|
97
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Una línea del transcript: un turno, `"other"` si es de otro tipo (maquinaria
|
|
94
|
+
* interna que se ignora), `"malformed"` si no se entiende, o null si está en
|
|
95
|
+
* blanco. Es lo que usan tanto el escaneo completo como `estela statusline`,
|
|
96
|
+
* que lee solo las líneas nuevas: los dos tienen que entender lo mismo.
|
|
97
|
+
*/
|
|
98
|
+
function parseTranscriptLine(line) {
|
|
99
|
+
if (!line.trim())
|
|
100
|
+
return null;
|
|
101
|
+
let raw;
|
|
102
|
+
try {
|
|
103
|
+
raw = JSON.parse(line);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Una línea a medio escribir mientras la sesión está viva es normal.
|
|
107
|
+
return "malformed";
|
|
108
|
+
}
|
|
109
|
+
if (raw.type !== "assistant")
|
|
110
|
+
return "other";
|
|
111
|
+
return toTurn(raw) ?? "malformed";
|
|
112
|
+
}
|
|
98
113
|
function toTurn(raw) {
|
|
99
114
|
const id = raw.message?.id;
|
|
100
115
|
const model = raw.message?.model;
|
|
@@ -163,8 +178,10 @@ function num(value) {
|
|
|
163
178
|
* es generar ese mismo identificador para cada repositorio conocido y ver cuál
|
|
164
179
|
* coincide.
|
|
165
180
|
*/
|
|
166
|
-
function resolveScratchpads(turns
|
|
167
|
-
|
|
181
|
+
function resolveScratchpads(turns,
|
|
182
|
+
/** Repositorios ya conocidos, para cuando el lote no trae la ruta real (la status line lee pocas líneas). */
|
|
183
|
+
knownRepos = []) {
|
|
184
|
+
const realPaths = new Set(knownRepos.filter((p) => !isScratchpad(p)));
|
|
168
185
|
for (const turn of turns) {
|
|
169
186
|
if (turn.repoPath && !isScratchpad(turn.repoPath))
|
|
170
187
|
realPaths.add(turn.repoPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/watchers/claude.ts"],"names":[],"mappings":";;AAyDA,
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/watchers/claude.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "estela",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Time tracking you never fill in: rebuilds your billable hours from Claude Code, Codex and GitHub Copilot sessions and your Git history, and splits what the AI cost per project.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"time-tracking",
|
package/web/app.css
CHANGED
|
@@ -101,6 +101,8 @@ button { font: inherit; color: inherit; border: 0; background: none; cursor: poi
|
|
|
101
101
|
/* Fijos, no var(--card-2)/var(--ink): la cabecera es blanca siempre (arriba),
|
|
102
102
|
y esos tokens se invierten en modo oscuro — la pestaña activa o en hover se
|
|
103
103
|
veía como una caja oscura flotando sobre el blanco fijo. */
|
|
104
|
+
/* Una pestaña no se parte en dos líneas: "Mi día" lo hacía al encoger. */
|
|
105
|
+
.tab { white-space: nowrap; }
|
|
104
106
|
.tab:hover { background: #EDEEEA; color: #191D1B; }
|
|
105
107
|
.tab.is-on { background: #E2EFEB; color: #0A5F52; font-weight: 600; }
|
|
106
108
|
|
|
@@ -441,6 +443,11 @@ main.wide { max-width: 1180px; }
|
|
|
441
443
|
font-variant-numeric: tabular-nums; white-space: nowrap;
|
|
442
444
|
}
|
|
443
445
|
|
|
446
|
+
/* Cuota: la parte de la semana de cada proyecto, a simple vista. */
|
|
447
|
+
.quota-bar { height: 5px; border-radius: 3px; background: var(--line); margin-top: 9px; overflow: hidden; }
|
|
448
|
+
.quota-bar i { display: block; height: 100%; border-radius: 3px; background: var(--jade); }
|
|
449
|
+
.quota-note { font-size: .83rem; color: var(--ink-3); margin: 10px 2px 0; line-height: 1.5; }
|
|
450
|
+
|
|
444
451
|
.tag {
|
|
445
452
|
display: inline-block; font-size: .72rem; font-weight: 600;
|
|
446
453
|
padding: 2px 8px; border-radius: 999px;
|
|
@@ -516,6 +523,35 @@ main.wide { max-width: 1180px; }
|
|
|
516
523
|
|
|
517
524
|
.upgrade-wrap { position: relative; }
|
|
518
525
|
.btn-upgrade { padding: 8px 16px; font-size: .88rem; }
|
|
526
|
+
/* Dos textos en el botón y el ancho elige: el largo no cabe en un móvil. El
|
|
527
|
+
lector de pantalla lee siempre el largo, por el aria-label. */
|
|
528
|
+
.btn-upgrade .up-short { display: none; }
|
|
529
|
+
|
|
530
|
+
/* La cabecera en pantallas estrechas. En una sola fila hacen falta ~1.080 px
|
|
531
|
+
en español (unos 110 más con el botón de Sincronizar de los planes de pago):
|
|
532
|
+
por debajo, a 400 px se salía casi el doble del ancho y la página entera se
|
|
533
|
+
deslizaba de lado, y hacia 1.000 "cabía" solo porque "Mi día" se partía en
|
|
534
|
+
dos líneas. Pasa a dos filas — arriba el logo y los botones, que bajan de
|
|
535
|
+
línea si no caben; abajo las pestañas a todo el ancho, deslizables de lado
|
|
536
|
+
si un idioma las alarga. Va aquí, después de .top-right, para que sus
|
|
537
|
+
reglas no la pisen. */
|
|
538
|
+
@media (max-width: 1200px) {
|
|
539
|
+
.top { flex-wrap: wrap; gap: 10px 12px; padding: 12px 16px 0; }
|
|
540
|
+
.top-right { flex-wrap: wrap; justify-content: flex-end; gap: 8px; min-width: 0; }
|
|
541
|
+
.tabs {
|
|
542
|
+
order: 3; flex: 1 1 100%; min-width: 0;
|
|
543
|
+
overflow-x: auto; scrollbar-width: none;
|
|
544
|
+
/* Hasta el borde de la pantalla, para que se vea que se puede deslizar. */
|
|
545
|
+
margin: 0 -16px; padding: 0 16px 10px;
|
|
546
|
+
}
|
|
547
|
+
.tabs::-webkit-scrollbar { display: none; }
|
|
548
|
+
.tab { flex: none; }
|
|
549
|
+
.btn-upgrade { padding: 7px 13px; font-size: .84rem; }
|
|
550
|
+
}
|
|
551
|
+
@media (max-width: 560px) {
|
|
552
|
+
.btn-upgrade .up-long { display: none; }
|
|
553
|
+
.btn-upgrade .up-short { display: inline; }
|
|
554
|
+
}
|
|
519
555
|
.upgrade-menu {
|
|
520
556
|
position: absolute; top: calc(100% + 8px); right: 0; z-index: 10;
|
|
521
557
|
background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
|
package/web/app.js
CHANGED
|
@@ -428,7 +428,14 @@ function haceCuanto(days) {
|
|
|
428
428
|
|
|
429
429
|
async function loadSummary() {
|
|
430
430
|
const { from, to } = periodRange(state.period === "all" ? "quarter" : state.period);
|
|
431
|
-
|
|
431
|
+
// La cuota es siempre de esta semana, sea cual sea el periodo elegido: si
|
|
432
|
+
// fallara, el resumen se pinta igual y la tarjeta simplemente no sale.
|
|
433
|
+
const [summary, quota] = await Promise.all([
|
|
434
|
+
api(`/api/summary?from=${from}&to=${to}`),
|
|
435
|
+
api("/api/quota").catch(() => null),
|
|
436
|
+
]);
|
|
437
|
+
state.summary = summary;
|
|
438
|
+
state.quota = quota;
|
|
432
439
|
renderSummary();
|
|
433
440
|
}
|
|
434
441
|
|
|
@@ -473,6 +480,8 @@ function renderSummary() {
|
|
|
473
480
|
parts.push(`<div class="plist">${s.projects.map(renderProjectRow).join("")}</div>`);
|
|
474
481
|
}
|
|
475
482
|
|
|
483
|
+
parts.push(renderQuota(state.quota));
|
|
484
|
+
|
|
476
485
|
if (s.activity.length) {
|
|
477
486
|
parts.push(`<h2 class="block-title">${tr("summary.activity")}</h2>`);
|
|
478
487
|
parts.push(`<div class="feed">${s.activity.map(renderActivity).join("")}</div>`);
|
|
@@ -510,6 +519,57 @@ function renderSummary() {
|
|
|
510
519
|
});
|
|
511
520
|
}
|
|
512
521
|
|
|
522
|
+
/* ¿Qué proyecto se come tu cuota? El mismo reparto de la semana que da
|
|
523
|
+
`estela quota`, por agente y nunca mezclados: Claude Code gasta la cuota de
|
|
524
|
+
Anthropic y Codex la de OpenAI. Solo consumo real: ni "te queda" ni
|
|
525
|
+
"se acaba", porque esos límites no se publican. */
|
|
526
|
+
function renderQuota(q) {
|
|
527
|
+
if (!q || (!q.agents.length && !q.excluded.length)) return "";
|
|
528
|
+
const AGENT = { "claude-code": "Claude Code", codex: "Codex" };
|
|
529
|
+
const out = [];
|
|
530
|
+
|
|
531
|
+
for (const a of q.agents) {
|
|
532
|
+
out.push(`<h2 class="block-title">${tr("quota.title", { agent: AGENT[a.agent] || a.agent })}</h2>`);
|
|
533
|
+
out.push(`<div class="plist">${a.week.projects.map(quotaRow).join("")}</div>`);
|
|
534
|
+
out.push(`<p class="quota-note">${esc(quotaComparison(a.comparison))}</p>`);
|
|
535
|
+
}
|
|
536
|
+
if (q.excluded.length) out.push(`<p class="quota-note">${tr("quota.copilot")}</p>`);
|
|
537
|
+
if (q.agents.length) out.push(`<p class="quota-note">${tr("quota.estimate")}</p>`);
|
|
538
|
+
return out.join("");
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
function quotaRow(p) {
|
|
542
|
+
const name = p.projectName ?? (p.folder ? tr("quota.folder", { folder: p.folder }) : tr("quota.noFolder"));
|
|
543
|
+
const pct = Math.round(p.share * 100);
|
|
544
|
+
return `
|
|
545
|
+
<div class="prow">
|
|
546
|
+
<div class="prow-text">
|
|
547
|
+
<div class="prow-name">${esc(name)}</div>
|
|
548
|
+
<div class="prow-meta">${tr("quota.breakdown", {
|
|
549
|
+
input: fmtTokens(p.input), output: fmtTokens(p.output),
|
|
550
|
+
read: fmtTokens(p.cacheRead), write: fmtTokens(p.cacheWrite) })}</div>
|
|
551
|
+
<div class="quota-bar"><i style="width:${pct}%"></i></div>
|
|
552
|
+
</div>
|
|
553
|
+
<div class="prow-figs">
|
|
554
|
+
<div class="prow-hours">${fmtTokens(p.total)}</div>
|
|
555
|
+
<div class="prow-amount">${tr("quota.share", { n: pct })}</div>
|
|
556
|
+
</div>
|
|
557
|
+
</div>`;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function quotaComparison(c) {
|
|
561
|
+
if (c.status !== "ok") return tr("quota.noHistory", { weeks: c.weeks, have: c.completeWeeks });
|
|
562
|
+
if (c.ratio === null) return tr("quota.noPastUsage", { current: fmtTokens(c.current), weeks: c.weeks });
|
|
563
|
+
const diff = Math.round((c.ratio - 1) * 100);
|
|
564
|
+
const how = diff > 0 ? tr("quota.more", { n: diff }) : diff < 0 ? tr("quota.less", { n: -diff }) : tr("quota.same");
|
|
565
|
+
return tr("quota.vsHistory", { current: fmtTokens(c.current), average: fmtTokens(c.average), weeks: c.weeks, how });
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/** Tokens con el formato corto del idioma: "22,7 M" o "22.7M". */
|
|
569
|
+
function fmtTokens(n) {
|
|
570
|
+
return new Intl.NumberFormat(localeTag(), { notation: "compact", maximumFractionDigits: 1 }).format(n);
|
|
571
|
+
}
|
|
572
|
+
|
|
513
573
|
function kpi(value, label, extra = "") {
|
|
514
574
|
return `<div class="kpi ${extra}">
|
|
515
575
|
<div class="kpi-value">${esc(value)}</div>
|
package/web/i18n.js
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"refresh.searching": "Buscando…",
|
|
41
41
|
"refresh.failed": "No se pudo actualizar",
|
|
42
42
|
"upgrade.btn": "Actualizar a Pro o Teams",
|
|
43
|
+
"upgrade.btnShort": "Pro o Teams",
|
|
43
44
|
"upgrade.cycle": "Ciclo de facturación",
|
|
44
45
|
"upgrade.monthly": "Mensual",
|
|
45
46
|
"upgrade.yearly": "Anual",
|
|
@@ -140,6 +141,19 @@
|
|
|
140
141
|
"summary.approveAll": "Hay <b>{n}</b> bloques de trabajo <b>tuyo</b> sin revisar en este periodo. Al configurar un proyecto entra de golpe todo su histórico. Pulsa el aviso de cada proyecto para ir a ellos.",
|
|
141
142
|
"summary.approveAll.btn": "Aprobar el periodo",
|
|
142
143
|
"summary.activity": "Actividad reciente",
|
|
144
|
+
"quota.title": "Cuota de {agent} esta semana",
|
|
145
|
+
"quota.breakdown": "entrada {input} · salida {output} · lect. caché {read} · escr. caché {write}",
|
|
146
|
+
"quota.share": "{n} % de la semana",
|
|
147
|
+
"quota.folder": "sin proyecto · {folder}",
|
|
148
|
+
"quota.noFolder": "sin carpeta",
|
|
149
|
+
"quota.vsHistory": "Frente a tu historial: {current} esta semana, y una media de {average} en el mismo tramo de las {weeks} semanas anteriores: {how}.",
|
|
150
|
+
"quota.noPastUsage": "Frente a tu historial: {current} esta semana; en el mismo tramo de las {weeks} semanas anteriores no hubo consumo.",
|
|
151
|
+
"quota.noHistory": "Sin historial suficiente para comparar: hacen falta {weeks} semanas completas y hay {have}.",
|
|
152
|
+
"quota.more": "un {n} % más",
|
|
153
|
+
"quota.less": "un {n} % menos",
|
|
154
|
+
"quota.same": "lo mismo",
|
|
155
|
+
"quota.copilot": "Copilot no guarda tokens fiables y queda fuera de este cálculo.",
|
|
156
|
+
"quota.estimate": "Solo consumo real, calculado en tu máquina: los límites de cada plan no se publican, y lo que uses en claude.ai u otro equipo también cuenta y Estela no lo ve. El detalle de la ventana de 5 h, con <code>estela quota</code>.",
|
|
143
157
|
"summary.nothingLeft": "Ya no queda nada por revisar ahí",
|
|
144
158
|
"summary.pendingHere": "{blocks} por revisar aquí · {more}",
|
|
145
159
|
"summary.moreDays": { one: "1 día más con pendientes", other: "{n} días más con pendientes" },
|
|
@@ -323,6 +337,7 @@
|
|
|
323
337
|
"refresh.searching": "Looking…",
|
|
324
338
|
"refresh.failed": "Couldn't refresh",
|
|
325
339
|
"upgrade.btn": "Upgrade to Pro or Teams",
|
|
340
|
+
"upgrade.btnShort": "Pro or Teams",
|
|
326
341
|
"upgrade.cycle": "Billing cycle",
|
|
327
342
|
"upgrade.monthly": "Monthly",
|
|
328
343
|
"upgrade.yearly": "Yearly",
|
|
@@ -423,6 +438,19 @@
|
|
|
423
438
|
"summary.approveAll": "There are <b>{n}</b> blocks of <b>your</b> work unreviewed in this period. Setting up a project brings in its whole history at once. Click each project's notice to go to them.",
|
|
424
439
|
"summary.approveAll.btn": "Approve the period",
|
|
425
440
|
"summary.activity": "Recent activity",
|
|
441
|
+
"quota.title": "{agent} quota this week",
|
|
442
|
+
"quota.breakdown": "input {input} · output {output} · cache read {read} · cache write {write}",
|
|
443
|
+
"quota.share": "{n}% of the week",
|
|
444
|
+
"quota.folder": "no project · {folder}",
|
|
445
|
+
"quota.noFolder": "no folder",
|
|
446
|
+
"quota.vsHistory": "Against your history: {current} this week, and an average of {average} over the same stretch of the previous {weeks} weeks: {how}.",
|
|
447
|
+
"quota.noPastUsage": "Against your history: {current} this week; over the same stretch of the previous {weeks} weeks there was no usage.",
|
|
448
|
+
"quota.noHistory": "Not enough history to compare: it takes {weeks} complete weeks and there are {have}.",
|
|
449
|
+
"quota.more": "{n}% more",
|
|
450
|
+
"quota.less": "{n}% less",
|
|
451
|
+
"quota.same": "about the same",
|
|
452
|
+
"quota.copilot": "Copilot doesn't record reliable tokens and is left out of this calculation.",
|
|
453
|
+
"quota.estimate": "Real usage only, calculated on your machine: each plan's limits aren't published, and anything you use on claude.ai or another machine also counts and Estela can't see it. For the 5-hour window, run <code>estela quota</code>.",
|
|
426
454
|
"summary.nothingLeft": "Nothing left to review there",
|
|
427
455
|
"summary.pendingHere": "{blocks} to review here · {more}",
|
|
428
456
|
"summary.moreDays": { one: "1 more day with pending blocks", other: "{n} more days with pending blocks" },
|
package/web/index.html
CHANGED
|
@@ -30,7 +30,10 @@
|
|
|
30
30
|
data-i18n="sync.now" data-i18n-title="sync.now.title"
|
|
31
31
|
title="Sube tus horas a la nube y baja lo de tus otras máquinas">Sincronizar</button>
|
|
32
32
|
<div class="upgrade-wrap" id="upgrade-wrap" hidden>
|
|
33
|
-
<button type="button" class="btn-main btn-upgrade" id="upgrade-btn"
|
|
33
|
+
<button type="button" class="btn-main btn-upgrade" id="upgrade-btn"
|
|
34
|
+
data-i18n-aria-label="upgrade.btn" aria-label="Actualizar a Pro o Teams"><span class="up-long"
|
|
35
|
+
data-i18n="upgrade.btn">Actualizar a Pro o Teams</span><span class="up-short"
|
|
36
|
+
data-i18n="upgrade.btnShort">Pro o Teams</span></button>
|
|
34
37
|
<div class="upgrade-menu" id="upgrade-menu" hidden>
|
|
35
38
|
<div class="upgrade-ciclo" role="group" aria-label="Ciclo de facturación" data-i18n-aria-label="upgrade.cycle">
|
|
36
39
|
<button type="button" data-ciclo="monthly" class="is-on" data-i18n="upgrade.monthly">Mensual</button>
|