@hasna/machines 0.0.14 → 0.0.16

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.
@@ -0,0 +1,557 @@
1
+ // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
12
+ var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
20
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
21
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
+ for (let key of __getOwnPropNames(mod))
23
+ if (!__hasOwnProp.call(to, key))
24
+ __defProp(to, key, {
25
+ get: __accessProp.bind(mod, key),
26
+ enumerable: true
27
+ });
28
+ if (canCache)
29
+ cache.set(mod, to);
30
+ return to;
31
+ };
32
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
33
+ var __returnValue = (v) => v;
34
+ function __exportSetter(name, newValue) {
35
+ this[name] = __returnValue.bind(null, newValue);
36
+ }
37
+ var __export = (target, all) => {
38
+ for (var name in all)
39
+ __defProp(target, name, {
40
+ get: all[name],
41
+ enumerable: true,
42
+ configurable: true,
43
+ set: __exportSetter.bind(all, name)
44
+ });
45
+ };
46
+
47
+ // src/db.ts
48
+ import { Database } from "bun:sqlite";
49
+ import { hostname } from "os";
50
+
51
+ // src/paths.ts
52
+ import { existsSync, mkdirSync } from "fs";
53
+ import { dirname, join, resolve } from "path";
54
+ function homeDir() {
55
+ return process.env["HOME"] || process.env["USERPROFILE"] || "~";
56
+ }
57
+ function getDataDir() {
58
+ return process.env["HASNA_MACHINES_DIR"] || join(homeDir(), ".hasna", "machines");
59
+ }
60
+ function getDbPath() {
61
+ return process.env["HASNA_MACHINES_DB_PATH"] || join(getDataDir(), "machines.db");
62
+ }
63
+ function getManifestPath() {
64
+ return process.env["HASNA_MACHINES_MANIFEST_PATH"] || join(getDataDir(), "machines.json");
65
+ }
66
+ function getNotificationsPath() {
67
+ return process.env["HASNA_MACHINES_NOTIFICATIONS_PATH"] || join(getDataDir(), "notifications.json");
68
+ }
69
+ function getClipboardKeyPath() {
70
+ return process.env["HASNA_MACHINES_CLIPBOARD_KEY_PATH"] || join(getDataDir(), "clipboard.key");
71
+ }
72
+ function getClipboardHistoryPath() {
73
+ return process.env["HASNA_MACHINES_CLIPBOARD_HISTORY_PATH"] || join(getDataDir(), "clipboard-history.json");
74
+ }
75
+ function ensureParentDir(filePath) {
76
+ if (filePath === ":memory:")
77
+ return;
78
+ const dir = dirname(resolve(filePath));
79
+ if (!existsSync(dir)) {
80
+ mkdirSync(dir, { recursive: true });
81
+ }
82
+ }
83
+ function ensureDataDir() {
84
+ const dir = getDataDir();
85
+ ensureParentDir(join(dir, ".keep"));
86
+ return dir;
87
+ }
88
+
89
+ // src/db.ts
90
+ class SqliteAdapter {
91
+ raw;
92
+ constructor(path) {
93
+ this.raw = new Database(path);
94
+ }
95
+ close() {
96
+ this.raw.close();
97
+ }
98
+ }
99
+ var adapter = null;
100
+ function createTables(db) {
101
+ db.exec(`
102
+ CREATE TABLE IF NOT EXISTS agent_heartbeats (
103
+ machine_id TEXT NOT NULL,
104
+ pid INTEGER NOT NULL,
105
+ status TEXT NOT NULL,
106
+ updated_at TEXT NOT NULL,
107
+ PRIMARY KEY (machine_id, pid)
108
+ )
109
+ `);
110
+ db.exec(`
111
+ CREATE TABLE IF NOT EXISTS setup_runs (
112
+ id TEXT PRIMARY KEY,
113
+ machine_id TEXT NOT NULL,
114
+ status TEXT NOT NULL,
115
+ details_json TEXT NOT NULL DEFAULT '[]',
116
+ created_at TEXT NOT NULL,
117
+ updated_at TEXT NOT NULL
118
+ )
119
+ `);
120
+ db.exec(`
121
+ CREATE TABLE IF NOT EXISTS sync_runs (
122
+ id TEXT PRIMARY KEY,
123
+ machine_id TEXT NOT NULL,
124
+ status TEXT NOT NULL,
125
+ actions_json TEXT NOT NULL DEFAULT '[]',
126
+ created_at TEXT NOT NULL,
127
+ updated_at TEXT NOT NULL
128
+ )
129
+ `);
130
+ }
131
+ function getAdapter(path = getDbPath()) {
132
+ if (path === ":memory:") {
133
+ const memoryAdapter = new SqliteAdapter(path);
134
+ createTables(memoryAdapter.raw);
135
+ return memoryAdapter;
136
+ }
137
+ if (adapter && adapter.raw.filename !== path) {
138
+ adapter.close();
139
+ adapter = null;
140
+ }
141
+ if (!adapter) {
142
+ ensureParentDir(path);
143
+ adapter = new SqliteAdapter(path);
144
+ adapter.raw.exec("PRAGMA journal_mode = WAL");
145
+ adapter.raw.exec("PRAGMA foreign_keys = ON");
146
+ createTables(adapter.raw);
147
+ }
148
+ return adapter;
149
+ }
150
+ function getDb(path = getDbPath()) {
151
+ return getAdapter(path).raw;
152
+ }
153
+ function closeDb() {
154
+ if (adapter) {
155
+ adapter.close();
156
+ adapter = null;
157
+ }
158
+ }
159
+ function upsertHeartbeat(machineId, pid = process.pid, status = "online") {
160
+ const db = getDb();
161
+ db.query(`INSERT INTO agent_heartbeats (machine_id, pid, status, updated_at)
162
+ VALUES (?, ?, ?, ?)
163
+ ON CONFLICT(machine_id, pid) DO UPDATE SET
164
+ status = excluded.status,
165
+ updated_at = excluded.updated_at`).run(machineId, pid, status, new Date().toISOString());
166
+ }
167
+ function getLocalMachineId() {
168
+ return process.env["HASNA_MACHINES_MACHINE_ID"] || hostname();
169
+ }
170
+ function listHeartbeats(machineId) {
171
+ const db = getDb();
172
+ if (machineId) {
173
+ return db.query(`SELECT machine_id, pid, status, updated_at
174
+ FROM agent_heartbeats
175
+ WHERE machine_id = ?
176
+ ORDER BY updated_at DESC`).all(machineId);
177
+ }
178
+ return db.query(`SELECT machine_id, pid, status, updated_at
179
+ FROM agent_heartbeats
180
+ ORDER BY updated_at DESC`).all();
181
+ }
182
+ function countRuns(table) {
183
+ const db = getDb();
184
+ const row = db.query(`SELECT COUNT(*) as count FROM ${table}`).get();
185
+ return row.count;
186
+ }
187
+ function setHeartbeatStatus(machineId, pid, status) {
188
+ const db = getDb();
189
+ db.query(`UPDATE agent_heartbeats
190
+ SET status = ?, updated_at = ?
191
+ WHERE machine_id = ? AND pid = ?`).run(status, new Date().toISOString(), machineId, pid);
192
+ }
193
+ function recordSetupRun(machineId, status, details) {
194
+ const db = getDb();
195
+ const now = new Date().toISOString();
196
+ db.query(`INSERT INTO setup_runs (id, machine_id, status, details_json, created_at, updated_at)
197
+ VALUES (?, ?, ?, ?, ?, ?)`).run(crypto.randomUUID(), machineId, status, JSON.stringify(details), now, now);
198
+ }
199
+ function recordSyncRun(machineId, status, actions) {
200
+ const db = getDb();
201
+ const now = new Date().toISOString();
202
+ db.query(`INSERT INTO sync_runs (id, machine_id, status, actions_json, created_at, updated_at)
203
+ VALUES (?, ?, ?, ?, ?, ?)`).run(crypto.randomUUID(), machineId, status, JSON.stringify(actions), now, now);
204
+ }
205
+
206
+ // src/pg-migrations.ts
207
+ var PG_MIGRATIONS = [
208
+ `
209
+ CREATE TABLE IF NOT EXISTS agent_heartbeats (
210
+ machine_id TEXT NOT NULL,
211
+ pid INTEGER NOT NULL,
212
+ status TEXT NOT NULL,
213
+ updated_at TIMESTAMPTZ NOT NULL,
214
+ PRIMARY KEY (machine_id, pid)
215
+ );
216
+
217
+ CREATE TABLE IF NOT EXISTS setup_runs (
218
+ id TEXT PRIMARY KEY,
219
+ machine_id TEXT NOT NULL,
220
+ status TEXT NOT NULL,
221
+ details_json TEXT NOT NULL DEFAULT '[]',
222
+ created_at TIMESTAMPTZ NOT NULL,
223
+ updated_at TIMESTAMPTZ NOT NULL
224
+ );
225
+
226
+ CREATE TABLE IF NOT EXISTS sync_runs (
227
+ id TEXT PRIMARY KEY,
228
+ machine_id TEXT NOT NULL,
229
+ status TEXT NOT NULL,
230
+ actions_json TEXT NOT NULL DEFAULT '[]',
231
+ created_at TIMESTAMPTZ NOT NULL,
232
+ updated_at TIMESTAMPTZ NOT NULL
233
+ );
234
+ `
235
+ ];
236
+
237
+ // src/remote-storage.ts
238
+ import pg from "pg";
239
+ function translatePlaceholders(sql) {
240
+ let index = 0;
241
+ return sql.replace(/\?/g, () => `$${++index}`);
242
+ }
243
+ function normalizeParams(params) {
244
+ const flat = params.length === 1 && Array.isArray(params[0]) ? params[0] : params;
245
+ return flat.map((value) => value === undefined ? null : value);
246
+ }
247
+ function sslConfigFor(connectionString) {
248
+ return connectionString.includes("sslmode=require") || connectionString.includes("ssl=true") ? { rejectUnauthorized: false } : undefined;
249
+ }
250
+
251
+ class PgAdapterAsync {
252
+ pool;
253
+ constructor(connectionString) {
254
+ this.pool = new pg.Pool({ connectionString, ssl: sslConfigFor(connectionString) });
255
+ }
256
+ async run(sql, ...params) {
257
+ const result = await this.pool.query(translatePlaceholders(sql), normalizeParams(params));
258
+ return { changes: result.rowCount ?? 0 };
259
+ }
260
+ async all(sql, ...params) {
261
+ const result = await this.pool.query(translatePlaceholders(sql), normalizeParams(params));
262
+ return result.rows;
263
+ }
264
+ async close() {
265
+ await this.pool.end();
266
+ }
267
+ }
268
+
269
+ // src/storage-sync.ts
270
+ var STORAGE_TABLES = [
271
+ "agent_heartbeats",
272
+ "setup_runs",
273
+ "sync_runs"
274
+ ];
275
+ var MACHINES_STORAGE_TABLES = STORAGE_TABLES;
276
+ var MACHINES_STORAGE_ENV = "HASNA_MACHINES_DATABASE_URL";
277
+ var MACHINES_STORAGE_FALLBACK_ENV = "MACHINES_DATABASE_URL";
278
+ var MACHINES_STORAGE_MODE_ENV = "HASNA_MACHINES_STORAGE_MODE";
279
+ var MACHINES_STORAGE_MODE_FALLBACK_ENV = "MACHINES_STORAGE_MODE";
280
+ var STORAGE_DATABASE_ENV = [MACHINES_STORAGE_ENV, MACHINES_STORAGE_FALLBACK_ENV];
281
+ var STORAGE_MODE_ENV = [MACHINES_STORAGE_MODE_ENV, MACHINES_STORAGE_MODE_FALLBACK_ENV];
282
+ var PRIMARY_KEYS = {
283
+ agent_heartbeats: ["machine_id", "pid"],
284
+ setup_runs: ["id"],
285
+ sync_runs: ["id"]
286
+ };
287
+ function readEnv(name) {
288
+ const value = process.env[name]?.trim();
289
+ return value || undefined;
290
+ }
291
+ function normalizeStorageMode(value) {
292
+ const normalized = value?.trim().toLowerCase();
293
+ if (normalized === "local" || normalized === "hybrid" || normalized === "remote")
294
+ return normalized;
295
+ return;
296
+ }
297
+ function getStorageDatabaseEnvName() {
298
+ for (const name of STORAGE_DATABASE_ENV) {
299
+ if (readEnv(name))
300
+ return name;
301
+ }
302
+ return null;
303
+ }
304
+ function getStorageDatabaseEnv() {
305
+ const name = getStorageDatabaseEnvName();
306
+ return name ? { name } : null;
307
+ }
308
+ function getStorageDatabaseUrl() {
309
+ const env = getStorageDatabaseEnv();
310
+ return env ? readEnv(env.name) ?? null : null;
311
+ }
312
+ function getStorageMode() {
313
+ const mode = normalizeStorageMode(readEnv(MACHINES_STORAGE_MODE_ENV)) ?? normalizeStorageMode(readEnv(MACHINES_STORAGE_MODE_FALLBACK_ENV));
314
+ if (mode)
315
+ return mode;
316
+ return getStorageDatabaseUrl() ? "hybrid" : "local";
317
+ }
318
+ async function getStoragePg() {
319
+ const url = getStorageDatabaseUrl();
320
+ if (!url) {
321
+ throw new Error("Missing HASNA_MACHINES_DATABASE_URL or MACHINES_DATABASE_URL");
322
+ }
323
+ return new PgAdapterAsync(url);
324
+ }
325
+ async function runStorageMigrations(remote) {
326
+ for (const sql of PG_MIGRATIONS)
327
+ await remote.run(sql);
328
+ }
329
+ async function storagePush(options) {
330
+ const remote = await getStoragePg();
331
+ const db = getDb();
332
+ try {
333
+ await runStorageMigrations(remote);
334
+ const results = [];
335
+ for (const table of resolveTables(options?.tables)) {
336
+ results.push(await pushTable(db, remote, table));
337
+ }
338
+ recordSyncMeta(db, "push", results);
339
+ return results;
340
+ } finally {
341
+ await remote.close();
342
+ }
343
+ }
344
+ async function storagePull(options) {
345
+ const remote = await getStoragePg();
346
+ const db = getDb();
347
+ try {
348
+ await runStorageMigrations(remote);
349
+ const results = [];
350
+ for (const table of resolveTables(options?.tables)) {
351
+ results.push(await pullTable(remote, db, table));
352
+ }
353
+ recordSyncMeta(db, "pull", results);
354
+ return results;
355
+ } finally {
356
+ await remote.close();
357
+ }
358
+ }
359
+ async function storageSync(options) {
360
+ const pull = await storagePull(options);
361
+ const push = await storagePush(options);
362
+ return { pull, push };
363
+ }
364
+ function getSyncMetaAll() {
365
+ const db = getDb();
366
+ ensureSyncMetaTable(db);
367
+ return db.query("SELECT table_name, last_synced_at, direction FROM _machines_sync_meta ORDER BY table_name, direction").all();
368
+ }
369
+ function getStorageStatus() {
370
+ const activeEnv = getStorageDatabaseEnv();
371
+ return {
372
+ configured: Boolean(activeEnv),
373
+ mode: getStorageMode(),
374
+ env: STORAGE_DATABASE_ENV,
375
+ activeEnv: activeEnv?.name ?? null,
376
+ service: "machines",
377
+ tables: STORAGE_TABLES,
378
+ sync: getSyncMetaAll()
379
+ };
380
+ }
381
+ function resolveTables(tables) {
382
+ if (!tables || tables.length === 0)
383
+ return [...STORAGE_TABLES];
384
+ const allowed = new Set(STORAGE_TABLES);
385
+ const requested = tables.map((table) => table.trim()).filter(Boolean);
386
+ const invalid = requested.filter((table) => !allowed.has(table));
387
+ if (invalid.length > 0)
388
+ throw new Error(`Unknown machines storage table(s): ${invalid.join(", ")}`);
389
+ return requested;
390
+ }
391
+ function parseStorageTables(value) {
392
+ if (!value)
393
+ return;
394
+ return resolveTables(Array.isArray(value) ? value : value.split(","));
395
+ }
396
+ async function pushTable(db, remote, table) {
397
+ const result = { table, rowsRead: 0, rowsWritten: 0, errors: [] };
398
+ try {
399
+ if (!tableExists(db, table))
400
+ return result;
401
+ const rows = db.query(`SELECT * FROM ${quoteIdent(table)}`).all();
402
+ result.rowsRead = rows.length;
403
+ if (rows.length === 0)
404
+ return result;
405
+ const remoteColumns = await getRemoteColumns(remote, table);
406
+ const columns = filterRemoteColumns(remoteColumns, Object.keys(rows[0]));
407
+ result.rowsWritten = await upsertPg(remote, table, columns, rows);
408
+ } catch (error) {
409
+ result.errors.push(error instanceof Error ? error.message : String(error));
410
+ }
411
+ return result;
412
+ }
413
+ async function pullTable(remote, db, table) {
414
+ const result = { table, rowsRead: 0, rowsWritten: 0, errors: [] };
415
+ try {
416
+ if (!tableExists(db, table))
417
+ return result;
418
+ const rows = await remote.all(`SELECT * FROM ${quoteIdent(table)}`);
419
+ result.rowsRead = rows.length;
420
+ if (rows.length === 0)
421
+ return result;
422
+ const columns = filterLocalColumns(db, table, Object.keys(rows[0]));
423
+ result.rowsWritten = upsertSqlite(db, table, columns, rows);
424
+ } catch (error) {
425
+ result.errors.push(error instanceof Error ? error.message : String(error));
426
+ }
427
+ return result;
428
+ }
429
+ async function getRemoteColumns(remote, table) {
430
+ const rows = await remote.all("SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' AND table_name = ?", table);
431
+ return new Set(rows.map((row) => row.column_name));
432
+ }
433
+ function filterRemoteColumns(remoteColumns, columns) {
434
+ if (remoteColumns.size === 0)
435
+ return columns;
436
+ return columns.filter((column) => remoteColumns.has(column));
437
+ }
438
+ function filterLocalColumns(db, table, columns) {
439
+ const rows = db.query(`PRAGMA table_info(${quoteIdent(table)})`).all();
440
+ const allowed = new Set(rows.map((row) => row.name));
441
+ return columns.filter((column) => allowed.has(column));
442
+ }
443
+ async function upsertPg(remote, table, columns, rows) {
444
+ if (columns.length === 0)
445
+ return 0;
446
+ const primaryKeys = PRIMARY_KEYS[table];
447
+ const columnList = columns.map(quoteIdent).join(", ");
448
+ const placeholders = columns.map(() => "?").join(", ");
449
+ const keyList = primaryKeys.map(quoteIdent).join(", ");
450
+ const updateColumns = columns.filter((column) => !primaryKeys.includes(column));
451
+ const fallbackKey = primaryKeys[0];
452
+ const setClause = updateColumns.length > 0 ? updateColumns.map((column) => `${quoteIdent(column)} = EXCLUDED.${quoteIdent(column)}`).join(", ") : `${quoteIdent(fallbackKey)} = EXCLUDED.${quoteIdent(fallbackKey)}`;
453
+ for (const row of rows) {
454
+ await remote.run(`INSERT INTO ${quoteIdent(table)} (${columnList}) VALUES (${placeholders})
455
+ ON CONFLICT (${keyList}) DO UPDATE SET ${setClause}`, ...columns.map((column) => coerceForPg(row[column])));
456
+ }
457
+ return rows.length;
458
+ }
459
+ function upsertSqlite(db, table, columns, rows) {
460
+ if (columns.length === 0)
461
+ return 0;
462
+ const primaryKeys = PRIMARY_KEYS[table];
463
+ const columnList = columns.map(quoteIdent).join(", ");
464
+ const placeholders = columns.map(() => "?").join(", ");
465
+ const keyList = primaryKeys.map(quoteIdent).join(", ");
466
+ const updateColumns = columns.filter((column) => !primaryKeys.includes(column));
467
+ const fallbackKey = primaryKeys[0];
468
+ const setClause = updateColumns.length > 0 ? updateColumns.map((column) => `${quoteIdent(column)} = excluded.${quoteIdent(column)}`).join(", ") : `${quoteIdent(fallbackKey)} = excluded.${quoteIdent(fallbackKey)}`;
469
+ const statement = db.query(`INSERT INTO ${quoteIdent(table)} (${columnList}) VALUES (${placeholders})
470
+ ON CONFLICT (${keyList}) DO UPDATE SET ${setClause}`);
471
+ const insert = db.transaction((batch) => {
472
+ for (const row of batch)
473
+ statement.run(...columns.map((column) => coerceForSqlite(row[column])));
474
+ });
475
+ insert(rows);
476
+ return rows.length;
477
+ }
478
+ function recordSyncMeta(db, direction, results) {
479
+ ensureSyncMetaTable(db);
480
+ const now = new Date().toISOString();
481
+ const statement = db.query(`
482
+ INSERT INTO _machines_sync_meta (table_name, last_synced_at, direction)
483
+ VALUES (?, ?, ?)
484
+ ON CONFLICT(table_name, direction) DO UPDATE SET last_synced_at = excluded.last_synced_at
485
+ `);
486
+ for (const result of results) {
487
+ if (result.errors.length > 0)
488
+ continue;
489
+ statement.run(result.table, now, direction);
490
+ }
491
+ }
492
+ function ensureSyncMetaTable(db) {
493
+ db.exec(`
494
+ CREATE TABLE IF NOT EXISTS _machines_sync_meta (
495
+ table_name TEXT NOT NULL,
496
+ last_synced_at TEXT,
497
+ direction TEXT NOT NULL CHECK(direction IN ('push', 'pull')),
498
+ PRIMARY KEY (table_name, direction)
499
+ )
500
+ `);
501
+ }
502
+ function tableExists(db, table) {
503
+ const row = db.query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(table);
504
+ return Boolean(row);
505
+ }
506
+ function quoteIdent(identifier) {
507
+ return `"${identifier.replace(/"/g, '""')}"`;
508
+ }
509
+ function coerceForPg(value) {
510
+ if (value === undefined || value === null)
511
+ return null;
512
+ if (value instanceof Date)
513
+ return value.toISOString();
514
+ if (Buffer.isBuffer(value) || value instanceof Uint8Array)
515
+ return value;
516
+ if (typeof value === "object")
517
+ return JSON.stringify(value);
518
+ return value;
519
+ }
520
+ function coerceForSqlite(value) {
521
+ if (value === undefined || value === null)
522
+ return null;
523
+ if (typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean")
524
+ return value;
525
+ if (value instanceof Date)
526
+ return value.toISOString();
527
+ if (Buffer.isBuffer(value) || value instanceof Uint8Array)
528
+ return value;
529
+ if (typeof value === "object")
530
+ return JSON.stringify(value);
531
+ return String(value);
532
+ }
533
+ export {
534
+ storageSync,
535
+ storagePush,
536
+ storagePull,
537
+ runStorageMigrations,
538
+ resolveTables,
539
+ parseStorageTables,
540
+ getSyncMetaAll,
541
+ getStorageStatus,
542
+ getStoragePg,
543
+ getStorageMode,
544
+ getStorageDatabaseUrl,
545
+ getStorageDatabaseEnvName,
546
+ getStorageDatabaseEnv,
547
+ STORAGE_TABLES,
548
+ STORAGE_MODE_ENV,
549
+ STORAGE_DATABASE_ENV,
550
+ PgAdapterAsync,
551
+ PG_MIGRATIONS,
552
+ MACHINES_STORAGE_TABLES,
553
+ MACHINES_STORAGE_MODE_FALLBACK_ENV,
554
+ MACHINES_STORAGE_MODE_ENV,
555
+ MACHINES_STORAGE_FALLBACK_ENV,
556
+ MACHINES_STORAGE_ENV
557
+ };
@@ -0,0 +1,55 @@
1
+ import type { MachinePlatform } from "./types.js";
2
+ export interface TopologyCommandResult {
3
+ stdout: string;
4
+ stderr: string;
5
+ exitCode: number;
6
+ }
7
+ export type TopologyCommandRunner = (command: string) => TopologyCommandResult;
8
+ export interface MachineTopologyOptions {
9
+ includeTailscale?: boolean;
10
+ runner?: TopologyCommandRunner;
11
+ now?: Date;
12
+ }
13
+ export interface MachineRouteHint {
14
+ kind: "local" | "lan" | "tailscale" | "ssh";
15
+ target: string;
16
+ reachable: boolean | null;
17
+ }
18
+ export interface MachineTopologyEntry {
19
+ machine_id: string;
20
+ hostname: string | null;
21
+ platform: MachinePlatform | string | null;
22
+ os: string | null;
23
+ user: string | null;
24
+ workspace_path: string | null;
25
+ manifest_declared: boolean;
26
+ heartbeat_status: "online" | "offline" | "unknown";
27
+ last_heartbeat_at: string | null;
28
+ tailscale: {
29
+ dns_name: string | null;
30
+ ips: string[];
31
+ online: boolean | null;
32
+ active: boolean | null;
33
+ last_seen: string | null;
34
+ };
35
+ ssh: {
36
+ address: string | null;
37
+ route: "local" | "lan" | "tailscale" | "unknown";
38
+ command_target: string | null;
39
+ };
40
+ route_hints: MachineRouteHint[];
41
+ tags: string[];
42
+ metadata: Record<string, unknown>;
43
+ }
44
+ export interface MachineTopology {
45
+ generated_at: string;
46
+ local_machine_id: string;
47
+ local_hostname: string;
48
+ current_platform: MachinePlatform | string;
49
+ manifest_path_known: boolean;
50
+ machines: MachineTopologyEntry[];
51
+ warnings: string[];
52
+ }
53
+ export declare function discoverMachineTopology(options?: MachineTopologyOptions): MachineTopology;
54
+ export declare function getLocalMachineTopology(options?: MachineTopologyOptions): MachineTopologyEntry;
55
+ //# sourceMappingURL=topology.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topology.d.ts","sourceRoot":"","sources":["../src/topology.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,qBAAqB,CAAC;AAE/E,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,WAAW,GAAG,KAAK,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAAC;IAC1C,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IACnD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE;QACT,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,GAAG,EAAE,MAAM,EAAE,CAAC;QACd,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;QACvB,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,CAAC;IACF,GAAG,EAAE;QACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,KAAK,EAAE,OAAO,GAAG,KAAK,GAAG,WAAW,GAAG,SAAS,CAAC;QACjD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B,CAAC;IACF,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,eAAe,GAAG,MAAM,CAAC;IAC3C,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAyKD,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAmC7F;AAED,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,sBAA2B,GAAG,oBAAoB,CAkBlG"}
package/dist/types.d.ts CHANGED
@@ -127,7 +127,7 @@ export interface InstalledAppStatus {
127
127
  }
128
128
  export interface AppsStatusResult {
129
129
  machineId: string;
130
- source: "local" | "lan" | "tailscale";
130
+ source: "local" | "lan" | "tailscale" | "ssh";
131
131
  apps: InstalledAppStatus[];
132
132
  }
133
133
  export interface AppsDiffResult extends AppsStatusResult {
@@ -142,7 +142,7 @@ export interface CliToolStatus {
142
142
  }
143
143
  export interface ClaudeCliStatusResult {
144
144
  machineId: string;
145
- source: "local" | "lan" | "tailscale";
145
+ source: "local" | "lan" | "tailscale" | "ssh";
146
146
  tools: CliToolStatus[];
147
147
  }
148
148
  export interface ClaudeCliDiffResult extends ClaudeCliStatusResult {
@@ -169,7 +169,7 @@ export interface DoctorCheck {
169
169
  }
170
170
  export interface DoctorReport {
171
171
  machineId: string;
172
- source: "local" | "lan" | "tailscale";
172
+ source: "local" | "lan" | "tailscale" | "ssh";
173
173
  manifestPath?: string;
174
174
  dbPath?: string;
175
175
  notificationsPath?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}