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.
Files changed (90) hide show
  1. package/README.md +96 -0
  2. package/dist/billing/assign.d.ts +45 -0
  3. package/dist/billing/assign.d.ts.map +1 -0
  4. package/dist/billing/assign.js +159 -0
  5. package/dist/billing/assign.js.map +1 -0
  6. package/dist/billing/assign.test.d.ts +2 -0
  7. package/dist/billing/assign.test.d.ts.map +1 -0
  8. package/dist/billing/assign.test.js +153 -0
  9. package/dist/billing/assign.test.js.map +1 -0
  10. package/dist/bin.js +23 -1
  11. package/dist/bin.js.map +1 -1
  12. package/dist/cli-import-recover.test.d.ts +2 -0
  13. package/dist/cli-import-recover.test.d.ts.map +1 -0
  14. package/dist/cli-import-recover.test.js +191 -0
  15. package/dist/cli-import-recover.test.js.map +1 -0
  16. package/dist/cli-quota.test.d.ts +2 -0
  17. package/dist/cli-quota.test.d.ts.map +1 -0
  18. package/dist/cli-quota.test.js +281 -0
  19. package/dist/cli-quota.test.js.map +1 -0
  20. package/dist/cli-statusline.test.d.ts +2 -0
  21. package/dist/cli-statusline.test.d.ts.map +1 -0
  22. package/dist/cli-statusline.test.js +333 -0
  23. package/dist/cli-statusline.test.js.map +1 -0
  24. package/dist/cli.d.ts.map +1 -1
  25. package/dist/cli.js +350 -49
  26. package/dist/cli.js.map +1 -1
  27. package/dist/db/store.d.ts +12 -1
  28. package/dist/db/store.d.ts.map +1 -1
  29. package/dist/db/store.js +52 -0
  30. package/dist/db/store.js.map +1 -1
  31. package/dist/demo.d.ts.map +1 -1
  32. package/dist/demo.js +53 -0
  33. package/dist/demo.js.map +1 -1
  34. package/dist/i18n/en.d.ts.map +1 -1
  35. package/dist/i18n/en.js +68 -0
  36. package/dist/i18n/en.js.map +1 -1
  37. package/dist/metrics/quota.d.ts +226 -0
  38. package/dist/metrics/quota.d.ts.map +1 -0
  39. package/dist/metrics/quota.js +291 -0
  40. package/dist/metrics/quota.js.map +1 -0
  41. package/dist/metrics/quota.test.d.ts +2 -0
  42. package/dist/metrics/quota.test.d.ts.map +1 -0
  43. package/dist/metrics/quota.test.js +325 -0
  44. package/dist/metrics/quota.test.js.map +1 -0
  45. package/dist/project-of.d.ts +52 -0
  46. package/dist/project-of.d.ts.map +1 -0
  47. package/dist/project-of.js +124 -0
  48. package/dist/project-of.js.map +1 -0
  49. package/dist/project-of.test.d.ts +2 -0
  50. package/dist/project-of.test.d.ts.map +1 -0
  51. package/dist/project-of.test.js +203 -0
  52. package/dist/project-of.test.js.map +1 -0
  53. package/dist/quota.d.ts +27 -0
  54. package/dist/quota.d.ts.map +1 -0
  55. package/dist/quota.js +79 -0
  56. package/dist/quota.js.map +1 -0
  57. package/dist/server.d.ts.map +1 -1
  58. package/dist/server.js +17 -26
  59. package/dist/server.js.map +1 -1
  60. package/dist/server.test.js +37 -0
  61. package/dist/server.test.js.map +1 -1
  62. package/dist/statusline-cache.d.ts +35 -0
  63. package/dist/statusline-cache.d.ts.map +1 -0
  64. package/dist/statusline-cache.js +57 -0
  65. package/dist/statusline-cache.js.map +1 -0
  66. package/dist/statusline-install.d.ts +52 -0
  67. package/dist/statusline-install.d.ts.map +1 -0
  68. package/dist/statusline-install.js +115 -0
  69. package/dist/statusline-install.js.map +1 -0
  70. package/dist/statusline-run.d.ts +8 -0
  71. package/dist/statusline-run.d.ts.map +1 -0
  72. package/dist/statusline-run.js +256 -0
  73. package/dist/statusline-run.js.map +1 -0
  74. package/dist/statusline.d.ts +71 -0
  75. package/dist/statusline.d.ts.map +1 -0
  76. package/dist/statusline.js +139 -0
  77. package/dist/statusline.js.map +1 -0
  78. package/dist/statusline.test.d.ts +2 -0
  79. package/dist/statusline.test.d.ts.map +1 -0
  80. package/dist/statusline.test.js +197 -0
  81. package/dist/statusline.test.js.map +1 -0
  82. package/dist/watchers/claude.d.ts +11 -1
  83. package/dist/watchers/claude.d.ts.map +1 -1
  84. package/dist/watchers/claude.js +32 -15
  85. package/dist/watchers/claude.js.map +1 -1
  86. package/package.json +1 -1
  87. package/web/app.css +36 -0
  88. package/web/app.js +61 -1
  89. package/web/i18n.js +28 -0
  90. 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":"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"}
@@ -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[]): 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,CA6EnF;AA2DD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAe3E"}
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"}
@@ -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
- if (!line.trim())
43
+ const parsed = parseTranscriptLine(line);
44
+ if (parsed === null)
42
45
  continue;
43
46
  recordsSeen++;
44
- let raw;
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
- const turn = toTurn(raw);
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
- const realPaths = new Set();
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":"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"}
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/watchers/claude.ts"],"names":[],"mappings":";;AAyDA,wCA6DC;AAQD,kDAWC;AA6ED,gDAmBC;AAED,oCAEC;AA7OD,qCAA2C;AAC3C,+CAAiD;AACjD,qCAAkC;AAClC,yCAAiC;AACjC,iDAAgD;AAGhD,+CAAsC;AACtC,0CAA4D;AAE5D;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,GAAG,IAAA,gBAAI,EAAC,IAAA,iBAAO,GAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AA+BpD,KAAK,UAAU,cAAc,CAAC,UAAuB,EAAE;IAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IACzC,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAE1C,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC3C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,iBAAiB,GAAG,CAAC,CAAC;IAC1B,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IAEzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;YACzC,IAAI,MAAM,KAAK,IAAI;gBAAE,SAAS;YAC9B,WAAW,EAAE,CAAC;YACd,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBAAC,cAAc,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YACvD,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;gBAAC,gBAAgB,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC7D,MAAM,IAAI,GAAG,MAAM,CAAC;YAEpB,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACjC,iBAAiB,EAAE,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE7B,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,KAAK;gBAAE,SAAS;YACvD,IAAI,OAAO,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC;gBAAE,SAAS;YAE1F,IAAI,IAAI,CAAC,eAAe;gBAAE,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACrE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,MAAM,YAAY,GAAG,WAAW,GAAG,cAAc,CAAC;IAClD,IAAI,YAAY,GAAG,CAAC,IAAI,gBAAgB,GAAG,YAAY,GAAG,IAAI,EAAE,CAAC;QAC/D,QAAQ,CAAC,IAAI,CACX,IAAA,aAAE,EAAA,GAAG,gBAAgB,OAAO,YAAY,iDAAiD;YACzF,IAAI,CAAC,CAAC,gBAAgB,GAAG,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YAC9D,IAAA,aAAE,EAAA,oFAAoF,CAAC,CAAC;IAC5F,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IAEtD,OAAO;QACL,KAAK;QACL,MAAM,EAAE;YACN,SAAS,EAAE,KAAK,CAAC,MAAM;YACvB,WAAW;YACX,aAAa,EAAE,KAAK,CAAC,MAAM;YAC3B,iBAAiB;YACjB,cAAc;YACd,gBAAgB;YAChB,gBAAgB,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC,IAAI,EAAE;YAC9C,QAAQ;SACT;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,GAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAuB,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,qEAAqE;QACrE,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,OAAO,CAAC;IAC7C,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;AACpC,CAAC;AAED,SAAS,MAAM,CAAC,GAAuB;IACrC,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;IACjC,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IAEhC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QACzF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5C,OAAO;QACL,KAAK,EAAE,aAAa;QACpB,MAAM,EAAE,EAAE;QACV,SAAS,EAAE,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;QACjE,EAAE;QACF,KAAK;QACL,QAAQ,EAAE,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,wBAAa,EAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;QACrE,MAAM,EAAE,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;QACjF,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;QACrC,eAAe,EAAE,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;KACtE,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAAC,KAA0C;IAC3D,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAE3F,MAAM,QAAQ,GAAG,KAAK,CAAC,gBAAgB,CAAwC,CAAC;IAChF,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;IAE7D,MAAM,SAAS,GAAG,QAAQ,KAAK,SAAS,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC;IAE/E,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACjC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QACnC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAChD,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;QACjD,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,SAAS,GAAG,CAAC,KAAc;IACzB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,kBAAkB,CAChC,KAA2B;AAC3B,6GAA6G;AAC7G,aAAgC,EAAE;IAElC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAS,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,SAAS;QAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IAEjE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QAChE,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACjD,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AACnE,CAAC;AAED,+EAA+E;AAC/E,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,4CAA4C;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvD,OAAO,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,oFAAoF;AACpF,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,QAAuB,EAAE,KAAwB;IACpE,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,yBAAc,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY;IACzC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,IAAA,gBAAI,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC;YACH,IAAI,CAAC,CAAC,MAAM,IAAA,eAAI,EAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE;gBAAE,SAAS;YAC/C,KAAK,MAAM,IAAI,IAAI,MAAM,IAAA,kBAAO,EAAC,GAAG,CAAC,EAAE,CAAC;gBACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+DAA+D;QACjE,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,SAAS,CAAC,IAAY;IACpC,MAAM,MAAM,GAAG,IAAA,0BAAgB,EAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,KAAK,CAAC,CAAC,IAAA,+BAAe,EAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IACjE,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "estela",
3
- "version": "0.1.39",
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
- state.summary = await api(`/api/summary?from=${from}&to=${to}`);
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" data-i18n="upgrade.btn">Actualizar a Pro o Teams</button>
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>