@hasna/economy 0.5.0 → 0.5.2
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 +13 -0
- package/dist/chunks/{index-kgy9b6bf.js → index-9d2aky06.js} +1 -1
- package/dist/chunks/{index-axh32d30.js → index-dj3tctqh.js} +11 -2
- package/dist/chunks/{index-kn5572kd.js → index-kzwqw3ve.js} +1 -1
- package/dist/chunks/{index-emvs5ph2.js → index-npsjjv96.js} +1 -1
- package/dist/chunks/{serve-0k69e4h9.js → serve-p2yarhm8.js} +28 -3
- package/dist/chunks/{tui-7f8f951w.js → tui-x64hjfrh.js} +3 -3
- package/dist/chunks/{watch-mm1j39vy.js → watch-bxstjpbx.js} +3 -3
- package/dist/cli/index.js +10 -10
- package/dist/db/legacy-large-schema.d.ts +6 -0
- package/dist/db/legacy-large-schema.d.ts.map +1 -0
- package/dist/db/pg-legacy-schema.d.ts +12 -0
- package/dist/db/pg-legacy-schema.d.ts.map +1 -0
- package/dist/db/pg-migrations.d.ts.map +1 -1
- package/dist/index.js +11 -2
- package/dist/mcp/index.js +11 -2
- package/dist/otel/index.js +11 -2
- package/dist/server/index.js +358 -51
- package/dist/server/legacy-limits.d.ts +51 -0
- package/dist/server/legacy-limits.d.ts.map +1 -0
- package/dist/server/legacy-operations.d.ts +2 -1
- package/dist/server/legacy-operations.d.ts.map +1 -1
- package/dist/server/legacy-plan.d.ts +2 -1
- package/dist/server/legacy-plan.d.ts.map +1 -1
- package/dist/server/legacy-preservation.d.ts +2 -1
- package/dist/server/legacy-preservation.d.ts.map +1 -1
- package/dist/server/service-worker.js +11 -2
- package/docs/historical-data-reconciliation.md +38 -0
- package/docs/postgresql-legacy-schema-repair.md +30 -0
- package/package.json +11 -2
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Artifact schemas select a closed resource envelope. A larger envelope is
|
|
2
|
+
* explicit and restricted to one complete session; ordinary artifacts keep
|
|
3
|
+
* their original limits. These profiles confer no reconciliation authority. */
|
|
4
|
+
export declare const LEGACY_STANDARD: {
|
|
5
|
+
readonly selection: "economy.legacy-selection.v1";
|
|
6
|
+
readonly plan: "economy.legacy-plan.v1";
|
|
7
|
+
readonly capsule: "economy.legacy-preservation.v1";
|
|
8
|
+
readonly receipt: "economy.legacy-operation-receipt.v1";
|
|
9
|
+
readonly items: 100;
|
|
10
|
+
readonly sessions: 100;
|
|
11
|
+
readonly members: 10000;
|
|
12
|
+
readonly inputBytes: number;
|
|
13
|
+
readonly originalBytes: number;
|
|
14
|
+
readonly capsuleBytes: number;
|
|
15
|
+
};
|
|
16
|
+
export declare const LEGACY_SINGLE_SESSION: {
|
|
17
|
+
readonly selection: "economy.legacy-session-selection.v1";
|
|
18
|
+
readonly plan: "economy.legacy-session-plan.v1";
|
|
19
|
+
readonly capsule: "economy.legacy-session-preservation.v1";
|
|
20
|
+
readonly receipt: "economy.legacy-session-operation-receipt.v1";
|
|
21
|
+
readonly items: 50000;
|
|
22
|
+
readonly sessions: 1;
|
|
23
|
+
readonly members: 50000;
|
|
24
|
+
readonly inputBytes: number;
|
|
25
|
+
readonly originalBytes: number;
|
|
26
|
+
readonly capsuleBytes: number;
|
|
27
|
+
};
|
|
28
|
+
export declare function legacyMode(kind: 'selection' | 'plan' | 'capsule' | 'receipt', schema: unknown): {
|
|
29
|
+
readonly selection: "economy.legacy-selection.v1";
|
|
30
|
+
readonly plan: "economy.legacy-plan.v1";
|
|
31
|
+
readonly capsule: "economy.legacy-preservation.v1";
|
|
32
|
+
readonly receipt: "economy.legacy-operation-receipt.v1";
|
|
33
|
+
readonly items: 100;
|
|
34
|
+
readonly sessions: 100;
|
|
35
|
+
readonly members: 10000;
|
|
36
|
+
readonly inputBytes: number;
|
|
37
|
+
readonly originalBytes: number;
|
|
38
|
+
readonly capsuleBytes: number;
|
|
39
|
+
} | {
|
|
40
|
+
readonly selection: "economy.legacy-session-selection.v1";
|
|
41
|
+
readonly plan: "economy.legacy-session-plan.v1";
|
|
42
|
+
readonly capsule: "economy.legacy-session-preservation.v1";
|
|
43
|
+
readonly receipt: "economy.legacy-session-operation-receipt.v1";
|
|
44
|
+
readonly items: 50000;
|
|
45
|
+
readonly sessions: 1;
|
|
46
|
+
readonly members: 50000;
|
|
47
|
+
readonly inputBytes: number;
|
|
48
|
+
readonly originalBytes: number;
|
|
49
|
+
readonly capsuleBytes: number;
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=legacy-limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-limits.d.ts","sourceRoot":"","sources":["../../src/server/legacy-limits.ts"],"names":[],"mappings":"AAAA;;+EAE+E;AAC/E,eAAO,MAAM,eAAe;;;;;;;;;;;CAKlB,CAAA;AAEV,eAAO,MAAM,qBAAqB;;;;;;;;;;;CAKxB,CAAA;AAEV,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;EAI7F"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type pg from 'pg';
|
|
2
|
+
import { LEGACY_STANDARD, LEGACY_SINGLE_SESSION } from './legacy-limits.js';
|
|
2
3
|
import type { LegacyReader } from './legacy-plan.js';
|
|
3
4
|
type Action = 'apply' | 'rollback';
|
|
4
5
|
export interface LegacyIntent {
|
|
@@ -19,7 +20,7 @@ export declare function parseLegacyIntent(action: Action, value: unknown): Legac
|
|
|
19
20
|
* complements exact database/relation locators; it is not ownership approval. */
|
|
20
21
|
export declare function legacyTargetDigest(target: string | pg.PoolConfig): string;
|
|
21
22
|
interface Receipt {
|
|
22
|
-
schema:
|
|
23
|
+
schema: typeof LEGACY_STANDARD.receipt | typeof LEGACY_SINGLE_SESSION.receipt;
|
|
23
24
|
action: Action;
|
|
24
25
|
operation_key: string;
|
|
25
26
|
apply_key: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy-operations.d.ts","sourceRoot":"","sources":["../../src/server/legacy-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"legacy-operations.d.ts","sourceRoot":"","sources":["../../src/server/legacy-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAc,MAAM,oBAAoB,CAAA;AAGvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAQpD,KAAK,MAAM,GAAC,OAAO,GAAC,UAAU,CAAA;AAC9B,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAC,MAAM,CAAC;IAAC,aAAa,EAAC,MAAM,CAAC;IAAC,aAAa,EAAC,MAAM,CAAC;IAAC,WAAW,EAAC,MAAM,CAAC;IAAC,cAAc,EAAC,MAAM,CAAA;IACpG,SAAS,EAAC,MAAM,CAAC;IAAC,aAAa,EAAC,MAAM,CAAC;IAAC,SAAS,CAAC,EAAC,MAAM,CAAA;CAC1D;AACD,4EAA4E;AAC5E,qBAAa,yBAA0B,SAAQ,KAAK;CAAG;AACvD,wBAAgB,iBAAiB,CAAC,MAAM,EAAC,MAAM,EAAC,KAAK,EAAC,OAAO,GAAE,YAAY,CAY1E;AACD;iFACiF;AACjF,wBAAgB,kBAAkB,CAAC,MAAM,EAAC,MAAM,GAAC,EAAE,CAAC,UAAU,GAAE,MAAM,CAOrE;AAiED,UAAU,OAAO;IACf,MAAM,EAAC,OAAO,eAAe,CAAC,OAAO,GAAC,OAAO,qBAAqB,CAAC,OAAO,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,aAAa,EAAC,MAAM,CAAC;IAAA,SAAS,EAAC,MAAM,CAAA;IAC9H,WAAW,EAAC,MAAM,CAAC;IAAA,cAAc,EAAC,MAAM,CAAC;IAAA,eAAe,EAAC,MAAM,CAAC;IAAA,kBAAkB,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAA;IACzG,mBAAmB,EAAC,CAAC,CAAC;IAAA,UAAU,EAAC,MAAM,CAAA;CACxC;AAoCD,wBAAsB,yBAAyB,CAAC,MAAM,EAAC,YAAY,EAAC,KAAK,EAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAC,MAAM,EAAC,MAAM;;;;;GAmChH;AACD,wBAAsB,4BAA4B,CAAC,MAAM,EAAC,YAAY,EAAC,KAAK,EAAC,OAAO,EAAC,MAAM,EAAC,MAAM;;;;;GAuBjG;AACD,4FAA4F;AAC5F,wBAAsB,mBAAmB,CAAC,MAAM,EAAC,YAAY,EAAC,SAAS,EAAC,MAAM;;;;;;;;;GAQ7E;AACD,wBAAgB,2BAA2B,CAAC,OAAO,EAAC,MAAM,EAAC,IAAI,EAAC,MAAM,EAAE,GAAE;IAAC,KAAK,CAAC,EAAC,MAAM,CAAC;IAAA,OAAO,CAAC,EAAC,MAAM,CAAC;IAAA,SAAS,CAAC,EAAC,MAAM,CAAA;CAAC,CAQ1H;AACD,wBAAsB,kBAAkB,CAAC,OAAO,EAAC,MAAM,EAAC,OAAO,EAAC,UAAU,CAAC,OAAO,2BAA2B,CAAC,iBAgC7G"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type LegacyFamily } from './legacy-inventory.js';
|
|
2
|
+
import { LEGACY_STANDARD, LEGACY_SINGLE_SESSION } from './legacy-limits.js';
|
|
2
3
|
export interface LegacyReader {
|
|
3
4
|
query(sql: string, values?: unknown[]): Promise<{
|
|
4
5
|
rows: Record<string, any>[];
|
|
@@ -30,7 +31,7 @@ export interface LegacyPlan {
|
|
|
30
31
|
}
|
|
31
32
|
type Disposition = 'quarantine_aggregate' | 'mark_billing_unknown';
|
|
32
33
|
export interface LegacySelection {
|
|
33
|
-
schema:
|
|
34
|
+
schema: typeof LEGACY_STANDARD.selection | typeof LEGACY_SINGLE_SESSION.selection;
|
|
34
35
|
items: Array<{
|
|
35
36
|
id: string;
|
|
36
37
|
family: LegacyFamily;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy-plan.d.ts","sourceRoot":"","sources":["../../src/server/legacy-plan.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"legacy-plan.d.ts","sourceRoot":"","sources":["../../src/server/legacy-plan.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAC7F,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAc,MAAM,oBAAoB,CAAA;AAEvF,MAAM,WAAW,YAAY;IAAG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE;AAClH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;IAChF,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;KAAE,CAAA;IACpG,KAAK,EAAE,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACvE,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACvG,mBAAmB,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CACxE;AACD,KAAK,WAAW,GAAG,sBAAsB,GAAG,sBAAsB,CAAA;AAClE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,eAAe,CAAC,SAAS,GAAG,OAAO,qBAAqB,CAAC,SAAS,CAAA;IACjF,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,YAAY,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5I;AAsBD,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAmBpE;AAED,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAqBrE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAG7D;AAED;mFACmF;AACnF,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAEjG;AAED,+EAA+E;AAC/E,wBAAsB,sBAAsB,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAClF,IAAI,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CA0EpD;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAU7E"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type LegacyPlan, type LegacyReader } from './legacy-plan.js';
|
|
2
|
+
import { LEGACY_STANDARD, LEGACY_SINGLE_SESSION } from './legacy-limits.js';
|
|
2
3
|
/** Validate the complete emitted proposal before taking a connection or opening output. */
|
|
3
4
|
export declare function parseLegacyPlan(value: unknown): LegacyPlan;
|
|
4
5
|
export declare function assertLegacyPlanCurrent(expected: LegacyPlan, current: LegacyPlan): void;
|
|
@@ -7,7 +8,7 @@ interface Original {
|
|
|
7
8
|
original: string;
|
|
8
9
|
}
|
|
9
10
|
export interface LegacyCapsule {
|
|
10
|
-
schema:
|
|
11
|
+
schema: typeof LEGACY_STANDARD.capsule | typeof LEGACY_SINGLE_SESSION.capsule;
|
|
11
12
|
plan: LegacyPlan;
|
|
12
13
|
captured_at: string;
|
|
13
14
|
requests: Original[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy-preservation.d.ts","sourceRoot":"","sources":["../../src/server/legacy-preservation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgD,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"legacy-preservation.d.ts","sourceRoot":"","sources":["../../src/server/legacy-preservation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgD,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACnH,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAc,MAAM,oBAAoB,CAAA;AAevF,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CA8C1D;AAOD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAEvF;AAED,UAAU,QAAQ;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AACnD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,eAAe,CAAC,OAAO,GAAG,OAAO,qBAAqB,CAAC,OAAO,CAAA;IAC7E,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,QAAQ,EAAE,CAAA;IACpB,QAAQ,EAAE,QAAQ,EAAE,CAAA;IACpB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CA4ChE;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAkB1G;AAmBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAU,GAAG,OAAO,CAS5E;AAED;sFACsF;AACtF,wBAAgB,kBAAkB,CAAC,IAAI,EAAC,MAAM,EAAC,KAAK,EAAC,OAAO;;;;;;;;;;;EAwB3D;AAED;;kFAEkF;AAClF,wBAAsB,qBAAqB,CAAC,MAAM,EAAC,YAAY,EAAC,KAAK,EAAC,OAAO,EAAC,KAAK,GAAC,aAAa,GAAC,WAAyB;;;;;;;;;;GAwD1H;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAC,MAAM,EAAC,IAAI,EAAC,MAAM,EAAE,GAAG;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,CAAC,EAAC,MAAM,CAAA;CAAC,CAM1G;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAC,MAAM,EAAC,OAAO,EAAC;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,CAAC,EAAC,MAAM,CAAA;CAAC,iBAgB/F"}
|
|
@@ -7266,7 +7266,7 @@ import { randomUUID } from "crypto";
|
|
|
7266
7266
|
// package.json
|
|
7267
7267
|
var package_default = {
|
|
7268
7268
|
name: "@hasna/economy",
|
|
7269
|
-
version: "0.5.
|
|
7269
|
+
version: "0.5.2",
|
|
7270
7270
|
description: "AI coding cost tracker \u2014 CLI + MCP server + REST API for Claude Code, Codex, OpenCode, Cursor, Pi, and Hermes, with legacy Gemini CLI session and Gemini API billing ingestion",
|
|
7271
7271
|
repository: {
|
|
7272
7272
|
type: "git",
|
|
@@ -7361,7 +7361,16 @@ var package_default = {
|
|
|
7361
7361
|
},
|
|
7362
7362
|
trustedDependencies: [
|
|
7363
7363
|
"@hasna/projects"
|
|
7364
|
-
]
|
|
7364
|
+
],
|
|
7365
|
+
overrides: {
|
|
7366
|
+
"fast-uri": "3.1.8",
|
|
7367
|
+
hono: "4.13.7",
|
|
7368
|
+
"ip-address": "10.7.1",
|
|
7369
|
+
nanoid: "5.1.16",
|
|
7370
|
+
"path-to-regexp": "8.4.0",
|
|
7371
|
+
undici: "6.28.1",
|
|
7372
|
+
"express-rate-limit": "8.7.0"
|
|
7373
|
+
}
|
|
7365
7374
|
};
|
|
7366
7375
|
|
|
7367
7376
|
// src/lib/package-metadata.ts
|
|
@@ -122,6 +122,44 @@ database backup, production ownership attestation or disaster-recovery exercise.
|
|
|
122
122
|
Neither command authorizes quarantine or performs application or rollback of a
|
|
123
123
|
reconciliation.
|
|
124
124
|
|
|
125
|
+
## One large session
|
|
126
|
+
|
|
127
|
+
When one complete session exceeds the ordinary envelope, select it explicitly
|
|
128
|
+
with `schema: "economy.legacy-session-selection.v1"` in the same selection file.
|
|
129
|
+
Use the same maintained `legacy-plan`, `legacy-preserve` and `legacy-rehearse`
|
|
130
|
+
commands. Every target still needs its exact original digest and reviewed
|
|
131
|
+
disposition, reason and evidence reference. The planner requires exactly one
|
|
132
|
+
session, preserves its entire request population including unselected rows, and
|
|
133
|
+
emits `economy.legacy-session-plan.v1`. Preservation emits
|
|
134
|
+
`economy.legacy-session-preservation.v1`; neither schema can be substituted for
|
|
135
|
+
its ordinary counterpart.
|
|
136
|
+
|
|
137
|
+
This mode accepts at most 50,000 selected requests, 50,000 complete-session
|
|
138
|
+
members, a 32 MiB selection file, 64 MiB of original row text, and a 128 MiB
|
|
139
|
+
preservation file. Each bound refuses the operation without truncation. Ordinary
|
|
140
|
+
artifacts retain their 100-target, 10,000-member, 256 KiB selection, 16 MiB
|
|
141
|
+
original and 32 MiB preservation bounds. A population above the explicit
|
|
142
|
+
single-session bounds still needs another reviewed procedure; the tool never
|
|
143
|
+
silently increases them.
|
|
144
|
+
|
|
145
|
+
Apply uses one set-based insertion for the selected dispositions and commits
|
|
146
|
+
one immutable capsule and receipt for the whole operation. Its receipt schema
|
|
147
|
+
is `economy.legacy-session-operation-receipt.v1`. Use the same exact-target
|
|
148
|
+
intent, observation, explicit retry and rollback commands described below.
|
|
149
|
+
Session overlap remains prohibited: select all reviewed targets for that
|
|
150
|
+
session together, instead of repeatedly preserving the same whole session for
|
|
151
|
+
small target batches. File and row preservation, typed restoration, complete
|
|
152
|
+
membership preconditions, ingestion exclusion and rollback checks all apply.
|
|
153
|
+
Use a version supporting these explicit artifact schemas for every stage;
|
|
154
|
+
older versions refuse them. These limits do not establish source provenance or
|
|
155
|
+
authorize changing a production report.
|
|
156
|
+
|
|
157
|
+
The appended PostgreSQL migration checks conflicts once for the inserted set,
|
|
158
|
+
including conflicts between operations in that same set. This avoids repeated
|
|
159
|
+
scans of a growing operation when existing history has small or stale planner
|
|
160
|
+
statistics. The 15-second statement timeout and session/request conflict rules
|
|
161
|
+
remain in force.
|
|
162
|
+
|
|
125
163
|
## Apply, observe and roll back
|
|
126
164
|
|
|
127
165
|
Deploy the reviewed runtime integration and apply its appended PostgreSQL schema
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Legacy PostgreSQL cost-center schema repair
|
|
2
|
+
|
|
3
|
+
Some existing databases record migrations 0–84 while missing `cost_centers`
|
|
4
|
+
and the nullable `cost_center_id` columns on `requests`, `sessions` and
|
|
5
|
+
`budgets`. Migration 102 requires those columns.
|
|
6
|
+
|
|
7
|
+
The explicit `economy-serve migrate` command checks this known layout before
|
|
8
|
+
running the numbered migrations. It adds the missing table, columns and four
|
|
9
|
+
indexes using their unchanged original definitions. It does not infer cost
|
|
10
|
+
center assignments, change existing row values or rewrite migration history.
|
|
11
|
+
Fresh and already complete databases need no compatibility repair.
|
|
12
|
+
|
|
13
|
+
The repair serializes with the existing migration runner. Its DDL and one
|
|
14
|
+
`legacy-cost-centers-v1` receipt commit in one transaction. The receipt records
|
|
15
|
+
the exact repair SQL hash. An existing receipt ledger must have the canonical
|
|
16
|
+
permanent shape, with no triggers, rewrite rules or row security. A completed
|
|
17
|
+
receipt with changed schema or hash is refused. Incompatible existing tables,
|
|
18
|
+
columns or indexes are also refused without replacing them.
|
|
19
|
+
|
|
20
|
+
Preserve and restore-test the database before using the normal deployment
|
|
21
|
+
migration operation. Server startup does not run this repair. If a connection
|
|
22
|
+
is lost during commit, keep the outcome uncertain and inspect the database
|
|
23
|
+
before an explicit retry; the command never retries automatically. A subsequent
|
|
24
|
+
invocation recognizes a committed matching receipt as `already_applied`.
|
|
25
|
+
Numbered migrations retain their separate atomic completion markers.
|
|
26
|
+
|
|
27
|
+
The migration JSON includes `repair.id`, `repair.status` and `repair.added`.
|
|
28
|
+
Possible statuses are `not_needed`, `applied` and `already_applied`. Retain that
|
|
29
|
+
result with the deployment and preservation records. Rolling application code
|
|
30
|
+
back does not remove the added schema or repair receipt.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/economy",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "AI coding cost tracker — CLI + MCP server + REST API for Claude Code, Codex, OpenCode, Cursor, Pi, and Hermes, with legacy Gemini CLI session and Gemini API billing ingestion",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -95,5 +95,14 @@
|
|
|
95
95
|
},
|
|
96
96
|
"trustedDependencies": [
|
|
97
97
|
"@hasna/projects"
|
|
98
|
-
]
|
|
98
|
+
],
|
|
99
|
+
"overrides": {
|
|
100
|
+
"fast-uri": "3.1.8",
|
|
101
|
+
"hono": "4.13.7",
|
|
102
|
+
"ip-address": "10.7.1",
|
|
103
|
+
"nanoid": "5.1.16",
|
|
104
|
+
"path-to-regexp": "8.4.0",
|
|
105
|
+
"undici": "6.28.1",
|
|
106
|
+
"express-rate-limit": "8.7.0"
|
|
107
|
+
}
|
|
99
108
|
}
|