@hasna/economy 0.3.6 → 0.3.8
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/CHANGELOG.md +31 -0
- package/README.md +73 -60
- package/dashboard/README.md +17 -64
- package/dist/cli/commands/extras.d.ts.map +1 -1
- package/dist/cli/commands/todos.d.ts +3 -0
- package/dist/cli/commands/todos.d.ts.map +1 -1
- package/dist/cli/index.js +914 -199
- package/dist/db/cloud.d.ts +3 -4
- package/dist/db/cloud.d.ts.map +1 -1
- package/dist/db/database.d.ts +10 -3
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/dialect.d.ts +13 -0
- package/dist/db/dialect.d.ts.map +1 -0
- package/dist/db/pg-migrate.d.ts +30 -0
- package/dist/db/pg-migrate.d.ts.map +1 -0
- package/dist/db/pg-migrations.d.ts.map +1 -1
- package/dist/db/sqlite-adapter.d.ts +36 -0
- package/dist/db/sqlite-adapter.d.ts.map +1 -0
- package/dist/db/sync-pg.d.ts +1 -1
- package/dist/db/sync-pg.d.ts.map +1 -1
- package/dist/index.js +309 -59
- package/dist/ingest/billing.d.ts +1 -1
- package/dist/ingest/billing.d.ts.map +1 -1
- package/dist/ingest/claude-quota.d.ts +1 -1
- package/dist/ingest/claude-quota.d.ts.map +1 -1
- package/dist/ingest/claude.d.ts +1 -1
- package/dist/ingest/claude.d.ts.map +1 -1
- package/dist/ingest/codex-quota.d.ts +1 -1
- package/dist/ingest/codex-quota.d.ts.map +1 -1
- package/dist/ingest/codex.d.ts +1 -1
- package/dist/ingest/codex.d.ts.map +1 -1
- package/dist/ingest/cursor.d.ts +1 -1
- package/dist/ingest/cursor.d.ts.map +1 -1
- package/dist/ingest/gemini.d.ts +1 -1
- package/dist/ingest/gemini.d.ts.map +1 -1
- package/dist/ingest/hermes.d.ts +1 -1
- package/dist/ingest/hermes.d.ts.map +1 -1
- package/dist/ingest/loops.d.ts +6 -0
- package/dist/ingest/loops.d.ts.map +1 -0
- package/dist/ingest/opencode.d.ts +1 -1
- package/dist/ingest/opencode.d.ts.map +1 -1
- package/dist/ingest/otel.d.ts +16 -3
- package/dist/ingest/otel.d.ts.map +1 -1
- package/dist/ingest/pi.d.ts +1 -1
- package/dist/ingest/pi.d.ts.map +1 -1
- package/dist/ingest/plugin.d.ts +1 -1
- package/dist/ingest/plugin.d.ts.map +1 -1
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/analytics.d.ts +1 -1
- package/dist/lib/analytics.d.ts.map +1 -1
- package/dist/lib/billing-diff.d.ts +1 -1
- package/dist/lib/billing-diff.d.ts.map +1 -1
- package/dist/lib/brief.d.ts +1 -1
- package/dist/lib/brief.d.ts.map +1 -1
- package/dist/lib/open-projects.d.ts +10 -2
- package/dist/lib/open-projects.d.ts.map +1 -1
- package/dist/lib/pricing.d.ts +1 -1
- package/dist/lib/pricing.d.ts.map +1 -1
- package/dist/lib/savings.d.ts +1 -1
- package/dist/lib/savings.d.ts.map +1 -1
- package/dist/lib/spikes.d.ts +1 -1
- package/dist/lib/spikes.d.ts.map +1 -1
- package/dist/lib/store/index.d.ts +9 -1
- package/dist/lib/store/index.d.ts.map +1 -1
- package/dist/lib/sync-all.d.ts +3 -1
- package/dist/lib/sync-all.d.ts.map +1 -1
- package/dist/lib/webhooks.d.ts +1 -1
- package/dist/lib/webhooks.d.ts.map +1 -1
- package/dist/mcp/index.js +757 -166
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/otel/index.js +262 -27
- package/dist/server/index.js +683 -135
- package/dist/server/serve.d.ts +1 -1
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/types/index.d.ts +37 -4
- package/dist/types/index.d.ts.map +1 -1
- package/docs/README.md +12 -0
- package/docs/cli.md +88 -0
- package/docs/configuration.md +86 -0
- package/docs/ingestion.md +47 -0
- package/docs/mcp.md +65 -0
- package/docs/otel.md +53 -0
- package/docs/rest-api.md +89 -0
- package/package.json +4 -5
- package/dist/lib/cloud-sync.d.ts +0 -35
- package/dist/lib/cloud-sync.d.ts.map +0 -1
- package/dist/lib/fleet-sync.d.ts +0 -61
- package/dist/lib/fleet-sync.d.ts.map +0 -1
- package/dist/lib/peer-sync.d.ts +0 -21
- package/dist/lib/peer-sync.d.ts.map +0 -1
- package/dist/storage.js +0 -2746
package/dist/server/serve.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SqliteAdapter as Database } from '
|
|
1
|
+
import type { SqliteAdapter as Database } from '../db/sqlite-adapter.js';
|
|
2
2
|
/** The serve OpenAPI document (source of the generated SDK), version-synced. */
|
|
3
3
|
export declare function openApiDocument(): Record<string, unknown>;
|
|
4
4
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AA8CxE,gFAAgF;AAChF,wBAAgB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzD;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CACV,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GAC7F,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC/E;AAuBD,UAAU,kBAAkB;IAC1B,EAAE,CAAC,EAAE,QAAQ,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAChC;AA6ED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAAE,YAAY,SAAwB,IACzF,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAwB7D;AAQD,MAAM,WAAW,cAAc;IAC7B;;wEAEoE;IACpE,aAAa,CAAC,EAAE,gBAAgB,CAAA;IAChC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAChE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,GAAE,cAAmB,IACxC,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CA+e/D;AAMD,wBAAgB,WAAW,CAAC,IAAI,SAAO,EAAE,OAAO,GAAE,kBAAuB,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,CAkDvG"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
export type { Agent, CostBasis } from '../lib/agents.js';
|
|
2
2
|
export { AGENTS, COST_BASIS, isAgent } from '../lib/agents.js';
|
|
3
3
|
export type Period = 'today' | 'yesterday' | 'week' | 'month' | 'year' | 'all';
|
|
4
|
+
export type EconomyAgent = import('../lib/agents.js').Agent | 'app' | 'service' | 'repo' | 'loop';
|
|
5
|
+
export type CostCenterKind = 'loop' | 'app' | 'repo' | 'service' | 'team';
|
|
6
|
+
export interface CostCenter {
|
|
7
|
+
id: string;
|
|
8
|
+
kind: CostCenterKind;
|
|
9
|
+
name: string;
|
|
10
|
+
repo_path?: string | null;
|
|
11
|
+
labels_json: string;
|
|
12
|
+
created_at: string;
|
|
13
|
+
updated_at?: string;
|
|
14
|
+
}
|
|
4
15
|
export interface EconomyRequest {
|
|
5
16
|
id: string;
|
|
6
|
-
agent:
|
|
17
|
+
agent: EconomyAgent;
|
|
7
18
|
session_id: string;
|
|
8
19
|
model: string;
|
|
9
20
|
input_tokens: number;
|
|
@@ -18,6 +29,7 @@ export interface EconomyRequest {
|
|
|
18
29
|
timestamp: string;
|
|
19
30
|
source_request_id: string;
|
|
20
31
|
machine_id?: string;
|
|
32
|
+
cost_center_id?: string | null;
|
|
21
33
|
attribution_tag?: string;
|
|
22
34
|
account_key?: string;
|
|
23
35
|
account_tool?: string;
|
|
@@ -29,7 +41,7 @@ export interface EconomyRequest {
|
|
|
29
41
|
}
|
|
30
42
|
export interface EconomySession {
|
|
31
43
|
id: string;
|
|
32
|
-
agent:
|
|
44
|
+
agent: EconomyAgent;
|
|
33
45
|
project_path: string;
|
|
34
46
|
project_name: string;
|
|
35
47
|
started_at: string;
|
|
@@ -38,6 +50,7 @@ export interface EconomySession {
|
|
|
38
50
|
total_tokens: number;
|
|
39
51
|
request_count: number;
|
|
40
52
|
machine_id?: string;
|
|
53
|
+
cost_center_id?: string | null;
|
|
41
54
|
attribution_tag?: string;
|
|
42
55
|
account_key?: string;
|
|
43
56
|
account_tool?: string;
|
|
@@ -59,6 +72,7 @@ export interface Budget {
|
|
|
59
72
|
id: string;
|
|
60
73
|
project_path: string | null;
|
|
61
74
|
agent: import('../lib/agents.js').Agent | null;
|
|
75
|
+
cost_center_id?: string | null;
|
|
62
76
|
period: 'daily' | 'weekly' | 'monthly';
|
|
63
77
|
limit_usd: number;
|
|
64
78
|
alert_at_percent: number;
|
|
@@ -92,7 +106,7 @@ export interface ZeroCostModelBreakdown {
|
|
|
92
106
|
}
|
|
93
107
|
export interface ModelBreakdown {
|
|
94
108
|
model: string;
|
|
95
|
-
agent:
|
|
109
|
+
agent: EconomyAgent;
|
|
96
110
|
requests: number;
|
|
97
111
|
input_tokens: number;
|
|
98
112
|
output_tokens: number;
|
|
@@ -109,7 +123,7 @@ export interface ProjectBreakdown {
|
|
|
109
123
|
last_active: string;
|
|
110
124
|
}
|
|
111
125
|
export interface AgentBreakdown {
|
|
112
|
-
agent:
|
|
126
|
+
agent: EconomyAgent;
|
|
113
127
|
sessions: number;
|
|
114
128
|
requests: number;
|
|
115
129
|
total_tokens: number;
|
|
@@ -140,6 +154,24 @@ export interface AccountBreakdown {
|
|
|
140
154
|
cost_usd: number;
|
|
141
155
|
last_active: string;
|
|
142
156
|
}
|
|
157
|
+
export interface CostCenterBreakdown {
|
|
158
|
+
cost_center_id: string;
|
|
159
|
+
kind: CostCenterKind;
|
|
160
|
+
name: string;
|
|
161
|
+
repo_path: string | null;
|
|
162
|
+
labels_json: string;
|
|
163
|
+
sessions: number;
|
|
164
|
+
requests: number;
|
|
165
|
+
total_tokens: number;
|
|
166
|
+
api_equivalent_usd: number;
|
|
167
|
+
billable_usd: number;
|
|
168
|
+
metered_api_usd: number;
|
|
169
|
+
subscription_included_usd: number;
|
|
170
|
+
estimated_usd: number;
|
|
171
|
+
unknown_usd: number;
|
|
172
|
+
cost_usd: number;
|
|
173
|
+
last_active: string;
|
|
174
|
+
}
|
|
143
175
|
export interface ModelPricing {
|
|
144
176
|
inputPer1M: number;
|
|
145
177
|
outputPer1M: number;
|
|
@@ -157,6 +189,7 @@ export interface SyncOptions {
|
|
|
157
189
|
cursor?: boolean;
|
|
158
190
|
pi?: boolean;
|
|
159
191
|
hermes?: boolean;
|
|
192
|
+
loops?: boolean;
|
|
160
193
|
verbose?: boolean;
|
|
161
194
|
dedupe?: boolean;
|
|
162
195
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAE9D,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Economy documentation
|
|
2
|
+
|
|
3
|
+
Economy can run as an on-machine SQLite application or as a client of a shared self-hosted HTTP service. These guides describe the current command and network surfaces:
|
|
4
|
+
|
|
5
|
+
- [CLI reference](cli.md) — the `economy` command and the four installed binaries.
|
|
6
|
+
- [Ingestion](ingestion.md) — supported sources, default paths, sync behavior, billing, and account attribution.
|
|
7
|
+
- [Configuration and deployment](configuration.md) — data paths, environment variables, local/server modes, and authentication.
|
|
8
|
+
- [REST API](rest-api.md) — canonical `/v1` routes, request conventions, probes, and legacy aliases.
|
|
9
|
+
- [MCP server](mcp.md) — stdio/HTTP setup and the available tools.
|
|
10
|
+
- [OTLP sidecar](otel.md) — OTLP metrics and the simplified `/ingest` payload.
|
|
11
|
+
|
|
12
|
+
For generated API details, start `economy-serve` and open [`/openapi.json`](http://127.0.0.1:3456/openapi.json). The checked-in source is [`openapi/economy.json`](../openapi/economy.json).
|
package/docs/cli.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# CLI reference
|
|
2
|
+
|
|
3
|
+
Installing `@hasna/economy` provides four binaries:
|
|
4
|
+
|
|
5
|
+
| Binary | Purpose |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `economy` | Ingest, query, and manage Economy data. |
|
|
8
|
+
| `economy-mcp` | Run the MCP server over stdio or Streamable HTTP. |
|
|
9
|
+
| `economy-serve` | Serve the REST API and built dashboard, or migrate a self-hosted database. |
|
|
10
|
+
| `economy-otel` | Ingest OTLP/HTTP metrics or simplified cost events into local SQLite. |
|
|
11
|
+
|
|
12
|
+
Use `<binary> --help` and `economy <command> --help` for the exact help emitted by the installed version.
|
|
13
|
+
|
|
14
|
+
## Core commands
|
|
15
|
+
|
|
16
|
+
The supported coding-agent values are `claude`, `takumi`, `codex`, `gemini`, `opencode`, `cursor`, `pi`, and `hermes`.
|
|
17
|
+
|
|
18
|
+
| Command | Current behavior and principal options |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| `economy sync` | Ingest every local source, or select sources with `--claude`, `--takumi`, `--codex`, `--gemini`, `--opencode`, `--cursor`, `--pi`, `--hermes`, or `--loops`. Maintenance flags are `--force`, `--backfill-machine`, and `--recalculate`; `--verbose` prints source details. |
|
|
21
|
+
| `economy today`, `week`, `month` | Auto-sync in local mode and print the corresponding summary. Auto-sync is skipped in cloud-client mode. |
|
|
22
|
+
| `economy sessions` | List sessions. Filters: `--agent`, `--project`, `--account`, `--machine`, `--since`, and `--search`; `--limit` defaults to 20; `--format` is `table`, `compact`, `csv`, or `json`. |
|
|
23
|
+
| `economy session <id>` | Show one session and its requests. IDs may be prefixes. `--limit` defaults to 20 and `--verbose` shows up to 50 requests. |
|
|
24
|
+
| `economy top` | Rank expensive sessions with `-n`, `--agent`, and `--since`. |
|
|
25
|
+
| `economy breakdown` | Group by `model`, `agent`, `project`, `account`, `cost-center`, `loop`, `app`, or `repo`; accepts `--since`, `--limit`, `--verbose`, and `--json`. |
|
|
26
|
+
| `economy accounts [period]` | Account/profile totals for `today`, `week`, `month`, `year`, or `all`; accepts `--limit`, `--verbose`, and `--json`. |
|
|
27
|
+
| `economy machines` | Machines represented in stored data; accepts `--limit` and `--verbose`. |
|
|
28
|
+
| `economy fleet` | Shared summary plus per-machine rows; accepts `--period`, `--limit`, `--verbose`, and `--json`. |
|
|
29
|
+
| `economy brief` | Fleet brief with `--since <24h|7d|ISO-date>`, `--machine <id|all>`, or `--json`. |
|
|
30
|
+
| `economy usage [period]` | Quota/usage snapshots with `--agent`, `--limit`, `--verbose`, or `--json`. |
|
|
31
|
+
| `economy savings [period]` | Subscription-versus-API-equivalent savings with `--agent` or `--json`. |
|
|
32
|
+
| `economy watch` | Poll recent costs, or use `--daemon` to sync watched local paths. Also accepts `--interval`, `--agent`, and macOS `--notify`. In cloud mode it streams the API and does not ingest local files. |
|
|
33
|
+
| `economy status` | Print one-line spend, fleet, storage, top-agent, and available quota status. |
|
|
34
|
+
| `economy doctor` | Check source paths/token availability, storage mode, pricing gaps, deduplication, and billing drift. |
|
|
35
|
+
| `economy init` | Print first-run local and cloud-client setup hints. |
|
|
36
|
+
|
|
37
|
+
Human output for high-cardinality commands is intentionally capped. Use the command's `--json`, `--verbose`, or `--limit` option when available. JSON output is complete; `--verbose` has command-specific semantics, so consult `--help`.
|
|
38
|
+
|
|
39
|
+
## Analysis and export
|
|
40
|
+
|
|
41
|
+
| Command | Behavior |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `economy export` | Export `sessions` or `requests` as CSV. `--period` accepts `today`, `week`, `month`, or `all`; `--output` writes a file instead of stdout. |
|
|
44
|
+
| `economy compare <period1> <period2>` | Compare `today`, `yesterday`, `week`, `lastweek`, `month`, or `lastmonth`. |
|
|
45
|
+
| `economy forecast` | Project the current month's total from the observed burn rate. |
|
|
46
|
+
| `economy efficiency` | Show output/input ratio, cache-hit percentage, and cost per 1,000 output tokens by model. |
|
|
47
|
+
| `economy estimate --model <id>` | Estimate cost from `--input` and `--output` token counts using the active pricing table. |
|
|
48
|
+
| `economy tui` | Terminal dashboard; `--watch` refreshes at `--interval` seconds. |
|
|
49
|
+
| `economy waybar` | Emit a Waybar-compatible JSON status object. |
|
|
50
|
+
| `economy bar tui`, `bar waybar` | Aliases for the TUI and Waybar commands. |
|
|
51
|
+
|
|
52
|
+
## Data management
|
|
53
|
+
|
|
54
|
+
| Command group | Subcommands |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| `economy budget` | `set` (`--limit` required; optional `--project`, `--agent`, `--cost-center`, `--period`, `--alert`), `list` (`--limit`, `--verbose`), `remove <id>`. |
|
|
57
|
+
| `economy goal` | `set` (`--limit` required; optional `--period`, `--project`, `--agent`), `list`, `status`, `remove <id>`. List/status accept `--limit` and `--verbose`. |
|
|
58
|
+
| `economy project` | `add <path> [--name]`, `list`, `show <nameOrPath>`, `rename <path> <name>`, `remove <path>`. |
|
|
59
|
+
| `economy pricing` | `list`, `set <model>`, `remove <model>`. Set accepts `--input`, `--output`, `--cache-read`, `--cache-write`, `--cache-write-1h`, and `--cache-storage`. |
|
|
60
|
+
| `economy subscriptions` | `set` (requires `--provider` and `--plan`; optional `--agent`, `--fee`, `--included`), `list`, `remove <id>`. |
|
|
61
|
+
| `economy billing` | `sync` (`--days`, provider selectors), `show --period`, and `diff --period`. Provider sync is local-only. |
|
|
62
|
+
| `economy config` | Show config, `get <key>`, `set <key> <value>`, or `webhook-test`. See [configuration](configuration.md). |
|
|
63
|
+
| `economy remove <type> <id>` | Top-level alias for removing a `budget`, `project`, `goal`, or `pricing` row. Alias: `rm`. |
|
|
64
|
+
|
|
65
|
+
## Integrations and utilities
|
|
66
|
+
|
|
67
|
+
| Command | Behavior |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `economy serve --port <port>` | Start the REST API in-process. Equivalent server controls are documented under [`economy-serve`](configuration.md#rest-server). |
|
|
70
|
+
| `economy dashboard --port <port>` | Start the server when necessary and open the dashboard URL. |
|
|
71
|
+
| `economy mcp` | Print Claude Code, Codex, and Gemini MCP configuration; select one or use `--all`. |
|
|
72
|
+
| `economy completion <shell>` | Print completion for `bash`, `zsh`, or `fish`. |
|
|
73
|
+
| `economy menubar` | `install [--force]`, `start`, `stop`, or `uninstall` the macOS Economy Bar app. |
|
|
74
|
+
| `economy brains` | `gather`, `train`, `model [set|clear]`, and `status`. Fine-tuning requires the optional `@hasna/brains` package; gathering does not. |
|
|
75
|
+
| `economy events`, `economy webhooks` | Event emit/list/replay and event-subscription commands supplied by `@hasna/events`; use the nested `--help` for options. |
|
|
76
|
+
| `economy todos` | Display the bundled Economy roadmap, filter tasks, or show a task ID. This is project planning data, not live service status. |
|
|
77
|
+
|
|
78
|
+
## Other binary help
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
economy-mcp [--http] [--port <port>]
|
|
82
|
+
economy-serve [--port <port>]
|
|
83
|
+
economy-serve migrate
|
|
84
|
+
economy-serve version
|
|
85
|
+
economy-otel [--port <port>]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`economy-mcp` and `economy-serve` support `--version`. See [MCP](mcp.md), [configuration](configuration.md), and [OTLP](otel.md) for environment controls and endpoints.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Configuration and deployment
|
|
2
|
+
|
|
3
|
+
## Local data
|
|
4
|
+
|
|
5
|
+
The default data directory is `~/.hasna/economy/` and the SQLite database is `~/.hasna/economy/economy.db`. On first access, regular files in an older `~/.economy/` directory are copied when the new directory does not yet exist.
|
|
6
|
+
|
|
7
|
+
| Variable | Effect |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `HASNA_ECONOMY_DB_PATH` | SQLite path; takes precedence over `ECONOMY_DB`. |
|
|
10
|
+
| `ECONOMY_DB` | Alternate SQLite path. `:memory:` is useful for tests. |
|
|
11
|
+
| `HASNA_ECONOMY_CONFIG_PATH` | Path to `config.json`; defaults under the data directory. |
|
|
12
|
+
| `ECONOMY_MACHINE_ID` | Machine identifier; otherwise Economy uses the normalized hostname. |
|
|
13
|
+
| `ECONOMY_TAG` | Fallback attribution tag on locally written sessions/requests. |
|
|
14
|
+
|
|
15
|
+
`economy config` reads and writes `config.json`. The defaults are `port=3456`, `default-period=today`, `auto-sync=true`, `sync-interval=30`, `alert-thresholds=[5,10,25,50,100]`, and `webhook-url=null`. At present, `webhook-url` drives budget notifications and `activeModel` drives `economy brains`; the other stored values are compatibility/settings metadata. Binary ports, periods, and watch intervals still come from command options or the environment described below.
|
|
16
|
+
|
|
17
|
+
## Account attribution
|
|
18
|
+
|
|
19
|
+
For an agent token such as `CODEX`, Economy checks these explicit forms before consulting `@hasna/accounts`:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
ECONOMY_CODEX_ACCOUNT_KEY or ECONOMY_CODEX_ACCOUNT
|
|
23
|
+
ECONOMY_ACCOUNT_KEY or ECONOMY_ACCOUNT
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Values may be `tool:name` (for example `codex:work`) or a bare name/email. The structured form is:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
ECONOMY_CODEX_ACCOUNT_TOOL / _NAME / _EMAIL
|
|
30
|
+
ECONOMY_ACCOUNT_TOOL / _NAME / _EMAIL
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The same agent-specific pattern applies to all eight supported agents. Account keys use the tool plus normalized email when available, otherwise the profile name.
|
|
34
|
+
|
|
35
|
+
## CLI/MCP cloud client
|
|
36
|
+
|
|
37
|
+
Local is the default. To route CLI and MCP data operations to a shared server, set:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
export HASNA_ECONOMY_API_URL=https://economy.example.com
|
|
41
|
+
export HASNA_ECONOMY_API_KEY='...'
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
URL plus key is itself a cloud-mode signal. You may explicitly set `HASNA_ECONOMY_STORAGE_MODE=cloud`; `self_hosted`, `remote`, and `hybrid` are accepted deprecated aliases. The resolver also accepts `HASNA_ECONOMY_MODE`, `ECONOMY_STORAGE_MODE`, and `ECONOMY_MODE`, plus unprefixed `ECONOMY_API_URL`/`ECONOMY_API_KEY` aliases. An existing `/v1` suffix is normalized, otherwise it is appended. Cloud mode with no key or an invalid URL fails rather than reading an unintended local dataset.
|
|
45
|
+
|
|
46
|
+
In cloud-client mode, data commands use the HTTP API, and local auto-sync, explicit `economy sync`, and `economy billing sync` are skipped. Clients never need or use a Postgres DSN.
|
|
47
|
+
|
|
48
|
+
## REST server
|
|
49
|
+
|
|
50
|
+
Start the local server with either:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
economy serve --port 3456
|
|
54
|
+
economy-serve --port 3456
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`ECONOMY_PORT` supplies the `economy-serve` default. `ECONOMY_BIND` (or `ECONOMY_HOST`) controls the local bind host. `ECONOMY_API_TOKEN` (or `HASNA_ECONOMY_API_TOKEN`) enables the local shared-token check; send it as `Authorization: Bearer ...` or `X-Economy-Token`.
|
|
58
|
+
|
|
59
|
+
Without a local token, the current server defaults to `0.0.0.0` and API routes are unauthenticated. Set a token and an intentional bind address before exposing a local-mode server to another host.
|
|
60
|
+
|
|
61
|
+
The server serves `dashboard/dist` and falls back to its `index.html` for non-API paths when those assets exist.
|
|
62
|
+
|
|
63
|
+
## Self-hosted server
|
|
64
|
+
|
|
65
|
+
The server switches to direct Postgres mode when `HASNA_ECONOMY_STORAGE_MODE=cloud` or when a DSN is present:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
HASNA_ECONOMY_DATABASE_URL
|
|
69
|
+
ECONOMY_DATABASE_URL
|
|
70
|
+
DATABASE_URL
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Apply migrations with `economy-serve migrate`. `ECONOMY_PG_POOL_MAX` defaults to 5. A non-loopback cloud server also requires one of `HASNA_ECONOMY_API_SIGNING_KEY`, `HASNA_API_SIGNING_KEY`, or `API_KEY_SIGNING_SECRET`; API keys are then verified by `@hasna/contracts`. The signing secret belongs only on the server.
|
|
74
|
+
|
|
75
|
+
See [REST API authentication](rest-api.md#authentication) for request headers and open probes.
|
|
76
|
+
|
|
77
|
+
## Other services
|
|
78
|
+
|
|
79
|
+
| Variable | Effect |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `MCP_HTTP=1` | Run `economy-mcp` in Streamable HTTP mode instead of stdio. |
|
|
82
|
+
| `MCP_HTTP_PORT` | MCP HTTP port; default 8860 and overridden by `--port`. |
|
|
83
|
+
| `ECONOMY_OTEL_PORT` | OTLP sidecar port; default 4318 and overridden by `--port`. |
|
|
84
|
+
| `ECONOMY_OTEL_BIND` | OTLP sidecar bind host; default `127.0.0.1`. |
|
|
85
|
+
|
|
86
|
+
Source- and billing-specific environment variables are listed in [Ingestion](ingestion.md).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Ingestion
|
|
2
|
+
|
|
3
|
+
`economy sync` imports local coding-agent usage into Economy's SQLite database. A sync with no source flag runs every source; one or more source flags limit the run. Reads such as `economy today` also auto-sync all local sources before querying.
|
|
4
|
+
|
|
5
|
+
In cloud-client mode, CLI and MCP reads/writes go directly to the shared HTTP API. Local `sync` and `billing sync` deliberately do nothing in that mode; ingest on a machine running in local mode, or use the authenticated server ingest endpoints.
|
|
6
|
+
|
|
7
|
+
## Sources
|
|
8
|
+
|
|
9
|
+
| Source | Default input | Notes and overrides |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| Claude Code | `~/.claude/projects/**/*.jsonl` | Imports assistant messages with usage, including cache tiers and supported pricing modifiers. Quota uses `~/.claude/.credentials.json`, `CLAUDE_OAUTH_TOKEN`, or `ANTHROPIC_OAUTH_TOKEN`. |
|
|
12
|
+
| Takumi | `~/.takumi/projects/**/*.jsonl` | Uses the same JSONL ingestion format as Claude. |
|
|
13
|
+
| Codex | `~/.codex/state_5.sqlite`, rollout JSONL, and `~/.codex/config.toml` | Overrides: `HASNA_ECONOMY_CODEX_DB_PATH`, `HASNA_ECONOMY_CODEX_CONFIG_PATH`. Quota uses `~/.codex/auth.json` or `CODEX_OAUTH_TOKEN`; `CODEX_USAGE_URL` can override the quota URL. |
|
|
14
|
+
| Codewith (reported as Codex) | `~/.codewith/state_5.sqlite` and `~/.codewith/config.toml` | Overrides: `HASNA_ECONOMY_CODEWITH_DB_PATH`, `HASNA_ECONOMY_CODEWITH_CONFIG_PATH`. An explicit Codex DB path disables default Codewith discovery unless a Codewith DB path is also explicit. |
|
|
15
|
+
| Gemini CLI | `~/.gemini/tmp` and `~/.gemini/history` | Overrides: `HASNA_ECONOMY_GEMINI_TMP_DIR`, `HASNA_ECONOMY_GEMINI_HISTORY_DIR`. |
|
|
16
|
+
| OpenCode | `~/.local/share/opencode/storage/message/**/*.json` | Imports assistant-message usage and uses the recorded cost when present. |
|
|
17
|
+
| Cursor | Cursor `/api/usage` and `/api/usage-summary` | Requires `CURSOR_SESSION_TOKEN` (or `CURSOR_API_TOKEN`). Creates daily usage snapshots and a subscription rollup when spend is present. |
|
|
18
|
+
| Pi | `~/.pi/agent/sessions/**/*.json` | Override with `PI_CODING_AGENT_SESSION_DIR`. Uses recorded turn cost; a missing cost remains zero until pricing is repaired or the source records one. |
|
|
19
|
+
| Hermes | `~/.hermes/state.db` | Imports session-level token and cost rollups. |
|
|
20
|
+
| OpenLoops | `~/.hasna/loops/loops.db` | Override with `HASNA_ECONOMY_LOOPS_DB_PATH`; price with `HASNA_ECONOMY_LOOPS_MODEL` or `ECONOMY_LOOPS_MODEL`. Imports orchestration/judge `goal_runs.tokens_used` only, into `loop:*` cost centers. |
|
|
21
|
+
|
|
22
|
+
Full, unfiltered sync also attempts to import active metadata from `@hasna/projects`. Missing files, optional registries, and unavailable quota credentials are skipped; use `--verbose` to see source-level diagnostics.
|
|
23
|
+
|
|
24
|
+
## Incremental and repair behavior
|
|
25
|
+
|
|
26
|
+
File/database state is cached in the `ingest_state` table, and request IDs are upserted and deduplicated. Consequently, normal repeated syncs are incremental.
|
|
27
|
+
|
|
28
|
+
- `--force` clears the ingest-state entries for the supported sources and reprocesses them.
|
|
29
|
+
- `--backfill-machine` fills empty `machine_id` values with `ECONOMY_MACHINE_ID` or the normalized hostname.
|
|
30
|
+
- `--recalculate` prices token-bearing requests whose `cost_usd` is zero, then rerolls affected sessions. It reports buckets still missing usable pricing.
|
|
31
|
+
- Budget webhooks are checked after a CLI or REST sync. Failed deliveries remain eligible for a later retry.
|
|
32
|
+
|
|
33
|
+
## Account and cost-center attribution
|
|
34
|
+
|
|
35
|
+
Economy first checks agent-specific overrides such as `ECONOMY_CODEX_ACCOUNT`, then generic `ECONOMY_ACCOUNT` overrides, then matching `@hasna/accounts` env-dir/applied/current profiles. An override may be `tool:name`, an email, or separate `*_ACCOUNT_TOOL`, `*_ACCOUNT_NAME`, and `*_ACCOUNT_EMAIL` fields. See [configuration](configuration.md#account-attribution).
|
|
36
|
+
|
|
37
|
+
Apps and services can report explicit project, repository, account, attribution-tag, and cost-center fields through [`economy-otel`](otel.md). `ECONOMY_TAG` supplies a fallback attribution tag for records written through the local database helpers.
|
|
38
|
+
|
|
39
|
+
## Provider billing
|
|
40
|
+
|
|
41
|
+
`economy billing sync --days 31` imports ground-truth daily billing locally:
|
|
42
|
+
|
|
43
|
+
- Anthropic: `HASNAXYZ_ANTHROPIC_LIVE_ADMIN_API_KEY` or `ANTHROPIC_ADMIN_API_KEY`.
|
|
44
|
+
- OpenAI: `HASNAXYZ_OPENAI_LIVE_ADMIN_API_KEY` or `OPENAI_ADMIN_API_KEY`.
|
|
45
|
+
- Gemini export: `HASNA_ECONOMY_GEMINI_BILLING_EXPORT_PATH`, `HASNAXYZ_ECONOMY_GEMINI_BILLING_EXPORT_PATH`, or `GEMINI_BILLING_EXPORT_PATH`.
|
|
46
|
+
|
|
47
|
+
Gemini imports JSON arrays, objects with a `rows` array, JSONL, or simple CSV. `economy billing show` compares totals; `economy billing diff` applies the reconciliation threshold.
|
package/docs/mcp.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# MCP server
|
|
2
|
+
|
|
3
|
+
`economy-mcp` uses stdio by default:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
claude mcp add --transport stdio --scope user economy -- economy-mcp
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Codex configuration:
|
|
10
|
+
|
|
11
|
+
```toml
|
|
12
|
+
[mcp_servers.economy]
|
|
13
|
+
command = "economy-mcp"
|
|
14
|
+
args = []
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Gemini settings:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"mcpServers": {
|
|
22
|
+
"economy": { "command": "economy-mcp", "args": [] }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`economy mcp --all` prints these snippets. The MCP server uses the same local-versus-cloud Store selection as the CLI; configure a shared API with `HASNA_ECONOMY_API_URL` and `HASNA_ECONOMY_API_KEY` as described in [configuration](configuration.md#climcp-cloud-client).
|
|
28
|
+
|
|
29
|
+
## Streamable HTTP
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
economy-mcp --http # http://127.0.0.1:8860/mcp
|
|
33
|
+
MCP_HTTP=1 economy-mcp # same
|
|
34
|
+
economy-mcp --http --port 8815
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`MCP_HTTP_PORT` supplies the default HTTP port. The transport binds to loopback, exposes `POST /mcp`, and exposes `GET /health`. Stdio remains the default when `--http`/`MCP_HTTP` is absent.
|
|
38
|
+
|
|
39
|
+
## Tools
|
|
40
|
+
|
|
41
|
+
Discovery helpers:
|
|
42
|
+
|
|
43
|
+
- `search_tools`, `describe_tools`
|
|
44
|
+
|
|
45
|
+
Cost and activity reads:
|
|
46
|
+
|
|
47
|
+
- `get_cost_summary`, `get_sessions`, `get_session_detail`, `get_top_sessions`
|
|
48
|
+
- `get_model_breakdown`, `get_project_breakdown`, `get_agent_breakdown`, `get_account_breakdown`, `get_cost_center_breakdown`
|
|
49
|
+
- `get_daily`, `list_machines`, `get_usage`, `get_savings`, `get_billing_summary`
|
|
50
|
+
|
|
51
|
+
Management and estimation:
|
|
52
|
+
|
|
53
|
+
- `get_budget_status`, `set_budget`, `remove_budget`
|
|
54
|
+
- `get_goals`, `set_goal`, `remove_goal`
|
|
55
|
+
- `get_pricing`, `set_pricing`, `remove_pricing`, `estimate_cost`
|
|
56
|
+
- `list_subscriptions`, `set_subscription`, `remove_subscription`
|
|
57
|
+
- `sync`, `send_feedback`
|
|
58
|
+
|
|
59
|
+
Shared agent-registry tools:
|
|
60
|
+
|
|
61
|
+
- `register_agent`, `heartbeat`, `set_focus`, `list_agents`
|
|
62
|
+
|
|
63
|
+
High-cardinality tools return compact text by default. Where the schema offers them, use `limit`, `verbose=true`, or `json=true`. Limits are clamped to 100 for MCP calls.
|
|
64
|
+
|
|
65
|
+
The `sync` tool accepts `all`, any supported coding agent, or `loops`. It ingests on-box files only in local mode. In cloud-client mode it returns an explanatory no-op because all other data tools already use the shared API.
|
package/docs/otel.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# OTLP/HTTP sidecar
|
|
2
|
+
|
|
3
|
+
`economy-otel` writes application/service metrics into the local Economy SQLite database:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
economy-otel --port 4318
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
It binds to `127.0.0.1` by default. Override the bind with `ECONOMY_OTEL_BIND` and the port with `ECONOMY_OTEL_PORT` or `--port`.
|
|
10
|
+
|
|
11
|
+
| Method | Path | Behavior |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `GET` | `/health` | `{ status, service, version }`. |
|
|
14
|
+
| `POST` | `/v1/metrics` | Parse an OTLP JSON `resourceMetrics` payload. |
|
|
15
|
+
| `POST` | `/ingest` | Parse one simplified JSON cost/token event. |
|
|
16
|
+
|
|
17
|
+
Other methods return 405. Invalid JSON returns 400. A valid payload with no recognized positive cost/token metrics returns `{ "ingested": 0, "message": "no matching metrics" }`.
|
|
18
|
+
|
|
19
|
+
## Simplified event
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
curl -X POST http://127.0.0.1:4318/ingest \
|
|
23
|
+
-H 'content-type: application/json' \
|
|
24
|
+
-d '{
|
|
25
|
+
"source": "app",
|
|
26
|
+
"cost_center": "alumia",
|
|
27
|
+
"cost_center_kind": "app",
|
|
28
|
+
"project_path": "/workspace/alumia",
|
|
29
|
+
"model": "gpt-5-mini",
|
|
30
|
+
"cost_usd": 0.12,
|
|
31
|
+
"input_tokens": 1200,
|
|
32
|
+
"output_tokens": 300
|
|
33
|
+
}'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Core fields are `agent`/`source`, `session_id`, `request_id` or `source_request_id`, `model`, `timestamp`, `cost_usd`, `input_tokens`, and `output_tokens`. An event must have positive cost or tokens.
|
|
37
|
+
|
|
38
|
+
Attribution fields include:
|
|
39
|
+
|
|
40
|
+
- `cost_center`, `cost_center_kind`, `cost_center_id`
|
|
41
|
+
- `attribution_tag`, `project_path`, `project_name`, `repo`
|
|
42
|
+
- `account_key`, `account_tool`, `account_name`, `account_email`, `account_source`
|
|
43
|
+
- `cost_basis` (`metered_api`, `subscription_included`, `estimated`, or `unknown`)
|
|
44
|
+
|
|
45
|
+
Cost-center kinds are `loop`, `app`, `repo`, `service`, and `team`. When kind and name are present, the sidecar creates a cost center such as `app:alumia` unless an explicit ID is supplied. Unknown agents normalize to the cost-center kind when it is a supported pseudo-agent (`app`, `service`, `repo`, `loop`), otherwise `service`.
|
|
46
|
+
|
|
47
|
+
## OTLP recognition
|
|
48
|
+
|
|
49
|
+
The OTLP parser reads sum or gauge data points. Metric names containing cost or `.usd` become cost; names containing input+token or `tokens.input` become input tokens; names containing output+token or `tokens.output` become output tokens. Points are joined by agent and request/event ID.
|
|
50
|
+
|
|
51
|
+
Resource and point attributes may use plain names (`model`, `session_id`, `request_id`, `project_path`, and the attribution fields above) or common dotted aliases such as `ai.model`, `session.id`, `event.id`, `service.name`, `economy.cost_center`, and `account.email`.
|
|
52
|
+
|
|
53
|
+
The sidecar always opens the local SQLite database. It does not forward to a cloud API; use the authenticated REST bulk-ingest path for remote ingestion.
|
package/docs/rest-api.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# REST API
|
|
2
|
+
|
|
3
|
+
Start the service with `economy-serve` or `economy serve`. The default local origin is `http://127.0.0.1:3456`; the bind behavior is detailed in [configuration](configuration.md#rest-server).
|
|
4
|
+
|
|
5
|
+
The canonical application prefix is `/v1`. Equivalent `/api` routes remain available for the bundled dashboard and older clients. Successful application responses use:
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{ "data": {}, "meta": {} }
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Errors use `{ "error": "message" }`. Foundation probes return a direct `{ status, version, mode, service }` object instead of the data envelope.
|
|
12
|
+
|
|
13
|
+
## Discovery and probes
|
|
14
|
+
|
|
15
|
+
| Method | Path | Purpose |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| `GET` | `/health`, `/healthz` | Liveness. |
|
|
18
|
+
| `GET` | `/ready`, `/readyz` | Storage readiness; may return 503. |
|
|
19
|
+
| `GET` | `/version`, `/v1/version` | Version and deployment mode. |
|
|
20
|
+
| `GET` | `/openapi.json` | Runtime-versioned OpenAPI document. |
|
|
21
|
+
|
|
22
|
+
These routes are open. The checked-in OpenAPI source is [`openapi/economy.json`](../openapi/economy.json).
|
|
23
|
+
|
|
24
|
+
## Authentication
|
|
25
|
+
|
|
26
|
+
In local mode, set `ECONOMY_API_TOKEN` or `HASNA_ECONOMY_API_TOKEN` and send either:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
Authorization: Bearer <token>
|
|
30
|
+
X-Economy-Token: <token>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
In self-hosted Postgres mode, send a valid Economy API key as `x-api-key` or a bearer token. All non-probe routes require a valid key when the server has an authenticator. Bulk ingest and feedback additionally request the `economy:write` scope.
|
|
34
|
+
|
|
35
|
+
## Read routes
|
|
36
|
+
|
|
37
|
+
| Method | Canonical path | Parameters/behavior |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| `GET` | `/v1/summary` | `period` (default `today`), optional `machine`. |
|
|
40
|
+
| `GET` | `/v1/machines` | Machine rollups and current machine metadata. |
|
|
41
|
+
| `GET` | `/v1/fleet` | `period` (default `month`), optional `machine`; returns summary, machines, registry. |
|
|
42
|
+
| `GET` | `/v1/daily` | `days` (default 30), optional `machine`. |
|
|
43
|
+
| `GET` | `/v1/hourly` | Optional `machine`; `hours` must be 1–48. |
|
|
44
|
+
| `GET` | `/v1/sessions` | `agent`, `project`, `search`, `machine`, `account`, `limit` (50), `offset` (0), `since`, and comma-separated `fields`. |
|
|
45
|
+
| `GET` | `/v1/sessions/{id}/requests` | Full ID or unique prefix; returns 404 when absent. |
|
|
46
|
+
| `GET` | `/v1/top` | `n` (default 10), optional `agent` and `since`. |
|
|
47
|
+
| `GET` | `/v1/models` | Model breakdown. |
|
|
48
|
+
| `GET` | `/v1/projects` | Project breakdown; `period` defaults to `all`, optional `machine`. |
|
|
49
|
+
| `GET` | `/v1/projects/detail` | Detailed project query; `q` is required. |
|
|
50
|
+
| `GET` | `/v1/accounts` | Account breakdown; `period` defaults to `all`, optional `machine`. |
|
|
51
|
+
| `GET` | `/v1/breakdown` | `by=model|project|agent|account|cost-center|loop|app|repo|service|team`, optional `period` and `machine`. |
|
|
52
|
+
| `GET` | `/v1/usage` | `period` (default `month`), optional valid `agent`. |
|
|
53
|
+
| `GET` | `/v1/savings` | `period` (default `month`), optional valid `agent`. |
|
|
54
|
+
| `GET` | `/v1/billing` | `period` (default `month`). |
|
|
55
|
+
| `GET` | `/v1/billing/diff` | `period` (default `month`), `threshold` percentage (default 15). |
|
|
56
|
+
| `GET` | `/v1/budgets` | Budget statuses. |
|
|
57
|
+
| `GET` | `/v1/goals` | Goal statuses. |
|
|
58
|
+
| `GET` | `/v1/pricing` | Model pricing rows. |
|
|
59
|
+
| `GET` | `/v1/subscriptions` | Subscription plans. |
|
|
60
|
+
| `GET` | `/v1/project-registry` | Registered projects. |
|
|
61
|
+
| `GET` | `/v1/brief` | Fleet brief; optional `since` and `machine`. |
|
|
62
|
+
| `GET` | `/v1/export` | `type=sessions|requests`, `period` (default `month`); returns rows in JSON for clients to encode. |
|
|
63
|
+
| `GET` | `/v1/compare` | Required `from` and `to` dates (`YYYY-MM-DD`). |
|
|
64
|
+
| `GET` | `/v1/forecast` | Current-month projection. |
|
|
65
|
+
| `GET` | `/v1/efficiency` | Per-model token efficiency. |
|
|
66
|
+
| `GET` | `/v1/requests` | Requests after required ISO `since`; used by live watch. |
|
|
67
|
+
|
|
68
|
+
Common period values are `today`, `yesterday`, `week`, `month`, `year`, and `all`, but individual routes accept the subset documented above.
|
|
69
|
+
|
|
70
|
+
## Mutation routes
|
|
71
|
+
|
|
72
|
+
| Method | Canonical path | Body/behavior |
|
|
73
|
+
| --- | --- | --- |
|
|
74
|
+
| `POST` | `/v1/budgets` | Positive `limit_usd`; optional `period`, `alert_at_percent`, `project_path`, `agent`, `cost_center_id`. |
|
|
75
|
+
| `DELETE` | `/v1/budgets/{id}` | Delete a budget. |
|
|
76
|
+
| `POST` | `/v1/goals` | Positive `limit_usd`; `period=day|week|month|year`; optional `project_path`, `agent`. |
|
|
77
|
+
| `DELETE` | `/v1/goals/{id}` | Delete a goal. |
|
|
78
|
+
| `POST` | `/v1/pricing` | `model`, non-negative input/output/cache pricing fields. |
|
|
79
|
+
| `DELETE` | `/v1/pricing/{model}` | Delete a URL-encoded model row. |
|
|
80
|
+
| `POST` | `/v1/subscriptions` | Required `provider` and `plan`; optional ID, agent, fee/inclusion, cycle/reset, and active fields. |
|
|
81
|
+
| `DELETE` | `/v1/subscriptions/{id}` | Delete a plan. |
|
|
82
|
+
| `POST` | `/v1/project-registry` | Required `path`; optional `name`, `description`, `tags`. |
|
|
83
|
+
| `DELETE` | `/v1/project-registry/{path}` | Delete a URL-encoded project path. |
|
|
84
|
+
| `POST` | `/v1/sync` | `{ "sources": "all" }` or one of the eight agents/`loops`; triggers server-local ingestion. |
|
|
85
|
+
| `POST` | `/v1/billing/sync` | Optional `days` (1–366) and `providers` from `anthropic`, `openai`, `gemini`. Provider failures are returned per provider. |
|
|
86
|
+
| `POST` | `/v1/ingest` | Idempotently merge arrays named `requests`, `sessions`, `projects`, `budgets`, `goals`, `billing_daily`, `model_pricing`, `subscriptions`, and `usage_snapshots`. |
|
|
87
|
+
| `POST` | `/v1/feedback` | Required `message`; optional `email` and `category=bug|feature|general`. |
|
|
88
|
+
|
|
89
|
+
Agent fields accept `claude`, `takumi`, `codex`, `gemini`, `opencode`, `cursor`, `pi`, or `hermes`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/economy",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "AI coding cost tracker — CLI + MCP server + REST API + web dashboard for Claude Code, Codex, Gemini, OpenCode, Cursor, Pi, and Hermes",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"dist",
|
|
30
|
+
"docs",
|
|
30
31
|
"dashboard/dist",
|
|
31
32
|
"LICENSE",
|
|
32
33
|
"README.md",
|
|
@@ -69,13 +70,12 @@
|
|
|
69
70
|
"access": "public"
|
|
70
71
|
},
|
|
71
72
|
"dependencies": {
|
|
72
|
-
"@hasna/accounts": "0.
|
|
73
|
+
"@hasna/accounts": "0.2.23",
|
|
73
74
|
"@hasna/agent-registry": "^0.1.0",
|
|
74
|
-
"@hasna/cloud": "0.1.24",
|
|
75
75
|
"@hasna/contracts": "^0.4.2",
|
|
76
76
|
"@hasna/events": "^0.1.7",
|
|
77
77
|
"@hasna/mcp-harness": "^0.1.0",
|
|
78
|
-
"@hasna/projects": "0.1.
|
|
78
|
+
"@hasna/projects": "0.1.95",
|
|
79
79
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
80
80
|
"chalk": "^5.4.1",
|
|
81
81
|
"commander": "^13.1.0",
|
|
@@ -89,7 +89,6 @@
|
|
|
89
89
|
"typescript": "^5.7.2"
|
|
90
90
|
},
|
|
91
91
|
"trustedDependencies": [
|
|
92
|
-
"@hasna/cloud",
|
|
93
92
|
"@hasna/projects"
|
|
94
93
|
]
|
|
95
94
|
}
|