@hasna/conversations 0.2.42 → 0.2.44
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/bin/hook.js +170 -20
- package/bin/index.js +478 -130
- package/bin/mcp.js +455 -107
- package/dist/index.js +385 -91
- package/dist/lib/messages.d.ts +1 -1
- package/dist/lib/presence.d.ts +2 -1
- package/dist/lib/webhooks.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,44 +5,65 @@ var __defProp = Object.defineProperty;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
8
13
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
9
21
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
22
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
23
|
for (let key of __getOwnPropNames(mod))
|
|
12
24
|
if (!__hasOwnProp.call(to, key))
|
|
13
25
|
__defProp(to, key, {
|
|
14
|
-
get: (
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
15
27
|
enumerable: true
|
|
16
28
|
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
17
31
|
return to;
|
|
18
32
|
};
|
|
19
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
20
33
|
var __toCommonJS = (from) => {
|
|
21
|
-
var entry = __moduleCache.get(from), desc;
|
|
34
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
22
35
|
if (entry)
|
|
23
36
|
return entry;
|
|
24
37
|
entry = __defProp({}, "__esModule", { value: true });
|
|
25
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
38
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
39
|
+
for (var key of __getOwnPropNames(from))
|
|
40
|
+
if (!__hasOwnProp.call(entry, key))
|
|
41
|
+
__defProp(entry, key, {
|
|
42
|
+
get: __accessProp.bind(from, key),
|
|
43
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
44
|
+
});
|
|
45
|
+
}
|
|
30
46
|
__moduleCache.set(from, entry);
|
|
31
47
|
return entry;
|
|
32
48
|
};
|
|
49
|
+
var __moduleCache;
|
|
33
50
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
51
|
+
var __returnValue = (v) => v;
|
|
52
|
+
function __exportSetter(name, newValue) {
|
|
53
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
54
|
+
}
|
|
34
55
|
var __export = (target, all) => {
|
|
35
56
|
for (var name in all)
|
|
36
57
|
__defProp(target, name, {
|
|
37
58
|
get: all[name],
|
|
38
59
|
enumerable: true,
|
|
39
60
|
configurable: true,
|
|
40
|
-
set: (
|
|
61
|
+
set: __exportSetter.bind(all, name)
|
|
41
62
|
});
|
|
42
63
|
};
|
|
43
64
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
44
65
|
|
|
45
|
-
//
|
|
66
|
+
// node_modules/@hasna/cloud/dist/index.js
|
|
46
67
|
import { createRequire } from "module";
|
|
47
68
|
import { Database } from "bun:sqlite";
|
|
48
69
|
import {
|
|
@@ -63,11 +84,11 @@ import { homedir as homedir4 } from "os";
|
|
|
63
84
|
import { join as join4 } from "path";
|
|
64
85
|
import { join as join6, dirname } from "path";
|
|
65
86
|
import { homedir as homedir5, platform } from "os";
|
|
66
|
-
function
|
|
87
|
+
function __accessProp2(key) {
|
|
67
88
|
return this[key];
|
|
68
89
|
}
|
|
69
|
-
function
|
|
70
|
-
this[name] =
|
|
90
|
+
function __exportSetter2(name, newValue) {
|
|
91
|
+
this[name] = __returnValue2.bind(null, newValue);
|
|
71
92
|
}
|
|
72
93
|
function translateSql(sql, dialect) {
|
|
73
94
|
if (dialect === "sqlite")
|
|
@@ -1097,10 +1118,10 @@ class SyncProgressTracker {
|
|
|
1097
1118
|
}
|
|
1098
1119
|
}
|
|
1099
1120
|
}
|
|
1100
|
-
var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2,
|
|
1121
|
+
var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node2, __toESMCache_esm2, __toESM2 = (mod, isNodeMode, target) => {
|
|
1101
1122
|
var canCache = mod != null && typeof mod === "object";
|
|
1102
1123
|
if (canCache) {
|
|
1103
|
-
var cache = isNodeMode ?
|
|
1124
|
+
var cache = isNodeMode ? __toESMCache_node2 ??= new WeakMap : __toESMCache_esm2 ??= new WeakMap;
|
|
1104
1125
|
var cached = cache.get(mod);
|
|
1105
1126
|
if (cached)
|
|
1106
1127
|
return cached;
|
|
@@ -1110,19 +1131,19 @@ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __t
|
|
|
1110
1131
|
for (let key of __getOwnPropNames2(mod))
|
|
1111
1132
|
if (!__hasOwnProp2.call(to, key))
|
|
1112
1133
|
__defProp2(to, key, {
|
|
1113
|
-
get:
|
|
1134
|
+
get: __accessProp2.bind(mod, key),
|
|
1114
1135
|
enumerable: true
|
|
1115
1136
|
});
|
|
1116
1137
|
if (canCache)
|
|
1117
1138
|
cache.set(mod, to);
|
|
1118
1139
|
return to;
|
|
1119
|
-
}, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports),
|
|
1140
|
+
}, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue2 = (v) => v, __export2 = (target, all) => {
|
|
1120
1141
|
for (var name in all)
|
|
1121
1142
|
__defProp2(target, name, {
|
|
1122
1143
|
get: all[name],
|
|
1123
1144
|
enumerable: true,
|
|
1124
1145
|
configurable: true,
|
|
1125
|
-
set:
|
|
1146
|
+
set: __exportSetter2.bind(all, name)
|
|
1126
1147
|
});
|
|
1127
1148
|
}, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), __require, require_postgres_array, require_arrayParser, require_postgres_date, require_mutable, require_postgres_interval, require_postgres_bytea, require_textParsers, require_pg_int8, require_binaryParsers, require_builtins, require_pg_types, require_defaults, require_utils, require_utils_legacy, require_utils_webcrypto, require_utils2, require_cert_signatures, require_sasl, require_type_overrides, require_pg_connection_string, require_connection_parameters, require_result, require_query, require_messages, require_buffer_writer, require_serializer, require_buffer_reader, require_parser, require_dist, require_empty, require_stream, require_connection, require_split2, require_helper, require_lib, require_client, require_pg_pool, require_query2, require_client2, require_lib2, import_lib, Client, Pool, Connection, types, Query, DatabaseError, escapeIdentifier, escapeLiteral, Result, TypeOverrides, defaults, esm_default, init_esm, init_adapter, util, objectUtil, ZodParsedType, getParsedType = (data) => {
|
|
1128
1149
|
const t = typeof data;
|
|
@@ -9459,6 +9480,137 @@ function getDbPath2() {
|
|
|
9459
9480
|
return process.env.CONVERSATIONS_DB_PATH;
|
|
9460
9481
|
return join5(getDataDir2(), "messages.db");
|
|
9461
9482
|
}
|
|
9483
|
+
function parsePresenceTimestamp(value) {
|
|
9484
|
+
if (typeof value !== "string" || !value)
|
|
9485
|
+
return 0;
|
|
9486
|
+
return new Date(`${value}Z`).getTime() || 0;
|
|
9487
|
+
}
|
|
9488
|
+
function normalizePresenceText(value) {
|
|
9489
|
+
if (typeof value !== "string")
|
|
9490
|
+
return null;
|
|
9491
|
+
const normalized = value.trim();
|
|
9492
|
+
return normalized ? normalized : null;
|
|
9493
|
+
}
|
|
9494
|
+
function shouldRebuildAgentPresenceTable(columns) {
|
|
9495
|
+
const byName = new Map(columns.map((column) => [column.name, column]));
|
|
9496
|
+
const agentCol = byName.get("agent");
|
|
9497
|
+
const projectCol = byName.get("project_id");
|
|
9498
|
+
if (!agentCol)
|
|
9499
|
+
return false;
|
|
9500
|
+
if (!projectCol)
|
|
9501
|
+
return true;
|
|
9502
|
+
return agentCol.pk !== 1 || projectCol.pk !== 2 || projectCol.notnull !== 1 || byName.has("pid");
|
|
9503
|
+
}
|
|
9504
|
+
function rebuildLegacyAgentPresenceTable(db2) {
|
|
9505
|
+
const fallbackNow = db2.prepare("SELECT strftime('%Y-%m-%dT%H:%M:%f', 'now') AS now").get().now;
|
|
9506
|
+
const legacyRows = db2.prepare("SELECT rowid AS _rowid, * FROM agent_presence").all();
|
|
9507
|
+
legacyRows.sort((left, right) => {
|
|
9508
|
+
const lastSeenDelta = parsePresenceTimestamp(right.last_seen_at) - parsePresenceTimestamp(left.last_seen_at);
|
|
9509
|
+
if (lastSeenDelta !== 0)
|
|
9510
|
+
return lastSeenDelta;
|
|
9511
|
+
const createdDelta = parsePresenceTimestamp(right.created_at) - parsePresenceTimestamp(left.created_at);
|
|
9512
|
+
if (createdDelta !== 0)
|
|
9513
|
+
return createdDelta;
|
|
9514
|
+
const projectDelta = Number(Boolean(normalizePresenceText(right.project_id))) - Number(Boolean(normalizePresenceText(left.project_id)));
|
|
9515
|
+
if (projectDelta !== 0)
|
|
9516
|
+
return projectDelta;
|
|
9517
|
+
return right._rowid - left._rowid;
|
|
9518
|
+
});
|
|
9519
|
+
const dedupedRows = new Map;
|
|
9520
|
+
for (const row of legacyRows) {
|
|
9521
|
+
const normalizedAgent = normalizePresenceText(row.agent)?.toLowerCase();
|
|
9522
|
+
if (!normalizedAgent)
|
|
9523
|
+
continue;
|
|
9524
|
+
const storedProjectId = normalizePresenceText(row.project_id) ?? "";
|
|
9525
|
+
const dedupeKey = `${normalizedAgent}\x00${storedProjectId}`;
|
|
9526
|
+
if (dedupedRows.has(dedupeKey))
|
|
9527
|
+
continue;
|
|
9528
|
+
dedupedRows.set(dedupeKey, row);
|
|
9529
|
+
}
|
|
9530
|
+
db2.exec("BEGIN");
|
|
9531
|
+
try {
|
|
9532
|
+
db2.exec(`
|
|
9533
|
+
CREATE TABLE agent_presence_new (
|
|
9534
|
+
id TEXT NOT NULL,
|
|
9535
|
+
agent TEXT NOT NULL,
|
|
9536
|
+
session_id TEXT,
|
|
9537
|
+
role TEXT NOT NULL DEFAULT 'agent',
|
|
9538
|
+
project_id TEXT NOT NULL DEFAULT '',
|
|
9539
|
+
status TEXT NOT NULL DEFAULT 'online',
|
|
9540
|
+
last_seen_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
|
|
9541
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
|
|
9542
|
+
metadata TEXT,
|
|
9543
|
+
PRIMARY KEY (agent, project_id)
|
|
9544
|
+
)
|
|
9545
|
+
`);
|
|
9546
|
+
const insertPresence = db2.prepare(`
|
|
9547
|
+
INSERT INTO agent_presence_new (id, agent, session_id, role, project_id, status, last_seen_at, created_at, metadata)
|
|
9548
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
9549
|
+
`);
|
|
9550
|
+
for (const [dedupeKey, row] of dedupedRows) {
|
|
9551
|
+
const [agent, projectKey] = dedupeKey.split("\x00");
|
|
9552
|
+
const id = normalizePresenceText(row.id) ?? crypto.randomUUID().slice(0, 8);
|
|
9553
|
+
const sessionId = normalizePresenceText(row.session_id);
|
|
9554
|
+
const role = normalizePresenceText(row.role) ?? "agent";
|
|
9555
|
+
const projectId = projectKey;
|
|
9556
|
+
const status = normalizePresenceText(row.status) ?? "online";
|
|
9557
|
+
const lastSeenAt = normalizePresenceText(row.last_seen_at) ?? fallbackNow;
|
|
9558
|
+
const createdAt = normalizePresenceText(row.created_at) ?? lastSeenAt;
|
|
9559
|
+
const metadata = typeof row.metadata === "string" ? row.metadata : row.metadata == null ? null : JSON.stringify(row.metadata);
|
|
9560
|
+
insertPresence.run(id, agent, sessionId, role, projectId, status, lastSeenAt, createdAt, metadata);
|
|
9561
|
+
}
|
|
9562
|
+
db2.exec("DROP TABLE agent_presence");
|
|
9563
|
+
db2.exec("ALTER TABLE agent_presence_new RENAME TO agent_presence");
|
|
9564
|
+
db2.exec("COMMIT");
|
|
9565
|
+
} catch (error) {
|
|
9566
|
+
db2.exec("ROLLBACK");
|
|
9567
|
+
throw error;
|
|
9568
|
+
}
|
|
9569
|
+
}
|
|
9570
|
+
function collapseDuplicateAgentPresenceRows(db2) {
|
|
9571
|
+
const rows = db2.prepare("SELECT rowid AS _rowid, * FROM agent_presence").all();
|
|
9572
|
+
rows.sort((left, right) => {
|
|
9573
|
+
const lastSeenDelta = parsePresenceTimestamp(right.last_seen_at) - parsePresenceTimestamp(left.last_seen_at);
|
|
9574
|
+
if (lastSeenDelta !== 0)
|
|
9575
|
+
return lastSeenDelta;
|
|
9576
|
+
const createdDelta = parsePresenceTimestamp(right.created_at) - parsePresenceTimestamp(left.created_at);
|
|
9577
|
+
if (createdDelta !== 0)
|
|
9578
|
+
return createdDelta;
|
|
9579
|
+
const projectDelta = Number(Boolean(normalizePresenceText(right.project_id))) - Number(Boolean(normalizePresenceText(left.project_id)));
|
|
9580
|
+
if (projectDelta !== 0)
|
|
9581
|
+
return projectDelta;
|
|
9582
|
+
return right._rowid - left._rowid;
|
|
9583
|
+
});
|
|
9584
|
+
const rowIdsToDelete = [];
|
|
9585
|
+
const seenAgents = new Set;
|
|
9586
|
+
for (const row of rows) {
|
|
9587
|
+
const normalizedAgent = normalizePresenceText(row.agent)?.toLowerCase();
|
|
9588
|
+
if (!normalizedAgent)
|
|
9589
|
+
continue;
|
|
9590
|
+
if (seenAgents.has(normalizedAgent)) {
|
|
9591
|
+
rowIdsToDelete.push(row._rowid);
|
|
9592
|
+
continue;
|
|
9593
|
+
}
|
|
9594
|
+
seenAgents.add(normalizedAgent);
|
|
9595
|
+
}
|
|
9596
|
+
if (rowIdsToDelete.length === 0)
|
|
9597
|
+
return;
|
|
9598
|
+
db2.exec("BEGIN");
|
|
9599
|
+
try {
|
|
9600
|
+
const deleteRow = db2.prepare("DELETE FROM agent_presence WHERE rowid = ?");
|
|
9601
|
+
for (const rowId of rowIdsToDelete) {
|
|
9602
|
+
deleteRow.run(rowId);
|
|
9603
|
+
}
|
|
9604
|
+
db2.exec("COMMIT");
|
|
9605
|
+
} catch (error) {
|
|
9606
|
+
db2.exec("ROLLBACK");
|
|
9607
|
+
throw error;
|
|
9608
|
+
}
|
|
9609
|
+
}
|
|
9610
|
+
function ensureAgentPresenceAgentUniqueIndex(db2) {
|
|
9611
|
+
collapseDuplicateAgentPresenceRows(db2);
|
|
9612
|
+
db2.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_presence_agent_unique ON agent_presence(agent)");
|
|
9613
|
+
}
|
|
9462
9614
|
function getDb() {
|
|
9463
9615
|
if (db)
|
|
9464
9616
|
return db;
|
|
@@ -9531,16 +9683,18 @@ function getDb() {
|
|
|
9531
9683
|
db.exec(`
|
|
9532
9684
|
CREATE TABLE IF NOT EXISTS agent_presence (
|
|
9533
9685
|
id TEXT NOT NULL,
|
|
9534
|
-
agent TEXT
|
|
9686
|
+
agent TEXT NOT NULL,
|
|
9535
9687
|
session_id TEXT,
|
|
9536
9688
|
role TEXT NOT NULL DEFAULT 'agent',
|
|
9537
|
-
project_id TEXT,
|
|
9689
|
+
project_id TEXT NOT NULL DEFAULT '',
|
|
9538
9690
|
status TEXT NOT NULL DEFAULT 'online',
|
|
9539
9691
|
last_seen_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
|
|
9540
9692
|
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
|
|
9541
|
-
metadata TEXT
|
|
9693
|
+
metadata TEXT,
|
|
9694
|
+
PRIMARY KEY (agent, project_id)
|
|
9542
9695
|
)
|
|
9543
9696
|
`);
|
|
9697
|
+
ensureAgentPresenceAgentUniqueIndex(db);
|
|
9544
9698
|
db.exec(`
|
|
9545
9699
|
CREATE TABLE IF NOT EXISTS resource_locks (
|
|
9546
9700
|
resource_type TEXT NOT NULL,
|
|
@@ -9642,8 +9796,13 @@ function getDb() {
|
|
|
9642
9796
|
db.exec("UPDATE messages SET uuid = lower(hex(randomblob(16))) WHERE uuid IS NULL");
|
|
9643
9797
|
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_messages_uuid ON messages(uuid)");
|
|
9644
9798
|
}
|
|
9645
|
-
|
|
9646
|
-
|
|
9799
|
+
let presenceCols = db.prepare("PRAGMA table_info(agent_presence)").all();
|
|
9800
|
+
let presenceColNames = presenceCols.map((c) => c.name);
|
|
9801
|
+
if (shouldRebuildAgentPresenceTable(presenceCols)) {
|
|
9802
|
+
rebuildLegacyAgentPresenceTable(db);
|
|
9803
|
+
presenceCols = db.prepare("PRAGMA table_info(agent_presence)").all();
|
|
9804
|
+
presenceColNames = presenceCols.map((c) => c.name);
|
|
9805
|
+
}
|
|
9647
9806
|
if (!presenceColNames.includes("id")) {
|
|
9648
9807
|
db.exec("ALTER TABLE agent_presence ADD COLUMN id TEXT NOT NULL DEFAULT ''");
|
|
9649
9808
|
const rows = db.prepare("SELECT agent FROM agent_presence").all();
|
|
@@ -9664,7 +9823,9 @@ function getDb() {
|
|
|
9664
9823
|
}
|
|
9665
9824
|
if (!presenceColNames.includes("project_id")) {
|
|
9666
9825
|
db.exec("ALTER TABLE agent_presence ADD COLUMN project_id TEXT");
|
|
9826
|
+
db.exec("UPDATE agent_presence SET project_id = '' WHERE project_id IS NULL");
|
|
9667
9827
|
}
|
|
9828
|
+
ensureAgentPresenceAgentUniqueIndex(db);
|
|
9668
9829
|
db.exec(`
|
|
9669
9830
|
CREATE TABLE IF NOT EXISTS message_read_receipts (
|
|
9670
9831
|
message_id INTEGER NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
|
|
@@ -11386,14 +11547,14 @@ Check the top-level render call using <` + parentName + ">.";
|
|
|
11386
11547
|
var thenableResult = result;
|
|
11387
11548
|
var wasAwaited = false;
|
|
11388
11549
|
var thenable = {
|
|
11389
|
-
then: function(
|
|
11550
|
+
then: function(resolve2, reject) {
|
|
11390
11551
|
wasAwaited = true;
|
|
11391
11552
|
thenableResult.then(function(returnValue2) {
|
|
11392
11553
|
popActScope(prevActScopeDepth);
|
|
11393
11554
|
if (actScopeDepth === 0) {
|
|
11394
|
-
recursivelyFlushAsyncActWork(returnValue2,
|
|
11555
|
+
recursivelyFlushAsyncActWork(returnValue2, resolve2, reject);
|
|
11395
11556
|
} else {
|
|
11396
|
-
|
|
11557
|
+
resolve2(returnValue2);
|
|
11397
11558
|
}
|
|
11398
11559
|
}, function(error2) {
|
|
11399
11560
|
popActScope(prevActScopeDepth);
|
|
@@ -11422,20 +11583,20 @@ Check the top-level render call using <` + parentName + ">.";
|
|
|
11422
11583
|
ReactCurrentActQueue.current = null;
|
|
11423
11584
|
}
|
|
11424
11585
|
var _thenable = {
|
|
11425
|
-
then: function(
|
|
11586
|
+
then: function(resolve2, reject) {
|
|
11426
11587
|
if (ReactCurrentActQueue.current === null) {
|
|
11427
11588
|
ReactCurrentActQueue.current = [];
|
|
11428
|
-
recursivelyFlushAsyncActWork(returnValue,
|
|
11589
|
+
recursivelyFlushAsyncActWork(returnValue, resolve2, reject);
|
|
11429
11590
|
} else {
|
|
11430
|
-
|
|
11591
|
+
resolve2(returnValue);
|
|
11431
11592
|
}
|
|
11432
11593
|
}
|
|
11433
11594
|
};
|
|
11434
11595
|
return _thenable;
|
|
11435
11596
|
} else {
|
|
11436
11597
|
var _thenable2 = {
|
|
11437
|
-
then: function(
|
|
11438
|
-
|
|
11598
|
+
then: function(resolve2, reject) {
|
|
11599
|
+
resolve2(returnValue);
|
|
11439
11600
|
}
|
|
11440
11601
|
};
|
|
11441
11602
|
return _thenable2;
|
|
@@ -11451,7 +11612,7 @@ Check the top-level render call using <` + parentName + ">.";
|
|
|
11451
11612
|
actScopeDepth = prevActScopeDepth;
|
|
11452
11613
|
}
|
|
11453
11614
|
}
|
|
11454
|
-
function recursivelyFlushAsyncActWork(returnValue,
|
|
11615
|
+
function recursivelyFlushAsyncActWork(returnValue, resolve2, reject) {
|
|
11455
11616
|
{
|
|
11456
11617
|
var queue = ReactCurrentActQueue.current;
|
|
11457
11618
|
if (queue !== null) {
|
|
@@ -11460,16 +11621,16 @@ Check the top-level render call using <` + parentName + ">.";
|
|
|
11460
11621
|
enqueueTask(function() {
|
|
11461
11622
|
if (queue.length === 0) {
|
|
11462
11623
|
ReactCurrentActQueue.current = null;
|
|
11463
|
-
|
|
11624
|
+
resolve2(returnValue);
|
|
11464
11625
|
} else {
|
|
11465
|
-
recursivelyFlushAsyncActWork(returnValue,
|
|
11626
|
+
recursivelyFlushAsyncActWork(returnValue, resolve2, reject);
|
|
11466
11627
|
}
|
|
11467
11628
|
});
|
|
11468
11629
|
} catch (error2) {
|
|
11469
11630
|
reject(error2);
|
|
11470
11631
|
}
|
|
11471
11632
|
} else {
|
|
11472
|
-
|
|
11633
|
+
resolve2(returnValue);
|
|
11473
11634
|
}
|
|
11474
11635
|
}
|
|
11475
11636
|
}
|
|
@@ -11560,13 +11721,15 @@ var require_react = __commonJS((exports, module) => {
|
|
|
11560
11721
|
// src/lib/messages.ts
|
|
11561
11722
|
init_db();
|
|
11562
11723
|
import { randomUUID } from "crypto";
|
|
11563
|
-
import { mkdirSync as mkdirSync5, copyFileSync as copyFileSync3, statSync as statSync2 } from "fs";
|
|
11564
|
-
import { join as join8 } from "path";
|
|
11724
|
+
import { mkdirSync as mkdirSync5, copyFileSync as copyFileSync3, statSync as statSync2, existsSync as existsSync6, realpathSync } from "fs";
|
|
11725
|
+
import { join as join8, basename, resolve } from "path";
|
|
11565
11726
|
|
|
11566
11727
|
// src/lib/webhooks.ts
|
|
11567
11728
|
init_db();
|
|
11568
11729
|
import { readFileSync as readFileSync2 } from "fs";
|
|
11569
11730
|
import { join as join7 } from "path";
|
|
11731
|
+
import dns from "dns";
|
|
11732
|
+
import net from "net";
|
|
11570
11733
|
var cachedConfig = null;
|
|
11571
11734
|
var configLoadedAt = 0;
|
|
11572
11735
|
var CONFIG_CACHE_MS = 1e4;
|
|
@@ -11601,6 +11764,44 @@ function matchesEvent(webhook, msg) {
|
|
|
11601
11764
|
}
|
|
11602
11765
|
return false;
|
|
11603
11766
|
}
|
|
11767
|
+
function isPrivateIP(ip) {
|
|
11768
|
+
if (net.isIPv4(ip)) {
|
|
11769
|
+
const parts = ip.split(".").map(Number);
|
|
11770
|
+
if (parts[0] === 10)
|
|
11771
|
+
return true;
|
|
11772
|
+
if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31)
|
|
11773
|
+
return true;
|
|
11774
|
+
if (parts[0] === 192 && parts[1] === 168)
|
|
11775
|
+
return true;
|
|
11776
|
+
if (parts[0] === 127)
|
|
11777
|
+
return true;
|
|
11778
|
+
if (parts[0] === 169 && parts[1] === 254)
|
|
11779
|
+
return true;
|
|
11780
|
+
if (parts[0] === 0)
|
|
11781
|
+
return true;
|
|
11782
|
+
} else if (net.isIPv6(ip)) {
|
|
11783
|
+
const lower = ip.toLowerCase();
|
|
11784
|
+
if (lower === "::1" || lower.startsWith("::ffff:") || lower.startsWith("fc") || lower.startsWith("fd"))
|
|
11785
|
+
return true;
|
|
11786
|
+
}
|
|
11787
|
+
return false;
|
|
11788
|
+
}
|
|
11789
|
+
async function validateWebhookUrl(urlStr) {
|
|
11790
|
+
try {
|
|
11791
|
+
const url = new URL(urlStr);
|
|
11792
|
+
if (url.protocol !== "https:")
|
|
11793
|
+
return false;
|
|
11794
|
+
const hostname = url.hostname;
|
|
11795
|
+
if (hostname === "localhost" || hostname === "0.0.0.0" || hostname === "127.0.0.1" || hostname === "::1")
|
|
11796
|
+
return false;
|
|
11797
|
+
const addresses = await dns.promises.lookup(hostname, { all: true });
|
|
11798
|
+
if (!Array.isArray(addresses))
|
|
11799
|
+
return false;
|
|
11800
|
+
return !addresses.some((a) => isPrivateIP(a.address));
|
|
11801
|
+
} catch {
|
|
11802
|
+
return false;
|
|
11803
|
+
}
|
|
11804
|
+
}
|
|
11604
11805
|
function fireWebhooks(msg) {
|
|
11605
11806
|
const config = loadConfig();
|
|
11606
11807
|
if (!config.webhooks || config.webhooks.length === 0)
|
|
@@ -11610,20 +11811,24 @@ function fireWebhooks(msg) {
|
|
|
11610
11811
|
continue;
|
|
11611
11812
|
if (!matchesEvent(webhook, msg))
|
|
11612
11813
|
continue;
|
|
11613
|
-
|
|
11614
|
-
|
|
11615
|
-
|
|
11616
|
-
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
|
|
11624
|
-
|
|
11625
|
-
|
|
11626
|
-
|
|
11814
|
+
validateWebhookUrl(webhook.url).then((valid) => {
|
|
11815
|
+
if (!valid)
|
|
11816
|
+
return;
|
|
11817
|
+
fetch(webhook.url, {
|
|
11818
|
+
method: "POST",
|
|
11819
|
+
headers: { "Content-Type": "application/json" },
|
|
11820
|
+
body: JSON.stringify({
|
|
11821
|
+
id: msg.id,
|
|
11822
|
+
from: msg.from_agent,
|
|
11823
|
+
to: msg.to_agent,
|
|
11824
|
+
space: msg.space,
|
|
11825
|
+
content: msg.content,
|
|
11826
|
+
priority: msg.priority,
|
|
11827
|
+
blocking: msg.blocking,
|
|
11828
|
+
created_at: msg.created_at
|
|
11829
|
+
})
|
|
11830
|
+
}).catch(() => {});
|
|
11831
|
+
});
|
|
11627
11832
|
}
|
|
11628
11833
|
}
|
|
11629
11834
|
|
|
@@ -11668,6 +11873,22 @@ function getAttachmentsDir() {
|
|
|
11668
11873
|
return process.env.CONVERSATIONS_ATTACHMENTS_DIR;
|
|
11669
11874
|
return join8(getDataDir2(), "attachments");
|
|
11670
11875
|
}
|
|
11876
|
+
function validateAttachment(sourcePath, name) {
|
|
11877
|
+
const absolute = resolve(sourcePath);
|
|
11878
|
+
if (!existsSync6(absolute)) {
|
|
11879
|
+
throw new Error(`Attachment source not found: ${sourcePath}`);
|
|
11880
|
+
}
|
|
11881
|
+
const real = realpathSync(absolute);
|
|
11882
|
+
const stat = statSync2(real);
|
|
11883
|
+
if (!stat.isFile()) {
|
|
11884
|
+
throw new Error(`Attachment source must be a regular file: ${sourcePath}`);
|
|
11885
|
+
}
|
|
11886
|
+
const safeName = basename(name.replace(/\0/g, ""));
|
|
11887
|
+
if (!safeName || safeName.startsWith(".")) {
|
|
11888
|
+
throw new Error(`Invalid attachment name: ${name}`);
|
|
11889
|
+
}
|
|
11890
|
+
return { safeSource: real, safeName };
|
|
11891
|
+
}
|
|
11671
11892
|
function guessMimeType(name) {
|
|
11672
11893
|
const ext = name.split(".").pop()?.toLowerCase();
|
|
11673
11894
|
const mimeMap = {
|
|
@@ -11739,14 +11960,15 @@ function sendMessage(opts) {
|
|
|
11739
11960
|
mkdirSync5(attachmentsDir, { recursive: true });
|
|
11740
11961
|
const attachmentInfos = [];
|
|
11741
11962
|
for (const att of opts.attachments) {
|
|
11742
|
-
const
|
|
11743
|
-
|
|
11963
|
+
const { safeSource, safeName } = validateAttachment(att.source_path, att.name);
|
|
11964
|
+
const destPath = join8(attachmentsDir, safeName);
|
|
11965
|
+
copyFileSync3(safeSource, destPath);
|
|
11744
11966
|
const stat = statSync2(destPath);
|
|
11745
11967
|
attachmentInfos.push({
|
|
11746
|
-
name:
|
|
11968
|
+
name: safeName,
|
|
11747
11969
|
path: destPath,
|
|
11748
11970
|
size: stat.size,
|
|
11749
|
-
mime_type: guessMimeType(
|
|
11971
|
+
mime_type: guessMimeType(safeName)
|
|
11750
11972
|
});
|
|
11751
11973
|
}
|
|
11752
11974
|
const attachmentsJson = JSON.stringify(attachmentInfos);
|
|
@@ -11808,8 +12030,10 @@ function readMessages(opts = {}) {
|
|
|
11808
12030
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
11809
12031
|
const resolvedLimit = isLatest ? Math.floor(opts.latest) : Number.isFinite(opts.limit) && opts.limit > 0 ? Math.floor(opts.limit) : 20;
|
|
11810
12032
|
const order = isLatest ? "DESC" : opts.order?.toLowerCase() === "desc" ? "DESC" : "ASC";
|
|
11811
|
-
const resolvedOffset =
|
|
11812
|
-
const
|
|
12033
|
+
const resolvedOffset = Number.isFinite(opts.offset) ? Math.floor(opts.offset) : 0;
|
|
12034
|
+
const safeLimit = Math.max(1, Math.min(resolvedLimit, 1e4));
|
|
12035
|
+
const safeOffset = Math.max(0, Math.floor(resolvedOffset));
|
|
12036
|
+
const rows = db2.prepare(`SELECT * FROM messages ${where} ORDER BY created_at ${order}, id ${order} LIMIT ${safeLimit} OFFSET ${safeOffset}`).all(...params);
|
|
11813
12037
|
let messages = rows.map(parseMessage);
|
|
11814
12038
|
if (opts.include_reply_counts && messages.length > 0) {
|
|
11815
12039
|
const db22 = getDb();
|
|
@@ -11954,8 +12178,9 @@ function getPinnedMessages(opts) {
|
|
|
11954
12178
|
params.push(opts.session_id);
|
|
11955
12179
|
}
|
|
11956
12180
|
const where = `WHERE ${conditions.join(" AND ")}`;
|
|
11957
|
-
const
|
|
11958
|
-
const
|
|
12181
|
+
const safeLimit = Number.isFinite(opts?.limit) && opts.limit > 0 ? Math.floor(opts.limit) : 0;
|
|
12182
|
+
const limitClause = safeLimit > 0 ? `LIMIT ${safeLimit}` : "";
|
|
12183
|
+
const rows = db2.prepare(`SELECT * FROM messages ${where} ORDER BY pinned_at DESC, id DESC ${limitClause}`).all(...params);
|
|
11959
12184
|
return rows.map(parseMessage);
|
|
11960
12185
|
}
|
|
11961
12186
|
function getUnreadBlockers(agent) {
|
|
@@ -13064,6 +13289,33 @@ function getReactionSummary(messageId) {
|
|
|
13064
13289
|
init_db();
|
|
13065
13290
|
var ONLINE_THRESHOLD_SECONDS = 60;
|
|
13066
13291
|
var CONFLICT_THRESHOLD_SECONDS = 30 * 60;
|
|
13292
|
+
function normalizeAgentName(name) {
|
|
13293
|
+
return name.trim().toLowerCase();
|
|
13294
|
+
}
|
|
13295
|
+
function toStoredProjectId(projectId) {
|
|
13296
|
+
const normalized = projectId?.trim() ?? "";
|
|
13297
|
+
return normalized || "";
|
|
13298
|
+
}
|
|
13299
|
+
function fromStoredProjectId(projectId) {
|
|
13300
|
+
const normalized = typeof projectId === "string" ? projectId.trim() : "";
|
|
13301
|
+
return normalized || null;
|
|
13302
|
+
}
|
|
13303
|
+
function getPresenceByAgent(db2, agent) {
|
|
13304
|
+
return db2.prepare(`
|
|
13305
|
+
SELECT * FROM agent_presence
|
|
13306
|
+
WHERE LOWER(agent) = ?
|
|
13307
|
+
ORDER BY last_seen_at DESC
|
|
13308
|
+
LIMIT 1
|
|
13309
|
+
`).get(agent);
|
|
13310
|
+
}
|
|
13311
|
+
function getPresenceByAgentAndProject(db2, agent, projectId) {
|
|
13312
|
+
return db2.prepare(`
|
|
13313
|
+
SELECT * FROM agent_presence
|
|
13314
|
+
WHERE LOWER(agent) = ? AND COALESCE(project_id, '') = ?
|
|
13315
|
+
ORDER BY last_seen_at DESC
|
|
13316
|
+
LIMIT 1
|
|
13317
|
+
`).get(agent, projectId);
|
|
13318
|
+
}
|
|
13067
13319
|
function parsePresence(row) {
|
|
13068
13320
|
let metadata = null;
|
|
13069
13321
|
if (row.metadata) {
|
|
@@ -13082,7 +13334,7 @@ function parsePresence(row) {
|
|
|
13082
13334
|
agent: row.agent,
|
|
13083
13335
|
session_id: row.session_id ?? null,
|
|
13084
13336
|
role: row.role || "agent",
|
|
13085
|
-
project_id: row.project_id
|
|
13337
|
+
project_id: fromStoredProjectId(row.project_id),
|
|
13086
13338
|
status: row.status,
|
|
13087
13339
|
last_seen_at: lastSeenAt,
|
|
13088
13340
|
created_at: row.created_at || lastSeenAt,
|
|
@@ -13100,9 +13352,10 @@ function isAgentConflict(result) {
|
|
|
13100
13352
|
}
|
|
13101
13353
|
function registerAgent(name, sessionId, role, projectId) {
|
|
13102
13354
|
const db2 = getDb();
|
|
13103
|
-
const normalizedName = name
|
|
13355
|
+
const normalizedName = normalizeAgentName(name);
|
|
13104
13356
|
const result = db2.transaction(() => {
|
|
13105
|
-
const existing = db2
|
|
13357
|
+
const existing = getPresenceByAgent(db2, normalizedName);
|
|
13358
|
+
const storedProjectId = toStoredProjectId(projectId ?? existing?.project_id);
|
|
13106
13359
|
if (existing) {
|
|
13107
13360
|
const lastSeenAt = existing.last_seen_at;
|
|
13108
13361
|
const existingSessionId = existing.session_id;
|
|
@@ -13120,12 +13373,26 @@ function registerAgent(name, sessionId, role, projectId) {
|
|
|
13120
13373
|
};
|
|
13121
13374
|
}
|
|
13122
13375
|
const tookOver = existingSessionId !== sessionId;
|
|
13123
|
-
|
|
13124
|
-
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
|
|
13128
|
-
|
|
13376
|
+
const existingId = existing.id;
|
|
13377
|
+
const target = getPresenceByAgentAndProject(db2, normalizedName, storedProjectId);
|
|
13378
|
+
if (target && target.id !== existingId) {
|
|
13379
|
+
db2.prepare(`
|
|
13380
|
+
UPDATE agent_presence
|
|
13381
|
+
SET session_id = ?, role = ?, status = 'online', last_seen_at = strftime('%Y-%m-%dT%H:%M:%f', 'now')
|
|
13382
|
+
WHERE id = ?
|
|
13383
|
+
`).run(sessionId, role || existing.role || "agent", target.id);
|
|
13384
|
+
db2.prepare("DELETE FROM agent_presence WHERE id = ?").run(existingId);
|
|
13385
|
+
} else {
|
|
13386
|
+
db2.prepare(`
|
|
13387
|
+
UPDATE agent_presence
|
|
13388
|
+
SET session_id = ?, role = ?, project_id = ?, status = 'online', last_seen_at = strftime('%Y-%m-%dT%H:%M:%f', 'now')
|
|
13389
|
+
WHERE id = ?
|
|
13390
|
+
`).run(sessionId, role || existing.role || "agent", storedProjectId, existingId);
|
|
13391
|
+
}
|
|
13392
|
+
const updated = getPresenceByAgentAndProject(db2, normalizedName, storedProjectId) ?? getPresenceByAgent(db2, normalizedName);
|
|
13393
|
+
if (!updated) {
|
|
13394
|
+
throw new Error(`Failed to update presence for agent "${normalizedName}"`);
|
|
13395
|
+
}
|
|
13129
13396
|
return { agent: parsePresence(updated), created: false, took_over: tookOver };
|
|
13130
13397
|
}
|
|
13131
13398
|
const id = crypto.randomUUID().slice(0, 8);
|
|
@@ -13133,33 +13400,60 @@ function registerAgent(name, sessionId, role, projectId) {
|
|
|
13133
13400
|
db2.prepare(`
|
|
13134
13401
|
INSERT INTO agent_presence (id, agent, session_id, role, project_id, status, last_seen_at, created_at)
|
|
13135
13402
|
VALUES (?, ?, ?, ?, ?, 'online', strftime('%Y-%m-%dT%H:%M:%f', 'now'), strftime('%Y-%m-%dT%H:%M:%f', 'now'))
|
|
13136
|
-
`).run(id, normalizedName, sessionId, resolvedRole,
|
|
13137
|
-
const created = db2
|
|
13403
|
+
`).run(id, normalizedName, sessionId, resolvedRole, storedProjectId);
|
|
13404
|
+
const created = getPresenceByAgentAndProject(db2, normalizedName, storedProjectId) ?? getPresenceByAgent(db2, normalizedName);
|
|
13405
|
+
if (!created) {
|
|
13406
|
+
throw new Error(`Failed to create presence for agent "${normalizedName}"`);
|
|
13407
|
+
}
|
|
13138
13408
|
return { agent: parsePresence(created), created: true, took_over: false };
|
|
13139
13409
|
});
|
|
13140
13410
|
return result;
|
|
13141
13411
|
}
|
|
13142
|
-
function heartbeat(agent, status, metadata, sessionId) {
|
|
13412
|
+
function heartbeat(agent, status, metadata, sessionId, projectId) {
|
|
13143
13413
|
const db2 = getDb();
|
|
13144
13414
|
const metadataJson = metadata ? JSON.stringify(metadata) : null;
|
|
13145
13415
|
const resolvedStatus = status || "online";
|
|
13146
|
-
const normalizedAgent = agent
|
|
13147
|
-
|
|
13148
|
-
|
|
13149
|
-
|
|
13150
|
-
|
|
13151
|
-
|
|
13152
|
-
|
|
13153
|
-
|
|
13154
|
-
|
|
13155
|
-
|
|
13156
|
-
|
|
13157
|
-
|
|
13416
|
+
const normalizedAgent = normalizeAgentName(agent);
|
|
13417
|
+
db2.transaction(() => {
|
|
13418
|
+
const existing = getPresenceByAgent(db2, normalizedAgent);
|
|
13419
|
+
const storedProjectId = toStoredProjectId(projectId ?? existing?.project_id);
|
|
13420
|
+
const id = existing?.id || crypto.randomUUID().slice(0, 8);
|
|
13421
|
+
if (existing) {
|
|
13422
|
+
const existingId = existing.id;
|
|
13423
|
+
const target = getPresenceByAgentAndProject(db2, normalizedAgent, storedProjectId);
|
|
13424
|
+
if (target && target.id !== existingId) {
|
|
13425
|
+
db2.prepare(`
|
|
13426
|
+
UPDATE agent_presence
|
|
13427
|
+
SET status = ?,
|
|
13428
|
+
last_seen_at = strftime('%Y-%m-%dT%H:%M:%f', 'now'),
|
|
13429
|
+
session_id = COALESCE(?, session_id),
|
|
13430
|
+
metadata = ?
|
|
13431
|
+
WHERE id = ?
|
|
13432
|
+
`).run(resolvedStatus, sessionId ?? null, metadataJson, target.id);
|
|
13433
|
+
db2.prepare("DELETE FROM agent_presence WHERE id = ?").run(existingId);
|
|
13434
|
+
return;
|
|
13435
|
+
}
|
|
13436
|
+
db2.prepare(`
|
|
13437
|
+
UPDATE agent_presence
|
|
13438
|
+
SET status = ?,
|
|
13439
|
+
last_seen_at = strftime('%Y-%m-%dT%H:%M:%f', 'now'),
|
|
13440
|
+
session_id = COALESCE(?, session_id),
|
|
13441
|
+
metadata = ?,
|
|
13442
|
+
project_id = ?
|
|
13443
|
+
WHERE id = ?
|
|
13444
|
+
`).run(resolvedStatus, sessionId ?? null, metadataJson, storedProjectId, existingId);
|
|
13445
|
+
return;
|
|
13446
|
+
}
|
|
13447
|
+
db2.prepare(`
|
|
13448
|
+
INSERT INTO agent_presence (id, agent, session_id, role, project_id, status, last_seen_at, created_at, metadata)
|
|
13449
|
+
VALUES (?, ?, ?, 'agent', ?, ?, strftime('%Y-%m-%dT%H:%M:%f', 'now'), strftime('%Y-%m-%dT%H:%M:%f', 'now'), ?)
|
|
13450
|
+
`).run(id, normalizedAgent, sessionId ?? null, storedProjectId, resolvedStatus, metadataJson);
|
|
13451
|
+
});
|
|
13158
13452
|
}
|
|
13159
13453
|
function getPresence(agent) {
|
|
13160
13454
|
const db2 = getDb();
|
|
13161
|
-
const normalizedAgent = agent
|
|
13162
|
-
const row = db2
|
|
13455
|
+
const normalizedAgent = normalizeAgentName(agent);
|
|
13456
|
+
const row = getPresenceByAgent(db2, normalizedAgent);
|
|
13163
13457
|
return row ? parsePresence(row) : null;
|
|
13164
13458
|
}
|
|
13165
13459
|
function listAgents(opts) {
|
|
@@ -13174,14 +13468,14 @@ function listAgents(opts) {
|
|
|
13174
13468
|
}
|
|
13175
13469
|
function removePresence(agent) {
|
|
13176
13470
|
const db2 = getDb();
|
|
13177
|
-
const normalizedAgent = agent
|
|
13471
|
+
const normalizedAgent = normalizeAgentName(agent);
|
|
13178
13472
|
const result = db2.prepare("DELETE FROM agent_presence WHERE LOWER(agent) = ?").run(normalizedAgent);
|
|
13179
13473
|
return result.changes > 0;
|
|
13180
13474
|
}
|
|
13181
13475
|
function renameAgent(oldName, newName) {
|
|
13182
13476
|
const db2 = getDb();
|
|
13183
|
-
const normalizedOld = oldName
|
|
13184
|
-
const normalizedNew = newName
|
|
13477
|
+
const normalizedOld = normalizeAgentName(oldName);
|
|
13478
|
+
const normalizedNew = normalizeAgentName(newName);
|
|
13185
13479
|
const existing = db2.prepare("SELECT agent FROM agent_presence WHERE LOWER(agent) = ?").get(normalizedOld);
|
|
13186
13480
|
if (!existing)
|
|
13187
13481
|
return false;
|
|
@@ -13888,13 +14182,13 @@ var gatherTrainingData = async (options = {}) => {
|
|
|
13888
14182
|
};
|
|
13889
14183
|
// src/lib/model-config.ts
|
|
13890
14184
|
init_db();
|
|
13891
|
-
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync7, existsSync as
|
|
14185
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync7, existsSync as existsSync7 } from "fs";
|
|
13892
14186
|
import { join as join10 } from "path";
|
|
13893
14187
|
var DEFAULT_MODEL = "gpt-4o-mini";
|
|
13894
14188
|
var CONFIG_DIR3 = getDataDir2();
|
|
13895
14189
|
var CONFIG_PATH2 = join10(CONFIG_DIR3, "config.json");
|
|
13896
14190
|
function readConfig() {
|
|
13897
|
-
if (!
|
|
14191
|
+
if (!existsSync7(CONFIG_PATH2))
|
|
13898
14192
|
return {};
|
|
13899
14193
|
try {
|
|
13900
14194
|
return JSON.parse(readFileSync4(CONFIG_PATH2, "utf-8"));
|
|
@@ -13903,7 +14197,7 @@ function readConfig() {
|
|
|
13903
14197
|
}
|
|
13904
14198
|
}
|
|
13905
14199
|
function writeConfig(config) {
|
|
13906
|
-
if (!
|
|
14200
|
+
if (!existsSync7(CONFIG_DIR3)) {
|
|
13907
14201
|
mkdirSync7(CONFIG_DIR3, { recursive: true });
|
|
13908
14202
|
}
|
|
13909
14203
|
writeFileSync3(CONFIG_PATH2, JSON.stringify(config, null, 2), "utf-8");
|