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,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
40
|
+
const node_child_process_1 = require("node:child_process");
|
|
41
|
+
const node_fs_1 = require("node:fs");
|
|
42
|
+
const node_os_1 = require("node:os");
|
|
43
|
+
const node_path_1 = require("node:path");
|
|
44
|
+
const node_test_1 = require("node:test");
|
|
45
|
+
const schema_js_1 = require("./db/schema.js");
|
|
46
|
+
const store = __importStar(require("./db/store.js"));
|
|
47
|
+
const quota_js_1 = require("./metrics/quota.js");
|
|
48
|
+
const quota_js_2 = require("./quota.js");
|
|
49
|
+
const paths_js_1 = require("./paths.js");
|
|
50
|
+
const project_of_js_1 = require("./project-of.js");
|
|
51
|
+
/**
|
|
52
|
+
* A qué proyecto va una sesión según su carpeta. El fallo de antes: una sesión
|
|
53
|
+
* en `repo/src` de un repo sin registrar salía como "src", y una en un
|
|
54
|
+
* worktree (que vive al lado del repo) no contaba para su proyecto.
|
|
55
|
+
*/
|
|
56
|
+
/** Un directorio temporal con la ruta real (en macOS /var es un enlace a /private/var). */
|
|
57
|
+
function tmp() {
|
|
58
|
+
return (0, node_fs_1.realpathSync)((0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "estela-root-")));
|
|
59
|
+
}
|
|
60
|
+
/** Un repo de mentira: basta la carpeta .git, no hace falta git. */
|
|
61
|
+
function repo(base, name) {
|
|
62
|
+
const r = (0, node_path_1.join)(base, name);
|
|
63
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(r, ".git", "worktrees"), { recursive: true });
|
|
64
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(r, "src"), { recursive: true });
|
|
65
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(r, "packages", "x", "src"), { recursive: true });
|
|
66
|
+
return r;
|
|
67
|
+
}
|
|
68
|
+
/** Un worktree como lo deja `git worktree add`: un fichero .git que apunta al principal. */
|
|
69
|
+
function worktree(main, at, name, relative = false) {
|
|
70
|
+
const meta = (0, node_path_1.join)(main, ".git", "worktrees", name);
|
|
71
|
+
(0, node_fs_1.mkdirSync)(meta, { recursive: true });
|
|
72
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(meta, "commondir"), "../..\n");
|
|
73
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(at, "lib"), { recursive: true });
|
|
74
|
+
const gitdir = relative ? (0, node_path_1.join)("..", "web", ".git", "worktrees", name) : meta;
|
|
75
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(at, ".git"), `gitdir: ${gitdir}\n`);
|
|
76
|
+
return at;
|
|
77
|
+
}
|
|
78
|
+
const n = (p) => (0, paths_js_1.normalizePath)(p);
|
|
79
|
+
// ── gitRoot ─────────────────────────────────────────────────────────────
|
|
80
|
+
(0, node_test_1.test)("subcarpetas: repo/src y repo/packages/x llevan a la raíz del repo", () => {
|
|
81
|
+
const base = tmp();
|
|
82
|
+
const r = repo(base, "web");
|
|
83
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)(r), n(r));
|
|
84
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)((0, node_path_1.join)(r, "src")), n(r));
|
|
85
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)((0, node_path_1.join)(r, "packages", "x", "src")), n(r));
|
|
86
|
+
});
|
|
87
|
+
(0, node_test_1.test)("worktree: lleva al repositorio principal, con gitdir absoluto o relativo", () => {
|
|
88
|
+
const base = tmp();
|
|
89
|
+
const main = repo(base, "web");
|
|
90
|
+
const wt = worktree(main, (0, node_path_1.join)(base, "web-feature"), "web-feature");
|
|
91
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)(wt), n(main));
|
|
92
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)((0, node_path_1.join)(wt, "lib")), n(main));
|
|
93
|
+
const rel = worktree(main, (0, node_path_1.join)(base, "web-fix"), "web-fix", true);
|
|
94
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)(rel), n(main));
|
|
95
|
+
});
|
|
96
|
+
(0, node_test_1.test)("submódulo: un .git fichero sin commondir es su propio repositorio", () => {
|
|
97
|
+
const base = tmp();
|
|
98
|
+
const main = repo(base, "web");
|
|
99
|
+
const sub = (0, node_path_1.join)(main, "vendor", "lib");
|
|
100
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(main, ".git", "modules", "lib"), { recursive: true });
|
|
101
|
+
(0, node_fs_1.mkdirSync)(sub, { recursive: true });
|
|
102
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(sub, ".git"), `gitdir: ${(0, node_path_1.join)(main, ".git", "modules", "lib")}\n`);
|
|
103
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)(sub), n(sub));
|
|
104
|
+
});
|
|
105
|
+
(0, node_test_1.test)("fuera de git: null; y una carpeta que ya no existe no rompe nada", () => {
|
|
106
|
+
const base = tmp();
|
|
107
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(base, "suelta"), { recursive: true });
|
|
108
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)((0, node_path_1.join)(base, "suelta")), null);
|
|
109
|
+
const r = repo(base, "web");
|
|
110
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)((0, node_path_1.join)(r, "borrada", "hace", "tiempo")), n(r), "sube aunque la carpeta no exista");
|
|
111
|
+
});
|
|
112
|
+
(0, node_test_1.test)("una ruta relativa o con ~ no busca raíz git: no puede caer en el repo de quien ejecuta", () => {
|
|
113
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)("~/code/web"), null);
|
|
114
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)("src"), null);
|
|
115
|
+
});
|
|
116
|
+
(0, node_test_1.test)("con git de verdad: un worktree creado con git worktree add", (t) => {
|
|
117
|
+
if ((0, node_child_process_1.spawnSync)("git", ["--version"]).status !== 0) {
|
|
118
|
+
t.skip("sin git");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const base = tmp();
|
|
122
|
+
const main = (0, node_path_1.join)(base, "app");
|
|
123
|
+
const git = (...args) => {
|
|
124
|
+
const r = (0, node_child_process_1.spawnSync)("git", args, { cwd: main, encoding: "utf8" });
|
|
125
|
+
strict_1.default.equal(r.status, 0, r.stderr);
|
|
126
|
+
};
|
|
127
|
+
(0, node_fs_1.mkdirSync)(main);
|
|
128
|
+
git("init", "-q");
|
|
129
|
+
git("-c", "user.email=t@t", "-c", "user.name=t", "commit", "-q", "--allow-empty", "-m", "x");
|
|
130
|
+
git("worktree", "add", "-q", (0, node_path_1.join)(base, "app-feature"));
|
|
131
|
+
strict_1.default.equal((0, project_of_js_1.gitRoot)((0, node_path_1.join)(base, "app-feature")), n(main));
|
|
132
|
+
});
|
|
133
|
+
// ── A qué proyecto va ───────────────────────────────────────────────────
|
|
134
|
+
function base() {
|
|
135
|
+
const b = tmp();
|
|
136
|
+
const web = repo(b, "web");
|
|
137
|
+
const db = (0, schema_js_1.openDatabase)(":memory:");
|
|
138
|
+
store.upsertClient(db, { id: "c", name: "C", currency: "EUR" });
|
|
139
|
+
store.upsertProject(db, { id: "web", clientId: "c", name: "Web", repoPaths: [n(web)], billable: true,
|
|
140
|
+
roundingMinutes: 0, aiCostPolicy: "absorbed", kind: "client" });
|
|
141
|
+
return { b, web, db };
|
|
142
|
+
}
|
|
143
|
+
(0, node_test_1.test)("una sesión en una subcarpeta o en un worktree cuenta para el proyecto del repo", () => {
|
|
144
|
+
const { b, web, db } = base();
|
|
145
|
+
try {
|
|
146
|
+
const owner = (0, project_of_js_1.ownerResolver)(db);
|
|
147
|
+
const wt = worktree(web, (0, node_path_1.join)(b, "web-feature"), "web-feature");
|
|
148
|
+
for (const dir of [web, (0, node_path_1.join)(web, "src"), (0, node_path_1.join)(web, "packages", "x"), wt, (0, node_path_1.join)(wt, "lib")]) {
|
|
149
|
+
strict_1.default.deepEqual(owner(n(dir)), { kind: "project", projectId: "web" }, dir);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
db.close();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
(0, node_test_1.test)("un subproyecto registrado dentro del monorepo no se pierde al subir a la raíz", () => {
|
|
157
|
+
const { web, db } = base();
|
|
158
|
+
try {
|
|
159
|
+
store.upsertProject(db, { id: "x", clientId: "c", name: "X", repoPaths: [n((0, node_path_1.join)(web, "packages", "x"))],
|
|
160
|
+
billable: true, roundingMinutes: 0, aiCostPolicy: "absorbed", kind: "client" });
|
|
161
|
+
const owner = (0, project_of_js_1.ownerResolver)(db);
|
|
162
|
+
strict_1.default.deepEqual(owner(n((0, node_path_1.join)(web, "packages", "x", "src"))), { kind: "project", projectId: "x" });
|
|
163
|
+
strict_1.default.deepEqual(owner(n((0, node_path_1.join)(web, "src"))), { kind: "project", projectId: "web" });
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
db.close();
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
(0, node_test_1.test)("sin proyecto: el nombre de la raíz git, nunca el de una subcarpeta; fuera de git, la carpeta", () => {
|
|
170
|
+
const { b, db } = base();
|
|
171
|
+
try {
|
|
172
|
+
const otro = repo(b, "otro-repo");
|
|
173
|
+
const owner = (0, project_of_js_1.ownerResolver)(db);
|
|
174
|
+
strict_1.default.deepEqual(owner(n((0, node_path_1.join)(otro, "packages", "x", "src"))), { kind: "folder", path: n(otro), name: "otro-repo", inGit: true });
|
|
175
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(b, "notas"));
|
|
176
|
+
strict_1.default.deepEqual(owner(n((0, node_path_1.join)(b, "notas"))), { kind: "folder", path: n((0, node_path_1.join)(b, "notas")), name: "notas", inGit: false });
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
db.close();
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
(0, node_test_1.test)("en quota, las subcarpetas de un repo sin registrar son una sola fila con su nombre", () => {
|
|
183
|
+
const { b, db } = base();
|
|
184
|
+
try {
|
|
185
|
+
const otro = repo(b, "otro-repo");
|
|
186
|
+
// Dentro de esta semana a cualquier hora, también un lunes a las 00:05.
|
|
187
|
+
const at = new Date(Math.max((0, quota_js_1.weekStart)(new Date()).getTime(), Date.now() - 10 * 60_000));
|
|
188
|
+
const turno = (id, cwd) => ({
|
|
189
|
+
agent: "claude-code", turnId: id, sessionId: "s", at, model: "claude-sonnet-4-6",
|
|
190
|
+
repoPath: n(cwd), branch: null, producerVersion: null,
|
|
191
|
+
tokens: { input: 0, output: 0, cacheRead: 100, cacheWrite5m: 0, cacheWrite1h: 0 },
|
|
192
|
+
});
|
|
193
|
+
store.saveTurns(db, [turno("a", (0, node_path_1.join)(otro, "src")), turno("b", (0, node_path_1.join)(otro, "packages", "x")), turno("c", otro)]);
|
|
194
|
+
const filas = (0, quota_js_2.loadQuotaReport)(db).agents[0].week.rows;
|
|
195
|
+
strict_1.default.equal(filas.length, 1);
|
|
196
|
+
strict_1.default.deepEqual(filas[0].bucket, { kind: "folder", folder: "otro-repo", path: n(otro) });
|
|
197
|
+
strict_1.default.equal(filas[0].usage.total, 300);
|
|
198
|
+
}
|
|
199
|
+
finally {
|
|
200
|
+
db.close();
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
//# sourceMappingURL=project-of.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-of.test.js","sourceRoot":"","sources":["../src/project-of.test.ts"],"names":[],"mappings":"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"}
|
package/dist/quota.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
2
|
+
import { type QuotaReport } from "./metrics/quota.js";
|
|
3
|
+
/**
|
|
4
|
+
* La cuota sobre la base: lo que comparten `estela quota` y el panel web.
|
|
5
|
+
* El cálculo vive en `metrics/quota.ts`; aquí solo se leen los datos.
|
|
6
|
+
*/
|
|
7
|
+
export interface QuotaLoadOptions {
|
|
8
|
+
/** % por precio de lista en vez de por tokens (`--weighted`). */
|
|
9
|
+
readonly weighted?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* La base de la que se lee, para encontrar al lado lo que guardó la status
|
|
12
|
+
* line (el `resets_at` de Claude Code). Sin ella, la ventana se estima.
|
|
13
|
+
*/
|
|
14
|
+
readonly dbPath?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function loadQuotaReport(db: DatabaseSync, now?: Date, options?: QuotaLoadOptions): QuotaReport;
|
|
17
|
+
/**
|
|
18
|
+
* Trae los turnos de esta semana antes de calcular.
|
|
19
|
+
*
|
|
20
|
+
* Sin esto, la "ventana actual" sería la de la última vez que alguien ejecutó
|
|
21
|
+
* `estela import`, que puede ser de ayer. Solo se leen los transcripts desde el
|
|
22
|
+
* lunes, y solo se guardan turnos: `INSERT OR IGNORE` sobre el `turn_id` hace
|
|
23
|
+
* que repetirlo no duplique nada, y el siguiente `import` reconstruye las horas
|
|
24
|
+
* con lo que lee él mismo, así que no se le quita trabajo.
|
|
25
|
+
*/
|
|
26
|
+
export declare function refreshQuotaTurns(db: DatabaseSync, since: Date): Promise<number>;
|
|
27
|
+
//# sourceMappingURL=quota.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota.d.ts","sourceRoot":"","sources":["../src/quota.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAA4D,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKhH;;;GAGG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,GAAE,IAAiB,EAAE,OAAO,GAAE,gBAAqB,GAAG,WAAW,CAsBrH;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAGtF"}
|
package/dist/quota.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadQuotaReport = loadQuotaReport;
|
|
37
|
+
exports.refreshQuotaTurns = refreshQuotaTurns;
|
|
38
|
+
const store = __importStar(require("./db/store.js"));
|
|
39
|
+
const quota_js_1 = require("./metrics/quota.js");
|
|
40
|
+
const project_of_js_1 = require("./project-of.js");
|
|
41
|
+
const statusline_cache_js_1 = require("./statusline-cache.js");
|
|
42
|
+
const agents_js_1 = require("./watchers/agents.js");
|
|
43
|
+
function loadQuotaReport(db, now = new Date(), options = {}) {
|
|
44
|
+
const range = (0, quota_js_1.quotaRange)(now);
|
|
45
|
+
const names = new Map(store.listProjects(db).map((p) => [p.id, p.name]));
|
|
46
|
+
// La carpeta, y si no, su raíz git: ver project-of.ts. Una carpeta sin
|
|
47
|
+
// proyecto sale con el nombre de su raíz git, no el de una subcarpeta.
|
|
48
|
+
const ownerOf = (0, project_of_js_1.ownerResolver)(db);
|
|
49
|
+
const bucketOf = (repoPath) => {
|
|
50
|
+
const o = ownerOf(repoPath);
|
|
51
|
+
if (o.kind === "project")
|
|
52
|
+
return { kind: "project", projectId: o.projectId, projectName: names.get(o.projectId) ?? o.projectId };
|
|
53
|
+
if (o.kind === "folder")
|
|
54
|
+
return { kind: "folder", folder: o.name, path: o.path };
|
|
55
|
+
return { kind: "none" };
|
|
56
|
+
};
|
|
57
|
+
return (0, quota_js_1.buildQuota)({
|
|
58
|
+
turns: store.quotaTurns(db, range.start, range.end),
|
|
59
|
+
firstTurnAt: store.firstTurnByAgent(db),
|
|
60
|
+
now,
|
|
61
|
+
bucketOf,
|
|
62
|
+
weighted: options.weighted === true,
|
|
63
|
+
claudeWindow: options.dbPath ? (0, quota_js_1.officialWindow)((0, statusline_cache_js_1.readFiveHourReset)(options.dbPath), now) : null,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Trae los turnos de esta semana antes de calcular.
|
|
68
|
+
*
|
|
69
|
+
* Sin esto, la "ventana actual" sería la de la última vez que alguien ejecutó
|
|
70
|
+
* `estela import`, que puede ser de ayer. Solo se leen los transcripts desde el
|
|
71
|
+
* lunes, y solo se guardan turnos: `INSERT OR IGNORE` sobre el `turn_id` hace
|
|
72
|
+
* que repetirlo no duplique nada, y el siguiente `import` reconstruye las horas
|
|
73
|
+
* con lo que lee él mismo, así que no se le quita trabajo.
|
|
74
|
+
*/
|
|
75
|
+
async function refreshQuotaTurns(db, since) {
|
|
76
|
+
const scans = await (0, agents_js_1.scanAgents)({ since });
|
|
77
|
+
return store.saveTurns(db, scans.flatMap((s) => [...s.turns]));
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=quota.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota.js","sourceRoot":"","sources":["../src/quota.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,0CAsBC;AAWD,8CAGC;AAzDD,qDAAuC;AACvC,iDAAgH;AAChH,mDAAgD;AAChD,+DAA0D;AAC1D,oDAAkD;AAiBlD,SAAgB,eAAe,CAAC,EAAgB,EAAE,MAAY,IAAI,IAAI,EAAE,EAAE,UAA4B,EAAE;IACtG,MAAM,KAAK,GAAG,IAAA,qBAAU,EAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEzE,uEAAuE;IACvE,uEAAuE;IACvE,MAAM,OAAO,GAAG,IAAA,6BAAa,EAAC,EAAE,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,CAAC,QAAuB,EAAe,EAAE;QACxD,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QACjI,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACjF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC,CAAC;IAEF,OAAO,IAAA,qBAAU,EAAC;QAChB,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC;QACnD,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACvC,GAAG;QACH,QAAQ;QACR,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,IAAI;QACnC,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,yBAAc,EAAC,IAAA,uCAAiB,EAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;KAC7F,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,iBAAiB,CAAC,EAAgB,EAAE,KAAW;IACnE,MAAM,KAAK,GAAG,MAAM,IAAA,sBAAU,EAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AA2EjG,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,8CAA8C;IAC9C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,qEAAqE;IACrE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AA0DD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAcD,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAErD;AA2CD,wBAAgB,WAAW,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6CxE"}
|
package/dist/server.js
CHANGED
|
@@ -60,6 +60,9 @@ const identity_js_1 = require("./watchers/identity.js");
|
|
|
60
60
|
const index_js_2 = require("./i18n/index.js");
|
|
61
61
|
const paths_js_1 = require("./paths.js");
|
|
62
62
|
const localize_js_1 = require("./billing/localize.js");
|
|
63
|
+
const assign_js_1 = require("./billing/assign.js");
|
|
64
|
+
const quota_js_1 = require("./metrics/quota.js");
|
|
65
|
+
const quota_js_2 = require("./quota.js");
|
|
63
66
|
const labels_js_1 = require("./i18n/labels.js");
|
|
64
67
|
/**
|
|
65
68
|
* Servidor local del dashboard.
|
|
@@ -139,32 +142,14 @@ async function importOnce(dbPath) {
|
|
|
139
142
|
const commits = (0, identity_js_1.onlyMine)(allRepoCommits, mine);
|
|
140
143
|
const fromAgents = (0, sessionize_js_1.attachCommits)((0, sessionize_js_1.sessionize)(turns), commits);
|
|
141
144
|
const fromCommits = (0, sessionize_js_1.withoutOverlap)((0, sessionize_js_1.sessionizeCommits)(commits), fromAgents);
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const project = store.getProject(db, projectId);
|
|
151
|
-
const day = (0, shared_1.localDate)(block.startedAt);
|
|
152
|
-
const slug = (block.branch ?? "sin-rama").replace(/[^a-zA-Z0-9]+/g, "-");
|
|
153
|
-
store.saveTimeEntry(db, {
|
|
154
|
-
id: `te_${projectId}_${day}_${slug}`,
|
|
155
|
-
projectId,
|
|
156
|
-
startedAt: block.startedAt, endedAt: block.endedAt, seconds: block.seconds,
|
|
157
|
-
description: (0, sessionize_js_1.describeBlock)(block),
|
|
158
|
-
billable: project.billable, invoiceId: null,
|
|
159
|
-
aiCost: block.aiCost,
|
|
160
|
-
// Sin agente no hay segundos de agente que atribuir.
|
|
161
|
-
agentSeconds: block.turnCount > 0 ? block.seconds : 0,
|
|
162
|
-
commitHashes: block.commits.map((c) => c.hash),
|
|
163
|
-
agents: block.turnCount > 0 ? [...(block.agents ?? ["claude-code"])] : [],
|
|
164
|
-
source: block.turnCount > 0 ? "agent" : "commit", kind: "development",
|
|
165
|
-
branch: block.branch,
|
|
166
|
-
workItems: (0, shared_1.extractWorkItems)(block.branch, block.commits.map((c) => c.subject), project.tracker),
|
|
167
|
-
});
|
|
145
|
+
// Las mismas reglas que `estela import` (billing/assign.ts). Las horas de
|
|
146
|
+
// subcarpetas y worktrees solo se recuperan si ya se confirmó una vez
|
|
147
|
+
// desde la terminal: el panel no cambia horas importadas en segundo plano
|
|
148
|
+
// sin que nadie haya visto antes qué iba a cambiar.
|
|
149
|
+
const recover = (0, node_fs_1.existsSync)((0, node_path_1.join)((0, node_path_1.dirname)(dbPath), ".recover-git-root"));
|
|
150
|
+
const plan = (0, assign_js_1.planEntries)(db, [...fromAgents, ...fromCommits], { recover });
|
|
151
|
+
for (const { entry } of plan.entries) {
|
|
152
|
+
store.saveTimeEntry(db, entry);
|
|
168
153
|
imputed++;
|
|
169
154
|
}
|
|
170
155
|
return imputed;
|
|
@@ -319,6 +304,12 @@ async function api(req, res, url, dbPath) {
|
|
|
319
304
|
const to = url.searchParams.get("to") ?? "";
|
|
320
305
|
return json(res, 200, buildSummary(db, from, to));
|
|
321
306
|
}
|
|
307
|
+
// Qué proyecto se come la cuota esta semana. Sin refrescar transcripts:
|
|
308
|
+
// el panel ya importa solo cada pocos minutos, y una petición web no debe
|
|
309
|
+
// ponerse a leer el disco entero.
|
|
310
|
+
if (path === "/api/quota" && req.method === "GET") {
|
|
311
|
+
return json(res, 200, (0, quota_js_1.quotaToJson)((0, quota_js_2.loadQuotaReport)(db, new Date(), { dbPath })));
|
|
312
|
+
}
|
|
322
313
|
if (path === "/api/day" && req.method === "GET") {
|
|
323
314
|
const date = url.searchParams.get("date") ?? todayIso();
|
|
324
315
|
return json(res, 200, buildDay(db, date));
|