@hasna/economy 0.3.7 → 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 +0 -4
- package/README.md +28 -61
- package/dashboard/README.md +17 -64
- package/dist/cli/index.js +221 -114
- package/dist/db/cloud.d.ts +3 -4
- package/dist/db/cloud.d.ts.map +1 -1
- package/dist/db/database.d.ts +2 -2
- 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/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 +129 -56
- 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 +1 -1
- package/dist/ingest/loops.d.ts.map +1 -1
- package/dist/ingest/opencode.d.ts +1 -1
- package/dist/ingest/opencode.d.ts.map +1 -1
- package/dist/ingest/otel.d.ts +1 -1
- 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/sync-all.d.ts +1 -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 +144 -94
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/otel/index.js +69 -4
- package/dist/server/index.js +248 -88
- package/dist/server/serve.d.ts +1 -1
- package/dist/server/serve.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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing-diff.d.ts","sourceRoot":"","sources":["../../src/lib/billing-diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"billing-diff.d.ts","sourceRoot":"","sources":["../../src/lib/billing-diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAExE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAS/C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC;AAED,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,YAAY,SAAK,GAChB,kBAAkB,CAsCpB"}
|
package/dist/lib/brief.d.ts
CHANGED
package/dist/lib/brief.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brief.d.ts","sourceRoot":"","sources":["../../src/lib/brief.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"brief.d.ts","sourceRoot":"","sources":["../../src/lib/brief.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAUxE,KAAK,WAAW,GAAG,OAAO,GAAG,MAAM,CAAA;AAEnC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,sBAAsB,EAAE,MAAM,CAAA;IAC9B,sBAAsB,EAAE,MAAM,CAAA;IAC9B,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,WAAW,GAAG,OAAO,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,SAAS,EAAE,kBAAkB,EAAE,CAAA;IAC/B,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,SAAS,EAAE;QACT,QAAQ,EAAE,qBAAqB,EAAE,CAAA;QACjC,gBAAgB,EAAE,MAAM,CAAA;QACxB,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;CACF;AAcD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,IAAI,CAAA;CACnB;AAyBD,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,CAWjF;AAsmBD,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAE,YAAiB,GAAG,YAAY,CAmD9E"}
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import type { SqliteAdapter as Database } from '
|
|
1
|
+
import type { SqliteAdapter as Database } from '../db/sqlite-adapter.js';
|
|
2
|
+
/**
|
|
3
|
+
* The subset of a project-registry row economy needs. The registry renamed its
|
|
4
|
+
* filesystem-path field `path` -> `primary_path` when projects became
|
|
5
|
+
* workspaces, so both spellings are accepted and `resolveProjectPath` below
|
|
6
|
+
* picks whichever is present. Keeping both means the injectable
|
|
7
|
+
* `listActiveProjects` seam (and its tests) stays valid across that rename.
|
|
8
|
+
*/
|
|
2
9
|
interface OpenProject {
|
|
3
10
|
id: string;
|
|
4
11
|
name: string;
|
|
5
12
|
description: string | null;
|
|
6
|
-
path
|
|
13
|
+
path?: string | null;
|
|
14
|
+
primary_path?: string | null;
|
|
7
15
|
tags: string[];
|
|
8
16
|
created_at: string;
|
|
9
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-projects.d.ts","sourceRoot":"","sources":["../../src/lib/open-projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"open-projects.d.ts","sourceRoot":"","sources":["../../src/lib/open-projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAGxE;;;;;;GAMG;AACH,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,KAAK,gBAAgB,GAAG,CAAC,OAAO,EAAE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,KAAK,WAAW,EAAE,CAAA;AAIvF,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,QAAQ,EACZ,kBAAkB,CAAC,EAAE,gBAAgB,GACpC,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA4BhD"}
|
package/dist/lib/pricing.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
|
import type { ModelPricing } from '../types/index.js';
|
|
3
3
|
import { type DbModelPricing } from '../db/database.js';
|
|
4
4
|
export declare const DEFAULT_PRICING: Record<string, ModelPricing>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/lib/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/lib/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAA6E,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAIlI,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CA+FxD,CAAA;AAqND,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOtD;AA2CD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAMtD;AA+GD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAoBjF;AA4BD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAG7D;AAMD,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,SAAI,EACnB,gBAAgB,SAAI,EACpB,kBAAkB,SAAI,EACtB,sBAAsB,SAAI,GACzB,MAAM,CAIR;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,SAAI,EACnB,gBAAgB,SAAI,EACpB,kBAAkB,SAAI,EACtB,sBAAsB,SAAI,GACzB,MAAM,CAIR;AAMD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAW7F;AAMD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,cAAc,EAAE,EACtB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,SAAI,EACnB,gBAAgB,SAAI,EACpB,kBAAkB,SAAI,EACtB,sBAAsB,SAAI,GACzB,MAAM,CAIR"}
|
package/dist/lib/savings.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
|
import type { Agent, CostBasis } from './agents.js';
|
|
3
3
|
import type { Period } from '../types/index.js';
|
|
4
4
|
export interface SavingsSummary {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"savings.d.ts","sourceRoot":"","sources":["../../src/lib/savings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"savings.d.ts","sourceRoot":"","sources":["../../src/lib/savings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,kBAAkB,EAAE,MAAM,CAAA;IAC1B,oBAAoB,EAAE,MAAM,CAAA;IAC5B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAA;CAClD;AAoCD,6EAA6E;AAC7E,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,GACtB,MAAM,CAER;AAED,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,GACZ,cAAc,CAmHhB;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAIhE"}
|
package/dist/lib/spikes.d.ts
CHANGED
package/dist/lib/spikes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spikes.d.ts","sourceRoot":"","sources":["../../src/lib/spikes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"spikes.d.ts","sourceRoot":"","sources":["../../src/lib/spikes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAExE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EACtD,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD,SAAS,EAAE,CAqBb;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,SAAK,GAAG,SAAS,EAAE,CAUtE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI,CAI5D"}
|
package/dist/lib/sync-all.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
|
import { ingestClaude, ingestTakumi } from '../ingest/claude.js';
|
|
3
3
|
import { ingestCodex } from '../ingest/codex.js';
|
|
4
4
|
import { ingestGemini } from '../ingest/gemini.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-all.d.ts","sourceRoot":"","sources":["../../src/lib/sync-all.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"sync-all.d.ts","sourceRoot":"","sources":["../../src/lib/sync-all.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAA;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAA;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAA;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAA;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAA;IACjD,EAAE,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAA;IACzC,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAA;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAA;IAC3D,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAA;IACzD,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,CA4B1F"}
|
package/dist/lib/webhooks.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/lib/webhooks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/lib/webhooks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAExE,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CtE"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -17,6 +17,62 @@ var __export = (target, all) => {
|
|
|
17
17
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
18
18
|
var __require = import.meta.require;
|
|
19
19
|
|
|
20
|
+
// src/db/sqlite-adapter.ts
|
|
21
|
+
import { Database } from "bun:sqlite";
|
|
22
|
+
|
|
23
|
+
class SqliteAdapter {
|
|
24
|
+
db;
|
|
25
|
+
constructor(path) {
|
|
26
|
+
this.db = new Database(path, { create: true });
|
|
27
|
+
this.db.exec("PRAGMA journal_mode=WAL");
|
|
28
|
+
this.db.exec("PRAGMA foreign_keys=ON");
|
|
29
|
+
}
|
|
30
|
+
run(sql, ...params) {
|
|
31
|
+
const result = this.db.prepare(sql).run(...params);
|
|
32
|
+
return { changes: result.changes, lastInsertRowid: result.lastInsertRowid };
|
|
33
|
+
}
|
|
34
|
+
get(sql, ...params) {
|
|
35
|
+
return this.db.prepare(sql).get(...params);
|
|
36
|
+
}
|
|
37
|
+
all(sql, ...params) {
|
|
38
|
+
return this.db.prepare(sql).all(...params);
|
|
39
|
+
}
|
|
40
|
+
exec(sql) {
|
|
41
|
+
this.db.exec(sql);
|
|
42
|
+
}
|
|
43
|
+
query(sql) {
|
|
44
|
+
return this.db.query(sql);
|
|
45
|
+
}
|
|
46
|
+
prepare(sql) {
|
|
47
|
+
const stmt = this.db.prepare(sql);
|
|
48
|
+
return {
|
|
49
|
+
run(...params) {
|
|
50
|
+
const r = stmt.run(...params);
|
|
51
|
+
return { changes: r.changes, lastInsertRowid: r.lastInsertRowid };
|
|
52
|
+
},
|
|
53
|
+
get(...params) {
|
|
54
|
+
return stmt.get(...params);
|
|
55
|
+
},
|
|
56
|
+
all(...params) {
|
|
57
|
+
return stmt.all(...params);
|
|
58
|
+
},
|
|
59
|
+
finalize() {
|
|
60
|
+
stmt.finalize();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
close() {
|
|
65
|
+
this.db.close();
|
|
66
|
+
}
|
|
67
|
+
transaction(fn) {
|
|
68
|
+
return this.db.transaction(fn)();
|
|
69
|
+
}
|
|
70
|
+
get raw() {
|
|
71
|
+
return this.db;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
var init_sqlite_adapter = () => {};
|
|
75
|
+
|
|
20
76
|
// src/lib/pricing.ts
|
|
21
77
|
var exports_pricing = {};
|
|
22
78
|
__export(exports_pricing, {
|
|
@@ -535,7 +591,6 @@ var init_pricing = __esm(() => {
|
|
|
535
591
|
});
|
|
536
592
|
|
|
537
593
|
// src/db/database.ts
|
|
538
|
-
import { SqliteAdapter as Database } from "@hasna/cloud";
|
|
539
594
|
import { execFileSync } from "child_process";
|
|
540
595
|
import { copyFileSync, existsSync, mkdirSync, readdirSync, statSync } from "fs";
|
|
541
596
|
import { hostname, platform } from "os";
|
|
@@ -628,7 +683,7 @@ function openDatabase(dbPath, skipSeed = false) {
|
|
|
628
683
|
mkdirSync(dir, { recursive: true });
|
|
629
684
|
}
|
|
630
685
|
const db = withSqliteBusyRetry(() => {
|
|
631
|
-
const opened = new
|
|
686
|
+
const opened = new SqliteAdapter(path);
|
|
632
687
|
try {
|
|
633
688
|
opened.exec("PRAGMA busy_timeout = 10000");
|
|
634
689
|
opened.exec("PRAGMA journal_mode = WAL");
|
|
@@ -1216,9 +1271,12 @@ function labelForPath(projectPath, projectName) {
|
|
|
1216
1271
|
function groupKeyForPath(projectPath, projectName) {
|
|
1217
1272
|
return labelForPath(projectPath, projectName).trim().toLowerCase();
|
|
1218
1273
|
}
|
|
1219
|
-
function
|
|
1220
|
-
|
|
1221
|
-
|
|
1274
|
+
function laterTimestamp(current, candidate) {
|
|
1275
|
+
if (!candidate)
|
|
1276
|
+
return current;
|
|
1277
|
+
return candidate > current ? candidate : current;
|
|
1278
|
+
}
|
|
1279
|
+
function queryProjectBreakdownScoped(db, requestWhere, sessionWhere, requestScopeParams = [], sessionScopeParams = [], machine) {
|
|
1222
1280
|
const sessionMachineClause = machine ? " AND (machine_id = ? OR id IN (SELECT DISTINCT session_id FROM requests WHERE machine_id = ?))" : "";
|
|
1223
1281
|
const requestMachineClause = machine ? " AND machine_id = ?" : "";
|
|
1224
1282
|
const sessionMachineParams = machine ? [machine, machine] : [];
|
|
@@ -1226,67 +1284,89 @@ function queryProjectBreakdown(db, period = "all", machine) {
|
|
|
1226
1284
|
const sessionOnlyMachineClause = machine ? " AND machine_id = ?" : "";
|
|
1227
1285
|
const sessionOnlyMachineParams = machine ? [machine] : [];
|
|
1228
1286
|
const sessions = db.prepare(`
|
|
1229
|
-
SELECT id, project_path, project_name
|
|
1287
|
+
SELECT id, project_path, project_name
|
|
1230
1288
|
FROM sessions
|
|
1231
1289
|
WHERE (project_path != '' OR project_name != '')${sessionMachineClause}
|
|
1232
1290
|
`).all(...sessionMachineParams);
|
|
1233
1291
|
const groups = new Map;
|
|
1292
|
+
const groupKeyBySession = new Map;
|
|
1234
1293
|
for (const s of sessions) {
|
|
1235
1294
|
const label = labelForPath(s.project_path, s.project_name);
|
|
1236
1295
|
if (!label)
|
|
1237
1296
|
continue;
|
|
1238
1297
|
const key = groupKeyForPath(s.project_path, s.project_name);
|
|
1239
|
-
const g = groups.get(key) ?? { label,
|
|
1240
|
-
g.sessionIds.push(s.id);
|
|
1298
|
+
const g = groups.get(key) ?? { label, samplePath: s.project_path, sessions: 0, requests: 0, total_tokens: 0, cost_usd: 0, last_active: "" };
|
|
1241
1299
|
if (!g.samplePath)
|
|
1242
1300
|
g.samplePath = s.project_path;
|
|
1243
1301
|
groups.set(key, g);
|
|
1302
|
+
groupKeyBySession.set(s.id, key);
|
|
1303
|
+
}
|
|
1304
|
+
const groupFor = (sessionId) => {
|
|
1305
|
+
const key = groupKeyBySession.get(sessionId);
|
|
1306
|
+
return key === undefined ? undefined : groups.get(key);
|
|
1307
|
+
};
|
|
1308
|
+
const requestRows = db.prepare(`
|
|
1309
|
+
SELECT session_id,
|
|
1310
|
+
COUNT(*) as requests,
|
|
1311
|
+
COALESCE(SUM(cost_usd), 0) as cost_usd,
|
|
1312
|
+
COALESCE(SUM(input_tokens + output_tokens + cache_read_tokens + cache_create_tokens), 0) as total_tokens,
|
|
1313
|
+
MAX(timestamp) as last_active
|
|
1314
|
+
FROM requests
|
|
1315
|
+
WHERE ${requestWhere}${requestMachineClause}
|
|
1316
|
+
GROUP BY session_id
|
|
1317
|
+
`).all(...requestScopeParams, ...requestMachineParams);
|
|
1318
|
+
for (const row of requestRows) {
|
|
1319
|
+
const g = groupFor(row.session_id);
|
|
1320
|
+
if (!g)
|
|
1321
|
+
continue;
|
|
1322
|
+
g.sessions += 1;
|
|
1323
|
+
g.requests += row.requests;
|
|
1324
|
+
g.cost_usd += row.cost_usd;
|
|
1325
|
+
g.total_tokens += row.total_tokens;
|
|
1326
|
+
g.last_active = laterTimestamp(g.last_active, row.last_active);
|
|
1327
|
+
}
|
|
1328
|
+
const sessionsWithRequests = new Set(db.prepare(`SELECT DISTINCT session_id FROM requests`).all().map((row) => row.session_id));
|
|
1329
|
+
const sessionOnlyRows = db.prepare(`
|
|
1330
|
+
SELECT id,
|
|
1331
|
+
COALESCE(request_count, 0) as request_count,
|
|
1332
|
+
COALESCE(total_tokens, 0) as total_tokens,
|
|
1333
|
+
COALESCE(total_cost_usd, 0) as total_cost_usd,
|
|
1334
|
+
started_at
|
|
1335
|
+
FROM sessions
|
|
1336
|
+
WHERE ${sessionWhere}${sessionOnlyMachineClause}
|
|
1337
|
+
`).all(...sessionScopeParams, ...sessionOnlyMachineParams);
|
|
1338
|
+
for (const row of sessionOnlyRows) {
|
|
1339
|
+
if (sessionsWithRequests.has(row.id))
|
|
1340
|
+
continue;
|
|
1341
|
+
const g = groupFor(row.id);
|
|
1342
|
+
if (!g)
|
|
1343
|
+
continue;
|
|
1344
|
+
g.sessions += 1;
|
|
1345
|
+
g.requests += row.request_count;
|
|
1346
|
+
g.total_tokens += row.total_tokens;
|
|
1347
|
+
g.cost_usd += row.total_cost_usd;
|
|
1348
|
+
g.last_active = laterTimestamp(g.last_active, row.started_at);
|
|
1244
1349
|
}
|
|
1245
1350
|
const result = [];
|
|
1246
1351
|
for (const g of groups.values()) {
|
|
1247
|
-
|
|
1248
|
-
const reqStats = placeholders.length ? db.prepare(`
|
|
1249
|
-
SELECT
|
|
1250
|
-
COUNT(DISTINCT session_id) as sessions,
|
|
1251
|
-
COUNT(*) as requests,
|
|
1252
|
-
COALESCE(SUM(cost_usd), 0) as cost_usd,
|
|
1253
|
-
COALESCE(SUM(input_tokens + output_tokens + cache_read_tokens + cache_create_tokens), 0) as total_tokens,
|
|
1254
|
-
MAX(timestamp) as last_active
|
|
1255
|
-
FROM requests
|
|
1256
|
-
WHERE session_id IN (${placeholders})
|
|
1257
|
-
AND ${requestWhere}
|
|
1258
|
-
${requestMachineClause}
|
|
1259
|
-
`).get(...g.sessionIds, ...requestMachineParams) : { sessions: 0, requests: 0, cost_usd: 0, total_tokens: 0, last_active: null };
|
|
1260
|
-
const sessionOnlyStats = placeholders.length ? db.prepare(`
|
|
1261
|
-
SELECT
|
|
1262
|
-
COUNT(*) as sessions,
|
|
1263
|
-
COALESCE(SUM(request_count), 0) as requests,
|
|
1264
|
-
COALESCE(SUM(total_tokens), 0) as total_tokens,
|
|
1265
|
-
COALESCE(SUM(total_cost_usd), 0) as cost_usd,
|
|
1266
|
-
MAX(started_at) as last_active
|
|
1267
|
-
FROM sessions
|
|
1268
|
-
WHERE id IN (${placeholders})
|
|
1269
|
-
AND ${sessionWhere}
|
|
1270
|
-
${sessionOnlyMachineClause}
|
|
1271
|
-
AND id NOT IN (SELECT DISTINCT session_id FROM requests)
|
|
1272
|
-
`).get(...g.sessionIds, ...sessionOnlyMachineParams) : { sessions: 0, requests: 0, total_tokens: 0, cost_usd: 0, last_active: null };
|
|
1273
|
-
const totalSessions = reqStats.sessions + sessionOnlyStats.sessions;
|
|
1274
|
-
if (totalSessions === 0)
|
|
1352
|
+
if (g.sessions === 0)
|
|
1275
1353
|
continue;
|
|
1276
|
-
const lastActive = [reqStats.last_active, sessionOnlyStats.last_active].filter(Boolean).sort().at(-1) ?? "";
|
|
1277
1354
|
result.push({
|
|
1278
1355
|
project_path: g.samplePath,
|
|
1279
1356
|
project_name: g.label,
|
|
1280
|
-
sessions:
|
|
1281
|
-
requests:
|
|
1282
|
-
total_tokens:
|
|
1283
|
-
cost_usd:
|
|
1284
|
-
last_active:
|
|
1357
|
+
sessions: g.sessions,
|
|
1358
|
+
requests: g.requests,
|
|
1359
|
+
total_tokens: g.total_tokens,
|
|
1360
|
+
cost_usd: g.cost_usd,
|
|
1361
|
+
last_active: g.last_active
|
|
1285
1362
|
});
|
|
1286
1363
|
}
|
|
1287
1364
|
result.sort((a, b) => b.cost_usd - a.cost_usd);
|
|
1288
1365
|
return result;
|
|
1289
1366
|
}
|
|
1367
|
+
function queryProjectBreakdown(db, period = "all", machine) {
|
|
1368
|
+
return queryProjectBreakdownScoped(db, requestPeriodWhere(period), sessionPeriodWhere(period), [], [], machine);
|
|
1369
|
+
}
|
|
1290
1370
|
function normalizeAccountEmail(email) {
|
|
1291
1371
|
return (email ?? "").trim().toLowerCase();
|
|
1292
1372
|
}
|
|
@@ -1560,17 +1640,8 @@ function queryCostCenterBreakdown(db, period = "all", filter = {}) {
|
|
|
1560
1640
|
filtered.sort((a, b) => b.cost_usd - a.cost_usd);
|
|
1561
1641
|
return filtered;
|
|
1562
1642
|
}
|
|
1563
|
-
function queryProjectBreakdownSince(db, since) {
|
|
1564
|
-
return db
|
|
1565
|
-
SELECT project_path, project_name,
|
|
1566
|
-
COUNT(*) as sessions,
|
|
1567
|
-
COALESCE(SUM(total_tokens), 0) as total_tokens,
|
|
1568
|
-
COALESCE(SUM(request_count), 0) as requests,
|
|
1569
|
-
COALESCE(SUM(total_cost_usd), 0) as cost_usd,
|
|
1570
|
-
MAX(started_at) as last_active
|
|
1571
|
-
FROM sessions WHERE started_at >= ?
|
|
1572
|
-
GROUP BY project_path ORDER BY cost_usd DESC
|
|
1573
|
-
`).all(since);
|
|
1643
|
+
function queryProjectBreakdownSince(db, since, machine) {
|
|
1644
|
+
return queryProjectBreakdownScoped(db, "timestamp >= ?", "started_at >= ?", [since], [since], machine);
|
|
1574
1645
|
}
|
|
1575
1646
|
function queryAgentBreakdownSince(db, since) {
|
|
1576
1647
|
return db.prepare(`
|
|
@@ -1984,7 +2055,9 @@ function dedupeRequests(db) {
|
|
|
1984
2055
|
}
|
|
1985
2056
|
return removed;
|
|
1986
2057
|
}
|
|
1987
|
-
var init_database = () => {
|
|
2058
|
+
var init_database = __esm(() => {
|
|
2059
|
+
init_sqlite_adapter();
|
|
2060
|
+
});
|
|
1988
2061
|
|
|
1989
2062
|
// src/mcp/index.ts
|
|
1990
2063
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -2008,7 +2081,6 @@ var packageMetadata = getPackageMetadata();
|
|
|
2008
2081
|
// src/mcp/server.ts
|
|
2009
2082
|
init_database();
|
|
2010
2083
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2011
|
-
import { registerCloudTools } from "@hasna/cloud";
|
|
2012
2084
|
import { registerAgentTools } from "@hasna/agent-registry";
|
|
2013
2085
|
import { z } from "zod";
|
|
2014
2086
|
|
|
@@ -2174,6 +2246,7 @@ function defaultCostBasisForAgent(agent) {
|
|
|
2174
2246
|
}
|
|
2175
2247
|
|
|
2176
2248
|
// src/lib/accounts.ts
|
|
2249
|
+
import { appliedProfileName, resolveStore } from "@hasna/accounts";
|
|
2177
2250
|
var AGENT_ACCOUNT_TOOLS = {
|
|
2178
2251
|
claude: ["claude"],
|
|
2179
2252
|
takumi: ["takumi", "claude"],
|
|
@@ -2238,57 +2311,35 @@ function envOverride(agent, env) {
|
|
|
2238
2311
|
account_source: "override"
|
|
2239
2312
|
};
|
|
2240
2313
|
}
|
|
2241
|
-
function
|
|
2242
|
-
try {
|
|
2243
|
-
return new Set(api.listTools().map((tool) => tool.id));
|
|
2244
|
-
} catch {
|
|
2245
|
-
return new Set;
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
function profileForEnvDir(api, tool, env) {
|
|
2314
|
+
async function profileForEnvDir(store, tool, env) {
|
|
2249
2315
|
const configuredDir = env[tool.envVar];
|
|
2250
2316
|
if (!configuredDir)
|
|
2251
2317
|
return null;
|
|
2252
2318
|
const normalized = normalizeDir(configuredDir);
|
|
2253
|
-
|
|
2254
|
-
return api.listProfiles(tool.id).find((profile) => normalizeDir(profile.dir) === normalized) ?? null;
|
|
2255
|
-
} catch {
|
|
2256
|
-
return null;
|
|
2257
|
-
}
|
|
2319
|
+
return (await store.listProfiles(tool.id)).find((profile) => normalizeDir(profile.dir) === normalized) ?? null;
|
|
2258
2320
|
}
|
|
2259
2321
|
async function resolveAccountForAgent(agent, env = process.env) {
|
|
2260
2322
|
const override = envOverride(agent, env);
|
|
2261
2323
|
if (override)
|
|
2262
2324
|
return override;
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
api = await import("@hasna/accounts");
|
|
2266
|
-
} catch {
|
|
2267
|
-
return null;
|
|
2268
|
-
}
|
|
2269
|
-
const toolIds = knownToolIds(api);
|
|
2325
|
+
const store = resolveStore(env);
|
|
2326
|
+
const tools = new Map((await store.listTools()).map((tool) => [tool.id, tool]));
|
|
2270
2327
|
for (const toolId of AGENT_ACCOUNT_TOOLS[agent]) {
|
|
2271
|
-
|
|
2328
|
+
const tool = tools.get(toolId);
|
|
2329
|
+
if (!tool)
|
|
2272
2330
|
continue;
|
|
2273
|
-
|
|
2274
|
-
try {
|
|
2275
|
-
tool = api.getTool(toolId);
|
|
2276
|
-
} catch {
|
|
2277
|
-
continue;
|
|
2278
|
-
}
|
|
2279
|
-
const envProfile = profileForEnvDir(api, tool, env);
|
|
2331
|
+
const envProfile = await profileForEnvDir(store, tool, env);
|
|
2280
2332
|
if (envProfile)
|
|
2281
2333
|
return fromProfile(envProfile, "env");
|
|
2282
|
-
|
|
2283
|
-
|
|
2334
|
+
const appliedName = appliedProfileName(toolId);
|
|
2335
|
+
if (appliedName) {
|
|
2336
|
+
const applied = await store.findProfile(appliedName, toolId);
|
|
2284
2337
|
if (applied)
|
|
2285
2338
|
return fromProfile(applied, "applied");
|
|
2286
|
-
}
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
return fromProfile(current, "current");
|
|
2291
|
-
} catch {}
|
|
2339
|
+
}
|
|
2340
|
+
const current = await store.currentProfile(toolId);
|
|
2341
|
+
if (current)
|
|
2342
|
+
return fromProfile(current, "current");
|
|
2292
2343
|
}
|
|
2293
2344
|
return null;
|
|
2294
2345
|
}
|
|
@@ -5150,7 +5201,7 @@ class LocalStore {
|
|
|
5150
5201
|
return query.since ? queryAgentBreakdownSince(this.db(), query.since) : queryAgentBreakdown(this.db(), query.period ?? "all", query.machine);
|
|
5151
5202
|
}
|
|
5152
5203
|
async projectBreakdown(query = {}) {
|
|
5153
|
-
return query.since ? queryProjectBreakdownSince(this.db(), query.since) : queryProjectBreakdown(this.db(), query.period ?? "all", query.machine);
|
|
5204
|
+
return query.since ? queryProjectBreakdownSince(this.db(), query.since, query.machine) : queryProjectBreakdown(this.db(), query.period ?? "all", query.machine);
|
|
5154
5205
|
}
|
|
5155
5206
|
async accountBreakdown(query = {}) {
|
|
5156
5207
|
return query.since ? queryAccountBreakdownSince(this.db(), query.since) : queryAccountBreakdown(this.db(), query.period ?? "all", query.machine);
|
|
@@ -5346,7 +5397,7 @@ class ApiStore {
|
|
|
5346
5397
|
return cloudListItems(this.cloud, "breakdown", q({ by: "agent", period: query.period, since: query.since }));
|
|
5347
5398
|
}
|
|
5348
5399
|
async projectBreakdown(query = {}) {
|
|
5349
|
-
return cloudListItems(this.cloud, "breakdown", q({ by: "project", period: query.period, since: query.since }));
|
|
5400
|
+
return cloudListItems(this.cloud, "breakdown", q({ by: "project", period: query.period, since: query.since, machine: query.machine }));
|
|
5350
5401
|
}
|
|
5351
5402
|
async accountBreakdown(query = {}) {
|
|
5352
5403
|
return cloudListItems(this.cloud, "breakdown", q({ by: "account", period: query.period, since: query.since }));
|
|
@@ -6104,7 +6155,6 @@ current machine: ${getMachineId()}`);
|
|
|
6104
6155
|
return textError(String(error));
|
|
6105
6156
|
}
|
|
6106
6157
|
});
|
|
6107
|
-
registerCloudTools(server, MCP_NAME);
|
|
6108
6158
|
return server;
|
|
6109
6159
|
}
|
|
6110
6160
|
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,QAAQ,YAAY,CAAA;AACjC,eAAO,MAAM,qBAAqB,OAAO,CAAA;AAEzC,wBAAgB,WAAW,IAAI,GAAG,CAm0BjC"}
|
package/dist/openapi.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAikD/C,CAAA;AACD,eAAe,WAAW,CAAA"}
|
package/dist/otel/index.js
CHANGED
|
@@ -16,6 +16,62 @@ var __export = (target, all) => {
|
|
|
16
16
|
};
|
|
17
17
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
18
18
|
|
|
19
|
+
// src/db/sqlite-adapter.ts
|
|
20
|
+
import { Database } from "bun:sqlite";
|
|
21
|
+
|
|
22
|
+
class SqliteAdapter {
|
|
23
|
+
db;
|
|
24
|
+
constructor(path) {
|
|
25
|
+
this.db = new Database(path, { create: true });
|
|
26
|
+
this.db.exec("PRAGMA journal_mode=WAL");
|
|
27
|
+
this.db.exec("PRAGMA foreign_keys=ON");
|
|
28
|
+
}
|
|
29
|
+
run(sql, ...params) {
|
|
30
|
+
const result = this.db.prepare(sql).run(...params);
|
|
31
|
+
return { changes: result.changes, lastInsertRowid: result.lastInsertRowid };
|
|
32
|
+
}
|
|
33
|
+
get(sql, ...params) {
|
|
34
|
+
return this.db.prepare(sql).get(...params);
|
|
35
|
+
}
|
|
36
|
+
all(sql, ...params) {
|
|
37
|
+
return this.db.prepare(sql).all(...params);
|
|
38
|
+
}
|
|
39
|
+
exec(sql) {
|
|
40
|
+
this.db.exec(sql);
|
|
41
|
+
}
|
|
42
|
+
query(sql) {
|
|
43
|
+
return this.db.query(sql);
|
|
44
|
+
}
|
|
45
|
+
prepare(sql) {
|
|
46
|
+
const stmt = this.db.prepare(sql);
|
|
47
|
+
return {
|
|
48
|
+
run(...params) {
|
|
49
|
+
const r = stmt.run(...params);
|
|
50
|
+
return { changes: r.changes, lastInsertRowid: r.lastInsertRowid };
|
|
51
|
+
},
|
|
52
|
+
get(...params) {
|
|
53
|
+
return stmt.get(...params);
|
|
54
|
+
},
|
|
55
|
+
all(...params) {
|
|
56
|
+
return stmt.all(...params);
|
|
57
|
+
},
|
|
58
|
+
finalize() {
|
|
59
|
+
stmt.finalize();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
close() {
|
|
64
|
+
this.db.close();
|
|
65
|
+
}
|
|
66
|
+
transaction(fn) {
|
|
67
|
+
return this.db.transaction(fn)();
|
|
68
|
+
}
|
|
69
|
+
get raw() {
|
|
70
|
+
return this.db;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
var init_sqlite_adapter = () => {};
|
|
74
|
+
|
|
19
75
|
// src/lib/pricing.ts
|
|
20
76
|
var exports_pricing = {};
|
|
21
77
|
__export(exports_pricing, {
|
|
@@ -534,7 +590,6 @@ var init_pricing = __esm(() => {
|
|
|
534
590
|
});
|
|
535
591
|
|
|
536
592
|
// src/db/database.ts
|
|
537
|
-
import { SqliteAdapter as Database } from "@hasna/cloud";
|
|
538
593
|
import { execFileSync } from "child_process";
|
|
539
594
|
import { copyFileSync, existsSync, mkdirSync, readdirSync, statSync } from "fs";
|
|
540
595
|
import { hostname, platform } from "os";
|
|
@@ -627,7 +682,7 @@ function openDatabase(dbPath, skipSeed = false) {
|
|
|
627
682
|
mkdirSync(dir, { recursive: true });
|
|
628
683
|
}
|
|
629
684
|
const db = withSqliteBusyRetry(() => {
|
|
630
|
-
const opened = new
|
|
685
|
+
const opened = new SqliteAdapter(path);
|
|
631
686
|
try {
|
|
632
687
|
opened.exec("PRAGMA busy_timeout = 10000");
|
|
633
688
|
opened.exec("PRAGMA journal_mode = WAL");
|
|
@@ -984,7 +1039,9 @@ function seedModelPricing(db, defaults) {
|
|
|
984
1039
|
});
|
|
985
1040
|
}
|
|
986
1041
|
}
|
|
987
|
-
var init_database = () => {
|
|
1042
|
+
var init_database = __esm(() => {
|
|
1043
|
+
init_sqlite_adapter();
|
|
1044
|
+
});
|
|
988
1045
|
|
|
989
1046
|
// src/otel/index.ts
|
|
990
1047
|
init_database();
|
|
@@ -1356,10 +1413,18 @@ function resolvePort(argv) {
|
|
|
1356
1413
|
}
|
|
1357
1414
|
var args = process.argv.slice(2);
|
|
1358
1415
|
if (args.includes("--help") || args.includes("-h")) {
|
|
1359
|
-
console.log(`Usage: economy-otel [
|
|
1416
|
+
console.log(`Usage: economy-otel [options]
|
|
1360
1417
|
|
|
1361
1418
|
OTLP/HTTP metrics sidecar \u2014 ingests *.cost.* / *.token.* metrics into economy.db
|
|
1362
1419
|
|
|
1420
|
+
Options:
|
|
1421
|
+
-p, --port <port> Port to bind (default: ECONOMY_OTEL_PORT or 4318)
|
|
1422
|
+
-h, --help display help for command
|
|
1423
|
+
|
|
1424
|
+
Environment:
|
|
1425
|
+
ECONOMY_OTEL_PORT Override the default port (4318)
|
|
1426
|
+
ECONOMY_OTEL_BIND Bind address (default: 127.0.0.1)
|
|
1427
|
+
|
|
1363
1428
|
Endpoints:
|
|
1364
1429
|
POST /v1/metrics OTLP JSON metrics
|
|
1365
1430
|
POST /ingest Simplified single-event JSON
|