@alfe.ai/gateway 0.4.0 → 0.6.0
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/bin/gateway.js +1 -1
- package/dist/health.js +271 -92
- package/dist/src/index.d.ts +23 -1
- package/dist/src/index.js +2 -2
- package/package.json +4 -4
package/dist/bin/gateway.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { a as installService, c as uninstallService, i as checkExistingDaemon, n as queryDaemonHealth, r as startDaemon, s as stopExistingDaemon, t as formatHealthReport, w as SOCKET_PATH } from "../health.js";
|
|
3
3
|
import { t as LOG_FILE } from "../logger.js";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
//#region bin/gateway.ts
|
package/dist/health.js
CHANGED
|
@@ -5266,7 +5266,7 @@ function isIPCResponse(msg) {
|
|
|
5266
5266
|
const PROTOCOL_VERSION = 1;
|
|
5267
5267
|
//#endregion
|
|
5268
5268
|
//#region src/runtime-gate.ts
|
|
5269
|
-
const log$
|
|
5269
|
+
const log$4 = logger$1.child({ component: "RuntimeGate" });
|
|
5270
5270
|
var RuntimeGate = class {
|
|
5271
5271
|
depth = 0;
|
|
5272
5272
|
wasRunning = false;
|
|
@@ -5284,7 +5284,7 @@ var RuntimeGate = class {
|
|
|
5284
5284
|
const rp = this.getRuntime();
|
|
5285
5285
|
this.wasRunning = rp?.isRunning ?? false;
|
|
5286
5286
|
if (rp && this.wasRunning) {
|
|
5287
|
-
log$
|
|
5287
|
+
log$4.info("Suspending runtime for mutating reconcile (avoid concurrent SQLite writers)");
|
|
5288
5288
|
await rp.stop();
|
|
5289
5289
|
}
|
|
5290
5290
|
}
|
|
@@ -5299,7 +5299,7 @@ var RuntimeGate = class {
|
|
|
5299
5299
|
if (this.depth < 0) this.depth = 0;
|
|
5300
5300
|
const rp = this.getRuntime();
|
|
5301
5301
|
if (rp && this.wasRunning) {
|
|
5302
|
-
log$
|
|
5302
|
+
log$4.info("Resuming runtime after mutating reconcile");
|
|
5303
5303
|
rp.resume();
|
|
5304
5304
|
}
|
|
5305
5305
|
this.wasRunning = false;
|
|
@@ -5314,12 +5314,12 @@ var RuntimeGate = class {
|
|
|
5314
5314
|
*/
|
|
5315
5315
|
requestRestart() {
|
|
5316
5316
|
if (this.depth > 0) {
|
|
5317
|
-
log$
|
|
5317
|
+
log$4.info("Runtime restart requested while suspended — deferring to pending resume");
|
|
5318
5318
|
return;
|
|
5319
5319
|
}
|
|
5320
5320
|
const rp = this.getRuntime();
|
|
5321
5321
|
if (rp) rp.restart().catch((err) => {
|
|
5322
|
-
log$
|
|
5322
|
+
log$4.error({ err: err instanceof Error ? err.message : String(err) }, "Failed to restart runtime");
|
|
5323
5323
|
});
|
|
5324
5324
|
}
|
|
5325
5325
|
};
|
|
@@ -5374,6 +5374,13 @@ const CLI_SENTRY_DSN = "https://82dde4631336561f2fcc89d7531623de@o45110082394521
|
|
|
5374
5374
|
* Mirrors `SENTRY_DSNS.agentRuntime` in `config/config.ts`.
|
|
5375
5375
|
*/
|
|
5376
5376
|
const AGENT_RUNTIME_SENTRY_DSN = "https://feb7fb2e3b8e723aec518e74715bfa6d@o4511008239452160.ingest.us.sentry.io/4511683667558400";
|
|
5377
|
+
/**
|
|
5378
|
+
* MCP tool/server failures on agent VMs — reported by the daemon-hosted MCP
|
|
5379
|
+
* bundler (tool errors, child crashes, stderr output). This is the SAME
|
|
5380
|
+
* project as the cloud MCP Fly service (`SENTRY_DSNS.mcp`); agent-side events
|
|
5381
|
+
* are distinguished by `source: agent-daemon` + `agentId` tags.
|
|
5382
|
+
*/
|
|
5383
|
+
const AGENT_MCP_SENTRY_DSN = "https://638309eac96146a945f46b578f10c806@o4511008239452160.ingest.us.sentry.io/4511146364174336";
|
|
5377
5384
|
/** Surface → Sentry project: `cli` and `agent-daemon` respectively. */
|
|
5378
5385
|
const SURFACE_DSNS = {
|
|
5379
5386
|
cli: CLI_SENTRY_DSN,
|
|
@@ -5382,13 +5389,16 @@ const SURFACE_DSNS = {
|
|
|
5382
5389
|
/** Held after a successful init so the capture helpers can run synchronously. */
|
|
5383
5390
|
let sentry = null;
|
|
5384
5391
|
/**
|
|
5385
|
-
*
|
|
5386
|
-
*
|
|
5387
|
-
*
|
|
5388
|
-
* pattern. `null` until `initAgentSentry({ surface: "daemon" })`
|
|
5392
|
+
* Additional bound clients (daemon surface only). The default client keeps the
|
|
5393
|
+
* daemon's own DSN; runtime child-process events and MCP failures are routed
|
|
5394
|
+
* to their own projects via explicitly-bound Scopes — the documented
|
|
5395
|
+
* multi-client pattern. `null` until `initAgentSentry({ surface: "daemon" })`
|
|
5396
|
+
* succeeds.
|
|
5389
5397
|
*/
|
|
5390
5398
|
let runtimeClient = null;
|
|
5391
5399
|
let runtimeScope = null;
|
|
5400
|
+
let mcpClient = null;
|
|
5401
|
+
let mcpScope = null;
|
|
5392
5402
|
/**
|
|
5393
5403
|
* Map the configured API URL to a coarse environment tag. Best-effort — returns
|
|
5394
5404
|
* `"unknown"` when no config is present yet (e.g. `alfe login` pre-setup).
|
|
@@ -5470,32 +5480,46 @@ async function initAgentSentry(options) {
|
|
|
5470
5480
|
const dsn = SURFACE_DSNS[options.surface].trim();
|
|
5471
5481
|
if (!dsn) return;
|
|
5472
5482
|
const mod = await import("@sentry/node");
|
|
5473
|
-
if (options.surface === "daemon"
|
|
5474
|
-
const
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5483
|
+
if (options.surface === "daemon") {
|
|
5484
|
+
const buildBoundScope = (dsn, extraTags) => {
|
|
5485
|
+
try {
|
|
5486
|
+
if (!dsn.trim()) return null;
|
|
5487
|
+
const client = new mod.NodeClient({
|
|
5488
|
+
dsn: dsn.trim(),
|
|
5489
|
+
environment: deriveEnvironment(),
|
|
5490
|
+
...options.release ? { release: options.release } : {},
|
|
5491
|
+
sampleRate: 1,
|
|
5492
|
+
tracesSampleRate: 0,
|
|
5493
|
+
sendDefaultPii: false,
|
|
5494
|
+
transport: mod.makeNodeTransport,
|
|
5495
|
+
stackParser: mod.defaultStackParser,
|
|
5496
|
+
integrations: [],
|
|
5497
|
+
beforeSend: (event) => scrubEvent(event)
|
|
5498
|
+
});
|
|
5499
|
+
client.init();
|
|
5500
|
+
const scope = new mod.Scope();
|
|
5501
|
+
scope.setClient(client);
|
|
5502
|
+
const runtime = deriveRuntime();
|
|
5503
|
+
if (runtime) scope.setTag("runtime", runtime);
|
|
5504
|
+
for (const [k, v] of Object.entries(extraTags)) scope.setTag(k, v);
|
|
5505
|
+
return {
|
|
5506
|
+
client,
|
|
5507
|
+
scope
|
|
5508
|
+
};
|
|
5509
|
+
} catch {
|
|
5510
|
+
return null;
|
|
5511
|
+
}
|
|
5512
|
+
};
|
|
5513
|
+
if (!runtimeScope) {
|
|
5514
|
+
const bound = buildBoundScope(AGENT_RUNTIME_SENTRY_DSN, {});
|
|
5515
|
+
runtimeClient = bound?.client ?? null;
|
|
5516
|
+
runtimeScope = bound?.scope ?? null;
|
|
5517
|
+
}
|
|
5518
|
+
if (!mcpScope) {
|
|
5519
|
+
const bound = buildBoundScope(AGENT_MCP_SENTRY_DSN, { source: "agent-daemon" });
|
|
5520
|
+
mcpClient = bound?.client ?? null;
|
|
5521
|
+
mcpScope = bound?.scope ?? null;
|
|
5495
5522
|
}
|
|
5496
|
-
} catch {
|
|
5497
|
-
runtimeClient = null;
|
|
5498
|
-
runtimeScope = null;
|
|
5499
5523
|
}
|
|
5500
5524
|
if (mod.getClient()) {
|
|
5501
5525
|
sentry = mod;
|
|
@@ -5527,11 +5551,14 @@ async function initAgentSentry(options) {
|
|
|
5527
5551
|
function setAgentContext(context) {
|
|
5528
5552
|
if (!sentry) return;
|
|
5529
5553
|
try {
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5554
|
+
for (const scope of [
|
|
5555
|
+
sentry,
|
|
5556
|
+
runtimeScope,
|
|
5557
|
+
mcpScope
|
|
5558
|
+
]) {
|
|
5559
|
+
if (!scope) continue;
|
|
5560
|
+
if (context.agentId) scope.setTag("agentId", context.agentId);
|
|
5561
|
+
if (context.runtime) scope.setTag("runtime", context.runtime);
|
|
5535
5562
|
}
|
|
5536
5563
|
} catch {}
|
|
5537
5564
|
}
|
|
@@ -5641,10 +5668,40 @@ function captureRuntimeErrorOutput(opts) {
|
|
|
5641
5668
|
scope.captureMessage(opts.lines[0].slice(0, 300), "error");
|
|
5642
5669
|
} catch {}
|
|
5643
5670
|
}
|
|
5671
|
+
/**
|
|
5672
|
+
* Capture an MCP failure (tool error, server crash, or error-looking stderr
|
|
5673
|
+
* output) into the `mcp` project via the daemon's bound MCP client. Throttling
|
|
5674
|
+
* is the caller's job (`mcp-error-capture.ts`). No-op when the MCP client is
|
|
5675
|
+
* not initialised. Never throws.
|
|
5676
|
+
*/
|
|
5677
|
+
function captureMcpFailure(opts) {
|
|
5678
|
+
if (!mcpScope) return;
|
|
5679
|
+
try {
|
|
5680
|
+
const scope = mcpScope.clone();
|
|
5681
|
+
for (const line of opts.lines ?? []) scope.addBreadcrumb({
|
|
5682
|
+
category: `mcp.${opts.server}`,
|
|
5683
|
+
level: "error",
|
|
5684
|
+
message: line
|
|
5685
|
+
});
|
|
5686
|
+
scope.setFingerprint([
|
|
5687
|
+
"agent-mcp",
|
|
5688
|
+
opts.server,
|
|
5689
|
+
opts.kind,
|
|
5690
|
+
...opts.tool ? [opts.tool] : []
|
|
5691
|
+
]);
|
|
5692
|
+
scope.setTags({
|
|
5693
|
+
server: opts.server,
|
|
5694
|
+
kind: opts.kind,
|
|
5695
|
+
...opts.tool ? { tool: opts.tool } : {},
|
|
5696
|
+
suppressedCount: String(opts.suppressedCount ?? 0)
|
|
5697
|
+
});
|
|
5698
|
+
scope.captureMessage(`MCP ${opts.server}${opts.tool ? `.${opts.tool}` : ""} ${opts.kind}: ${opts.message.slice(0, 300)}`, "error");
|
|
5699
|
+
} catch {}
|
|
5700
|
+
}
|
|
5644
5701
|
/** Flush queued events (small timeout) so short-lived commands deliver them. */
|
|
5645
5702
|
async function flushSentry(timeoutMs = 2e3) {
|
|
5646
|
-
try {
|
|
5647
|
-
if (
|
|
5703
|
+
for (const client of [runtimeClient, mcpClient]) try {
|
|
5704
|
+
if (client) await client.flush(timeoutMs);
|
|
5648
5705
|
} catch {}
|
|
5649
5706
|
if (!sentry) return;
|
|
5650
5707
|
try {
|
|
@@ -5664,7 +5721,7 @@ function captureFatal(cause) {
|
|
|
5664
5721
|
}
|
|
5665
5722
|
//#endregion
|
|
5666
5723
|
//#region src/reconciliation.ts
|
|
5667
|
-
const log$
|
|
5724
|
+
const log$3 = logger$1.child({ component: "Reconciliation" });
|
|
5668
5725
|
/**
|
|
5669
5726
|
* How many times reconcile will re-attempt activation of an intact integration
|
|
5670
5727
|
* stuck in `error` (with no reinstall requested) before giving up and waiting
|
|
@@ -5734,7 +5791,7 @@ var ReconciliationEngine = class {
|
|
|
5734
5791
|
try {
|
|
5735
5792
|
localIntegrations = await this.manager.getInstalledIntegrations();
|
|
5736
5793
|
} catch (err) {
|
|
5737
|
-
log$
|
|
5794
|
+
log$3.error({ err }, "Failed to get local integrations");
|
|
5738
5795
|
localIntegrations = [];
|
|
5739
5796
|
}
|
|
5740
5797
|
const localMap = new Map(localIntegrations.map((i) => [i.id, i]));
|
|
@@ -5753,10 +5810,10 @@ var ReconciliationEngine = class {
|
|
|
5753
5810
|
try {
|
|
5754
5811
|
if (!local) {
|
|
5755
5812
|
await this.ensureSuspended();
|
|
5756
|
-
log$
|
|
5813
|
+
log$3.info(`Installing ${id}@${desired.version}`);
|
|
5757
5814
|
await this.manager.install(id, desired.version, desired.config, desired.customSource);
|
|
5758
5815
|
report.installed.push(id);
|
|
5759
|
-
log$
|
|
5816
|
+
log$3.info(`Activating ${id}`);
|
|
5760
5817
|
if ((await this.manager.activate(id)).configApplied) report.configApplied = true;
|
|
5761
5818
|
report.activated.push(id);
|
|
5762
5819
|
report.results.push({
|
|
@@ -5767,22 +5824,54 @@ var ReconciliationEngine = class {
|
|
|
5767
5824
|
return;
|
|
5768
5825
|
}
|
|
5769
5826
|
if (local.version !== desired.version && desired.version !== "" && local.version !== "unknown") {
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5827
|
+
if (desired.reinstallRequestedAt && local.installedAt && desired.reinstallRequestedAt > local.installedAt) {
|
|
5828
|
+
await this.ensureSuspended();
|
|
5829
|
+
log$3.info(`Reinstalling ${id} on version change (reinstall requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt}): ${local.version} → ${desired.version}`);
|
|
5830
|
+
this.manager.resetReinstallAttempts(id);
|
|
5831
|
+
this.activateAttempts.delete(id);
|
|
5832
|
+
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
|
|
5833
|
+
report.installed.push(id);
|
|
5834
|
+
report.activated.push(id);
|
|
5835
|
+
report.results.push({
|
|
5836
|
+
integrationId: id,
|
|
5837
|
+
action: "installed",
|
|
5838
|
+
actualStatus: "active"
|
|
5839
|
+
});
|
|
5840
|
+
return;
|
|
5841
|
+
}
|
|
5842
|
+
log$3.info(`Upgrading ${id} in place: ${local.version} → ${desired.version}`);
|
|
5843
|
+
try {
|
|
5844
|
+
if ((await this.manager.upgrade(id, desired.version, desired.config, desired.customSource, { onBeforeRuntimeMutation: () => this.ensureSuspended() })).configApplied) report.configApplied = true;
|
|
5845
|
+
this.manager.resetReinstallAttempts(id);
|
|
5846
|
+
this.activateAttempts.delete(id);
|
|
5847
|
+
report.installed.push(id);
|
|
5848
|
+
report.activated.push(id);
|
|
5849
|
+
report.results.push({
|
|
5850
|
+
integrationId: id,
|
|
5851
|
+
action: "activated",
|
|
5852
|
+
actualStatus: "active"
|
|
5853
|
+
});
|
|
5854
|
+
} catch (upgradeErr) {
|
|
5855
|
+
const upgradeMsg = upgradeErr instanceof Error ? upgradeErr.message : String(upgradeErr);
|
|
5856
|
+
log$3.error({ err: upgradeErr }, `Upgrade failed for ${id}`);
|
|
5857
|
+
captureIntegrationFailure(id, "upgrade", upgradeErr);
|
|
5858
|
+
report.errors.push({
|
|
5859
|
+
integrationId: id,
|
|
5860
|
+
error: upgradeMsg
|
|
5861
|
+
});
|
|
5862
|
+
report.results.push({
|
|
5863
|
+
integrationId: id,
|
|
5864
|
+
action: "error",
|
|
5865
|
+
actualStatus: "error",
|
|
5866
|
+
errorMessage: upgradeMsg
|
|
5867
|
+
});
|
|
5868
|
+
}
|
|
5780
5869
|
return;
|
|
5781
5870
|
}
|
|
5782
5871
|
if (local.status === "error") {
|
|
5783
5872
|
if (desired.reinstallRequestedAt && local.installedAt && desired.reinstallRequestedAt > local.installedAt) {
|
|
5784
5873
|
await this.ensureSuspended();
|
|
5785
|
-
log$
|
|
5874
|
+
log$3.info(`Reinstalling ${id} from error state (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
|
|
5786
5875
|
this.manager.resetReinstallAttempts(id);
|
|
5787
5876
|
this.activateAttempts.delete(id);
|
|
5788
5877
|
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
|
|
@@ -5798,7 +5887,7 @@ var ReconciliationEngine = class {
|
|
|
5798
5887
|
if (!await this.manager.isInstallIntact(id)) {
|
|
5799
5888
|
const attempts = this.manager.getReinstallAttempts(id);
|
|
5800
5889
|
if (attempts >= 3) {
|
|
5801
|
-
log$
|
|
5890
|
+
log$3.error(`Auto-reinstall blocked for ${id} — ${String(attempts)} consecutive failures. Manual reinstall required.`);
|
|
5802
5891
|
captureIntegrationFailure(id, "reinstall", `Max auto-reinstall attempts (${String(attempts)}) reached — manual reinstall required`);
|
|
5803
5892
|
report.errors.push({
|
|
5804
5893
|
integrationId: id,
|
|
@@ -5813,7 +5902,7 @@ var ReconciliationEngine = class {
|
|
|
5813
5902
|
return;
|
|
5814
5903
|
}
|
|
5815
5904
|
await this.ensureSuspended();
|
|
5816
|
-
log$
|
|
5905
|
+
log$3.info(`Auto-reinstalling ${id} — install directory is corrupted or missing (attempt ${String(attempts + 1)}/3)`);
|
|
5817
5906
|
this.manager.incrementReinstallAttempts(id);
|
|
5818
5907
|
try {
|
|
5819
5908
|
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
|
|
@@ -5828,7 +5917,7 @@ var ReconciliationEngine = class {
|
|
|
5828
5917
|
});
|
|
5829
5918
|
} catch (reinstallErr) {
|
|
5830
5919
|
const reinstallMsg = reinstallErr instanceof Error ? reinstallErr.message : String(reinstallErr);
|
|
5831
|
-
log$
|
|
5920
|
+
log$3.error({ err: reinstallErr }, `Auto-reinstall failed for ${id}`);
|
|
5832
5921
|
captureIntegrationFailure(id, "reinstall", reinstallErr);
|
|
5833
5922
|
report.errors.push({
|
|
5834
5923
|
integrationId: id,
|
|
@@ -5847,9 +5936,9 @@ var ReconciliationEngine = class {
|
|
|
5847
5936
|
if (activateAttempts < MAX_ERROR_ACTIVATE_ATTEMPTS) {
|
|
5848
5937
|
this.activateAttempts.set(id, activateAttempts + 1);
|
|
5849
5938
|
await this.ensureSuspended();
|
|
5850
|
-
log$
|
|
5939
|
+
log$3.info(`Re-activating ${id} from error state (attempt ${String(activateAttempts + 1)}/${String(MAX_ERROR_ACTIVATE_ATTEMPTS)})`);
|
|
5851
5940
|
try {
|
|
5852
|
-
if ((await this.manager.activate(id)).configApplied) report.configApplied = true;
|
|
5941
|
+
if ((await this.manager.activate(id, { forcePlugins: true })).configApplied) report.configApplied = true;
|
|
5853
5942
|
this.activateAttempts.delete(id);
|
|
5854
5943
|
report.activated.push(id);
|
|
5855
5944
|
report.results.push({
|
|
@@ -5860,7 +5949,7 @@ var ReconciliationEngine = class {
|
|
|
5860
5949
|
return;
|
|
5861
5950
|
} catch (reactivateErr) {
|
|
5862
5951
|
const reactivateMsg = reactivateErr instanceof Error ? reactivateErr.message : String(reactivateErr);
|
|
5863
|
-
log$
|
|
5952
|
+
log$3.warn(`Re-activation of ${id} from error state failed (attempt ${String(activateAttempts + 1)}/${String(MAX_ERROR_ACTIVATE_ATTEMPTS)}): ${reactivateMsg}`);
|
|
5864
5953
|
captureIntegrationFailure(id, "reactivate", reactivateErr);
|
|
5865
5954
|
report.errors.push({
|
|
5866
5955
|
integrationId: id,
|
|
@@ -5875,7 +5964,7 @@ var ReconciliationEngine = class {
|
|
|
5875
5964
|
return;
|
|
5876
5965
|
}
|
|
5877
5966
|
}
|
|
5878
|
-
log$
|
|
5967
|
+
log$3.warn(`Integration ${id} is in error state — re-activation exhausted, waiting for reinstall request`);
|
|
5879
5968
|
captureIntegrationFailure(id, "reactivate", `Integration ${id} stuck in error state — re-activation attempts exhausted`);
|
|
5880
5969
|
report.errors.push({
|
|
5881
5970
|
integrationId: id,
|
|
@@ -5891,8 +5980,8 @@ var ReconciliationEngine = class {
|
|
|
5891
5980
|
}
|
|
5892
5981
|
if (local.status !== "active") {
|
|
5893
5982
|
await this.ensureSuspended();
|
|
5894
|
-
log$
|
|
5895
|
-
if ((await this.manager.activate(id)).configApplied) report.configApplied = true;
|
|
5983
|
+
log$3.info(`Activating ${id}`);
|
|
5984
|
+
if ((await this.manager.activate(id, { forcePlugins: true })).configApplied) report.configApplied = true;
|
|
5896
5985
|
report.activated.push(id);
|
|
5897
5986
|
report.results.push({
|
|
5898
5987
|
integrationId: id,
|
|
@@ -5903,7 +5992,7 @@ var ReconciliationEngine = class {
|
|
|
5903
5992
|
}
|
|
5904
5993
|
if (desired.reinstallRequestedAt && local.installedAt && desired.reinstallRequestedAt > local.installedAt) {
|
|
5905
5994
|
await this.ensureSuspended();
|
|
5906
|
-
log$
|
|
5995
|
+
log$3.info(`Reinstall requested for ${id} (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
|
|
5907
5996
|
this.manager.resetReinstallAttempts(id);
|
|
5908
5997
|
this.activateAttempts.delete(id);
|
|
5909
5998
|
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
|
|
@@ -5924,7 +6013,7 @@ var ReconciliationEngine = class {
|
|
|
5924
6013
|
});
|
|
5925
6014
|
} catch (err) {
|
|
5926
6015
|
const message = err instanceof Error ? err.message : String(err);
|
|
5927
|
-
log$
|
|
6016
|
+
log$3.error({ err }, `Error reconciling ${id}`);
|
|
5928
6017
|
captureIntegrationFailure(id, "reconcile_active", err);
|
|
5929
6018
|
report.errors.push({
|
|
5930
6019
|
integrationId: id,
|
|
@@ -5949,7 +6038,7 @@ var ReconciliationEngine = class {
|
|
|
5949
6038
|
}
|
|
5950
6039
|
try {
|
|
5951
6040
|
await this.ensureSuspended();
|
|
5952
|
-
log$
|
|
6041
|
+
log$3.info(`Removing ${id}`);
|
|
5953
6042
|
if (local.status === "active") {
|
|
5954
6043
|
await this.manager.deactivate(id);
|
|
5955
6044
|
report.deactivated.push(id);
|
|
@@ -5963,7 +6052,7 @@ var ReconciliationEngine = class {
|
|
|
5963
6052
|
});
|
|
5964
6053
|
} catch (err) {
|
|
5965
6054
|
const message = err instanceof Error ? err.message : String(err);
|
|
5966
|
-
log$
|
|
6055
|
+
log$3.error({ err }, `Error removing ${id}`);
|
|
5967
6056
|
captureIntegrationFailure(id, "reconcile_removed", err);
|
|
5968
6057
|
report.errors.push({
|
|
5969
6058
|
integrationId: id,
|
|
@@ -22275,7 +22364,7 @@ var CaptureThrottle = class {
|
|
|
22275
22364
|
* Spawns the runtime binary, pipes stdout/stderr to the daemon logger,
|
|
22276
22365
|
* and restarts on crash with exponential backoff.
|
|
22277
22366
|
*/
|
|
22278
|
-
const log$
|
|
22367
|
+
const log$2 = createLogger("RuntimeProcess");
|
|
22279
22368
|
/** Quiet-period flush for a pending multi-line error block (e.g. a traceback
|
|
22280
22369
|
* followed by silence — no closing line ever arrives to complete it). */
|
|
22281
22370
|
const DETECTOR_FLUSH_DEBOUNCE_MS = 1500;
|
|
@@ -22322,7 +22411,7 @@ var RuntimeProcess = class {
|
|
|
22322
22411
|
if (this.stopped) return;
|
|
22323
22412
|
const { command, args } = this.resolveCommand();
|
|
22324
22413
|
this.lastStartTime = Date.now();
|
|
22325
|
-
log$
|
|
22414
|
+
log$2.info({
|
|
22326
22415
|
runtime: this.options.runtime,
|
|
22327
22416
|
command,
|
|
22328
22417
|
args,
|
|
@@ -22343,7 +22432,7 @@ var RuntimeProcess = class {
|
|
|
22343
22432
|
this.child.stdout?.on("data", (data) => {
|
|
22344
22433
|
const lines = data.toString().trim().split("\n");
|
|
22345
22434
|
for (const line of lines) {
|
|
22346
|
-
log$
|
|
22435
|
+
log$2.info({
|
|
22347
22436
|
runtime: this.options.runtime,
|
|
22348
22437
|
stream: "stdout"
|
|
22349
22438
|
}, line);
|
|
@@ -22353,7 +22442,7 @@ var RuntimeProcess = class {
|
|
|
22353
22442
|
this.child.stderr?.on("data", (data) => {
|
|
22354
22443
|
const lines = data.toString().trim().split("\n");
|
|
22355
22444
|
for (const line of lines) {
|
|
22356
|
-
log$
|
|
22445
|
+
log$2.warn({
|
|
22357
22446
|
runtime: this.options.runtime,
|
|
22358
22447
|
stream: "stderr"
|
|
22359
22448
|
}, line);
|
|
@@ -22363,7 +22452,7 @@ var RuntimeProcess = class {
|
|
|
22363
22452
|
this.child.on("exit", (code, signal) => {
|
|
22364
22453
|
this.child = null;
|
|
22365
22454
|
if (this.stopped) {
|
|
22366
|
-
log$
|
|
22455
|
+
log$2.info({
|
|
22367
22456
|
runtime: this.options.runtime,
|
|
22368
22457
|
code,
|
|
22369
22458
|
signal
|
|
@@ -22371,7 +22460,7 @@ var RuntimeProcess = class {
|
|
|
22371
22460
|
return;
|
|
22372
22461
|
}
|
|
22373
22462
|
if (code === 0 && signal == null) {
|
|
22374
|
-
log$
|
|
22463
|
+
log$2.info({
|
|
22375
22464
|
runtime: this.options.runtime,
|
|
22376
22465
|
code
|
|
22377
22466
|
}, "Runtime exited gracefully — restarting");
|
|
@@ -22381,7 +22470,7 @@ var RuntimeProcess = class {
|
|
|
22381
22470
|
}, 500);
|
|
22382
22471
|
return;
|
|
22383
22472
|
}
|
|
22384
|
-
log$
|
|
22473
|
+
log$2.warn({
|
|
22385
22474
|
runtime: this.options.runtime,
|
|
22386
22475
|
code,
|
|
22387
22476
|
signal,
|
|
@@ -22402,7 +22491,7 @@ var RuntimeProcess = class {
|
|
|
22402
22491
|
recentOutput: this.ringBuffer.snapshot(),
|
|
22403
22492
|
crashesSuppressed: crash.suppressedCount
|
|
22404
22493
|
});
|
|
22405
|
-
else log$
|
|
22494
|
+
else log$2.debug({
|
|
22406
22495
|
runtime: this.options.runtime,
|
|
22407
22496
|
suppressed: crash.suppressedCount
|
|
22408
22497
|
}, "Crash capture suppressed by throttle");
|
|
@@ -22414,7 +22503,7 @@ var RuntimeProcess = class {
|
|
|
22414
22503
|
this.backoffMs = Math.min(this.backoffMs * 2, BACKOFF_MAX_MS);
|
|
22415
22504
|
});
|
|
22416
22505
|
this.child.on("error", (err) => {
|
|
22417
|
-
log$
|
|
22506
|
+
log$2.error({
|
|
22418
22507
|
runtime: this.options.runtime,
|
|
22419
22508
|
err: err.message
|
|
22420
22509
|
}, "Runtime process error");
|
|
@@ -22453,7 +22542,7 @@ var RuntimeProcess = class {
|
|
|
22453
22542
|
this.emitErrorBlock(this.detector.flush());
|
|
22454
22543
|
}, DETECTOR_FLUSH_DEBOUNCE_MS);
|
|
22455
22544
|
} catch (err) {
|
|
22456
|
-
log$
|
|
22545
|
+
log$2.debug({
|
|
22457
22546
|
runtime: this.options.runtime,
|
|
22458
22547
|
err: err instanceof Error ? err.message : String(err)
|
|
22459
22548
|
}, "Runtime output observation failed");
|
|
@@ -22464,7 +22553,7 @@ var RuntimeProcess = class {
|
|
|
22464
22553
|
if (!block) return;
|
|
22465
22554
|
const { allow, suppressedCount } = this.throttle.allowErrorCapture(block.fingerprintKey);
|
|
22466
22555
|
if (!allow) {
|
|
22467
|
-
log$
|
|
22556
|
+
log$2.debug({
|
|
22468
22557
|
runtime: this.options.runtime,
|
|
22469
22558
|
kind: block.kind,
|
|
22470
22559
|
suppressed: suppressedCount
|
|
@@ -22498,7 +22587,7 @@ var RuntimeProcess = class {
|
|
|
22498
22587
|
if (!child) return;
|
|
22499
22588
|
return new Promise((resolve) => {
|
|
22500
22589
|
const killTimer = setTimeout(() => {
|
|
22501
|
-
log$
|
|
22590
|
+
log$2.warn({ runtime: this.options.runtime }, "Runtime did not exit in time — sending SIGKILL");
|
|
22502
22591
|
child.kill("SIGKILL");
|
|
22503
22592
|
}, 5e3);
|
|
22504
22593
|
child.on("exit", () => {
|
|
@@ -22523,7 +22612,7 @@ var RuntimeProcess = class {
|
|
|
22523
22612
|
* Restart the runtime process (stop then start with fresh backoff).
|
|
22524
22613
|
*/
|
|
22525
22614
|
async restart() {
|
|
22526
|
-
log$
|
|
22615
|
+
log$2.info({ runtime: this.options.runtime }, "Restarting runtime...");
|
|
22527
22616
|
await this.stop();
|
|
22528
22617
|
this.stopped = false;
|
|
22529
22618
|
this.backoffMs = BACKOFF_INITIAL_MS;
|
|
@@ -22545,7 +22634,7 @@ var RuntimeProcess = class {
|
|
|
22545
22634
|
* this registry from active integration manifests. Handler files are loaded
|
|
22546
22635
|
* via ESM dynamic import on first use and cached until the registry is cleared.
|
|
22547
22636
|
*/
|
|
22548
|
-
const log = createLogger("CommandRegistry");
|
|
22637
|
+
const log$1 = createLogger("CommandRegistry");
|
|
22549
22638
|
var CommandRegistry = class {
|
|
22550
22639
|
commands = /* @__PURE__ */ new Map();
|
|
22551
22640
|
version = 0;
|
|
@@ -22556,7 +22645,7 @@ var CommandRegistry = class {
|
|
|
22556
22645
|
register(integrationId, name, handlerPath, method = "handle", timeoutMs = 3e4) {
|
|
22557
22646
|
const existing = this.commands.get(name);
|
|
22558
22647
|
if (existing) {
|
|
22559
|
-
log.warn({
|
|
22648
|
+
log$1.warn({
|
|
22560
22649
|
command: name,
|
|
22561
22650
|
existing: existing.integrationId,
|
|
22562
22651
|
attempted: integrationId
|
|
@@ -22564,7 +22653,7 @@ var CommandRegistry = class {
|
|
|
22564
22653
|
return;
|
|
22565
22654
|
}
|
|
22566
22655
|
if (!existsSync(handlerPath)) {
|
|
22567
|
-
log.warn({
|
|
22656
|
+
log$1.warn({
|
|
22568
22657
|
command: name,
|
|
22569
22658
|
handlerPath,
|
|
22570
22659
|
integrationId
|
|
@@ -22579,7 +22668,7 @@ var CommandRegistry = class {
|
|
|
22579
22668
|
timeoutMs,
|
|
22580
22669
|
handler: null
|
|
22581
22670
|
});
|
|
22582
|
-
log.info({
|
|
22671
|
+
log$1.info({
|
|
22583
22672
|
command: name,
|
|
22584
22673
|
integrationId,
|
|
22585
22674
|
handlerPath,
|
|
@@ -22593,7 +22682,7 @@ var CommandRegistry = class {
|
|
|
22593
22682
|
unregisterAll(integrationId) {
|
|
22594
22683
|
for (const [name, entry] of this.commands) if (entry.integrationId === integrationId) {
|
|
22595
22684
|
this.commands.delete(name);
|
|
22596
|
-
log.info({
|
|
22685
|
+
log$1.info({
|
|
22597
22686
|
command: name,
|
|
22598
22687
|
integrationId
|
|
22599
22688
|
}, "Unregistered command");
|
|
@@ -22631,7 +22720,7 @@ var CommandRegistry = class {
|
|
|
22631
22720
|
entry.handler = fn;
|
|
22632
22721
|
} catch (err) {
|
|
22633
22722
|
const message = err instanceof Error ? err.message : String(err);
|
|
22634
|
-
log.error({
|
|
22723
|
+
log$1.error({
|
|
22635
22724
|
err: message,
|
|
22636
22725
|
command: name,
|
|
22637
22726
|
handlerPath: entry.handlerPath
|
|
@@ -22652,7 +22741,7 @@ var CommandRegistry = class {
|
|
|
22652
22741
|
})]);
|
|
22653
22742
|
} catch (err) {
|
|
22654
22743
|
const message = err instanceof Error ? err.message : String(err);
|
|
22655
|
-
log.error({
|
|
22744
|
+
log$1.error({
|
|
22656
22745
|
err: message,
|
|
22657
22746
|
command: name
|
|
22658
22747
|
}, "Command execution failed");
|
|
@@ -22681,7 +22770,7 @@ var CommandRegistry = class {
|
|
|
22681
22770
|
clear() {
|
|
22682
22771
|
this.commands.clear();
|
|
22683
22772
|
this.version++;
|
|
22684
|
-
log.info({ version: this.version }, "Command registry cleared");
|
|
22773
|
+
log$1.info({ version: this.version }, "Command registry cleared");
|
|
22685
22774
|
}
|
|
22686
22775
|
};
|
|
22687
22776
|
//#endregion
|
|
@@ -22970,6 +23059,93 @@ function writeSentinel(path) {
|
|
|
22970
23059
|
} catch {}
|
|
22971
23060
|
}
|
|
22972
23061
|
//#endregion
|
|
23062
|
+
//#region src/mcp-error-capture.ts
|
|
23063
|
+
const log = createLogger("McpErrorCapture");
|
|
23064
|
+
/** Quiet-period flush for a pending multi-line stderr block. */
|
|
23065
|
+
const MCP_STDERR_FLUSH_DEBOUNCE_MS = 1500;
|
|
23066
|
+
function createMcpErrorHooks() {
|
|
23067
|
+
const resultErrorThrottle = new CaptureThrottle(6e4);
|
|
23068
|
+
const errorThrottle = new CaptureThrottle(6e4);
|
|
23069
|
+
const crashThrottle = new CaptureThrottle(6e4);
|
|
23070
|
+
const throttleFor = (kind) => kind === "tool-result-error" ? resultErrorThrottle : kind === "server-crash" ? crashThrottle : errorThrottle;
|
|
23071
|
+
const detectors = /* @__PURE__ */ new Map();
|
|
23072
|
+
const flushTimers = /* @__PURE__ */ new Map();
|
|
23073
|
+
const capture = (opts) => {
|
|
23074
|
+
const { allow, suppressedCount } = throttleFor(opts.kind).allowErrorCapture(opts.fingerprintKey);
|
|
23075
|
+
if (!allow) {
|
|
23076
|
+
log.debug({
|
|
23077
|
+
server: opts.server,
|
|
23078
|
+
kind: opts.kind,
|
|
23079
|
+
suppressed: suppressedCount
|
|
23080
|
+
}, "MCP failure capture suppressed by throttle");
|
|
23081
|
+
return;
|
|
23082
|
+
}
|
|
23083
|
+
captureMcpFailure({
|
|
23084
|
+
...opts,
|
|
23085
|
+
suppressedCount
|
|
23086
|
+
});
|
|
23087
|
+
};
|
|
23088
|
+
const emitBlock = (server, block) => {
|
|
23089
|
+
if (!block) return;
|
|
23090
|
+
capture({
|
|
23091
|
+
server,
|
|
23092
|
+
kind: "stderr-output",
|
|
23093
|
+
message: block.lines[0],
|
|
23094
|
+
lines: block.lines,
|
|
23095
|
+
fingerprintKey: `stderr:${server}:${block.fingerprintKey}`
|
|
23096
|
+
});
|
|
23097
|
+
};
|
|
23098
|
+
return {
|
|
23099
|
+
onToolError: (info) => {
|
|
23100
|
+
capture({
|
|
23101
|
+
server: info.server,
|
|
23102
|
+
tool: info.tool,
|
|
23103
|
+
kind: info.kind === "thrown" ? "tool-thrown" : "tool-result-error",
|
|
23104
|
+
message: info.message,
|
|
23105
|
+
fingerprintKey: `tool:${info.server}:${info.tool}:${toFingerprintKey(info.message)}`
|
|
23106
|
+
});
|
|
23107
|
+
},
|
|
23108
|
+
onServerCrash: (server) => {
|
|
23109
|
+
const timer = flushTimers.get(server);
|
|
23110
|
+
if (timer) {
|
|
23111
|
+
clearTimeout(timer);
|
|
23112
|
+
flushTimers.delete(server);
|
|
23113
|
+
}
|
|
23114
|
+
emitBlock(server, detectors.get(server)?.flush() ?? null);
|
|
23115
|
+
capture({
|
|
23116
|
+
server,
|
|
23117
|
+
kind: "server-crash",
|
|
23118
|
+
message: "MCP server connection closed unexpectedly",
|
|
23119
|
+
fingerprintKey: `crash:${server}`
|
|
23120
|
+
});
|
|
23121
|
+
},
|
|
23122
|
+
onServerStderr: (server, line) => {
|
|
23123
|
+
let detector = detectors.get(server);
|
|
23124
|
+
if (!detector) {
|
|
23125
|
+
detector = new ErrorLineDetector();
|
|
23126
|
+
detectors.set(server, detector);
|
|
23127
|
+
}
|
|
23128
|
+
for (const block of detector.feed("stderr", line)) emitBlock(server, block);
|
|
23129
|
+
const existing = flushTimers.get(server);
|
|
23130
|
+
if (existing) {
|
|
23131
|
+
clearTimeout(existing);
|
|
23132
|
+
flushTimers.delete(server);
|
|
23133
|
+
}
|
|
23134
|
+
if (detector.isCollecting) {
|
|
23135
|
+
const target = detector;
|
|
23136
|
+
flushTimers.set(server, setTimeout(() => {
|
|
23137
|
+
flushTimers.delete(server);
|
|
23138
|
+
emitBlock(server, target.flush());
|
|
23139
|
+
}, MCP_STDERR_FLUSH_DEBOUNCE_MS));
|
|
23140
|
+
}
|
|
23141
|
+
},
|
|
23142
|
+
dispose: () => {
|
|
23143
|
+
for (const timer of flushTimers.values()) clearTimeout(timer);
|
|
23144
|
+
flushTimers.clear();
|
|
23145
|
+
}
|
|
23146
|
+
};
|
|
23147
|
+
}
|
|
23148
|
+
//#endregion
|
|
22973
23149
|
//#region src/daemon.ts
|
|
22974
23150
|
/**
|
|
22975
23151
|
* Alfe Gateway Daemon — main entry point.
|
|
@@ -23354,9 +23530,11 @@ async function startDaemon() {
|
|
|
23354
23530
|
});
|
|
23355
23531
|
const mcpManager = new Manager({ logger: logger$1 });
|
|
23356
23532
|
mcpManagerRef = mcpManager;
|
|
23533
|
+
const mcpErrorHooks = createMcpErrorHooks();
|
|
23357
23534
|
mcpBundler = new McpBundler({
|
|
23358
23535
|
logger: logger$1,
|
|
23359
|
-
idleTtlMs: 0
|
|
23536
|
+
idleTtlMs: 0,
|
|
23537
|
+
...mcpErrorHooks
|
|
23360
23538
|
}, { connect: defaultConnect });
|
|
23361
23539
|
if (config.runtime === "hermes") logger$1.info("Hermes runtime — daemon MCP bundler left idle (store mirrored to config.yaml by HermesMcpSync)");
|
|
23362
23540
|
else {
|
|
@@ -23483,6 +23661,7 @@ async function startDaemon() {
|
|
|
23483
23661
|
mcpBundler = null;
|
|
23484
23662
|
logger$1.debug("MCP bundler stopped");
|
|
23485
23663
|
}
|
|
23664
|
+
mcpErrorHooks.dispose();
|
|
23486
23665
|
logger$1.debug("Stopping MCP bundler manager...");
|
|
23487
23666
|
await mcpManager.dispose();
|
|
23488
23667
|
mcpManagerRef = null;
|
|
@@ -24207,4 +24386,4 @@ function formatDuration(ms) {
|
|
|
24207
24386
|
return `${String(Math.round(seconds / 3600))}h`;
|
|
24208
24387
|
}
|
|
24209
24388
|
//#endregion
|
|
24210
|
-
export {
|
|
24389
|
+
export { PID_PATH as C, resolveAgentIdentity as D, loadDaemonConfig as E, PINNED_OPENCLAW_VERSION as O, ALFE_DIR as S, fetchAgentConfig as T, captureRuntimeErrorOutput as _, installService as a, setAgentContext as b, uninstallService as c, AGENT_RUNTIME_SENTRY_DSN as d, captureCliFailure as f, captureRuntimeCrash as g, captureMcpFailure as h, checkExistingDaemon as i, AGENT_DAEMON_SENTRY_DSN as l, captureIntegrationFailure as m, queryDaemonHealth as n, startService as o, captureFatal as p, startDaemon as r, stopExistingDaemon as s, formatHealthReport as t, AGENT_MCP_SENTRY_DSN as u, flushSentry as v, SOCKET_PATH as w, PROTOCOL_VERSION as x, initAgentSentry as y };
|
package/dist/src/index.d.ts
CHANGED
|
@@ -81,6 +81,13 @@ declare const AGENT_DAEMON_SENTRY_DSN = "https://a47f010d8d39fb4350f913492189f28
|
|
|
81
81
|
* Mirrors `SENTRY_DSNS.agentRuntime` in `config/config.ts`.
|
|
82
82
|
*/
|
|
83
83
|
declare const AGENT_RUNTIME_SENTRY_DSN = "https://feb7fb2e3b8e723aec518e74715bfa6d@o4511008239452160.ingest.us.sentry.io/4511683667558400";
|
|
84
|
+
/**
|
|
85
|
+
* MCP tool/server failures on agent VMs — reported by the daemon-hosted MCP
|
|
86
|
+
* bundler (tool errors, child crashes, stderr output). This is the SAME
|
|
87
|
+
* project as the cloud MCP Fly service (`SENTRY_DSNS.mcp`); agent-side events
|
|
88
|
+
* are distinguished by `source: agent-daemon` + `agentId` tags.
|
|
89
|
+
*/
|
|
90
|
+
declare const AGENT_MCP_SENTRY_DSN = "https://638309eac96146a945f46b578f10c806@o4511008239452160.ingest.us.sentry.io/4511146364174336";
|
|
84
91
|
/** Which surface initialised Sentry — tagged on every event. */
|
|
85
92
|
type SentrySurface = "cli" | "daemon";
|
|
86
93
|
interface InitAgentSentryOptions {
|
|
@@ -157,6 +164,21 @@ declare function captureRuntimeErrorOutput(opts: {
|
|
|
157
164
|
fingerprintKey: string;
|
|
158
165
|
suppressedCount?: number;
|
|
159
166
|
}): void;
|
|
167
|
+
/**
|
|
168
|
+
* Capture an MCP failure (tool error, server crash, or error-looking stderr
|
|
169
|
+
* output) into the `mcp` project via the daemon's bound MCP client. Throttling
|
|
170
|
+
* is the caller's job (`mcp-error-capture.ts`). No-op when the MCP client is
|
|
171
|
+
* not initialised. Never throws.
|
|
172
|
+
*/
|
|
173
|
+
declare function captureMcpFailure(opts: {
|
|
174
|
+
server: string;
|
|
175
|
+
tool?: string;
|
|
176
|
+
kind: "tool-thrown" | "tool-result-error" | "server-crash" | "stderr-output";
|
|
177
|
+
message: string;
|
|
178
|
+
/** Optional context lines (stderr block) — attached as breadcrumbs. */
|
|
179
|
+
lines?: readonly string[];
|
|
180
|
+
suppressedCount?: number;
|
|
181
|
+
}): void;
|
|
160
182
|
/** Flush queued events (small timeout) so short-lived commands deliver them. */
|
|
161
183
|
declare function flushSentry(timeoutMs?: number): Promise<void>;
|
|
162
184
|
/**
|
|
@@ -338,4 +360,4 @@ declare function checkExistingDaemon(): Promise<number | null>;
|
|
|
338
360
|
*/
|
|
339
361
|
declare function stopExistingDaemon(): Promise<boolean>;
|
|
340
362
|
//#endregion
|
|
341
|
-
export { AGENT_DAEMON_SENTRY_DSN, AGENT_RUNTIME_SENTRY_DSN, ALFE_DIR, type AgentIdentity, type AgentWorkspaceConfig, type DaemonConfig, type DaemonHealth, type IPCEvent, type IPCRequest, type IPCResponse, type InitAgentSentryOptions, PID_PATH, PINNED_OPENCLAW_VERSION, PROTOCOL_VERSION, type RuntimeOutputLine, SOCKET_PATH, type SentrySurface, captureCliFailure, captureFatal, captureIntegrationFailure, captureRuntimeCrash, captureRuntimeErrorOutput, checkExistingDaemon, fetchAgentConfig, flushSentry, formatHealthReport, initAgentSentry, installService, loadDaemonConfig, logger, queryDaemonHealth, resolveAgentIdentity, setAgentContext, startDaemon, startService, stopExistingDaemon, uninstallService };
|
|
363
|
+
export { AGENT_DAEMON_SENTRY_DSN, AGENT_MCP_SENTRY_DSN, AGENT_RUNTIME_SENTRY_DSN, ALFE_DIR, type AgentIdentity, type AgentWorkspaceConfig, type DaemonConfig, type DaemonHealth, type IPCEvent, type IPCRequest, type IPCResponse, type InitAgentSentryOptions, PID_PATH, PINNED_OPENCLAW_VERSION, PROTOCOL_VERSION, type RuntimeOutputLine, SOCKET_PATH, type SentrySurface, captureCliFailure, captureFatal, captureIntegrationFailure, captureMcpFailure, captureRuntimeCrash, captureRuntimeErrorOutput, checkExistingDaemon, fetchAgentConfig, flushSentry, formatHealthReport, initAgentSentry, installService, loadDaemonConfig, logger, queryDaemonHealth, resolveAgentIdentity, setAgentContext, startDaemon, startService, stopExistingDaemon, uninstallService };
|
package/dist/src/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as PID_PATH, D as resolveAgentIdentity, E as loadDaemonConfig, O as PINNED_OPENCLAW_VERSION, S as ALFE_DIR, T as fetchAgentConfig, _ as captureRuntimeErrorOutput, a as installService, b as setAgentContext, c as uninstallService, d as AGENT_RUNTIME_SENTRY_DSN, f as captureCliFailure, g as captureRuntimeCrash, h as captureMcpFailure, i as checkExistingDaemon, l as AGENT_DAEMON_SENTRY_DSN, m as captureIntegrationFailure, n as queryDaemonHealth, o as startService, p as captureFatal, r as startDaemon, s as stopExistingDaemon, t as formatHealthReport, u as AGENT_MCP_SENTRY_DSN, v as flushSentry, w as SOCKET_PATH, x as PROTOCOL_VERSION, y as initAgentSentry } from "../health.js";
|
|
2
2
|
import { n as logger } from "../logger.js";
|
|
3
|
-
export { AGENT_DAEMON_SENTRY_DSN, AGENT_RUNTIME_SENTRY_DSN, ALFE_DIR, PID_PATH, PINNED_OPENCLAW_VERSION, PROTOCOL_VERSION, SOCKET_PATH, captureCliFailure, captureFatal, captureIntegrationFailure, captureRuntimeCrash, captureRuntimeErrorOutput, checkExistingDaemon, fetchAgentConfig, flushSentry, formatHealthReport, initAgentSentry, installService, loadDaemonConfig, logger, queryDaemonHealth, resolveAgentIdentity, setAgentContext, startDaemon, startService, stopExistingDaemon, uninstallService };
|
|
3
|
+
export { AGENT_DAEMON_SENTRY_DSN, AGENT_MCP_SENTRY_DSN, AGENT_RUNTIME_SENTRY_DSN, ALFE_DIR, PID_PATH, PINNED_OPENCLAW_VERSION, PROTOCOL_VERSION, SOCKET_PATH, captureCliFailure, captureFatal, captureIntegrationFailure, captureMcpFailure, captureRuntimeCrash, captureRuntimeErrorOutput, checkExistingDaemon, fetchAgentConfig, flushSentry, formatHealthReport, initAgentSentry, installService, loadDaemonConfig, logger, queryDaemonHealth, resolveAgentIdentity, setAgentContext, startDaemon, startService, stopExistingDaemon, uninstallService };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/gateway",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Alfe local gateway daemon — persistent control plane for agent integrations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"pino-roll": "^1.2.0",
|
|
24
24
|
"smol-toml": ">=1.6.1",
|
|
25
25
|
"ws": "^8.18.0",
|
|
26
|
-
"@alfe.ai/agent-api-client": "^0.
|
|
26
|
+
"@alfe.ai/agent-api-client": "^0.8.0",
|
|
27
27
|
"@alfe.ai/ai-proxy-local": "^0.0.13",
|
|
28
28
|
"@alfe.ai/config": "^0.3.0",
|
|
29
29
|
"@alfe.ai/integration-manifest": "^0.3.1",
|
|
30
|
-
"@alfe.ai/integrations": "^0.
|
|
31
|
-
"@alfe.ai/mcp-bundler": "^0.
|
|
30
|
+
"@alfe.ai/integrations": "^0.3.0",
|
|
31
|
+
"@alfe.ai/mcp-bundler": "^0.3.0"
|
|
32
32
|
},
|
|
33
33
|
"license": "UNLICENSED",
|
|
34
34
|
"homepage": "https://alfe.ai",
|