@hasna/economy 0.2.26 → 0.2.27
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/dist/cli/index.js +355 -24
- package/dist/db/database.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +361 -31
- package/dist/lib/peer-sync.d.ts +21 -0
- package/dist/lib/peer-sync.d.ts.map +1 -0
- package/dist/mcp/index.js +49 -13
- package/dist/server/index.js +49 -13
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1087,9 +1087,7 @@ function queryAgentBreakdown(db, period = "all") {
|
|
|
1087
1087
|
}
|
|
1088
1088
|
return [...groups.values()].sort((a, b) => b.api_equivalent_usd - a.api_equivalent_usd);
|
|
1089
1089
|
}
|
|
1090
|
-
function
|
|
1091
|
-
if (projectName && projectName.trim() !== "")
|
|
1092
|
-
return projectName;
|
|
1090
|
+
function pathProjectLabel(projectPath) {
|
|
1093
1091
|
if (!projectPath)
|
|
1094
1092
|
return "";
|
|
1095
1093
|
const segments = projectPath.split("/").filter(Boolean);
|
|
@@ -1098,12 +1096,45 @@ function labelForPath(projectPath, projectName) {
|
|
|
1098
1096
|
if (projectPrefix.test(seg))
|
|
1099
1097
|
return seg;
|
|
1100
1098
|
}
|
|
1101
|
-
const generic = new Set([
|
|
1099
|
+
const generic = new Set([
|
|
1100
|
+
"web",
|
|
1101
|
+
"app",
|
|
1102
|
+
"apps",
|
|
1103
|
+
"packages",
|
|
1104
|
+
"src",
|
|
1105
|
+
"lib",
|
|
1106
|
+
"server",
|
|
1107
|
+
"client",
|
|
1108
|
+
"api",
|
|
1109
|
+
"frontend",
|
|
1110
|
+
"backend",
|
|
1111
|
+
"home",
|
|
1112
|
+
"users",
|
|
1113
|
+
"workspace",
|
|
1114
|
+
"workspaces",
|
|
1115
|
+
"hasna"
|
|
1116
|
+
]);
|
|
1102
1117
|
for (let i = segments.length - 1;i >= 0; i--) {
|
|
1103
1118
|
if (!generic.has(segments[i].toLowerCase()))
|
|
1104
1119
|
return segments[i];
|
|
1105
1120
|
}
|
|
1106
|
-
return
|
|
1121
|
+
return null;
|
|
1122
|
+
}
|
|
1123
|
+
function isRepoLikeLabel(label) {
|
|
1124
|
+
return /^(open|skill|hook|service|connect|platform|agent|tool|iapp|project|scaffold|capp)-/.test(label) || label.includes("-");
|
|
1125
|
+
}
|
|
1126
|
+
function labelForPath(projectPath, projectName) {
|
|
1127
|
+
const pathLabel = pathProjectLabel(projectPath);
|
|
1128
|
+
if (pathLabel && (!projectName || projectName.trim() === "" || isRepoLikeLabel(pathLabel)))
|
|
1129
|
+
return pathLabel;
|
|
1130
|
+
if (projectName && projectName.trim() !== "")
|
|
1131
|
+
return projectName;
|
|
1132
|
+
if (pathLabel)
|
|
1133
|
+
return pathLabel;
|
|
1134
|
+
return projectPath;
|
|
1135
|
+
}
|
|
1136
|
+
function groupKeyForPath(projectPath, projectName) {
|
|
1137
|
+
return labelForPath(projectPath, projectName).trim().toLowerCase();
|
|
1107
1138
|
}
|
|
1108
1139
|
function queryProjectBreakdown(db, period = "all") {
|
|
1109
1140
|
const requestWhere = requestPeriodWhere(period);
|
|
@@ -1118,14 +1149,15 @@ function queryProjectBreakdown(db, period = "all") {
|
|
|
1118
1149
|
const label = labelForPath(s.project_path, s.project_name);
|
|
1119
1150
|
if (!label)
|
|
1120
1151
|
continue;
|
|
1121
|
-
const
|
|
1152
|
+
const key = groupKeyForPath(s.project_path, s.project_name);
|
|
1153
|
+
const g = groups.get(key) ?? { label, sessionIds: [], samplePath: s.project_path };
|
|
1122
1154
|
g.sessionIds.push(s.id);
|
|
1123
1155
|
if (!g.samplePath)
|
|
1124
1156
|
g.samplePath = s.project_path;
|
|
1125
|
-
groups.set(
|
|
1157
|
+
groups.set(key, g);
|
|
1126
1158
|
}
|
|
1127
1159
|
const result = [];
|
|
1128
|
-
for (const
|
|
1160
|
+
for (const g of groups.values()) {
|
|
1129
1161
|
const placeholders = g.sessionIds.map(() => "?").join(",");
|
|
1130
1162
|
const reqStats = placeholders.length ? db.prepare(`
|
|
1131
1163
|
SELECT
|
|
@@ -1156,7 +1188,7 @@ function queryProjectBreakdown(db, period = "all") {
|
|
|
1156
1188
|
const lastActive = [reqStats.last_active, sessionOnlyStats.last_active].filter(Boolean).sort().at(-1) ?? "";
|
|
1157
1189
|
result.push({
|
|
1158
1190
|
project_path: g.samplePath,
|
|
1159
|
-
project_name: label,
|
|
1191
|
+
project_name: g.label,
|
|
1160
1192
|
sessions: totalSessions,
|
|
1161
1193
|
requests: reqStats.requests + sessionOnlyStats.requests,
|
|
1162
1194
|
total_tokens: reqStats.total_tokens + sessionOnlyStats.total_tokens,
|
|
@@ -1488,17 +1520,21 @@ function listMachineRegistry(db) {
|
|
|
1488
1520
|
}
|
|
1489
1521
|
function dedupeRequests(db) {
|
|
1490
1522
|
const dupes = db.prepare(`
|
|
1491
|
-
SELECT source_request_id, agent, MIN(id) as keep_id, COUNT(*) as cnt
|
|
1523
|
+
SELECT source_request_id, agent, COALESCE(machine_id, '') as machine_id, MIN(id) as keep_id, COUNT(*) as cnt
|
|
1492
1524
|
FROM requests
|
|
1493
1525
|
WHERE source_request_id != '' AND source_request_id IS NOT NULL
|
|
1494
|
-
GROUP BY source_request_id, agent
|
|
1526
|
+
GROUP BY source_request_id, agent, COALESCE(machine_id, '')
|
|
1495
1527
|
HAVING cnt > 1
|
|
1496
1528
|
`).all();
|
|
1497
1529
|
let removed = 0;
|
|
1498
1530
|
for (const row of dupes) {
|
|
1499
1531
|
const result = db.prepare(`
|
|
1500
|
-
DELETE FROM requests
|
|
1501
|
-
|
|
1532
|
+
DELETE FROM requests
|
|
1533
|
+
WHERE source_request_id = ?
|
|
1534
|
+
AND agent = ?
|
|
1535
|
+
AND COALESCE(machine_id, '') = ?
|
|
1536
|
+
AND id != ?
|
|
1537
|
+
`).run(row.source_request_id, row.agent, row.machine_id, row.keep_id);
|
|
1502
1538
|
removed += result.changes;
|
|
1503
1539
|
}
|
|
1504
1540
|
return removed;
|
|
@@ -4028,7 +4064,7 @@ __export(exports_config, {
|
|
|
4028
4064
|
loadConfig: () => loadConfig2,
|
|
4029
4065
|
getConfigValue: () => getConfigValue
|
|
4030
4066
|
});
|
|
4031
|
-
import { existsSync as
|
|
4067
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
|
|
4032
4068
|
import { dirname as dirname2, join as join12 } from "path";
|
|
4033
4069
|
function getConfigPath() {
|
|
4034
4070
|
return process.env["HASNA_ECONOMY_CONFIG_PATH"] ?? join12(getDataDir(), "config.json");
|
|
@@ -4036,7 +4072,7 @@ function getConfigPath() {
|
|
|
4036
4072
|
function loadConfig2() {
|
|
4037
4073
|
try {
|
|
4038
4074
|
const configPath = getConfigPath();
|
|
4039
|
-
if (
|
|
4075
|
+
if (existsSync13(configPath)) {
|
|
4040
4076
|
const raw = readFileSync11(configPath, "utf-8");
|
|
4041
4077
|
return { ...DEFAULTS, ...JSON.parse(raw) };
|
|
4042
4078
|
}
|
|
@@ -4046,7 +4082,7 @@ function loadConfig2() {
|
|
|
4046
4082
|
function saveConfig2(config) {
|
|
4047
4083
|
const configPath = getConfigPath();
|
|
4048
4084
|
const dir = dirname2(configPath);
|
|
4049
|
-
if (!
|
|
4085
|
+
if (!existsSync13(dir))
|
|
4050
4086
|
mkdirSync3(dir, { recursive: true });
|
|
4051
4087
|
writeFileSync2(configPath, JSON.stringify(config, null, 2) + `
|
|
4052
4088
|
`);
|
|
@@ -4190,7 +4226,7 @@ var init_webhooks = __esm(() => {
|
|
|
4190
4226
|
});
|
|
4191
4227
|
|
|
4192
4228
|
// src/lib/watch-paths.ts
|
|
4193
|
-
import { existsSync as
|
|
4229
|
+
import { existsSync as existsSync14 } from "fs";
|
|
4194
4230
|
function getWatchPaths() {
|
|
4195
4231
|
const p = agentPaths();
|
|
4196
4232
|
const candidates = [
|
|
@@ -4203,7 +4239,7 @@ function getWatchPaths() {
|
|
|
4203
4239
|
p.piSessions,
|
|
4204
4240
|
p.hermesDir
|
|
4205
4241
|
];
|
|
4206
|
-
return candidates.filter((path) =>
|
|
4242
|
+
return candidates.filter((path) => existsSync14(path));
|
|
4207
4243
|
}
|
|
4208
4244
|
var init_watch_paths = __esm(() => {
|
|
4209
4245
|
init_paths();
|
|
@@ -4373,7 +4409,7 @@ __export(exports_serve, {
|
|
|
4373
4409
|
createHandler: () => createHandler
|
|
4374
4410
|
});
|
|
4375
4411
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
4376
|
-
import { existsSync as
|
|
4412
|
+
import { existsSync as existsSync15 } from "fs";
|
|
4377
4413
|
import { resolve, sep } from "path";
|
|
4378
4414
|
function json(data, status = 200) {
|
|
4379
4415
|
return new Response(JSON.stringify(data), {
|
|
@@ -4438,13 +4474,13 @@ function createServerFetch(apiHandler, dashboardDir = DEFAULT_DASHBOARD_DIR) {
|
|
|
4438
4474
|
if (url.pathname.startsWith("/api") || url.pathname === "/health") {
|
|
4439
4475
|
return apiHandler(req);
|
|
4440
4476
|
}
|
|
4441
|
-
if (
|
|
4477
|
+
if (existsSync15(dashboardDir)) {
|
|
4442
4478
|
const filePath = dashboardPath(dashboardDir, url.pathname);
|
|
4443
|
-
if (filePath &&
|
|
4479
|
+
if (filePath && existsSync15(filePath)) {
|
|
4444
4480
|
return new Response(Bun.file(filePath));
|
|
4445
4481
|
}
|
|
4446
4482
|
const indexPath = dashboardPath(dashboardDir, "/");
|
|
4447
|
-
if (indexPath &&
|
|
4483
|
+
if (indexPath && existsSync15(indexPath)) {
|
|
4448
4484
|
return new Response(Bun.file(indexPath));
|
|
4449
4485
|
}
|
|
4450
4486
|
}
|
|
@@ -4841,14 +4877,14 @@ __export(exports_menubar, {
|
|
|
4841
4877
|
});
|
|
4842
4878
|
import chalk6 from "chalk";
|
|
4843
4879
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
4844
|
-
import { cpSync, existsSync as
|
|
4880
|
+
import { cpSync, existsSync as existsSync16, mkdirSync as mkdirSync4, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
4845
4881
|
import { tmpdir, arch } from "os";
|
|
4846
4882
|
import { join as join13 } from "path";
|
|
4847
4883
|
function getArch() {
|
|
4848
4884
|
return arch() === "arm64" ? "arm64" : "x86_64";
|
|
4849
4885
|
}
|
|
4850
4886
|
function isInstalled() {
|
|
4851
|
-
return
|
|
4887
|
+
return existsSync16(APP_PATH);
|
|
4852
4888
|
}
|
|
4853
4889
|
function isRunning() {
|
|
4854
4890
|
try {
|
|
@@ -6182,6 +6218,7 @@ var TOP_LEVEL = [
|
|
|
6182
6218
|
"init",
|
|
6183
6219
|
"estimate",
|
|
6184
6220
|
"fleet",
|
|
6221
|
+
"merge-db",
|
|
6185
6222
|
"todos",
|
|
6186
6223
|
"serve",
|
|
6187
6224
|
"mcp",
|
|
@@ -6535,6 +6572,285 @@ function registerFleetCommands(program) {
|
|
|
6535
6572
|
init_agents();
|
|
6536
6573
|
init_sync_all();
|
|
6537
6574
|
init_cloud_sync();
|
|
6575
|
+
|
|
6576
|
+
// src/lib/peer-sync.ts
|
|
6577
|
+
init_database();
|
|
6578
|
+
init_package_metadata();
|
|
6579
|
+
import { Database as BunDatabase2 } from "bun:sqlite";
|
|
6580
|
+
import { existsSync as existsSync12 } from "fs";
|
|
6581
|
+
var GENERIC_PEER_TABLES = [
|
|
6582
|
+
"usage_snapshots",
|
|
6583
|
+
"subscriptions",
|
|
6584
|
+
"billing_daily",
|
|
6585
|
+
"savings_daily",
|
|
6586
|
+
"budgets",
|
|
6587
|
+
"goals",
|
|
6588
|
+
"model_pricing",
|
|
6589
|
+
"machines"
|
|
6590
|
+
];
|
|
6591
|
+
function quoteIdent(identifier) {
|
|
6592
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
6593
|
+
}
|
|
6594
|
+
function tableExists(db, table) {
|
|
6595
|
+
const row = db.prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`).get(table);
|
|
6596
|
+
return Boolean(row);
|
|
6597
|
+
}
|
|
6598
|
+
function tableColumns(db, table) {
|
|
6599
|
+
if (!tableExists(db, table))
|
|
6600
|
+
return [];
|
|
6601
|
+
return db.prepare(`PRAGMA table_info(${quoteIdent(table)})`).all();
|
|
6602
|
+
}
|
|
6603
|
+
function commonColumns(source, target, table) {
|
|
6604
|
+
const sourceCols = new Set(tableColumns(source, table).map((c) => c.name));
|
|
6605
|
+
return tableColumns(target, table).map((c) => c.name).filter((c) => sourceCols.has(c));
|
|
6606
|
+
}
|
|
6607
|
+
function primaryKeyColumns(db, table) {
|
|
6608
|
+
return tableColumns(db, table).filter((c) => c.pk > 0).sort((a, b) => a.pk - b.pk).map((c) => c.name);
|
|
6609
|
+
}
|
|
6610
|
+
function selectRows(source, table, columns) {
|
|
6611
|
+
if (columns.length === 0)
|
|
6612
|
+
return [];
|
|
6613
|
+
const select = columns.map(quoteIdent).join(", ");
|
|
6614
|
+
return source.prepare(`SELECT ${select} FROM ${quoteIdent(table)}`).all();
|
|
6615
|
+
}
|
|
6616
|
+
function rowByKey(target, table, keyColumns, row) {
|
|
6617
|
+
if (keyColumns.length === 0)
|
|
6618
|
+
return null;
|
|
6619
|
+
if (keyColumns.some((c) => row[c] == null))
|
|
6620
|
+
return null;
|
|
6621
|
+
const where = keyColumns.map((c) => `${quoteIdent(c)} = ?`).join(" AND ");
|
|
6622
|
+
return target.prepare(`SELECT * FROM ${quoteIdent(table)} WHERE ${where}`).get(...keyColumns.map((c) => row[c]));
|
|
6623
|
+
}
|
|
6624
|
+
function hasId(target, table, id) {
|
|
6625
|
+
return target.prepare(`SELECT id, machine_id FROM ${quoteIdent(table)} WHERE id = ?`).get(id);
|
|
6626
|
+
}
|
|
6627
|
+
function shouldReplace(source, existing) {
|
|
6628
|
+
if (!existing)
|
|
6629
|
+
return true;
|
|
6630
|
+
const sourceUpdated = source["updated_at"];
|
|
6631
|
+
const existingUpdated = existing["updated_at"];
|
|
6632
|
+
if (typeof sourceUpdated === "string" && typeof existingUpdated === "string" && existingUpdated !== "") {
|
|
6633
|
+
return sourceUpdated >= existingUpdated;
|
|
6634
|
+
}
|
|
6635
|
+
return true;
|
|
6636
|
+
}
|
|
6637
|
+
function normalizeRow(row, columns, sourceMachine, now) {
|
|
6638
|
+
const next = { ...row };
|
|
6639
|
+
if (columns.includes("machine_id") && (!next["machine_id"] || next["machine_id"] === "")) {
|
|
6640
|
+
next["machine_id"] = sourceMachine;
|
|
6641
|
+
}
|
|
6642
|
+
if (columns.includes("updated_at") && (!next["updated_at"] || next["updated_at"] === "")) {
|
|
6643
|
+
next["updated_at"] = next["timestamp"] ?? next["started_at"] ?? next["created_at"] ?? now;
|
|
6644
|
+
}
|
|
6645
|
+
if (columns.includes("synced_at") && next["synced_at"] == null)
|
|
6646
|
+
next["synced_at"] = "";
|
|
6647
|
+
if (columns.includes("attribution_tag") && next["attribution_tag"] == null)
|
|
6648
|
+
next["attribution_tag"] = "";
|
|
6649
|
+
return next;
|
|
6650
|
+
}
|
|
6651
|
+
function insertOrReplace(target, table, columns, row) {
|
|
6652
|
+
const colSql = columns.map(quoteIdent).join(", ");
|
|
6653
|
+
const placeholders = columns.map(() => "?").join(", ");
|
|
6654
|
+
target.prepare(`
|
|
6655
|
+
INSERT OR REPLACE INTO ${quoteIdent(table)} (${colSql})
|
|
6656
|
+
VALUES (${placeholders})
|
|
6657
|
+
`).run(...columns.map((c) => row[c] ?? null));
|
|
6658
|
+
}
|
|
6659
|
+
function collisionId(target, table, machine, originalId) {
|
|
6660
|
+
const base = `${machine || "peer"}:${originalId}`;
|
|
6661
|
+
const baseRow = hasId(target, table, base);
|
|
6662
|
+
if (!baseRow || String(baseRow["machine_id"] ?? "") === machine)
|
|
6663
|
+
return base;
|
|
6664
|
+
for (let i = 2;; i++) {
|
|
6665
|
+
const candidate = `${base}:${i}`;
|
|
6666
|
+
const row = hasId(target, table, candidate);
|
|
6667
|
+
if (!row || String(row["machine_id"] ?? "") === machine)
|
|
6668
|
+
return candidate;
|
|
6669
|
+
}
|
|
6670
|
+
}
|
|
6671
|
+
function mergeIdentityTable(target, source, table, sourceMachine, now, sessionIdMap) {
|
|
6672
|
+
const stats = { table, inserted: 0, updated: 0, skipped: 0, collisions: 0 };
|
|
6673
|
+
const columns = commonColumns(source, target, table);
|
|
6674
|
+
const rows = selectRows(source, table, columns);
|
|
6675
|
+
const idMap = new Map;
|
|
6676
|
+
for (const raw of rows) {
|
|
6677
|
+
const row = normalizeRow(raw, columns, sourceMachine, now);
|
|
6678
|
+
const originalId = String(row["id"] ?? "");
|
|
6679
|
+
if (!originalId) {
|
|
6680
|
+
stats.skipped++;
|
|
6681
|
+
continue;
|
|
6682
|
+
}
|
|
6683
|
+
const machine = String(row["machine_id"] ?? "");
|
|
6684
|
+
const directExisting = hasId(target, table, originalId);
|
|
6685
|
+
if (directExisting && String(directExisting["machine_id"] ?? "") !== machine) {
|
|
6686
|
+
row["id"] = collisionId(target, table, machine, originalId);
|
|
6687
|
+
stats.collisions++;
|
|
6688
|
+
}
|
|
6689
|
+
if (table === "requests" && sessionIdMap) {
|
|
6690
|
+
const originalSessionId = String(row["session_id"] ?? "");
|
|
6691
|
+
row["session_id"] = sessionIdMap.get(originalSessionId) ?? originalSessionId;
|
|
6692
|
+
}
|
|
6693
|
+
const existing = hasId(target, table, String(row["id"]));
|
|
6694
|
+
idMap.set(originalId, String(row["id"]));
|
|
6695
|
+
if (existing && !shouldReplace(row, existing)) {
|
|
6696
|
+
stats.skipped++;
|
|
6697
|
+
continue;
|
|
6698
|
+
}
|
|
6699
|
+
insertOrReplace(target, table, columns, row);
|
|
6700
|
+
if (existing)
|
|
6701
|
+
stats.updated++;
|
|
6702
|
+
else
|
|
6703
|
+
stats.inserted++;
|
|
6704
|
+
}
|
|
6705
|
+
return { stats, idMap };
|
|
6706
|
+
}
|
|
6707
|
+
function mergeProjects(target, source) {
|
|
6708
|
+
const table = "projects";
|
|
6709
|
+
const stats = { table, inserted: 0, updated: 0, skipped: 0, collisions: 0 };
|
|
6710
|
+
const columns = commonColumns(source, target, table);
|
|
6711
|
+
const rows = selectRows(source, table, columns);
|
|
6712
|
+
for (const raw of rows) {
|
|
6713
|
+
const row = { ...raw };
|
|
6714
|
+
const path = String(row["path"] ?? "");
|
|
6715
|
+
const id = String(row["id"] ?? "");
|
|
6716
|
+
if (!path || !id) {
|
|
6717
|
+
stats.skipped++;
|
|
6718
|
+
continue;
|
|
6719
|
+
}
|
|
6720
|
+
const existingByPath = target.prepare(`SELECT * FROM projects WHERE path = ?`).get(path);
|
|
6721
|
+
if (existingByPath) {
|
|
6722
|
+
row["id"] = existingByPath["id"] ?? id;
|
|
6723
|
+
insertOrReplace(target, table, columns, row);
|
|
6724
|
+
stats.updated++;
|
|
6725
|
+
continue;
|
|
6726
|
+
}
|
|
6727
|
+
const existingById = target.prepare(`SELECT * FROM projects WHERE id = ?`).get(id);
|
|
6728
|
+
if (existingById && String(existingById["path"] ?? "") !== path) {
|
|
6729
|
+
row["id"] = `peer:${id}`;
|
|
6730
|
+
stats.collisions++;
|
|
6731
|
+
while (target.prepare(`SELECT id FROM projects WHERE id = ?`).get(row["id"])) {
|
|
6732
|
+
row["id"] = `peer:${String(row["id"])}`;
|
|
6733
|
+
}
|
|
6734
|
+
}
|
|
6735
|
+
insertOrReplace(target, table, columns, row);
|
|
6736
|
+
stats.inserted++;
|
|
6737
|
+
}
|
|
6738
|
+
return stats;
|
|
6739
|
+
}
|
|
6740
|
+
function mergeGenericTable(target, source, table, sourceMachine, now) {
|
|
6741
|
+
const stats = { table, inserted: 0, updated: 0, skipped: 0, collisions: 0 };
|
|
6742
|
+
const columns = commonColumns(source, target, table);
|
|
6743
|
+
const keyColumns = primaryKeyColumns(target, table).filter((c) => columns.includes(c));
|
|
6744
|
+
const rows = selectRows(source, table, columns);
|
|
6745
|
+
for (const raw of rows) {
|
|
6746
|
+
const row = normalizeRow(raw, columns, sourceMachine, now);
|
|
6747
|
+
const existing = rowByKey(target, table, keyColumns, row);
|
|
6748
|
+
if (existing && !shouldReplace(row, existing)) {
|
|
6749
|
+
stats.skipped++;
|
|
6750
|
+
continue;
|
|
6751
|
+
}
|
|
6752
|
+
insertOrReplace(target, table, columns, row);
|
|
6753
|
+
if (existing)
|
|
6754
|
+
stats.updated++;
|
|
6755
|
+
else
|
|
6756
|
+
stats.inserted++;
|
|
6757
|
+
}
|
|
6758
|
+
return stats;
|
|
6759
|
+
}
|
|
6760
|
+
function detectSourceMachine(source, fallback) {
|
|
6761
|
+
if (fallback && fallback.trim())
|
|
6762
|
+
return fallback.trim();
|
|
6763
|
+
const counts = new Map;
|
|
6764
|
+
for (const table of ["sessions", "requests", "usage_snapshots"]) {
|
|
6765
|
+
if (!tableExists(source, table))
|
|
6766
|
+
continue;
|
|
6767
|
+
const rows = source.prepare(`
|
|
6768
|
+
SELECT machine_id, COUNT(*) as cnt
|
|
6769
|
+
FROM ${quoteIdent(table)}
|
|
6770
|
+
WHERE machine_id != '' AND machine_id IS NOT NULL
|
|
6771
|
+
GROUP BY machine_id
|
|
6772
|
+
`).all();
|
|
6773
|
+
for (const row of rows) {
|
|
6774
|
+
counts.set(row.machine_id, (counts.get(row.machine_id) ?? 0) + row.cnt);
|
|
6775
|
+
}
|
|
6776
|
+
}
|
|
6777
|
+
let best = "";
|
|
6778
|
+
let bestCount = -1;
|
|
6779
|
+
for (const [machine, count] of counts.entries()) {
|
|
6780
|
+
if (count > bestCount) {
|
|
6781
|
+
best = machine;
|
|
6782
|
+
bestCount = count;
|
|
6783
|
+
}
|
|
6784
|
+
}
|
|
6785
|
+
return best || "peer";
|
|
6786
|
+
}
|
|
6787
|
+
function ensureMachineRegistry(target, machine, now) {
|
|
6788
|
+
if (!machine)
|
|
6789
|
+
return;
|
|
6790
|
+
target.prepare(`
|
|
6791
|
+
INSERT INTO machines (machine_id, hostname, last_seen_at, last_push_at, last_pull_at, economy_version, updated_at)
|
|
6792
|
+
VALUES (?, ?, ?, NULL, ?, ?, ?)
|
|
6793
|
+
ON CONFLICT(machine_id) DO UPDATE SET
|
|
6794
|
+
hostname = COALESCE(NULLIF(machines.hostname, ''), excluded.hostname),
|
|
6795
|
+
last_seen_at = CASE
|
|
6796
|
+
WHEN machines.last_seen_at IS NULL OR machines.last_seen_at < excluded.last_seen_at THEN excluded.last_seen_at
|
|
6797
|
+
ELSE machines.last_seen_at
|
|
6798
|
+
END,
|
|
6799
|
+
last_pull_at = excluded.last_pull_at,
|
|
6800
|
+
economy_version = excluded.economy_version,
|
|
6801
|
+
updated_at = excluded.updated_at
|
|
6802
|
+
`).run(machine, machine, now, now, packageMetadata.version, now);
|
|
6803
|
+
}
|
|
6804
|
+
function openSourceDatabase(path) {
|
|
6805
|
+
try {
|
|
6806
|
+
return new BunDatabase2(path, { readonly: true });
|
|
6807
|
+
} catch {
|
|
6808
|
+
return new BunDatabase2(path);
|
|
6809
|
+
}
|
|
6810
|
+
}
|
|
6811
|
+
function mergePeerDatabase(target, sourcePath, opts = {}) {
|
|
6812
|
+
if (!existsSync12(sourcePath))
|
|
6813
|
+
throw new Error(`source database does not exist: ${sourcePath}`);
|
|
6814
|
+
const source = openSourceDatabase(sourcePath);
|
|
6815
|
+
const now = opts.now ?? new Date().toISOString();
|
|
6816
|
+
const sourceMachine = detectSourceMachine(source, opts.sourceMachine);
|
|
6817
|
+
const tables = [];
|
|
6818
|
+
try {
|
|
6819
|
+
target.exec("PRAGMA foreign_keys = OFF");
|
|
6820
|
+
target.exec("BEGIN IMMEDIATE");
|
|
6821
|
+
try {
|
|
6822
|
+
tables.push(mergeProjects(target, source));
|
|
6823
|
+
const sessionMerge = mergeIdentityTable(target, source, "sessions", sourceMachine, now);
|
|
6824
|
+
tables.push(sessionMerge.stats);
|
|
6825
|
+
tables.push(mergeIdentityTable(target, source, "requests", sourceMachine, now, sessionMerge.idMap).stats);
|
|
6826
|
+
for (const table of GENERIC_PEER_TABLES) {
|
|
6827
|
+
tables.push(mergeGenericTable(target, source, table, sourceMachine, now));
|
|
6828
|
+
}
|
|
6829
|
+
ensureMachineRegistry(target, sourceMachine, now);
|
|
6830
|
+
target.exec("COMMIT");
|
|
6831
|
+
} catch (err) {
|
|
6832
|
+
target.exec("ROLLBACK");
|
|
6833
|
+
throw err;
|
|
6834
|
+
} finally {
|
|
6835
|
+
target.exec("PRAGMA foreign_keys = ON");
|
|
6836
|
+
}
|
|
6837
|
+
} finally {
|
|
6838
|
+
source.close();
|
|
6839
|
+
}
|
|
6840
|
+
const deduped = dedupeRequests(target);
|
|
6841
|
+
const rowsWritten = tables.reduce((sum, table) => sum + table.inserted + table.updated, 0);
|
|
6842
|
+
const collisions = tables.reduce((sum, table) => sum + table.collisions, 0);
|
|
6843
|
+
return {
|
|
6844
|
+
source_path: sourcePath,
|
|
6845
|
+
source_machine: sourceMachine,
|
|
6846
|
+
rows_written: rowsWritten,
|
|
6847
|
+
collisions,
|
|
6848
|
+
deduped,
|
|
6849
|
+
tables: tables.filter((t) => t.inserted || t.updated || t.skipped || t.collisions)
|
|
6850
|
+
};
|
|
6851
|
+
}
|
|
6852
|
+
|
|
6853
|
+
// src/cli/index.ts
|
|
6538
6854
|
init_database();
|
|
6539
6855
|
init_database();
|
|
6540
6856
|
init_billing();
|
|
@@ -7361,6 +7677,21 @@ program.command("machines").description("List all machines that have synced data
|
|
|
7361
7677
|
${chalk7.dim("Current machine:")} ${chalk7.bold(current)}`);
|
|
7362
7678
|
console.log();
|
|
7363
7679
|
});
|
|
7680
|
+
program.command("merge-db <source-db>").description("Merge another Economy SQLite database into this machine").option("--source-machine <id>", "Machine id to use for source rows that do not have one").option("--json", "Output JSON").action((sourceDb, opts) => {
|
|
7681
|
+
const db = openDatabase();
|
|
7682
|
+
const result = mergePeerDatabase(db, sourceDb, { sourceMachine: opts.sourceMachine });
|
|
7683
|
+
if (opts.json) {
|
|
7684
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7685
|
+
return;
|
|
7686
|
+
}
|
|
7687
|
+
console.log();
|
|
7688
|
+
console.log(chalk7.bold.cyan(` Merged Economy DB \u2014 ${result.source_machine}`));
|
|
7689
|
+
console.log(` Rows written: ${fmtCount(result.rows_written)} \xB7 collisions remapped: ${fmtCount(result.collisions)} \xB7 deduped: ${fmtCount(result.deduped)}`);
|
|
7690
|
+
for (const table of result.tables) {
|
|
7691
|
+
console.log(` ${chalk7.white(table.table.padEnd(16))}` + ` inserted ${fmtCount(table.inserted).padStart(6)}` + ` updated ${fmtCount(table.updated).padStart(6)}` + ` skipped ${fmtCount(table.skipped).padStart(6)}` + ` collisions ${fmtCount(table.collisions).padStart(3)}`);
|
|
7692
|
+
}
|
|
7693
|
+
console.log();
|
|
7694
|
+
});
|
|
7364
7695
|
program.command("export").description("Export data as CSV").option("--type <type>", "Data type: sessions or requests", "sessions").option("--period <period>", "Period: today|week|month|all", "month").option("--output <file>", "Output file path (default: stdout)").action(async (opts) => {
|
|
7365
7696
|
await autoSync();
|
|
7366
7697
|
const db = openDatabase();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,cAAc,CAAA;AAKxD,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,cAAc,EACd,MAAM,EACN,YAAY,EACZ,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,MAAM,EACN,aAAa,EACd,MAAM,mBAAmB,CAAA;AAE1B,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAkBnC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAIlC;AAED,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,UAAQ,GAAG,QAAQ,CAgBxE;AAkRD,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CAuBrE;AAID,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAkBzE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CA2BnE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAE,aAAkB,GAAG,cAAc,EAAE,CAuBxF;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,SAAK,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE,CAKvF;AAID,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,UAAQ,GAAG,WAAW,CA8B7G;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,GAAG,cAAc,EAAE,CAUlE;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAE,MAAc,GAAG,cAAc,EAAE,CA0E1F;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './lib/pricing.js';
|
|
|
4
4
|
export * from './lib/gatherer.js';
|
|
5
5
|
export * from './lib/model-config.js';
|
|
6
6
|
export * from './lib/open-projects.js';
|
|
7
|
+
export * from './lib/peer-sync.js';
|
|
7
8
|
export * from './ingest/claude.js';
|
|
8
9
|
export * from './ingest/codex.js';
|
|
9
10
|
export * from './ingest/gemini.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA"}
|