haansi 0.1.30 → 0.1.32
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/haansi.js +407 -110
- package/package.json +1 -1
package/dist/haansi.js
CHANGED
|
@@ -95,7 +95,7 @@ var require_package = __commonJS({
|
|
|
95
95
|
"package.json"(exports2, module2) {
|
|
96
96
|
module2.exports = {
|
|
97
97
|
name: "haansi",
|
|
98
|
-
version: "0.1.
|
|
98
|
+
version: "0.1.32",
|
|
99
99
|
description: "Haansi CLI - Session collector and MCP server for Claude Code & OpenAI Codex",
|
|
100
100
|
bin: {
|
|
101
101
|
haansi: "./dist/haansi.js"
|
|
@@ -1203,16 +1203,37 @@ var init_metrics = __esm({
|
|
|
1203
1203
|
MetricsService = class {
|
|
1204
1204
|
projectId;
|
|
1205
1205
|
serviceName;
|
|
1206
|
-
isLocal;
|
|
1207
1206
|
constructor(serviceName, projectId) {
|
|
1208
1207
|
this.serviceName = serviceName;
|
|
1209
1208
|
this.projectId = projectId === null ? "" : projectId || process.env.GCP_PROJECT_ID || "";
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1209
|
+
}
|
|
1210
|
+
/**
|
|
1211
|
+
* Whether to log to the console instead of a cloud backend.
|
|
1212
|
+
*
|
|
1213
|
+
* TWO BUGS LIVED IN THE OLD VERSION OF THIS, and both silently discarded
|
|
1214
|
+
* every metric on AWS.
|
|
1215
|
+
*
|
|
1216
|
+
* It read `NODE_ENV === "development" || !projectId`, where `projectId`
|
|
1217
|
+
* falls back to `GCP_PROJECT_ID`. On AWS that variable is unset — so a
|
|
1218
|
+
* production service classified itself as local and logged metrics to
|
|
1219
|
+
* stdout, where nothing could alarm or autoscale on them. The GCP-shaped
|
|
1220
|
+
* question ("do I have a project id?") had become a proxy for "am I in the
|
|
1221
|
+
* cloud?" the moment a second provider existed.
|
|
1222
|
+
*
|
|
1223
|
+
* And it was evaluated ONCE, in the constructor. Services construct
|
|
1224
|
+
* MetricsService at module load and register their cloud provider during
|
|
1225
|
+
* startup, so even on GCP the answer could be computed before the backend
|
|
1226
|
+
* that would have answered it existed.
|
|
1227
|
+
*
|
|
1228
|
+
* Now it asks the question that actually matters, at the moment it matters:
|
|
1229
|
+
* is there a registered backend to send to? A registered backend means
|
|
1230
|
+
* cloud, whatever any environment variable says. Development still forces
|
|
1231
|
+
* console so a local run never writes to a real metric namespace.
|
|
1232
|
+
*/
|
|
1233
|
+
get isLocal() {
|
|
1234
|
+
if (process.env.NODE_ENV === "development") return true;
|
|
1235
|
+
if (getCloudBackend2()) return false;
|
|
1236
|
+
return !this.projectId;
|
|
1216
1237
|
}
|
|
1217
1238
|
/**
|
|
1218
1239
|
* Record a custom metric
|
|
@@ -1651,6 +1672,110 @@ var init_observability_service = __esm({
|
|
|
1651
1672
|
}
|
|
1652
1673
|
});
|
|
1653
1674
|
|
|
1675
|
+
// ../../packages/@company/observability/src/scaling-metrics.ts
|
|
1676
|
+
function spec(s) {
|
|
1677
|
+
return s;
|
|
1678
|
+
}
|
|
1679
|
+
var SCALING_METRICS_SERVICE, SCALING_METRICS_NAMESPACE, SCALING_METRICS;
|
|
1680
|
+
var init_scaling_metrics = __esm({
|
|
1681
|
+
"../../packages/@company/observability/src/scaling-metrics.ts"() {
|
|
1682
|
+
"use strict";
|
|
1683
|
+
init_types();
|
|
1684
|
+
SCALING_METRICS_SERVICE = "backlog-reconciler";
|
|
1685
|
+
SCALING_METRICS_NAMESPACE = `Haansi/${SCALING_METRICS_SERVICE}`;
|
|
1686
|
+
SCALING_METRICS = {
|
|
1687
|
+
CANONICAL_BACKLOG_EVENTS: spec({
|
|
1688
|
+
name: "haansi/ingestion/canonical_backlog_events",
|
|
1689
|
+
unit: "Count",
|
|
1690
|
+
description: "source_events rows awaiting normalization (normalized_at IS NULL), all orgs.",
|
|
1691
|
+
dimensions: ["environment"],
|
|
1692
|
+
treatMissingData: "breaching",
|
|
1693
|
+
missingDataRationale: "The reconciler is the only publisher and runs on a schedule independent of every worker. Its silence means the reconciler itself is broken, and the backlog it was watching is unobserved rather than empty. Scaling out against an unknown backlog wastes money; scaling in loses the queue. Breaching keeps capacity up until a human looks."
|
|
1694
|
+
}),
|
|
1695
|
+
CANONICAL_BACKLOG_OLDEST_SECONDS: spec({
|
|
1696
|
+
name: "haansi/ingestion/canonical_backlog_oldest_seconds",
|
|
1697
|
+
unit: "Seconds",
|
|
1698
|
+
description: "Age of the oldest un-normalized source_event. The latency signal count cannot give.",
|
|
1699
|
+
dimensions: ["environment"],
|
|
1700
|
+
treatMissingData: "breaching",
|
|
1701
|
+
missingDataRationale: "Same publisher as the count, so the same reasoning: absence means unobserved, not fresh."
|
|
1702
|
+
}),
|
|
1703
|
+
SESSION_MINING_BACKLOG_RUNS: spec({
|
|
1704
|
+
name: "haansi/mining/session_backlog_runs",
|
|
1705
|
+
unit: "Count",
|
|
1706
|
+
description: "session_mining_runs not in a terminal stage, all orgs. Includes rows awaiting a provider batch.",
|
|
1707
|
+
dimensions: ["environment", "queue"],
|
|
1708
|
+
treatMissingData: "breaching",
|
|
1709
|
+
missingDataRationale: "Published by the reconciler, not by the mining workers it measures, so absence is a reconciler fault rather than an empty queue."
|
|
1710
|
+
}),
|
|
1711
|
+
SESSION_MINING_OLDEST_SECONDS: spec({
|
|
1712
|
+
name: "haansi/mining/session_backlog_oldest_seconds",
|
|
1713
|
+
unit: "Seconds",
|
|
1714
|
+
description: "Age of the oldest non-terminal session mining run, by stage queue.",
|
|
1715
|
+
dimensions: ["environment", "queue"],
|
|
1716
|
+
treatMissingData: "breaching",
|
|
1717
|
+
missingDataRationale: "As above \u2014 reconciler-published."
|
|
1718
|
+
}),
|
|
1719
|
+
SESSION_MINING_FAILED_RUNS: spec({
|
|
1720
|
+
name: "haansi/mining/session_failed_runs",
|
|
1721
|
+
unit: "Count",
|
|
1722
|
+
description: "session_mining_runs in stage 'failed', all orgs.",
|
|
1723
|
+
dimensions: ["environment"],
|
|
1724
|
+
treatMissingData: "notBreaching",
|
|
1725
|
+
missingDataRationale: "The ONE deliberate exception. This drives alerting, not scaling: no capacity decision reads it, so a missing value cannot cost or lose anything. Treating absence as breaching would page on the reconciler being down, which its own liveness metric already covers."
|
|
1726
|
+
}),
|
|
1727
|
+
EMBEDDING_BACKLOG_ROWS: spec({
|
|
1728
|
+
name: "haansi/embeddings/backlog_rows",
|
|
1729
|
+
unit: "Count",
|
|
1730
|
+
description: "Rows with a NULL embedding across the intelligence tables that carry one.",
|
|
1731
|
+
dimensions: ["environment", "workload"],
|
|
1732
|
+
treatMissingData: "breaching",
|
|
1733
|
+
missingDataRationale: "This is the metric that must be able to wake a fleet from zero, so it is published by the reconciler and never by an embedding worker. A worker-published version of it would read as zero precisely when the fleet is asleep with work pending \u2014 the failure this whole phase exists to remove."
|
|
1734
|
+
}),
|
|
1735
|
+
EMBEDDING_BACKLOG_OLDEST_SECONDS: spec({
|
|
1736
|
+
name: "haansi/embeddings/backlog_oldest_seconds",
|
|
1737
|
+
unit: "Seconds",
|
|
1738
|
+
description: "Age of the oldest row still missing an embedding.",
|
|
1739
|
+
dimensions: ["environment", "workload"],
|
|
1740
|
+
treatMissingData: "breaching",
|
|
1741
|
+
missingDataRationale: "As above \u2014 reconciler-published wake source."
|
|
1742
|
+
}),
|
|
1743
|
+
EMBEDDING_CLAIMS_PENDING: spec({
|
|
1744
|
+
name: "haansi/embeddings/claims_pending",
|
|
1745
|
+
unit: "Count",
|
|
1746
|
+
description: "embedding_claims awaiting a worker (pending, or leased with an expired lease).",
|
|
1747
|
+
dimensions: ["environment"],
|
|
1748
|
+
treatMissingData: "breaching",
|
|
1749
|
+
missingDataRationale: "Reconciler-published, so absence means the queue is unobserved rather than empty. This is the signal that sizes the worker fleet; reading silence as zero would scale it away with work queued."
|
|
1750
|
+
}),
|
|
1751
|
+
EMBEDDING_CLAIMS_ACTIVE_LEASES: spec({
|
|
1752
|
+
name: "haansi/embeddings/claims_active_leases",
|
|
1753
|
+
unit: "Count",
|
|
1754
|
+
description: "Claims currently leased with an unexpired lease \u2014 work in flight right now.",
|
|
1755
|
+
dimensions: ["environment"],
|
|
1756
|
+
treatMissingData: "breaching",
|
|
1757
|
+
missingDataRationale: "This is the SCALE-IN PROTECTION signal: a non-zero value means a worker is mid-inference and must not be terminated. Absence has to read as 'possibly busy', because the alternative \u2014 assuming idle \u2014 kills a worker holding a lease and the claim then waits out its full lease window before anyone retries it."
|
|
1758
|
+
}),
|
|
1759
|
+
EMBEDDING_CLAIMS_OLDEST_SECONDS: spec({
|
|
1760
|
+
name: "haansi/embeddings/claims_oldest_seconds",
|
|
1761
|
+
unit: "Seconds",
|
|
1762
|
+
description: "Age of the oldest outstanding claim. The latency signal a count cannot give.",
|
|
1763
|
+
dimensions: ["environment"],
|
|
1764
|
+
treatMissingData: "breaching",
|
|
1765
|
+
missingDataRationale: "As above. A queue of five that has not moved in an hour is a stuck consumer, and a count-only alarm reads it as healthy."
|
|
1766
|
+
}),
|
|
1767
|
+
RECONCILER_LIVENESS: spec({
|
|
1768
|
+
name: "haansi/reconciler/liveness",
|
|
1769
|
+
unit: "Count",
|
|
1770
|
+
description: "Emitted as 1 by every successful reconciler run. The publisher's own heartbeat.",
|
|
1771
|
+
dimensions: ["environment"],
|
|
1772
|
+
treatMissingData: "breaching",
|
|
1773
|
+
missingDataRationale: "Every other metric here declares that its absence means 'the reconciler is broken'. This is the metric that says so directly, so an operator gets one alarm naming the cause instead of six naming symptoms."
|
|
1774
|
+
})
|
|
1775
|
+
};
|
|
1776
|
+
}
|
|
1777
|
+
});
|
|
1778
|
+
|
|
1654
1779
|
// ../../packages/@company/observability/src/middleware.ts
|
|
1655
1780
|
var init_middleware = __esm({
|
|
1656
1781
|
"../../packages/@company/observability/src/middleware.ts"() {
|
|
@@ -1666,6 +1791,15 @@ var init_health = __esm({
|
|
|
1666
1791
|
}
|
|
1667
1792
|
});
|
|
1668
1793
|
|
|
1794
|
+
// ../../packages/@company/observability/src/degradation.ts
|
|
1795
|
+
var init_degradation = __esm({
|
|
1796
|
+
"../../packages/@company/observability/src/degradation.ts"() {
|
|
1797
|
+
"use strict";
|
|
1798
|
+
init_types();
|
|
1799
|
+
init_observability_service();
|
|
1800
|
+
}
|
|
1801
|
+
});
|
|
1802
|
+
|
|
1669
1803
|
// ../../packages/@company/observability/src/index.ts
|
|
1670
1804
|
var defaultObservability, getDefaultObservability, observability;
|
|
1671
1805
|
var init_src2 = __esm({
|
|
@@ -1674,8 +1808,11 @@ var init_src2 = __esm({
|
|
|
1674
1808
|
init_observability_service();
|
|
1675
1809
|
init_logger();
|
|
1676
1810
|
init_metrics();
|
|
1811
|
+
init_scaling_metrics();
|
|
1677
1812
|
init_middleware();
|
|
1678
1813
|
init_health();
|
|
1814
|
+
init_degradation();
|
|
1815
|
+
init_types();
|
|
1679
1816
|
defaultObservability = null;
|
|
1680
1817
|
getDefaultObservability = () => {
|
|
1681
1818
|
if (!defaultObservability) {
|
|
@@ -1956,10 +2093,11 @@ var init_agents = __esm({
|
|
|
1956
2093
|
}
|
|
1957
2094
|
});
|
|
1958
2095
|
|
|
1959
|
-
// ../service-capture/
|
|
2096
|
+
// ../service-capture/agent-sessions/collector.ts
|
|
1960
2097
|
var collector_exports = {};
|
|
1961
2098
|
__export(collector_exports, {
|
|
1962
|
-
collect: () => collect
|
|
2099
|
+
collect: () => collect,
|
|
2100
|
+
uploadSession: () => uploadSession
|
|
1963
2101
|
});
|
|
1964
2102
|
function edgeScrub(content) {
|
|
1965
2103
|
let result = content;
|
|
@@ -2122,9 +2260,12 @@ async function getUploadedSessions(apiUrl2, token) {
|
|
|
2122
2260
|
});
|
|
2123
2261
|
}
|
|
2124
2262
|
return map2;
|
|
2125
|
-
} catch {
|
|
2126
|
-
logger.warn(
|
|
2127
|
-
|
|
2263
|
+
} catch (err) {
|
|
2264
|
+
void logger.warn(
|
|
2265
|
+
"Could not fetch uploaded sessions list \u2014 skipping this run rather than re-uploading everything",
|
|
2266
|
+
{ error: err?.message ?? String(err) }
|
|
2267
|
+
);
|
|
2268
|
+
return null;
|
|
2128
2269
|
}
|
|
2129
2270
|
}
|
|
2130
2271
|
async function uploadSession(sessionId, content, apiUrl2, token, agentSource, gitInfo) {
|
|
@@ -2139,19 +2280,86 @@ async function uploadSession(sessionId, content, apiUrl2, token, agentSource, gi
|
|
|
2139
2280
|
if (gitInfo?.gitRemoteUrl) headers["x-git-remote-url"] = gitInfo.gitRemoteUrl;
|
|
2140
2281
|
if (gitInfo?.gitCommit) headers["x-git-commit"] = gitInfo.gitCommit;
|
|
2141
2282
|
if (gitInfo?.gitBranch) headers["x-git-branch"] = gitInfo.gitBranch;
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2283
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
2284
|
+
const response = await fetch(`${apiUrl2}/api/v1/capture/sessions/raw`, {
|
|
2285
|
+
method: "POST",
|
|
2286
|
+
headers,
|
|
2287
|
+
body: new Uint8Array(body)
|
|
2288
|
+
});
|
|
2289
|
+
if (response.ok) return;
|
|
2290
|
+
if (response.status === 429 && attempt < UPLOAD_RATE_LIMIT_RETRIES) {
|
|
2291
|
+
const retryAfter = Number(response.headers.get("Retry-After"));
|
|
2292
|
+
const waitMs = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1e3 : DEFAULT_RATE_LIMIT_WAIT_MS;
|
|
2293
|
+
await new Promise((resolve4) => setTimeout(resolve4, waitMs));
|
|
2294
|
+
continue;
|
|
2295
|
+
}
|
|
2148
2296
|
const text = await response.text().catch(() => "");
|
|
2149
|
-
|
|
2297
|
+
const err = new Error(
|
|
2150
2298
|
`Upload failed (${response.status}): ${text.slice(0, 200)}`
|
|
2151
2299
|
);
|
|
2300
|
+
if (response.status === 429) {
|
|
2301
|
+
err.rateLimited = true;
|
|
2302
|
+
}
|
|
2303
|
+
throw err;
|
|
2152
2304
|
}
|
|
2153
2305
|
}
|
|
2154
|
-
|
|
2306
|
+
function acquireRunLock() {
|
|
2307
|
+
try {
|
|
2308
|
+
(0, import_fs3.mkdirSync)((0, import_path3.join)((0, import_os3.homedir)(), ".haansi"), { recursive: true });
|
|
2309
|
+
} catch {
|
|
2310
|
+
}
|
|
2311
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
2312
|
+
try {
|
|
2313
|
+
const fd = (0, import_fs3.openSync)(LOCK_FILE, "wx");
|
|
2314
|
+
(0, import_fs3.writeSync)(fd, String(process.pid));
|
|
2315
|
+
return fd;
|
|
2316
|
+
} catch {
|
|
2317
|
+
const holder = Number(
|
|
2318
|
+
(() => {
|
|
2319
|
+
try {
|
|
2320
|
+
return (0, import_fs3.readFileSync)(LOCK_FILE, "utf-8").trim();
|
|
2321
|
+
} catch {
|
|
2322
|
+
return "";
|
|
2323
|
+
}
|
|
2324
|
+
})()
|
|
2325
|
+
);
|
|
2326
|
+
if (!holder || !isProcessAlive(holder)) {
|
|
2327
|
+
try {
|
|
2328
|
+
(0, import_fs3.unlinkSync)(LOCK_FILE);
|
|
2329
|
+
} catch {
|
|
2330
|
+
}
|
|
2331
|
+
continue;
|
|
2332
|
+
}
|
|
2333
|
+
void logger.warn(
|
|
2334
|
+
"Another collector run is in progress \u2014 skipping this run",
|
|
2335
|
+
{
|
|
2336
|
+
holderPid: holder
|
|
2337
|
+
}
|
|
2338
|
+
);
|
|
2339
|
+
return null;
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
return null;
|
|
2343
|
+
}
|
|
2344
|
+
function isProcessAlive(pid) {
|
|
2345
|
+
try {
|
|
2346
|
+
process.kill(pid, 0);
|
|
2347
|
+
return true;
|
|
2348
|
+
} catch (err) {
|
|
2349
|
+
return err?.code === "EPERM";
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
function releaseRunLock(fd) {
|
|
2353
|
+
try {
|
|
2354
|
+
(0, import_fs3.closeSync)(fd);
|
|
2355
|
+
} catch {
|
|
2356
|
+
}
|
|
2357
|
+
try {
|
|
2358
|
+
(0, import_fs3.unlinkSync)(LOCK_FILE);
|
|
2359
|
+
} catch {
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
async function collectLocked(options) {
|
|
2155
2363
|
const apiUrl2 = process.env.HAANSI_API_URL ?? DEFAULT_API_URL2;
|
|
2156
2364
|
const token = resolveToken2();
|
|
2157
2365
|
if (!token && !options.dryRun) {
|
|
@@ -2170,7 +2378,15 @@ async function collect(options) {
|
|
|
2170
2378
|
let uploaded = 0;
|
|
2171
2379
|
let skipped = 0;
|
|
2172
2380
|
let errors = 0;
|
|
2381
|
+
let deferred = 0;
|
|
2173
2382
|
const remoteMap = options.forceAll ? /* @__PURE__ */ new Map() : await getUploadedSessions(apiUrl2, token);
|
|
2383
|
+
if (remoteMap === null) {
|
|
2384
|
+
void logger.warn("Skipping collection: server inventory unavailable", {
|
|
2385
|
+
localSessions: localSessions.length,
|
|
2386
|
+
hint: "re-authenticate with `haansi auth login` if this persists"
|
|
2387
|
+
});
|
|
2388
|
+
return { uploaded: 0, skipped: localSessions.length, errors: 0 };
|
|
2389
|
+
}
|
|
2174
2390
|
const toUpload = [];
|
|
2175
2391
|
for (const session of localSessions) {
|
|
2176
2392
|
const remote = remoteMap.get(session.sessionId);
|
|
@@ -2246,11 +2462,22 @@ async function collect(options) {
|
|
|
2246
2462
|
}
|
|
2247
2463
|
);
|
|
2248
2464
|
} catch (err) {
|
|
2249
|
-
|
|
2250
|
-
|
|
2465
|
+
if (err?.rateLimited) {
|
|
2466
|
+
deferred++;
|
|
2467
|
+
void logger.info(`Rate limited, will retry next run: ${shortId}`);
|
|
2468
|
+
} else {
|
|
2469
|
+
errors++;
|
|
2470
|
+
logger.error(`Failed to upload ${shortId}`, { err: err.message });
|
|
2471
|
+
}
|
|
2251
2472
|
}
|
|
2252
2473
|
}
|
|
2253
|
-
|
|
2474
|
+
if (deferred > 0) {
|
|
2475
|
+
void logger.info(
|
|
2476
|
+
`${deferred} session(s) deferred by the upload rate limit \u2014 they remain queued`,
|
|
2477
|
+
{ deferred, uploaded }
|
|
2478
|
+
);
|
|
2479
|
+
}
|
|
2480
|
+
return { uploaded, skipped, errors, deferred };
|
|
2254
2481
|
}
|
|
2255
2482
|
async function main() {
|
|
2256
2483
|
const forceAll = process.argv.includes("--force-all");
|
|
@@ -2269,9 +2496,19 @@ async function main() {
|
|
|
2269
2496
|
});
|
|
2270
2497
|
if (errors > 0) process.exit(1);
|
|
2271
2498
|
}
|
|
2272
|
-
|
|
2499
|
+
async function collect(options) {
|
|
2500
|
+
if (options.dryRun) return collectLocked(options);
|
|
2501
|
+
const lock = acquireRunLock();
|
|
2502
|
+
if (lock === null) return { uploaded: 0, skipped: 0, errors: 0 };
|
|
2503
|
+
try {
|
|
2504
|
+
return await collectLocked(options);
|
|
2505
|
+
} finally {
|
|
2506
|
+
releaseRunLock(lock);
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
var import_dotenv, import_path3, import_fs3, import_os3, import_zlib, import_child_process, logger, DEFAULT_API_URL2, CREDENTIALS_FILE4, LOCK_FILE, MIN_LINES, EDGE_SCRUB_PATTERNS, GIT_BIN_CANDIDATES, resolvedGitBin, UPLOAD_RATE_LIMIT_RETRIES, DEFAULT_RATE_LIMIT_WAIT_MS;
|
|
2273
2510
|
var init_collector = __esm({
|
|
2274
|
-
"../service-capture/
|
|
2511
|
+
"../service-capture/agent-sessions/collector.ts"() {
|
|
2275
2512
|
"use strict";
|
|
2276
2513
|
import_dotenv = __toESM(require_main());
|
|
2277
2514
|
import_path3 = require("path");
|
|
@@ -2286,6 +2523,7 @@ var init_collector = __esm({
|
|
|
2286
2523
|
logger = createLogger("session-collector");
|
|
2287
2524
|
DEFAULT_API_URL2 = SERVICE_URL_DEFAULTS.haansiApiBaseUrl;
|
|
2288
2525
|
CREDENTIALS_FILE4 = (0, import_path3.join)((0, import_os3.homedir)(), ".haansi", "credentials.json");
|
|
2526
|
+
LOCK_FILE = (0, import_path3.join)((0, import_os3.homedir)(), ".haansi", "collector.lock");
|
|
2289
2527
|
MIN_LINES = 4;
|
|
2290
2528
|
EDGE_SCRUB_PATTERNS = [
|
|
2291
2529
|
{
|
|
@@ -2332,6 +2570,8 @@ var init_collector = __esm({
|
|
|
2332
2570
|
"/usr/local/bin/git",
|
|
2333
2571
|
"/usr/bin/git"
|
|
2334
2572
|
];
|
|
2573
|
+
UPLOAD_RATE_LIMIT_RETRIES = 2;
|
|
2574
|
+
DEFAULT_RATE_LIMIT_WAIT_MS = 6e4;
|
|
2335
2575
|
if (require.main === module) {
|
|
2336
2576
|
main().catch((err) => {
|
|
2337
2577
|
logger.error("Collector failed", err);
|
|
@@ -3358,7 +3598,50 @@ var require_node_cron = __commonJS({
|
|
|
3358
3598
|
}
|
|
3359
3599
|
});
|
|
3360
3600
|
|
|
3361
|
-
// ../service-capture/
|
|
3601
|
+
// ../service-capture/agent-sessions/log-rotation.ts
|
|
3602
|
+
function rotateLogIfLarge(logFile, maxBytes = MAX_LOG_BYTES, keepBytes = KEEP_TAIL_BYTES) {
|
|
3603
|
+
let sizeBefore = 0;
|
|
3604
|
+
try {
|
|
3605
|
+
sizeBefore = (0, import_fs4.statSync)(logFile).size;
|
|
3606
|
+
} catch {
|
|
3607
|
+
return { rotated: false, sizeBefore: 0, tailKept: 0 };
|
|
3608
|
+
}
|
|
3609
|
+
if (sizeBefore <= maxBytes) {
|
|
3610
|
+
return { rotated: false, sizeBefore, tailKept: 0 };
|
|
3611
|
+
}
|
|
3612
|
+
let tailKept = 0;
|
|
3613
|
+
try {
|
|
3614
|
+
const start = Math.max(0, sizeBefore - keepBytes);
|
|
3615
|
+
const length = sizeBefore - start;
|
|
3616
|
+
const buf = Buffer.alloc(length);
|
|
3617
|
+
const fd = (0, import_fs4.openSync)(logFile, "r");
|
|
3618
|
+
try {
|
|
3619
|
+
(0, import_fs4.readSync)(fd, buf, 0, length, start);
|
|
3620
|
+
} finally {
|
|
3621
|
+
(0, import_fs4.closeSync)(fd);
|
|
3622
|
+
}
|
|
3623
|
+
(0, import_fs4.writeFileSync)(`${logFile}.1`, buf);
|
|
3624
|
+
tailKept = length;
|
|
3625
|
+
} catch {
|
|
3626
|
+
}
|
|
3627
|
+
try {
|
|
3628
|
+
(0, import_fs4.truncateSync)(logFile, 0);
|
|
3629
|
+
} catch {
|
|
3630
|
+
return { rotated: false, sizeBefore, tailKept };
|
|
3631
|
+
}
|
|
3632
|
+
return { rotated: true, sizeBefore, tailKept };
|
|
3633
|
+
}
|
|
3634
|
+
var import_fs4, MAX_LOG_BYTES, KEEP_TAIL_BYTES;
|
|
3635
|
+
var init_log_rotation = __esm({
|
|
3636
|
+
"../service-capture/agent-sessions/log-rotation.ts"() {
|
|
3637
|
+
"use strict";
|
|
3638
|
+
import_fs4 = require("fs");
|
|
3639
|
+
MAX_LOG_BYTES = 10 * 1024 * 1024;
|
|
3640
|
+
KEEP_TAIL_BYTES = 1 * 1024 * 1024;
|
|
3641
|
+
}
|
|
3642
|
+
});
|
|
3643
|
+
|
|
3644
|
+
// ../service-capture/agent-sessions/collector-daemon.ts
|
|
3362
3645
|
var collector_daemon_exports = {};
|
|
3363
3646
|
function resolveAgentsEnv() {
|
|
3364
3647
|
const raw = process.env.HAANSI_AGENTS;
|
|
@@ -3369,16 +3652,27 @@ function resolveAgentsEnv() {
|
|
|
3369
3652
|
}
|
|
3370
3653
|
function getOnDiskVersion() {
|
|
3371
3654
|
try {
|
|
3372
|
-
const realEntry = (0,
|
|
3655
|
+
const realEntry = (0, import_fs5.realpathSync)(process.argv[1]);
|
|
3373
3656
|
const pkgPath = (0, import_path4.resolve)((0, import_path4.dirname)(realEntry), "..", "package.json");
|
|
3374
|
-
if (!(0,
|
|
3375
|
-
const pkg = JSON.parse((0,
|
|
3657
|
+
if (!(0, import_fs5.existsSync)(pkgPath)) return null;
|
|
3658
|
+
const pkg = JSON.parse((0, import_fs5.readFileSync)(pkgPath, "utf-8"));
|
|
3376
3659
|
return pkg.version ?? null;
|
|
3377
3660
|
} catch {
|
|
3378
3661
|
return null;
|
|
3379
3662
|
}
|
|
3380
3663
|
}
|
|
3664
|
+
function trimLog() {
|
|
3665
|
+
const { rotated, sizeBefore, tailKept } = rotateLogIfLarge(LOG_FILE);
|
|
3666
|
+
if (rotated) {
|
|
3667
|
+
logger2.info("Rotated daemon log", {
|
|
3668
|
+
sizeBefore,
|
|
3669
|
+
tailKept,
|
|
3670
|
+
previous: `${LOG_FILE}.1`
|
|
3671
|
+
});
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3381
3674
|
async function run() {
|
|
3675
|
+
trimLog();
|
|
3382
3676
|
const agents = resolveAgentsEnv();
|
|
3383
3677
|
logger2.info("Collect run starting", { agents: agents?.join(",") ?? "all" });
|
|
3384
3678
|
const start = Date.now();
|
|
@@ -3420,21 +3714,24 @@ async function main2() {
|
|
|
3420
3714
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
3421
3715
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
3422
3716
|
}
|
|
3423
|
-
var import_dotenv2,
|
|
3717
|
+
var import_dotenv2, import_fs5, import_path4, import_os4, import_node_cron, logger2, IN_MEMORY_VERSION, SCHEDULE, LOG_FILE;
|
|
3424
3718
|
var init_collector_daemon = __esm({
|
|
3425
|
-
"../service-capture/
|
|
3719
|
+
"../service-capture/agent-sessions/collector-daemon.ts"() {
|
|
3426
3720
|
"use strict";
|
|
3427
3721
|
import_dotenv2 = __toESM(require_main());
|
|
3428
|
-
|
|
3722
|
+
import_fs5 = require("fs");
|
|
3429
3723
|
import_path4 = require("path");
|
|
3724
|
+
import_os4 = require("os");
|
|
3430
3725
|
import_node_cron = __toESM(require_node_cron());
|
|
3431
3726
|
init_collector();
|
|
3432
3727
|
init_src2();
|
|
3728
|
+
init_log_rotation();
|
|
3433
3729
|
(0, import_dotenv2.config)({ path: (0, import_path4.resolve)(__dirname, "../../../.env") });
|
|
3434
3730
|
logger2 = createLogger("collector-daemon");
|
|
3435
3731
|
IN_MEMORY_VERSION = // eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
3436
3732
|
require_package().version;
|
|
3437
3733
|
SCHEDULE = process.env.HAANSI_COLLECT_SCHEDULE ?? process.env.CLAUDE_COLLECT_SCHEDULE ?? "*/30 * * * *";
|
|
3734
|
+
LOG_FILE = (0, import_path4.join)((0, import_os4.homedir)(), ".haansi", "daemon.log");
|
|
3438
3735
|
main2().catch((err) => {
|
|
3439
3736
|
logger2.error("Daemon failed to start", err);
|
|
3440
3737
|
process.exit(1);
|
|
@@ -3442,7 +3739,7 @@ var init_collector_daemon = __esm({
|
|
|
3442
3739
|
}
|
|
3443
3740
|
});
|
|
3444
3741
|
|
|
3445
|
-
// ../service-capture/
|
|
3742
|
+
// ../service-capture/agent-sessions/http-timeout.ts
|
|
3446
3743
|
async function fetchWithTimeout(url2, init2 = {}, timeoutMs = 15e3) {
|
|
3447
3744
|
const controller = new AbortController();
|
|
3448
3745
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -3453,7 +3750,7 @@ async function fetchWithTimeout(url2, init2 = {}, timeoutMs = 15e3) {
|
|
|
3453
3750
|
}
|
|
3454
3751
|
}
|
|
3455
3752
|
var init_http_timeout = __esm({
|
|
3456
|
-
"../service-capture/
|
|
3753
|
+
"../service-capture/agent-sessions/http-timeout.ts"() {
|
|
3457
3754
|
"use strict";
|
|
3458
3755
|
}
|
|
3459
3756
|
});
|
|
@@ -52281,7 +52578,7 @@ var require_view = __commonJS({
|
|
|
52281
52578
|
var dirname3 = path.dirname;
|
|
52282
52579
|
var basename3 = path.basename;
|
|
52283
52580
|
var extname = path.extname;
|
|
52284
|
-
var
|
|
52581
|
+
var join13 = path.join;
|
|
52285
52582
|
var resolve4 = path.resolve;
|
|
52286
52583
|
module2.exports = View;
|
|
52287
52584
|
function View(name, options) {
|
|
@@ -52343,12 +52640,12 @@ var require_view = __commonJS({
|
|
|
52343
52640
|
};
|
|
52344
52641
|
View.prototype.resolve = function resolve5(dir, file2) {
|
|
52345
52642
|
var ext = this.ext;
|
|
52346
|
-
var path2 =
|
|
52643
|
+
var path2 = join13(dir, file2);
|
|
52347
52644
|
var stat = tryStat(path2);
|
|
52348
52645
|
if (stat && stat.isFile()) {
|
|
52349
52646
|
return path2;
|
|
52350
52647
|
}
|
|
52351
|
-
path2 =
|
|
52648
|
+
path2 = join13(dir, basename3(file2, ext), "index" + ext);
|
|
52352
52649
|
stat = tryStat(path2);
|
|
52353
52650
|
if (stat && stat.isFile()) {
|
|
52354
52651
|
return path2;
|
|
@@ -54773,24 +55070,24 @@ var require_charset = __commonJS({
|
|
|
54773
55070
|
function getCharsetPriority(charset, accepted, index) {
|
|
54774
55071
|
var priority = { o: -1, q: 0, s: 0 };
|
|
54775
55072
|
for (var i = 0; i < accepted.length; i++) {
|
|
54776
|
-
var
|
|
54777
|
-
if (
|
|
54778
|
-
priority =
|
|
55073
|
+
var spec2 = specify(charset, accepted[i], index);
|
|
55074
|
+
if (spec2 && (priority.s - spec2.s || priority.q - spec2.q || priority.o - spec2.o) < 0) {
|
|
55075
|
+
priority = spec2;
|
|
54779
55076
|
}
|
|
54780
55077
|
}
|
|
54781
55078
|
return priority;
|
|
54782
55079
|
}
|
|
54783
|
-
function specify(charset,
|
|
55080
|
+
function specify(charset, spec2, index) {
|
|
54784
55081
|
var s = 0;
|
|
54785
|
-
if (
|
|
55082
|
+
if (spec2.charset.toLowerCase() === charset.toLowerCase()) {
|
|
54786
55083
|
s |= 1;
|
|
54787
|
-
} else if (
|
|
55084
|
+
} else if (spec2.charset !== "*") {
|
|
54788
55085
|
return null;
|
|
54789
55086
|
}
|
|
54790
55087
|
return {
|
|
54791
55088
|
i: index,
|
|
54792
|
-
o:
|
|
54793
|
-
q:
|
|
55089
|
+
o: spec2.i,
|
|
55090
|
+
q: spec2.q,
|
|
54794
55091
|
s
|
|
54795
55092
|
};
|
|
54796
55093
|
}
|
|
@@ -54809,11 +55106,11 @@ var require_charset = __commonJS({
|
|
|
54809
55106
|
function compareSpecs(a, b) {
|
|
54810
55107
|
return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0;
|
|
54811
55108
|
}
|
|
54812
|
-
function getFullCharset(
|
|
54813
|
-
return
|
|
55109
|
+
function getFullCharset(spec2) {
|
|
55110
|
+
return spec2.charset;
|
|
54814
55111
|
}
|
|
54815
|
-
function isQuality(
|
|
54816
|
-
return
|
|
55112
|
+
function isQuality(spec2) {
|
|
55113
|
+
return spec2.q > 0;
|
|
54817
55114
|
}
|
|
54818
55115
|
}
|
|
54819
55116
|
});
|
|
@@ -54871,25 +55168,25 @@ var require_encoding = __commonJS({
|
|
|
54871
55168
|
function getEncodingPriority(encoding, accepted, index) {
|
|
54872
55169
|
var priority = { encoding, o: -1, q: 0, s: 0 };
|
|
54873
55170
|
for (var i = 0; i < accepted.length; i++) {
|
|
54874
|
-
var
|
|
54875
|
-
if (
|
|
54876
|
-
priority =
|
|
55171
|
+
var spec2 = specify(encoding, accepted[i], index);
|
|
55172
|
+
if (spec2 && (priority.s - spec2.s || priority.q - spec2.q || priority.o - spec2.o) < 0) {
|
|
55173
|
+
priority = spec2;
|
|
54877
55174
|
}
|
|
54878
55175
|
}
|
|
54879
55176
|
return priority;
|
|
54880
55177
|
}
|
|
54881
|
-
function specify(encoding,
|
|
55178
|
+
function specify(encoding, spec2, index) {
|
|
54882
55179
|
var s = 0;
|
|
54883
|
-
if (
|
|
55180
|
+
if (spec2.encoding.toLowerCase() === encoding.toLowerCase()) {
|
|
54884
55181
|
s |= 1;
|
|
54885
|
-
} else if (
|
|
55182
|
+
} else if (spec2.encoding !== "*") {
|
|
54886
55183
|
return null;
|
|
54887
55184
|
}
|
|
54888
55185
|
return {
|
|
54889
55186
|
encoding,
|
|
54890
55187
|
i: index,
|
|
54891
|
-
o:
|
|
54892
|
-
q:
|
|
55188
|
+
o: spec2.i,
|
|
55189
|
+
q: spec2.q,
|
|
54893
55190
|
s
|
|
54894
55191
|
};
|
|
54895
55192
|
}
|
|
@@ -54922,11 +55219,11 @@ var require_encoding = __commonJS({
|
|
|
54922
55219
|
function compareSpecs(a, b) {
|
|
54923
55220
|
return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i;
|
|
54924
55221
|
}
|
|
54925
|
-
function getFullEncoding(
|
|
54926
|
-
return
|
|
55222
|
+
function getFullEncoding(spec2) {
|
|
55223
|
+
return spec2.encoding;
|
|
54927
55224
|
}
|
|
54928
|
-
function isQuality(
|
|
54929
|
-
return
|
|
55225
|
+
function isQuality(spec2) {
|
|
55226
|
+
return spec2.q > 0;
|
|
54930
55227
|
}
|
|
54931
55228
|
}
|
|
54932
55229
|
});
|
|
@@ -54975,30 +55272,30 @@ var require_language = __commonJS({
|
|
|
54975
55272
|
function getLanguagePriority(language, accepted, index) {
|
|
54976
55273
|
var priority = { o: -1, q: 0, s: 0 };
|
|
54977
55274
|
for (var i = 0; i < accepted.length; i++) {
|
|
54978
|
-
var
|
|
54979
|
-
if (
|
|
54980
|
-
priority =
|
|
55275
|
+
var spec2 = specify(language, accepted[i], index);
|
|
55276
|
+
if (spec2 && (priority.s - spec2.s || priority.q - spec2.q || priority.o - spec2.o) < 0) {
|
|
55277
|
+
priority = spec2;
|
|
54981
55278
|
}
|
|
54982
55279
|
}
|
|
54983
55280
|
return priority;
|
|
54984
55281
|
}
|
|
54985
|
-
function specify(language,
|
|
55282
|
+
function specify(language, spec2, index) {
|
|
54986
55283
|
var p = parseLanguage(language);
|
|
54987
55284
|
if (!p) return null;
|
|
54988
55285
|
var s = 0;
|
|
54989
|
-
if (
|
|
55286
|
+
if (spec2.full.toLowerCase() === p.full.toLowerCase()) {
|
|
54990
55287
|
s |= 4;
|
|
54991
|
-
} else if (
|
|
55288
|
+
} else if (spec2.prefix.toLowerCase() === p.full.toLowerCase()) {
|
|
54992
55289
|
s |= 2;
|
|
54993
|
-
} else if (
|
|
55290
|
+
} else if (spec2.full.toLowerCase() === p.prefix.toLowerCase()) {
|
|
54994
55291
|
s |= 1;
|
|
54995
|
-
} else if (
|
|
55292
|
+
} else if (spec2.full !== "*") {
|
|
54996
55293
|
return null;
|
|
54997
55294
|
}
|
|
54998
55295
|
return {
|
|
54999
55296
|
i: index,
|
|
55000
|
-
o:
|
|
55001
|
-
q:
|
|
55297
|
+
o: spec2.i,
|
|
55298
|
+
q: spec2.q,
|
|
55002
55299
|
s
|
|
55003
55300
|
};
|
|
55004
55301
|
}
|
|
@@ -55017,11 +55314,11 @@ var require_language = __commonJS({
|
|
|
55017
55314
|
function compareSpecs(a, b) {
|
|
55018
55315
|
return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0;
|
|
55019
55316
|
}
|
|
55020
|
-
function getFullLanguage(
|
|
55021
|
-
return
|
|
55317
|
+
function getFullLanguage(spec2) {
|
|
55318
|
+
return spec2.full;
|
|
55022
55319
|
}
|
|
55023
|
-
function isQuality(
|
|
55024
|
-
return
|
|
55320
|
+
function isQuality(spec2) {
|
|
55321
|
+
return spec2.q > 0;
|
|
55025
55322
|
}
|
|
55026
55323
|
}
|
|
55027
55324
|
});
|
|
@@ -55076,33 +55373,33 @@ var require_mediaType = __commonJS({
|
|
|
55076
55373
|
function getMediaTypePriority(type, accepted, index) {
|
|
55077
55374
|
var priority = { o: -1, q: 0, s: 0 };
|
|
55078
55375
|
for (var i = 0; i < accepted.length; i++) {
|
|
55079
|
-
var
|
|
55080
|
-
if (
|
|
55081
|
-
priority =
|
|
55376
|
+
var spec2 = specify(type, accepted[i], index);
|
|
55377
|
+
if (spec2 && (priority.s - spec2.s || priority.q - spec2.q || priority.o - spec2.o) < 0) {
|
|
55378
|
+
priority = spec2;
|
|
55082
55379
|
}
|
|
55083
55380
|
}
|
|
55084
55381
|
return priority;
|
|
55085
55382
|
}
|
|
55086
|
-
function specify(type,
|
|
55383
|
+
function specify(type, spec2, index) {
|
|
55087
55384
|
var p = parseMediaType(type);
|
|
55088
55385
|
var s = 0;
|
|
55089
55386
|
if (!p) {
|
|
55090
55387
|
return null;
|
|
55091
55388
|
}
|
|
55092
|
-
if (
|
|
55389
|
+
if (spec2.type.toLowerCase() == p.type.toLowerCase()) {
|
|
55093
55390
|
s |= 4;
|
|
55094
|
-
} else if (
|
|
55391
|
+
} else if (spec2.type != "*") {
|
|
55095
55392
|
return null;
|
|
55096
55393
|
}
|
|
55097
|
-
if (
|
|
55394
|
+
if (spec2.subtype.toLowerCase() == p.subtype.toLowerCase()) {
|
|
55098
55395
|
s |= 2;
|
|
55099
|
-
} else if (
|
|
55396
|
+
} else if (spec2.subtype != "*") {
|
|
55100
55397
|
return null;
|
|
55101
55398
|
}
|
|
55102
|
-
var keys = Object.keys(
|
|
55399
|
+
var keys = Object.keys(spec2.params);
|
|
55103
55400
|
if (keys.length > 0) {
|
|
55104
55401
|
if (keys.every(function(k) {
|
|
55105
|
-
return
|
|
55402
|
+
return spec2.params[k] == "*" || (spec2.params[k] || "").toLowerCase() == (p.params[k] || "").toLowerCase();
|
|
55106
55403
|
})) {
|
|
55107
55404
|
s |= 1;
|
|
55108
55405
|
} else {
|
|
@@ -55111,8 +55408,8 @@ var require_mediaType = __commonJS({
|
|
|
55111
55408
|
}
|
|
55112
55409
|
return {
|
|
55113
55410
|
i: index,
|
|
55114
|
-
o:
|
|
55115
|
-
q:
|
|
55411
|
+
o: spec2.i,
|
|
55412
|
+
q: spec2.q,
|
|
55116
55413
|
s
|
|
55117
55414
|
};
|
|
55118
55415
|
}
|
|
@@ -55131,11 +55428,11 @@ var require_mediaType = __commonJS({
|
|
|
55131
55428
|
function compareSpecs(a, b) {
|
|
55132
55429
|
return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0;
|
|
55133
55430
|
}
|
|
55134
|
-
function getFullType(
|
|
55135
|
-
return
|
|
55431
|
+
function getFullType(spec2) {
|
|
55432
|
+
return spec2.type + "/" + spec2.subtype;
|
|
55136
55433
|
}
|
|
55137
|
-
function isQuality(
|
|
55138
|
-
return
|
|
55434
|
+
function isQuality(spec2) {
|
|
55435
|
+
return spec2.q > 0;
|
|
55139
55436
|
}
|
|
55140
55437
|
function quoteCount(string3) {
|
|
55141
55438
|
var count = 0;
|
|
@@ -55993,7 +56290,7 @@ var require_send = __commonJS({
|
|
|
55993
56290
|
var Stream = require("stream");
|
|
55994
56291
|
var util2 = require("util");
|
|
55995
56292
|
var extname = path.extname;
|
|
55996
|
-
var
|
|
56293
|
+
var join13 = path.join;
|
|
55997
56294
|
var normalize = path.normalize;
|
|
55998
56295
|
var resolve4 = path.resolve;
|
|
55999
56296
|
var sep = path.sep;
|
|
@@ -56165,7 +56462,7 @@ var require_send = __commonJS({
|
|
|
56165
56462
|
return res;
|
|
56166
56463
|
}
|
|
56167
56464
|
parts = path2.split(sep);
|
|
56168
|
-
path2 = normalize(
|
|
56465
|
+
path2 = normalize(join13(root, path2));
|
|
56169
56466
|
} else {
|
|
56170
56467
|
if (UP_PATH_REGEXP.test(path2)) {
|
|
56171
56468
|
debug('malicious path "%s"', path2);
|
|
@@ -56298,7 +56595,7 @@ var require_send = __commonJS({
|
|
|
56298
56595
|
if (err) return self.onStatError(err);
|
|
56299
56596
|
return self.error(404);
|
|
56300
56597
|
}
|
|
56301
|
-
var p =
|
|
56598
|
+
var p = join13(path2, self._index[i]);
|
|
56302
56599
|
debug('stat "%s"', p);
|
|
56303
56600
|
fs.stat(p, function(err2, stat) {
|
|
56304
56601
|
if (err2) return next(err2);
|
|
@@ -58391,13 +58688,13 @@ var init_streamableHttp = __esm({
|
|
|
58391
58688
|
}
|
|
58392
58689
|
});
|
|
58393
58690
|
|
|
58394
|
-
// ../service-capture/
|
|
58691
|
+
// ../service-capture/agent-sessions/mcp-server.ts
|
|
58395
58692
|
var mcp_server_exports = {};
|
|
58396
58693
|
function resolveToken3() {
|
|
58397
58694
|
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
58398
|
-
if ((0,
|
|
58695
|
+
if ((0, import_fs6.existsSync)(CREDENTIALS_FILE5)) {
|
|
58399
58696
|
try {
|
|
58400
|
-
const creds = JSON.parse((0,
|
|
58697
|
+
const creds = JSON.parse((0, import_fs6.readFileSync)(CREDENTIALS_FILE5, "utf-8"));
|
|
58401
58698
|
if (creds.token) return creds.token;
|
|
58402
58699
|
} catch {
|
|
58403
58700
|
}
|
|
@@ -58482,14 +58779,14 @@ async function main3() {
|
|
|
58482
58779
|
}
|
|
58483
58780
|
warmupInBackground();
|
|
58484
58781
|
}
|
|
58485
|
-
var import_dotenv3, import_path5,
|
|
58782
|
+
var import_dotenv3, import_path5, import_fs6, import_os5, DEFAULT_API_URL3, CREDENTIALS_FILE5, API_URL, AGENT_SOURCE, DEFAULT_SOURCE_TOOL, TOKEN, contextSchema, isCollecting, lastCollectTime, COLLECT_COOLDOWN_MS, mcpServer, server;
|
|
58486
58783
|
var init_mcp_server2 = __esm({
|
|
58487
|
-
"../service-capture/
|
|
58784
|
+
"../service-capture/agent-sessions/mcp-server.ts"() {
|
|
58488
58785
|
"use strict";
|
|
58489
58786
|
import_dotenv3 = __toESM(require_main());
|
|
58490
58787
|
import_path5 = require("path");
|
|
58491
|
-
|
|
58492
|
-
|
|
58788
|
+
import_fs6 = require("fs");
|
|
58789
|
+
import_os5 = require("os");
|
|
58493
58790
|
init_collector();
|
|
58494
58791
|
init_http_timeout();
|
|
58495
58792
|
init_service_urls();
|
|
@@ -58499,7 +58796,7 @@ var init_mcp_server2 = __esm({
|
|
|
58499
58796
|
init_types4();
|
|
58500
58797
|
(0, import_dotenv3.config)({ path: (0, import_path5.resolve)(__dirname, "../../../.env") });
|
|
58501
58798
|
DEFAULT_API_URL3 = SERVICE_URL_DEFAULTS.haansiApiBaseUrl;
|
|
58502
|
-
CREDENTIALS_FILE5 = (0, import_path5.join)((0,
|
|
58799
|
+
CREDENTIALS_FILE5 = (0, import_path5.join)((0, import_os5.homedir)(), ".haansi", "credentials.json");
|
|
58503
58800
|
API_URL = process.env.HAANSI_API_URL ?? DEFAULT_API_URL3;
|
|
58504
58801
|
AGENT_SOURCE = process.env.HAANSI_AGENT_SOURCE?.toLowerCase();
|
|
58505
58802
|
DEFAULT_SOURCE_TOOL = AGENT_SOURCE === "codex" ? "codex-mcp" : "claude-code-mcp";
|
|
@@ -58999,8 +59296,8 @@ function warnIfStaleDevBundle(haansiPath) {
|
|
|
58999
59296
|
const bundle = (0, import_node_fs6.realpathSync)(haansiPath);
|
|
59000
59297
|
const repoRoot = (0, import_node_path5.dirname)((0, import_node_path5.dirname)((0, import_node_path5.dirname)((0, import_node_path5.dirname)(bundle))));
|
|
59001
59298
|
const sources = [
|
|
59002
|
-
"apps/service-capture/
|
|
59003
|
-
"apps/service-capture/
|
|
59299
|
+
"apps/service-capture/agent-sessions/collector.ts",
|
|
59300
|
+
"apps/service-capture/agent-sessions/collector-daemon.ts",
|
|
59004
59301
|
"apps/service-capture/common/agents/codex.ts",
|
|
59005
59302
|
"apps/service-capture/common/agents/claude-code.ts"
|
|
59006
59303
|
].map((p) => (0, import_node_path5.join)(repoRoot, p));
|
|
@@ -59041,9 +59338,9 @@ function buildPlist(haansiPath) {
|
|
|
59041
59338
|
<key>KeepAlive</key>
|
|
59042
59339
|
<true/>
|
|
59043
59340
|
<key>StandardOutPath</key>
|
|
59044
|
-
<string>${
|
|
59341
|
+
<string>${LOG_FILE2}</string>
|
|
59045
59342
|
<key>StandardErrorPath</key>
|
|
59046
|
-
<string>${
|
|
59343
|
+
<string>${LOG_FILE2}</string>
|
|
59047
59344
|
</dict>
|
|
59048
59345
|
</plist>`;
|
|
59049
59346
|
}
|
|
@@ -59074,12 +59371,12 @@ async function setupDaemon(uninstall) {
|
|
|
59074
59371
|
(0, import_node_child_process3.spawnSync)("launchctl", ["load", PLIST_PATH], { stdio: "inherit" });
|
|
59075
59372
|
console.log("Daemon installed and started.");
|
|
59076
59373
|
console.log(`Plist : ${PLIST_PATH}`);
|
|
59077
|
-
console.log(`Logs : ${
|
|
59374
|
+
console.log(`Logs : ${LOG_FILE2}`);
|
|
59078
59375
|
console.log(`
|
|
59079
59376
|
The daemon will start automatically on every login.`);
|
|
59080
59377
|
console.log(`To uninstall: haansi setup-daemon --uninstall`);
|
|
59081
59378
|
}
|
|
59082
|
-
var import_node_child_process3, import_node_fs6, import_node_path5, import_node_os5, PLIST_LABEL, PLIST_PATH,
|
|
59379
|
+
var import_node_child_process3, import_node_fs6, import_node_path5, import_node_os5, PLIST_LABEL, PLIST_PATH, LOG_FILE2;
|
|
59083
59380
|
var init_setup_daemon = __esm({
|
|
59084
59381
|
"src/commands/setup-daemon.ts"() {
|
|
59085
59382
|
"use strict";
|
|
@@ -59094,7 +59391,7 @@ var init_setup_daemon = __esm({
|
|
|
59094
59391
|
"LaunchAgents",
|
|
59095
59392
|
`${PLIST_LABEL}.plist`
|
|
59096
59393
|
);
|
|
59097
|
-
|
|
59394
|
+
LOG_FILE2 = (0, import_node_path5.join)((0, import_node_os5.homedir)(), ".haansi", "daemon.log");
|
|
59098
59395
|
}
|
|
59099
59396
|
});
|
|
59100
59397
|
|