estela 0.1.20 → 0.1.22
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 +110 -95
- package/dist/billing/amortize.d.ts.map +1 -1
- package/dist/billing/amortize.js +3 -2
- package/dist/billing/amortize.js.map +1 -1
- package/dist/billing/invoice.d.ts.map +1 -1
- package/dist/billing/invoice.js +19 -18
- package/dist/billing/invoice.js.map +1 -1
- package/dist/billing/sessionize.d.ts.map +1 -1
- package/dist/billing/sessionize.js +7 -3
- package/dist/billing/sessionize.js.map +1 -1
- package/dist/billing/sessionize.test.js +26 -0
- package/dist/billing/sessionize.test.js.map +1 -1
- package/dist/billing.d.ts.map +1 -1
- package/dist/billing.js +5 -4
- package/dist/billing.js.map +1 -1
- package/dist/bin.js +6 -2
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +311 -164
- package/dist/cli.js.map +1 -1
- package/dist/cloud/auth.d.ts.map +1 -1
- package/dist/cloud/auth.js +9 -8
- package/dist/cloud/auth.js.map +1 -1
- package/dist/cloud/client.d.ts.map +1 -1
- package/dist/cloud/client.js +11 -6
- package/dist/cloud/client.js.map +1 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +4 -3
- package/dist/db/schema.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +50 -45
- package/dist/doctor.js.map +1 -1
- package/dist/i18n/en.d.ts +10 -0
- package/dist/i18n/en.d.ts.map +1 -0
- package/dist/i18n/en.js +327 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/i18n.test.d.ts +2 -0
- package/dist/i18n/i18n.test.d.ts.map +1 -0
- package/dist/i18n/i18n.test.js +201 -0
- package/dist/i18n/i18n.test.js.map +1 -0
- package/dist/i18n/index.d.ts +54 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +106 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +6 -5
- package/dist/publish.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +31 -29
- package/dist/server.js.map +1 -1
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +8 -5
- package/dist/setup.js.map +1 -1
- package/dist/sync/team.d.ts.map +1 -1
- package/dist/sync/team.js +7 -6
- package/dist/sync/team.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +7 -6
- package/dist/sync.js.map +1 -1
- package/dist/team.d.ts.map +1 -1
- package/dist/team.js +9 -8
- package/dist/team.js.map +1 -1
- package/dist/updateCheck.d.ts.map +1 -1
- package/dist/updateCheck.js +3 -2
- package/dist/updateCheck.js.map +1 -1
- package/dist/watchers/claude.d.ts.map +1 -1
- package/dist/watchers/claude.js +3 -2
- package/dist/watchers/claude.js.map +1 -1
- package/node_modules/@estela/shared/dist/money.d.ts +1 -0
- package/node_modules/@estela/shared/dist/money.d.ts.map +1 -1
- package/node_modules/@estela/shared/dist/money.js +9 -1
- package/node_modules/@estela/shared/dist/money.js.map +1 -1
- package/package.json +1 -1
- package/web/app.js +12 -7
package/README.md
CHANGED
|
@@ -1,168 +1,183 @@
|
|
|
1
1
|
# Estela
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
**English** · [Español](https://github.com/jdleonruiz/estela-cli/blob/main/README.es.md)
|
|
4
|
+
|
|
5
|
+
Development time tracking you **don't have to fill in**. Estela reads what your
|
|
6
|
+
AI agents and your Git already wrote to disk and rebuilds where your time went,
|
|
7
|
+
along with what the AI cost.
|
|
6
8
|
|
|
7
9
|
```sh
|
|
8
10
|
npx estela setup
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
Twenty seconds later you have the last few months of your history. No account,
|
|
14
|
+
no card, and nothing leaves your machine.
|
|
13
15
|
|
|
14
16
|
---
|
|
15
17
|
|
|
16
|
-
##
|
|
18
|
+
## Why it exists
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
A timer you have to remember to start always fails. And with an AI agent, time
|
|
21
|
+
isn't measured in keystrokes anymore: it goes into writing the prompt, reading
|
|
22
|
+
what comes back, and trying it out.
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
`~/.claude/projects/`
|
|
24
|
-
|
|
24
|
+
But that work **leaves a trail**. Claude Code saves every session in
|
|
25
|
+
`~/.claude/projects/` with its exact model and tokens. Git records when you
|
|
26
|
+
committed and what. Estela reads both and lines them up.
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
What it doesn't do:
|
|
27
29
|
|
|
28
|
-
- **
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- **
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
- **It doesn't install hooks.** Your `husky` and `lefthook` stay untouched, and
|
|
31
|
+
your commit messages aren't modified. An identifier written into history
|
|
32
|
+
can't be taken back once it's pushed.
|
|
33
|
+
- **It doesn't inspect processes or your terminal.** It reads files that already
|
|
34
|
+
exist.
|
|
35
|
+
- **It doesn't store the content of your prompts.** Only when, how much, and
|
|
36
|
+
with which model.
|
|
37
|
+
- **It doesn't send anything anywhere.** The free plan is entirely local.
|
|
35
38
|
|
|
36
|
-
##
|
|
39
|
+
## Getting started
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
You need **Node 22.5 or later** (for `node:sqlite`).
|
|
39
42
|
|
|
40
43
|
```sh
|
|
41
|
-
npx estela setup #
|
|
42
|
-
npx estela web #
|
|
43
|
-
npx estela doctor #
|
|
44
|
+
npx estela setup # detects agents and repositories, rebuilds your history
|
|
45
|
+
npx estela web # opens the dashboard at http://localhost:4319
|
|
46
|
+
npx estela doctor # checks your data and flags anything wrong
|
|
44
47
|
npx estela --version
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
No Claude Code? It still works: without transcripts, Estela rebuilds your time
|
|
51
|
+
from your commits alone, and marks it as estimated.
|
|
52
|
+
|
|
53
|
+
`npm` doesn't update global installs on its own. If you installed with
|
|
54
|
+
`npm install -g estela`, Estela tells you when there's a newer version (it asks
|
|
55
|
+
npm at most once a day, in the background, without blocking anything); update
|
|
56
|
+
with `npm install -g estela@latest`.
|
|
51
57
|
|
|
52
|
-
`setup` no
|
|
53
|
-
|
|
58
|
+
`setup` asks no questions and doesn't overwrite anything you've set up by hand:
|
|
59
|
+
you can run it again.
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
Estela speaks English and Spanish, following your system's language. Force one
|
|
62
|
+
with `--lang en` on any command, or `ESTELA_LANG=en` for good.
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
## Reporting to a client
|
|
65
|
+
|
|
66
|
+
Projects are created as internal and without a rate, because making one up
|
|
67
|
+
would produce fake numbers from the first minute. When one belongs to a real
|
|
68
|
+
client:
|
|
59
69
|
|
|
60
70
|
```sh
|
|
61
71
|
estela client add --id acme --name "ACME" --currency EUR
|
|
62
|
-
estela project add --id acme-web --client acme --name "
|
|
72
|
+
estela project add --id acme-web --client acme --name "ACME website" --repo ~/dev/acme-web
|
|
63
73
|
estela rate set --project acme-web --rate 50
|
|
64
74
|
|
|
65
|
-
estela author --project acme-web #
|
|
75
|
+
estela author --project acme-web # which email you commit with there
|
|
66
76
|
estela report --project acme-web --cutoff 2026-08-31 --dry-run
|
|
67
77
|
```
|
|
68
78
|
|
|
69
|
-
**`estela author`
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
**`estela author` matters more than it looks.** In a client's repository you
|
|
80
|
+
almost never commit with your global email, and without telling Estela it
|
|
81
|
+
captures three commits out of seventeen hundred.
|
|
82
|
+
|
|
83
|
+
The report backs up your work with hours and commits. It isn't an invoice:
|
|
84
|
+
Estela doesn't issue tax documents, so attach it to your own.
|
|
72
85
|
|
|
73
|
-
##
|
|
86
|
+
## Sharing progress with your client
|
|
74
87
|
|
|
75
88
|
```sh
|
|
76
|
-
estela login --email
|
|
89
|
+
estela login --email you@example.com # once
|
|
77
90
|
estela publish --project acme-web
|
|
78
91
|
```
|
|
79
92
|
|
|
80
|
-
|
|
81
|
-
getestela.dev — no
|
|
82
|
-
**
|
|
83
|
-
|
|
84
|
-
|
|
93
|
+
This uploads a read-only dashboard with an unguessable link, hosted on
|
|
94
|
+
getestela.dev — no server of your own needed. It shows hours and commits;
|
|
95
|
+
**never your rate or your AI usage**, because as long as you're the one paying
|
|
96
|
+
for it that spend is yours, and a client who knows which part an AI generated
|
|
97
|
+
has a new argument for negotiating your rate down.
|
|
85
98
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
99
|
+
Publishing again from the same machine reuses the link automatically. From a
|
|
100
|
+
different machine, pass `--token` with the existing one, or your client ends up
|
|
101
|
+
with a dead link. The Free plan allows one published dashboard at a time; Pro
|
|
102
|
+
and Teams have no limit.
|
|
89
103
|
|
|
90
|
-
##
|
|
104
|
+
## What the AI actually costs
|
|
91
105
|
|
|
92
|
-
|
|
93
|
-
|
|
106
|
+
On a flat subscription, your real spend isn't the sum of the tokens: it's the
|
|
107
|
+
fee split across what you used.
|
|
94
108
|
|
|
95
109
|
```sh
|
|
96
110
|
estela subscription add --id max --name "Claude Max" --fee 100
|
|
97
111
|
estela ai-cost
|
|
98
112
|
```
|
|
99
113
|
|
|
100
|
-
|
|
101
|
-
|
|
114
|
+
Cache is counted separately because it's usually most of the bill — ignoring it
|
|
115
|
+
underestimated spend fivefold.
|
|
102
116
|
|
|
103
|
-
##
|
|
117
|
+
## Hours no import will infer
|
|
104
118
|
|
|
105
|
-
|
|
106
|
-
|
|
119
|
+
Meetings, travel, research, and development without an agent that didn't leave
|
|
120
|
+
commits either:
|
|
107
121
|
|
|
108
122
|
```sh
|
|
109
|
-
estela log --project acme-web --hours 1.5 --kind meeting --what "
|
|
123
|
+
estela log --project acme-web --hours 1.5 --kind meeting --what "Weekly check-in"
|
|
110
124
|
```
|
|
111
125
|
|
|
112
|
-
|
|
126
|
+
An import never touches them.
|
|
113
127
|
|
|
114
|
-
##
|
|
128
|
+
## Work without an agent
|
|
115
129
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
130
|
+
If you coded by hand, your commits are still a trail: Estela infers the time
|
|
131
|
+
from them and marks it as **estimated**, so you know which part of your hours is
|
|
132
|
+
measured and which is assumed. The estimate errs on the short side on purpose:
|
|
133
|
+
these hours end up in a report someone pays for.
|
|
120
134
|
|
|
121
|
-
##
|
|
135
|
+
## Plans
|
|
122
136
|
|
|
123
137
|
| | Free | Pro | Teams |
|
|
124
138
|
|---|---|---|---|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
139
|
+
| Everything above, locally | ✓ | ✓ | ✓ |
|
|
140
|
+
| Sync across machines | — | ✓ | ✓ |
|
|
141
|
+
| Hosted dashboards at once | 1 | unlimited | unlimited |
|
|
142
|
+
| **Measured** team hours | — | — | ✓ |
|
|
143
|
+
| AI budget per project | — | — | ✓ |
|
|
130
144
|
|
|
131
|
-
Pro
|
|
132
|
-
|
|
133
|
-
|
|
145
|
+
Pro is one person on several machines; Teams is several people. AI cost is
|
|
146
|
+
reported **per project, never per person**: what each person spends out of their
|
|
147
|
+
own pocket is theirs.
|
|
134
148
|
|
|
135
|
-
|
|
149
|
+
More at [getestela.dev](https://getestela.dev/en/).
|
|
136
150
|
|
|
137
|
-
##
|
|
151
|
+
## Development
|
|
138
152
|
|
|
139
153
|
```sh
|
|
140
154
|
npm install
|
|
141
|
-
npm
|
|
142
|
-
node --test packages/daemon/dist/**/*.test.js
|
|
155
|
+
npm test
|
|
143
156
|
```
|
|
144
157
|
|
|
145
|
-
Node 22
|
|
146
|
-
|
|
147
|
-
|
|
158
|
+
Node 22 and **zero runtime dependencies**, on purpose: nobody installs a program
|
|
159
|
+
that reads their transcripts if they can't audit it, and an empty dependency
|
|
160
|
+
list can be audited in an afternoon.
|
|
148
161
|
|
|
149
|
-
##
|
|
162
|
+
## Open source, closed service
|
|
150
163
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
`npm install estela
|
|
164
|
+
Everything that installs on your machine is open source under the MIT license:
|
|
165
|
+
the CLI, what reads your transcripts and your git, what calculates hours and
|
|
166
|
+
cost, and the dashboard that `estela web` opens. It's exactly what
|
|
167
|
+
`npm install estela` downloads, and you can read it at
|
|
155
168
|
[github.com/jdleonruiz/estela-cli](https://github.com/jdleonruiz/estela-cli).
|
|
169
|
+
Each npm version has a matching tag there.
|
|
156
170
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
171
|
+
What **isn't** here is the paid service: the server that syncs your machines and
|
|
172
|
+
the one behind team projects. That part is closed, and it's what keeps the
|
|
173
|
+
project going.
|
|
160
174
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
175
|
+
The split isn't an accident. The free plan works entirely without an account,
|
|
176
|
+
a card, or a network connection, and that claim is worth nothing if you have to
|
|
177
|
+
take it on faith: with the code in front of you, you can check for yourself that
|
|
178
|
+
nothing leaves your machine.
|
|
164
179
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
180
|
+
The test fixtures are made up on purpose. The cases come from real repositories
|
|
181
|
+
— that's why they cover messes nobody would think of — but neither a client's
|
|
182
|
+
team roster nor how much each of its people commits belongs in a public
|
|
183
|
+
repository.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"amortize.d.ts","sourceRoot":"","sources":["../../src/billing/amortize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"amortize.d.ts","sourceRoot":"","sources":["../../src/billing/amortize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAIlF;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,SAAS,cAAc,EAAE,EAC/B,aAAa,EAAE,SAAS,YAAY,EAAE,EACtC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,cAAc,EAAE,CAiClB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAkB/F;AAED,0CAA0C;AAC1C,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE1C;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,KAAK,GAAG,IAAI,CAMd"}
|
package/dist/billing/amortize.js
CHANGED
|
@@ -5,6 +5,7 @@ exports.feeForMonth = feeForMonth;
|
|
|
5
5
|
exports.monthOf = monthOf;
|
|
6
6
|
exports.shareForProject = shareForProject;
|
|
7
7
|
const shared_1 = require("@estela/shared");
|
|
8
|
+
const index_js_1 = require("../i18n/index.js");
|
|
8
9
|
/**
|
|
9
10
|
* @param monthTotals Consumo total del mes en **toda** tu máquina, incluido el
|
|
10
11
|
* trabajo que aún no has asignado a ningún proyecto. Es el denominador
|
|
@@ -61,8 +62,8 @@ function feeForMonth(subscriptions, month) {
|
|
|
61
62
|
let total = 0;
|
|
62
63
|
for (const s of active) {
|
|
63
64
|
if (s.monthlyFee.currency !== currency) {
|
|
64
|
-
throw new TypeError(`Suscripciones en monedas distintas en ${month} (${currency} y ${s.monthlyFee.currency}). ` +
|
|
65
|
-
|
|
65
|
+
throw new TypeError((0, index_js_1.tr) `Suscripciones en monedas distintas en ${month} (${currency} y ${s.monthlyFee.currency}). ` +
|
|
66
|
+
(0, index_js_1.tr) `Unifica la moneda de las suscripciones: no se convierten automáticamente.`);
|
|
66
67
|
}
|
|
67
68
|
total += s.monthlyFee.amount;
|
|
68
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"amortize.js","sourceRoot":"","sources":["../../src/billing/amortize.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"amortize.js","sourceRoot":"","sources":["../../src/billing/amortize.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoice.d.ts","sourceRoot":"","sources":["../../src/billing/invoice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACF,MAAM,EAAE,OAAO,EAAe,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAC5E,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"invoice.d.ts","sourceRoot":"","sources":["../../src/billing/invoice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACF,MAAM,EAAE,OAAO,EAAe,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAC5E,MAAM,gBAAgB,CAAC;AAOxB;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,YAAa,SAAQ,KAAK;CAAG;AAE1C,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAwF9D;AAED,8EAA8E;AAC9E,wBAAgB,MAAM,CACpB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,IAAI,GACP,KAAK,GAAG,IAAI,CAOd;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAgDxF;AAED,oEAAoE;AACpE,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG;IAC7D,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;CACjE,CAUA"}
|
package/dist/billing/invoice.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.rateAt = rateAt;
|
|
|
6
6
|
exports.renderInvoice = renderInvoice;
|
|
7
7
|
exports.marginOf = marginOf;
|
|
8
8
|
const shared_1 = require("@estela/shared");
|
|
9
|
+
const index_js_1 = require("../i18n/index.js");
|
|
9
10
|
class InvoiceError extends Error {
|
|
10
11
|
}
|
|
11
12
|
exports.InvoiceError = InvoiceError;
|
|
@@ -18,19 +19,19 @@ function issueInvoice(input) {
|
|
|
18
19
|
.filter((e) => e.endedAt <= cutoffAt)
|
|
19
20
|
.sort((a, b) => a.startedAt.getTime() - b.startedAt.getTime());
|
|
20
21
|
if (pending.length === 0) {
|
|
21
|
-
throw new InvoiceError(`No hay horas pendientes de facturar en "${project.name}" hasta ${cutoffAt.toISOString().slice(0, 10)}.`);
|
|
22
|
+
throw new InvoiceError((0, index_js_1.tr) `No hay horas pendientes de facturar en "${project.name}" hasta ${cutoffAt.toISOString().slice(0, 10)}.`);
|
|
22
23
|
}
|
|
23
24
|
const lines = [];
|
|
24
25
|
let totalSeconds = 0;
|
|
25
26
|
for (const entry of pending) {
|
|
26
27
|
const rate = rateAt(rates, project.id, entry.startedAt);
|
|
27
28
|
if (!rate) {
|
|
28
|
-
throw new InvoiceError(`Sin tarifa vigente para "${project.name}" el ${entry.startedAt.toISOString().slice(0, 10)}. ` +
|
|
29
|
-
`Define una con: estela rate set --project ${project.id} --rate <importe> --currency ${client.currency}`);
|
|
29
|
+
throw new InvoiceError((0, index_js_1.tr) `Sin tarifa vigente para "${project.name}" el ${entry.startedAt.toISOString().slice(0, 10)}. ` +
|
|
30
|
+
(0, index_js_1.tr) `Define una con: estela rate set --project ${project.id} --rate <importe> --currency ${client.currency}`);
|
|
30
31
|
}
|
|
31
32
|
if (rate.currency !== client.currency) {
|
|
32
|
-
throw new InvoiceError(`La tarifa de "${project.name}" está en ${rate.currency} pero a ${client.name} se le factura en ` +
|
|
33
|
-
`${client.currency}. Corrige la tarifa o la moneda del cliente: no se convierte automáticamente.`);
|
|
33
|
+
throw new InvoiceError((0, index_js_1.tr) `La tarifa de "${project.name}" está en ${rate.currency} pero a ${client.name} se le factura en ` +
|
|
34
|
+
(0, index_js_1.tr) `${client.currency}. Corrige la tarifa o la moneda del cliente: no se convierte automáticamente.`);
|
|
34
35
|
}
|
|
35
36
|
const seconds = (0, shared_1.roundSeconds)(entry.seconds, project.roundingMinutes);
|
|
36
37
|
if (seconds === 0)
|
|
@@ -44,7 +45,7 @@ function issueInvoice(input) {
|
|
|
44
45
|
});
|
|
45
46
|
}
|
|
46
47
|
if (lines.length === 0) {
|
|
47
|
-
throw new InvoiceError(`Todas las entradas quedaron en cero tras redondear a ${project.roundingMinutes} min.`);
|
|
48
|
+
throw new InvoiceError((0, index_js_1.tr) `Todas las entradas quedaron en cero tras redondear a ${project.roundingMinutes} min.`);
|
|
48
49
|
}
|
|
49
50
|
const subtotal = (0, shared_1.sumMoney)(lines.map((l) => l.amount), client.currency);
|
|
50
51
|
const aiCost = (0, shared_1.sumAiCost)(pending.map((e) => e.aiCost));
|
|
@@ -55,8 +56,8 @@ function issueInvoice(input) {
|
|
|
55
56
|
usdFxRate = 1;
|
|
56
57
|
}
|
|
57
58
|
else if (input.usdFxRate === undefined) {
|
|
58
|
-
throw new InvoiceError(`"${project.name}" repercute el coste de IA (${(0, shared_1.formatAiCost)(aiCost)} USD) y se factura en ` +
|
|
59
|
-
`${client.currency}. Indica el tipo de cambio del día con --fx <USD->${client.currency}>.`);
|
|
59
|
+
throw new InvoiceError((0, index_js_1.tr) `"${project.name}" repercute el coste de IA (${(0, shared_1.formatAiCost)(aiCost)} USD) y se factura en ` +
|
|
60
|
+
(0, index_js_1.tr) `${client.currency}. Indica el tipo de cambio del día con --fx <USD->${client.currency}>.`);
|
|
60
61
|
}
|
|
61
62
|
else {
|
|
62
63
|
usdFxRate = input.usdFxRate;
|
|
@@ -98,13 +99,13 @@ function renderInvoice(invoice, client, project) {
|
|
|
98
99
|
const rule = "─".repeat(78);
|
|
99
100
|
const date = (d) => d.toISOString().slice(0, 10);
|
|
100
101
|
out.push(rule);
|
|
101
|
-
out.push(`INFORME DE HORAS ${invoice.number}`.padEnd(52) + `Emitido: ${date(invoice.issuedAt)}`);
|
|
102
|
+
out.push((0, index_js_1.tr) `INFORME DE HORAS ${invoice.number}`.padEnd(52) + (0, index_js_1.tr) `Emitido: ${date(invoice.issuedAt)}`);
|
|
102
103
|
out.push(rule);
|
|
103
|
-
out.push(`Cliente: ${client.name}
|
|
104
|
-
out.push(`Proyecto: ${project.name}`);
|
|
105
|
-
out.push(`Periodo: ${date(invoice.periodStart)} -> ${date(invoice.cutoffAt)}`);
|
|
104
|
+
out.push((0, index_js_1.tr) `Cliente: ${client.name}` + (client.taxId ? ` (${client.taxId})` : ""));
|
|
105
|
+
out.push((0, index_js_1.tr) `Proyecto: ${project.name}`);
|
|
106
|
+
out.push((0, index_js_1.tr) `Periodo: ${date(invoice.periodStart)} -> ${date(invoice.cutoffAt)}`);
|
|
106
107
|
out.push("");
|
|
107
|
-
out.push(
|
|
108
|
+
out.push((0, index_js_1.tr) `CONCEPTO`.padEnd(46) + (0, index_js_1.tr) `TIEMPO`.padStart(9) + (0, index_js_1.tr) `TARIFA`.padStart(11) + (0, index_js_1.tr) `IMPORTE`.padStart(12));
|
|
108
109
|
out.push(rule);
|
|
109
110
|
for (const line of invoice.lines) {
|
|
110
111
|
const desc = line.description.length > 45 ? line.description.slice(0, 42) + "..." : line.description;
|
|
@@ -114,20 +115,20 @@ function renderInvoice(invoice, client, project) {
|
|
|
114
115
|
(0, shared_1.formatMoney)(line.amount).padStart(12));
|
|
115
116
|
}
|
|
116
117
|
out.push(rule);
|
|
117
|
-
out.push(`${invoice.lines.length} conceptos`.padEnd(46) +
|
|
118
|
+
out.push((0, index_js_1.tr) `${invoice.lines.length} conceptos`.padEnd(46) +
|
|
118
119
|
(0, shared_1.formatDuration)(invoice.totalSeconds).padStart(9) +
|
|
119
120
|
"".padStart(11) +
|
|
120
121
|
(0, shared_1.formatMoney)(invoice.subtotal).padStart(12));
|
|
121
122
|
if (invoice.aiCostBilled) {
|
|
122
|
-
out.push(`Coste de IA repercutido (1 USD = ${invoice.usdFxRate} ${invoice.currency})`.padEnd(66) +
|
|
123
|
+
out.push((0, index_js_1.tr) `Coste de IA repercutido (1 USD = ${invoice.usdFxRate} ${invoice.currency})`.padEnd(66) +
|
|
123
124
|
(0, shared_1.formatMoney)(invoice.aiCostBilled).padStart(12));
|
|
124
125
|
}
|
|
125
126
|
out.push("");
|
|
126
|
-
out.push(
|
|
127
|
+
out.push((0, index_js_1.tr) `VALOR DEL TRABAJO`.padEnd(66) + (0, shared_1.formatMoney)(invoice.total).padStart(12));
|
|
127
128
|
out.push(rule);
|
|
128
129
|
if (project.aiCostPolicy === "absorbed" && invoice.aiCost.microUsd > 0) {
|
|
129
|
-
out.push(`Interno (no facturado): IA del periodo ${(0, shared_1.formatAiCost)(invoice.aiCost)} USD ` +
|
|
130
|
-
`en tarifa API equivalente.`);
|
|
130
|
+
out.push((0, index_js_1.tr) `Interno (no facturado): IA del periodo ${(0, shared_1.formatAiCost)(invoice.aiCost)} USD ` +
|
|
131
|
+
(0, index_js_1.tr) `en tarifa API equivalente.`);
|
|
131
132
|
}
|
|
132
133
|
if (invoice.notes)
|
|
133
134
|
out.push(invoice.notes);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoice.js","sourceRoot":"","sources":["../../src/billing/invoice.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"invoice.js","sourceRoot":"","sources":["../../src/billing/invoice.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionize.d.ts","sourceRoot":"","sources":["../../src/billing/sessionize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"sessionize.d.ts","sourceRoot":"","sources":["../../src/billing/sessionize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAKtE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,gFAAgF;IAChF,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAKD,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,OAAO,GAAE,iBAAsB,GAC9B,SAAS,EAAE,CAkCb;AAqCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,MAAM,GAAE,CAAC,KAAK,EAAE,SAAS,KAAK,MAAgC,GAC7D,SAAS,EAAE,CAiEb;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAYtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,YAAY,SAAK,GAChB,SAAS,EAAE,CAcb;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5D,SAAS,EAAE,CAgDb;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,SAAS,SAAS,EAAE,EAClC,WAAW,EAAE,SAAS,SAAS,EAAE,GAChC,SAAS,EAAE,CAKb"}
|
|
@@ -8,6 +8,7 @@ exports.sessionizeCommits = sessionizeCommits;
|
|
|
8
8
|
exports.withoutOverlap = withoutOverlap;
|
|
9
9
|
const shared_1 = require("@estela/shared");
|
|
10
10
|
const cost_js_1 = require("../pricing/cost.js");
|
|
11
|
+
const index_js_1 = require("../i18n/index.js");
|
|
11
12
|
const DEFAULT_GAP_MINUTES = 30;
|
|
12
13
|
const DEFAULT_TAIL_MINUTES = 2;
|
|
13
14
|
function sessionize(turns, options = {}) {
|
|
@@ -170,11 +171,14 @@ function describeBlock(block) {
|
|
|
170
171
|
const subjects = [...new Set(block.commits.map((c) => c.subject).filter(Boolean))];
|
|
171
172
|
if (subjects.length === 1)
|
|
172
173
|
return subjects[0];
|
|
173
|
-
|
|
174
|
-
|
|
174
|
+
// "+1 commits más" salía en la descripción de cualquier bloque con dos asuntos.
|
|
175
|
+
if (subjects.length === 2)
|
|
176
|
+
return (0, index_js_1.tr) `${subjects[0]} (+1 commit más)`;
|
|
177
|
+
if (subjects.length > 2) {
|
|
178
|
+
return (0, index_js_1.tr) `${subjects[0]} (+${subjects.length - 1} commits más)`;
|
|
175
179
|
}
|
|
176
180
|
const branch = block.branch?.replace(/^(feature|feat|fix|chore)\//, "") ?? null;
|
|
177
|
-
return branch ? `Desarrollo en ${branch}` :
|
|
181
|
+
return branch ? (0, index_js_1.tr) `Desarrollo en ${branch}` : (0, index_js_1.tr) `Desarrollo`;
|
|
178
182
|
}
|
|
179
183
|
/**
|
|
180
184
|
* Asocia commits a bloques por solapamiento temporal.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionize.js","sourceRoot":"","sources":["../../src/billing/sessionize.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"sessionize.js","sourceRoot":"","sources":["../../src/billing/sessionize.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
7
7
|
const node_test_1 = require("node:test");
|
|
8
|
+
const index_js_1 = require("../i18n/index.js");
|
|
8
9
|
const sessionize_js_1 = require("./sessionize.js");
|
|
9
10
|
// --- Trabajo sin agente ------------------------------------------------------
|
|
10
11
|
function commit(hash, iso, repo = "/r", branch = "main") {
|
|
@@ -133,4 +134,29 @@ function commit(hash, iso, repo = "/r", branch = "main") {
|
|
|
133
134
|
const [fusionado] = (0, sessionize_js_1.groupByBranchAndDay)(bloques, () => "proyecto");
|
|
134
135
|
strict_1.default.equal(fusionado.seconds, suma, "sin solape no se pierde ni un segundo");
|
|
135
136
|
});
|
|
137
|
+
// ── Descripción de un bloque ────────────────────────────────────────────────
|
|
138
|
+
function bloqueCon(asuntos, branch = "main") {
|
|
139
|
+
const at = new Date("2026-09-14T10:00:00Z");
|
|
140
|
+
return {
|
|
141
|
+
startedAt: at, endedAt: at, seconds: 3600, repoPath: "/r", branch, turnCount: 1,
|
|
142
|
+
aiCost: { microUsd: 0 }, models: [], sessionIds: [], unpricedModels: [],
|
|
143
|
+
commits: asuntos.map((subject, i) => ({ ...commit(`h${i}`, "2026-09-14T10:00:00Z"), subject })),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
(0, node_test_1.test)("describeBlock: un commit más va en singular, en los dos idiomas", () => {
|
|
147
|
+
// Salía "(+1 commits más)" / "(+1 more commits)" en cualquier bloque con dos
|
|
148
|
+
// asuntos distintos, y esa descripción es la que acaba en el informe.
|
|
149
|
+
try {
|
|
150
|
+
(0, index_js_1.setLang)("es");
|
|
151
|
+
strict_1.default.equal((0, sessionize_js_1.describeBlock)(bloqueCon(["a", "b"])), "a (+1 commit más)");
|
|
152
|
+
strict_1.default.equal((0, sessionize_js_1.describeBlock)(bloqueCon(["a", "b", "c"])), "a (+2 commits más)");
|
|
153
|
+
(0, index_js_1.setLang)("en");
|
|
154
|
+
strict_1.default.equal((0, sessionize_js_1.describeBlock)(bloqueCon(["a", "b"])), "a (+1 more commit)");
|
|
155
|
+
strict_1.default.equal((0, sessionize_js_1.describeBlock)(bloqueCon(["a", "b", "c"])), "a (+2 more commits)");
|
|
156
|
+
strict_1.default.equal((0, sessionize_js_1.describeBlock)(bloqueCon([], null)), "Development", "sin asuntos ni rama, también traducido");
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
(0, index_js_1.setLang)("es");
|
|
160
|
+
}
|
|
161
|
+
});
|
|
136
162
|
//# sourceMappingURL=sessionize.test.js.map
|