@alan-ai-hq/agent-manager 0.1.78 → 0.1.80
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/__tests__/binding-switch-git.test.d.ts +2 -0
- package/dist/__tests__/binding-switch-git.test.d.ts.map +1 -0
- package/dist/__tests__/binding-switch-git.test.js +610 -0
- package/dist/__tests__/binding-switch-git.test.js.map +1 -0
- package/dist/__tests__/cli-ensure-install.test.d.ts +2 -0
- package/dist/__tests__/cli-ensure-install.test.d.ts.map +1 -0
- package/dist/__tests__/cli-ensure-install.test.js +109 -0
- package/dist/__tests__/cli-ensure-install.test.js.map +1 -0
- package/dist/__tests__/cli-executable.test.d.ts +2 -0
- package/dist/__tests__/cli-executable.test.d.ts.map +1 -0
- package/dist/__tests__/cli-executable.test.js +129 -0
- package/dist/__tests__/cli-executable.test.js.map +1 -0
- package/dist/__tests__/cli-help.test.d.ts +2 -0
- package/dist/__tests__/cli-help.test.d.ts.map +1 -0
- package/dist/__tests__/cli-help.test.js +34 -0
- package/dist/__tests__/cli-help.test.js.map +1 -0
- package/dist/__tests__/computer-readiness.test.d.ts +2 -0
- package/dist/__tests__/computer-readiness.test.d.ts.map +1 -0
- package/dist/__tests__/computer-readiness.test.js +63 -0
- package/dist/__tests__/computer-readiness.test.js.map +1 -0
- package/dist/__tests__/core-agent-workflow-context.test.d.ts +2 -0
- package/dist/__tests__/core-agent-workflow-context.test.d.ts.map +1 -0
- package/dist/__tests__/core-agent-workflow-context.test.js +139 -0
- package/dist/__tests__/core-agent-workflow-context.test.js.map +1 -0
- package/dist/__tests__/daemon-reconcile-ask.test.d.ts +2 -0
- package/dist/__tests__/daemon-reconcile-ask.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-reconcile-ask.test.js +86 -0
- package/dist/__tests__/daemon-reconcile-ask.test.js.map +1 -0
- package/dist/__tests__/daemon-socket.integration.test.d.ts +2 -0
- package/dist/__tests__/daemon-socket.integration.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-socket.integration.test.js +450 -0
- package/dist/__tests__/daemon-socket.integration.test.js.map +1 -0
- package/dist/__tests__/daemon.test.d.ts +2 -0
- package/dist/__tests__/daemon.test.d.ts.map +1 -0
- package/dist/__tests__/daemon.test.js +3975 -0
- package/dist/__tests__/daemon.test.js.map +1 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts +2 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts.map +1 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.js +129 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.js.map +1 -0
- package/dist/__tests__/event-outbox-persist-failure.test.d.ts +2 -0
- package/dist/__tests__/event-outbox-persist-failure.test.d.ts.map +1 -0
- package/dist/__tests__/event-outbox-persist-failure.test.js +84 -0
- package/dist/__tests__/event-outbox-persist-failure.test.js.map +1 -0
- package/dist/__tests__/event-outbox.test.d.ts +2 -0
- package/dist/__tests__/event-outbox.test.d.ts.map +1 -0
- package/dist/__tests__/event-outbox.test.js +256 -0
- package/dist/__tests__/event-outbox.test.js.map +1 -0
- package/dist/__tests__/fake-provider-cli.test.d.ts +2 -0
- package/dist/__tests__/fake-provider-cli.test.d.ts.map +1 -0
- package/dist/__tests__/fake-provider-cli.test.js +46 -0
- package/dist/__tests__/fake-provider-cli.test.js.map +1 -0
- package/dist/__tests__/generated-images.test.d.ts +2 -0
- package/dist/__tests__/generated-images.test.d.ts.map +1 -0
- package/dist/__tests__/generated-images.test.js +132 -0
- package/dist/__tests__/generated-images.test.js.map +1 -0
- package/dist/__tests__/lifecycle-logger.test.d.ts +2 -0
- package/dist/__tests__/lifecycle-logger.test.d.ts.map +1 -0
- package/dist/__tests__/lifecycle-logger.test.js +49 -0
- package/dist/__tests__/lifecycle-logger.test.js.map +1 -0
- package/dist/__tests__/local-skill-scan.test.d.ts +2 -0
- package/dist/__tests__/local-skill-scan.test.d.ts.map +1 -0
- package/dist/__tests__/local-skill-scan.test.js +91 -0
- package/dist/__tests__/local-skill-scan.test.js.map +1 -0
- package/dist/__tests__/local-workspace-migration.test.d.ts +2 -0
- package/dist/__tests__/local-workspace-migration.test.d.ts.map +1 -0
- package/dist/__tests__/local-workspace-migration.test.js +195 -0
- package/dist/__tests__/local-workspace-migration.test.js.map +1 -0
- package/dist/__tests__/mcp-inspect-timeout.test.d.ts +2 -0
- package/dist/__tests__/mcp-inspect-timeout.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-inspect-timeout.test.js +97 -0
- package/dist/__tests__/mcp-inspect-timeout.test.js.map +1 -0
- package/dist/__tests__/mcp-readiness.test.d.ts +2 -0
- package/dist/__tests__/mcp-readiness.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-readiness.test.js +267 -0
- package/dist/__tests__/mcp-readiness.test.js.map +1 -0
- package/dist/__tests__/mcp-registration-cli.test.d.ts +2 -0
- package/dist/__tests__/mcp-registration-cli.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-registration-cli.test.js +71 -0
- package/dist/__tests__/mcp-registration-cli.test.js.map +1 -0
- package/dist/__tests__/mcp-registration.test.d.ts +2 -0
- package/dist/__tests__/mcp-registration.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-registration.test.js +426 -0
- package/dist/__tests__/mcp-registration.test.js.map +1 -0
- package/dist/__tests__/model-scan-runner.test.d.ts +2 -0
- package/dist/__tests__/model-scan-runner.test.d.ts.map +1 -0
- package/dist/__tests__/model-scan-runner.test.js +67 -0
- package/dist/__tests__/model-scan-runner.test.js.map +1 -0
- package/dist/__tests__/network-diagnostics.test.d.ts +2 -0
- package/dist/__tests__/network-diagnostics.test.d.ts.map +1 -0
- package/dist/__tests__/network-diagnostics.test.js +26 -0
- package/dist/__tests__/network-diagnostics.test.js.map +1 -0
- package/dist/__tests__/observable-map.test.d.ts +2 -0
- package/dist/__tests__/observable-map.test.d.ts.map +1 -0
- package/dist/__tests__/observable-map.test.js +54 -0
- package/dist/__tests__/observable-map.test.js.map +1 -0
- package/dist/__tests__/provider-auth-preflight.test.d.ts +2 -0
- package/dist/__tests__/provider-auth-preflight.test.d.ts.map +1 -0
- package/dist/__tests__/provider-auth-preflight.test.js +123 -0
- package/dist/__tests__/provider-auth-preflight.test.js.map +1 -0
- package/dist/__tests__/provider-model-discovery.test.d.ts +2 -0
- package/dist/__tests__/provider-model-discovery.test.d.ts.map +1 -0
- package/dist/__tests__/provider-model-discovery.test.js +472 -0
- package/dist/__tests__/provider-model-discovery.test.js.map +1 -0
- package/dist/__tests__/remove-worktrees-if-clean.test.d.ts +2 -0
- package/dist/__tests__/remove-worktrees-if-clean.test.d.ts.map +1 -0
- package/dist/__tests__/remove-worktrees-if-clean.test.js +221 -0
- package/dist/__tests__/remove-worktrees-if-clean.test.js.map +1 -0
- package/dist/__tests__/resume-fallback-env.test.d.ts +2 -0
- package/dist/__tests__/resume-fallback-env.test.d.ts.map +1 -0
- package/dist/__tests__/resume-fallback-env.test.js +28 -0
- package/dist/__tests__/resume-fallback-env.test.js.map +1 -0
- package/dist/__tests__/run-journal.test.d.ts +2 -0
- package/dist/__tests__/run-journal.test.d.ts.map +1 -0
- package/dist/__tests__/run-journal.test.js +121 -0
- package/dist/__tests__/run-journal.test.js.map +1 -0
- package/dist/__tests__/run-start-gate.test.d.ts +2 -0
- package/dist/__tests__/run-start-gate.test.d.ts.map +1 -0
- package/dist/__tests__/run-start-gate.test.js +29 -0
- package/dist/__tests__/run-start-gate.test.js.map +1 -0
- package/dist/__tests__/runtime-capabilities-sync.test.d.ts +2 -0
- package/dist/__tests__/runtime-capabilities-sync.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-capabilities-sync.test.js +66 -0
- package/dist/__tests__/runtime-capabilities-sync.test.js.map +1 -0
- package/dist/__tests__/runtime-config.test.d.ts +2 -0
- package/dist/__tests__/runtime-config.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-config.test.js +102 -0
- package/dist/__tests__/runtime-config.test.js.map +1 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts +2 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.js +159 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.js.map +1 -0
- package/dist/__tests__/sandbox-outbox.test.d.ts +2 -0
- package/dist/__tests__/sandbox-outbox.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-outbox.test.js +214 -0
- package/dist/__tests__/sandbox-outbox.test.js.map +1 -0
- package/dist/__tests__/sandbox-workflow-context.test.d.ts +2 -0
- package/dist/__tests__/sandbox-workflow-context.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-workflow-context.test.js +396 -0
- package/dist/__tests__/sandbox-workflow-context.test.js.map +1 -0
- package/dist/__tests__/service-manager.test.d.ts +2 -0
- package/dist/__tests__/service-manager.test.d.ts.map +1 -0
- package/dist/__tests__/service-manager.test.js +50 -0
- package/dist/__tests__/service-manager.test.js.map +1 -0
- package/dist/__tests__/sleep-inhibitor.test.d.ts +2 -0
- package/dist/__tests__/sleep-inhibitor.test.d.ts.map +1 -0
- package/dist/__tests__/sleep-inhibitor.test.js +236 -0
- package/dist/__tests__/sleep-inhibitor.test.js.map +1 -0
- package/dist/__tests__/status-local-workspace.test.d.ts +2 -0
- package/dist/__tests__/status-local-workspace.test.d.ts.map +1 -0
- package/dist/__tests__/status-local-workspace.test.js +121 -0
- package/dist/__tests__/status-local-workspace.test.js.map +1 -0
- package/dist/__tests__/suspension-detector.test.d.ts +2 -0
- package/dist/__tests__/suspension-detector.test.d.ts.map +1 -0
- package/dist/__tests__/suspension-detector.test.js +112 -0
- package/dist/__tests__/suspension-detector.test.js.map +1 -0
- package/dist/__tests__/web-presenter-parent-events.test.d.ts +2 -0
- package/dist/__tests__/web-presenter-parent-events.test.d.ts.map +1 -0
- package/dist/__tests__/web-presenter-parent-events.test.js +130 -0
- package/dist/__tests__/web-presenter-parent-events.test.js.map +1 -0
- package/dist/__tests__/workspace-relocation.test.d.ts +2 -0
- package/dist/__tests__/workspace-relocation.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-relocation.test.js +66 -0
- package/dist/__tests__/workspace-relocation.test.js.map +1 -0
- package/dist/__tests__/workspace-run-lease.test.d.ts +2 -0
- package/dist/__tests__/workspace-run-lease.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-run-lease.test.js +230 -0
- package/dist/__tests__/workspace-run-lease.test.js.map +1 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts +2 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.js +61 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.js.map +1 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts +2 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.js +109 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.js.map +1 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts +2 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.js +167 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.js.map +1 -0
- package/dist/aiden-system-prompt.d.ts +6 -0
- package/dist/aiden-system-prompt.d.ts.map +1 -0
- package/dist/aiden-system-prompt.js +6 -0
- package/dist/aiden-system-prompt.js.map +1 -0
- package/dist/binding-switch-git.d.ts +26 -0
- package/dist/binding-switch-git.d.ts.map +1 -0
- package/dist/binding-switch-git.js +973 -0
- package/dist/binding-switch-git.js.map +1 -0
- package/dist/cli-ensure-install.d.ts +39 -0
- package/dist/cli-ensure-install.d.ts.map +1 -0
- package/dist/cli-ensure-install.js +133 -0
- package/dist/cli-ensure-install.js.map +1 -0
- package/dist/cli-executable.d.ts +97 -0
- package/dist/cli-executable.d.ts.map +1 -0
- package/dist/cli-executable.js +432 -0
- package/dist/cli-executable.js.map +1 -0
- package/dist/cli-help.d.ts +7 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +49 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/computer-readiness.d.ts +42 -0
- package/dist/computer-readiness.d.ts.map +1 -0
- package/dist/computer-readiness.js +191 -0
- package/dist/computer-readiness.js.map +1 -0
- package/dist/core-agent.d.ts +47 -0
- package/dist/core-agent.d.ts.map +1 -0
- package/dist/core-agent.js +364 -0
- package/dist/core-agent.js.map +1 -0
- package/dist/daemon.d.ts +392 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +4711 -0
- package/dist/daemon.js.map +1 -0
- package/dist/event-outbox.d.ts +83 -0
- package/dist/event-outbox.d.ts.map +1 -0
- package/dist/event-outbox.js +440 -0
- package/dist/event-outbox.js.map +1 -0
- package/dist/fake-provider-cli.d.ts +13 -0
- package/dist/fake-provider-cli.d.ts.map +1 -0
- package/dist/fake-provider-cli.js +53 -0
- package/dist/fake-provider-cli.js.map +1 -0
- package/dist/generated-images.d.ts +2 -0
- package/dist/generated-images.d.ts.map +1 -0
- package/dist/generated-images.js +2 -0
- package/dist/generated-images.js.map +1 -0
- package/dist/index.cjs +1037 -188
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +209 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle-logger.d.ts +25 -0
- package/dist/lifecycle-logger.d.ts.map +1 -0
- package/dist/lifecycle-logger.js +73 -0
- package/dist/lifecycle-logger.js.map +1 -0
- package/dist/local-skill-scan.d.ts +21 -0
- package/dist/local-skill-scan.d.ts.map +1 -0
- package/dist/local-skill-scan.js +109 -0
- package/dist/local-skill-scan.js.map +1 -0
- package/dist/local-workspace-migration.d.ts +68 -0
- package/dist/local-workspace-migration.d.ts.map +1 -0
- package/dist/local-workspace-migration.js +157 -0
- package/dist/local-workspace-migration.js.map +1 -0
- package/dist/mcp-readiness.d.ts +59 -0
- package/dist/mcp-readiness.d.ts.map +1 -0
- package/dist/mcp-readiness.js +202 -0
- package/dist/mcp-readiness.js.map +1 -0
- package/dist/mcp-registration.d.ts +75 -0
- package/dist/mcp-registration.d.ts.map +1 -0
- package/dist/mcp-registration.js +563 -0
- package/dist/mcp-registration.js.map +1 -0
- package/dist/model-scan-runner.d.ts +15 -0
- package/dist/model-scan-runner.d.ts.map +1 -0
- package/dist/model-scan-runner.js +51 -0
- package/dist/model-scan-runner.js.map +1 -0
- package/dist/network-diagnostics.d.ts +8 -0
- package/dist/network-diagnostics.d.ts.map +1 -0
- package/dist/network-diagnostics.js +56 -0
- package/dist/network-diagnostics.js.map +1 -0
- package/dist/observable-map.d.ts +25 -0
- package/dist/observable-map.d.ts.map +1 -0
- package/dist/observable-map.js +42 -0
- package/dist/observable-map.js.map +1 -0
- package/dist/provider-auth-preflight.d.ts +22 -0
- package/dist/provider-auth-preflight.d.ts.map +1 -0
- package/dist/provider-auth-preflight.js +110 -0
- package/dist/provider-auth-preflight.js.map +1 -0
- package/dist/provider-model-discovery.d.ts +38 -0
- package/dist/provider-model-discovery.d.ts.map +1 -0
- package/dist/provider-model-discovery.js +519 -0
- package/dist/provider-model-discovery.js.map +1 -0
- package/dist/resume-fallback-env.d.ts +20 -0
- package/dist/resume-fallback-env.d.ts.map +1 -0
- package/dist/resume-fallback-env.js +30 -0
- package/dist/resume-fallback-env.js.map +1 -0
- package/dist/run-journal.d.ts +53 -0
- package/dist/run-journal.d.ts.map +1 -0
- package/dist/run-journal.js +193 -0
- package/dist/run-journal.js.map +1 -0
- package/dist/run-start-gate.d.ts +9 -0
- package/dist/run-start-gate.d.ts.map +1 -0
- package/dist/run-start-gate.js +24 -0
- package/dist/run-start-gate.js.map +1 -0
- package/dist/runtime-backends.d.ts +2 -0
- package/dist/runtime-backends.d.ts.map +1 -0
- package/dist/runtime-backends.js +2 -0
- package/dist/runtime-backends.js.map +1 -0
- package/dist/runtime-capabilities-sync.d.ts +33 -0
- package/dist/runtime-capabilities-sync.d.ts.map +1 -0
- package/dist/runtime-capabilities-sync.js +56 -0
- package/dist/runtime-capabilities-sync.js.map +1 -0
- package/dist/runtime-config.d.ts +24 -0
- package/dist/runtime-config.d.ts.map +1 -0
- package/dist/runtime-config.js +124 -0
- package/dist/runtime-config.js.map +1 -0
- package/dist/sandbox-outbox.d.ts +122 -0
- package/dist/sandbox-outbox.d.ts.map +1 -0
- package/dist/sandbox-outbox.js +180 -0
- package/dist/sandbox-outbox.js.map +1 -0
- package/dist/sandbox.d.ts +44 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +438 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/service-manager.d.ts +28 -0
- package/dist/service-manager.d.ts.map +1 -0
- package/dist/service-manager.js +259 -0
- package/dist/service-manager.js.map +1 -0
- package/dist/sleep-inhibitor.d.ts +111 -0
- package/dist/sleep-inhibitor.d.ts.map +1 -0
- package/dist/sleep-inhibitor.js +412 -0
- package/dist/sleep-inhibitor.js.map +1 -0
- package/dist/suspension-detector.d.ts +48 -0
- package/dist/suspension-detector.d.ts.map +1 -0
- package/dist/suspension-detector.js +89 -0
- package/dist/suspension-detector.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/updater.d.ts +15 -0
- package/dist/updater.d.ts.map +1 -0
- package/dist/updater.js +50 -0
- package/dist/updater.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/dist/web-presenter.d.ts +55 -0
- package/dist/web-presenter.d.ts.map +1 -0
- package/dist/web-presenter.js +265 -0
- package/dist/web-presenter.js.map +1 -0
- package/dist/workspace-relocation.d.ts +22 -0
- package/dist/workspace-relocation.d.ts.map +1 -0
- package/dist/workspace-relocation.js +90 -0
- package/dist/workspace-relocation.js.map +1 -0
- package/dist/workspace-run-lease.d.ts +97 -0
- package/dist/workspace-run-lease.d.ts.map +1 -0
- package/dist/workspace-run-lease.js +241 -0
- package/dist/workspace-run-lease.js.map +1 -0
- package/dist/ws-client.d.ts +194 -0
- package/dist/ws-client.d.ts.map +1 -0
- package/dist/ws-client.js +282 -0
- package/dist/ws-client.js.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -15240,7 +15240,7 @@ function describeError(error61) {
|
|
|
15240
15240
|
}
|
|
15241
15241
|
|
|
15242
15242
|
// src/version.ts
|
|
15243
|
-
var AGENT_VERSION = "0.1.
|
|
15243
|
+
var AGENT_VERSION = "0.1.80";
|
|
15244
15244
|
|
|
15245
15245
|
// src/daemon-worktree.ts
|
|
15246
15246
|
var import_node_child_process3 = require("child_process");
|
|
@@ -15576,8 +15576,8 @@ var RESOURCE_CLASS_GC_TIME_MS = {
|
|
|
15576
15576
|
var import_node_fs2 = require("fs");
|
|
15577
15577
|
var import_node_os2 = require("os");
|
|
15578
15578
|
var import_node_path2 = require("path");
|
|
15579
|
-
function resolveAlanDefaultWorkspacePath(
|
|
15580
|
-
return (0, import_node_path2.join)(
|
|
15579
|
+
function resolveAlanDefaultWorkspacePath(homeDirectory2 = (0, import_node_os2.homedir)()) {
|
|
15580
|
+
return (0, import_node_path2.join)(homeDirectory2, ".alan", "workspace");
|
|
15581
15581
|
}
|
|
15582
15582
|
|
|
15583
15583
|
// src/local-workspace-migration.ts
|
|
@@ -35665,6 +35665,22 @@ var import_node_os4 = require("os");
|
|
|
35665
35665
|
var import_node_path5 = require("path");
|
|
35666
35666
|
var DEFAULT_AGENT_DIR = (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".alan", "agent");
|
|
35667
35667
|
var LEGACY_AGENT_DIR = (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".aiden", "agent");
|
|
35668
|
+
function configuredConfigPathFromEnvironment() {
|
|
35669
|
+
const explicit = process.env.ALAN_AGENT_CONFIG_PATH?.trim() || process.env.ALAN_AGENT_CONFIG?.trim();
|
|
35670
|
+
return explicit || void 0;
|
|
35671
|
+
}
|
|
35672
|
+
function resolveIsolatedAgentBaseDir(profile) {
|
|
35673
|
+
switch (profile) {
|
|
35674
|
+
case "local":
|
|
35675
|
+
return (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".alan-dev", "agent");
|
|
35676
|
+
case "staging":
|
|
35677
|
+
return (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".alan-staging", "agent");
|
|
35678
|
+
case "custom":
|
|
35679
|
+
return (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".alan-prod", "agent");
|
|
35680
|
+
default:
|
|
35681
|
+
return null;
|
|
35682
|
+
}
|
|
35683
|
+
}
|
|
35668
35684
|
var AGENT_CONFIG_KEYS = /* @__PURE__ */ new Map([
|
|
35669
35685
|
["apiUrl", "string"],
|
|
35670
35686
|
["wsUrl", "string"],
|
|
@@ -35742,9 +35758,13 @@ function resolveAgentConfigPath(input2) {
|
|
|
35742
35758
|
const profile = normalizeAgentEndpointProfile(
|
|
35743
35759
|
typeof input2?.profile === "string" ? input2.profile : input2?.profile ?? null
|
|
35744
35760
|
) ?? "production";
|
|
35745
|
-
|
|
35746
|
-
|
|
35747
|
-
|
|
35761
|
+
if (input2?.baseDir !== void 0) {
|
|
35762
|
+
return (0, import_node_path5.join)(input2.baseDir, resolveAgentConfigFileName(profile));
|
|
35763
|
+
}
|
|
35764
|
+
const isolatedBaseDir = profile === "production" ? null : resolveIsolatedAgentBaseDir(profile);
|
|
35765
|
+
if (isolatedBaseDir) return (0, import_node_path5.join)(isolatedBaseDir, "config.json");
|
|
35766
|
+
migrateLegacyAgentConfig({ profile });
|
|
35767
|
+
return (0, import_node_path5.join)(DEFAULT_AGENT_DIR, resolveAgentConfigFileName(profile));
|
|
35748
35768
|
}
|
|
35749
35769
|
function configExistsAtPath(configPath) {
|
|
35750
35770
|
return (0, import_node_fs5.existsSync)(configPath);
|
|
@@ -35760,13 +35780,22 @@ function explicitConfigPathFromArgs(args) {
|
|
|
35760
35780
|
const prefix = "--config-path=";
|
|
35761
35781
|
return args.find((arg) => arg.startsWith(prefix))?.slice(prefix.length).trim() || void 0;
|
|
35762
35782
|
}
|
|
35783
|
+
function hasExplicitProfileArg(args) {
|
|
35784
|
+
return args.some((arg) => arg === "--profile" || arg.startsWith("--profile="));
|
|
35785
|
+
}
|
|
35763
35786
|
function bindAgentConfigPathFromArgs(args) {
|
|
35764
35787
|
const argumentPath = explicitConfigPathFromArgs(args);
|
|
35765
35788
|
if (argumentPath) {
|
|
35766
35789
|
process.env.ALAN_AGENT_CONFIG_PATH = argumentPath;
|
|
35767
35790
|
return argumentPath;
|
|
35768
35791
|
}
|
|
35769
|
-
|
|
35792
|
+
if (hasExplicitProfileArg(args)) {
|
|
35793
|
+
const profile2 = resolveEndpointProfileFromArgs(args);
|
|
35794
|
+
const configPath2 = resolveAgentConfigPath({ profile: profile2 });
|
|
35795
|
+
process.env.ALAN_AGENT_CONFIG_PATH = configPath2;
|
|
35796
|
+
return configPath2;
|
|
35797
|
+
}
|
|
35798
|
+
const explicit = configuredConfigPathFromEnvironment();
|
|
35770
35799
|
if (explicit) return explicit;
|
|
35771
35800
|
const profile = resolveEndpointProfileFromArgs(args);
|
|
35772
35801
|
const configPath = resolveAgentConfigPath({ profile });
|
|
@@ -60269,9 +60298,9 @@ function buildMcpParamHeaders(declarations, args) {
|
|
|
60269
60298
|
for (const decl of declarations) {
|
|
60270
60299
|
const raw = valueAtPath(args, decl.path);
|
|
60271
60300
|
if (raw === void 0 || raw === null) continue;
|
|
60272
|
-
const
|
|
60273
|
-
if (
|
|
60274
|
-
out[`${MCP_PARAM_HEADER_PREFIX}${decl.headerName}`] = encodeMcpParamValue(
|
|
60301
|
+
const stringValue2 = mcpParamPrimitiveToString(raw);
|
|
60302
|
+
if (stringValue2 === void 0) continue;
|
|
60303
|
+
out[`${MCP_PARAM_HEADER_PREFIX}${decl.headerName}`] = encodeMcpParamValue(stringValue2);
|
|
60275
60304
|
}
|
|
60276
60305
|
return out;
|
|
60277
60306
|
}
|
|
@@ -72840,9 +72869,29 @@ function failureFromError(error61, paths) {
|
|
|
72840
72869
|
stage: "protocol",
|
|
72841
72870
|
message: "Alan's tool service returned an invalid MCP response.",
|
|
72842
72871
|
retryable: false,
|
|
72843
|
-
paths
|
|
72872
|
+
paths,
|
|
72873
|
+
diagnostic: describeReadinessError(error61)
|
|
72844
72874
|
};
|
|
72845
72875
|
}
|
|
72876
|
+
function describeReadinessError(error61) {
|
|
72877
|
+
if (!(error61 instanceof Error)) return String(error61);
|
|
72878
|
+
const parts2 = [];
|
|
72879
|
+
let current = error61;
|
|
72880
|
+
for (let depth = 0; current instanceof Error && depth < 4; depth += 1) {
|
|
72881
|
+
const { name, message } = current;
|
|
72882
|
+
const { code, status } = current;
|
|
72883
|
+
parts2.push(
|
|
72884
|
+
[
|
|
72885
|
+
name,
|
|
72886
|
+
message,
|
|
72887
|
+
code === void 0 ? "" : `code=${String(code)}`,
|
|
72888
|
+
status === void 0 ? "" : `status=${String(status)}`
|
|
72889
|
+
].filter(Boolean).join(" ")
|
|
72890
|
+
);
|
|
72891
|
+
current = current.cause;
|
|
72892
|
+
}
|
|
72893
|
+
return parts2.join(" <- ");
|
|
72894
|
+
}
|
|
72846
72895
|
async function waitBeforeRetry() {
|
|
72847
72896
|
await new Promise((resolve15) => setTimeout(resolve15, RETRY_DELAY_MS2));
|
|
72848
72897
|
}
|
|
@@ -73283,7 +73332,8 @@ async function handleAgentExecute(ctx, payload) {
|
|
|
73283
73332
|
console.warn("[alan-agent] Alan MCP readiness observed failure", {
|
|
73284
73333
|
...correlation,
|
|
73285
73334
|
code: failure.code,
|
|
73286
|
-
stage: failure.stage
|
|
73335
|
+
stage: failure.stage,
|
|
73336
|
+
...failure.diagnostic ? { diagnostic: failure.diagnostic } : {}
|
|
73287
73337
|
});
|
|
73288
73338
|
}
|
|
73289
73339
|
});
|
|
@@ -74207,7 +74257,7 @@ var NativeTranscriptStreamer = class {
|
|
|
74207
74257
|
continue;
|
|
74208
74258
|
}
|
|
74209
74259
|
const parsed = parseJsonObject3(raw);
|
|
74210
|
-
const events = parsed ?
|
|
74260
|
+
const events = parsed ? providerRecordToAgentEvents(hook.provider, parsed) : [];
|
|
74211
74261
|
for (let index = 0; index < events.length; index += 1) {
|
|
74212
74262
|
const deliveredEvent = events[index];
|
|
74213
74263
|
const sourceCursor = `${start.generation}:${recordEndOffset}:${index}`;
|
|
@@ -74267,12 +74317,62 @@ function parseJsonObject3(value2) {
|
|
|
74267
74317
|
return null;
|
|
74268
74318
|
}
|
|
74269
74319
|
}
|
|
74270
|
-
function
|
|
74320
|
+
function providerRecordToAgentEvents(provider, record2) {
|
|
74321
|
+
if (provider === "codex") return codexRecordToAgentEvents(record2);
|
|
74322
|
+
if (provider === "copilot") return copilotRecordToAgentEvents(record2);
|
|
74323
|
+
return claudeCompatibleRecordToAgentEvents(record2);
|
|
74324
|
+
}
|
|
74325
|
+
function copilotRecordToAgentEvents(record2) {
|
|
74326
|
+
if (typeof record2.type !== "string" || !isRecord2(record2.data)) return [];
|
|
74327
|
+
const timestamp = timestampOf(record2) ? Date.parse(timestampOf(record2)) : Date.now();
|
|
74328
|
+
const ts = Number.isFinite(timestamp) ? timestamp : Date.now();
|
|
74329
|
+
const data = record2.data;
|
|
74330
|
+
if (record2.type === "assistant.message") {
|
|
74331
|
+
const events = [];
|
|
74332
|
+
if (typeof data.reasoningText === "string" && data.reasoningText.length > 0) {
|
|
74333
|
+
events.push({ type: "thinking", text: data.reasoningText, ts });
|
|
74334
|
+
}
|
|
74335
|
+
if (typeof data.content === "string" && data.content.length > 0) {
|
|
74336
|
+
events.push({ type: "text", text: data.content, ts });
|
|
74337
|
+
}
|
|
74338
|
+
if (Array.isArray(data.toolRequests)) {
|
|
74339
|
+
for (const request of data.toolRequests) {
|
|
74340
|
+
if (!isRecord2(request)) continue;
|
|
74341
|
+
const id = stringValue(request.id, request.toolCallId, request.tool_call_id);
|
|
74342
|
+
const name = stringValue(request.name, request.toolName, request.tool_name);
|
|
74343
|
+
if (id && name) {
|
|
74344
|
+
events.push({
|
|
74345
|
+
type: "tool_use",
|
|
74346
|
+
id,
|
|
74347
|
+
name,
|
|
74348
|
+
input: request.arguments ?? request.input,
|
|
74349
|
+
ts
|
|
74350
|
+
});
|
|
74351
|
+
}
|
|
74352
|
+
}
|
|
74353
|
+
}
|
|
74354
|
+
return events;
|
|
74355
|
+
}
|
|
74356
|
+
if (record2.type === "tool.execution_complete" || record2.type === "tool.execution_end") {
|
|
74357
|
+
const id = stringValue(data.toolCallId, data.tool_call_id, data.id);
|
|
74358
|
+
if (!id) return [];
|
|
74359
|
+
return [
|
|
74360
|
+
{
|
|
74361
|
+
type: "tool_result",
|
|
74362
|
+
id,
|
|
74363
|
+
content: extractText2(data.result ?? data.output ?? data.content),
|
|
74364
|
+
ts
|
|
74365
|
+
}
|
|
74366
|
+
];
|
|
74367
|
+
}
|
|
74368
|
+
return [];
|
|
74369
|
+
}
|
|
74370
|
+
function claudeCompatibleRecordToAgentEvents(record2) {
|
|
74271
74371
|
const timestamp = timestampOf(record2) ? Date.parse(timestampOf(record2)) : Date.now();
|
|
74272
74372
|
const ts = Number.isFinite(timestamp) ? timestamp : Date.now();
|
|
74273
74373
|
const message = isRecord2(record2.message) ? record2.message : record2;
|
|
74274
74374
|
const content = message.content;
|
|
74275
|
-
const role = typeof message.role === "string" ? message.role : typeof record2.type === "string" ? record2.type : null;
|
|
74375
|
+
const role = typeof message.role === "string" ? message.role : typeof record2.role === "string" ? record2.role : typeof record2.type === "string" ? record2.type : null;
|
|
74276
74376
|
if (role === "user") {
|
|
74277
74377
|
if (!Array.isArray(content)) return [];
|
|
74278
74378
|
return content.flatMap((block) => {
|
|
@@ -74310,6 +74410,47 @@ function claudeRecordToAgentEvents(record2) {
|
|
|
74310
74410
|
return [{ type: "text", text: content, ts }];
|
|
74311
74411
|
return [];
|
|
74312
74412
|
}
|
|
74413
|
+
function codexRecordToAgentEvents(record2) {
|
|
74414
|
+
if (record2.type !== "response_item" || !isRecord2(record2.payload)) return [];
|
|
74415
|
+
const payload = record2.payload;
|
|
74416
|
+
const timestamp = timestampOf(record2) ? Date.parse(timestampOf(record2)) : Date.now();
|
|
74417
|
+
const ts = Number.isFinite(timestamp) ? timestamp : Date.now();
|
|
74418
|
+
if (payload.type === "message" && payload.role === "assistant") {
|
|
74419
|
+
if (!Array.isArray(payload.content)) return [];
|
|
74420
|
+
return payload.content.flatMap((block) => {
|
|
74421
|
+
if (!isRecord2(block) || block.type !== "output_text" || typeof block.text !== "string") {
|
|
74422
|
+
return [];
|
|
74423
|
+
}
|
|
74424
|
+
return block.text ? [{ type: "text", text: block.text, ts }] : [];
|
|
74425
|
+
});
|
|
74426
|
+
}
|
|
74427
|
+
if (payload.type === "reasoning") {
|
|
74428
|
+
const text = extractText2(payload.summary);
|
|
74429
|
+
return text ? [{ type: "thinking", text, ts }] : [];
|
|
74430
|
+
}
|
|
74431
|
+
if (payload.type === "custom_tool_call") {
|
|
74432
|
+
const id = stringValue(payload.call_id, payload.id);
|
|
74433
|
+
const name = stringValue(payload.name);
|
|
74434
|
+
if (!id || !name) return [];
|
|
74435
|
+
return [{ type: "tool_use", id, name, input: parseEmbeddedJson(payload.input), ts }];
|
|
74436
|
+
}
|
|
74437
|
+
if (payload.type === "custom_tool_call_output") {
|
|
74438
|
+
const id = stringValue(payload.call_id, payload.id);
|
|
74439
|
+
return id ? [{ type: "tool_result", id, content: extractText2(payload.output), ts }] : [];
|
|
74440
|
+
}
|
|
74441
|
+
return [];
|
|
74442
|
+
}
|
|
74443
|
+
function stringValue(...values) {
|
|
74444
|
+
return values.find((value2) => typeof value2 === "string" && value2.length > 0) ?? null;
|
|
74445
|
+
}
|
|
74446
|
+
function parseEmbeddedJson(value2) {
|
|
74447
|
+
if (typeof value2 !== "string") return value2;
|
|
74448
|
+
try {
|
|
74449
|
+
return JSON.parse(value2);
|
|
74450
|
+
} catch {
|
|
74451
|
+
return value2;
|
|
74452
|
+
}
|
|
74453
|
+
}
|
|
74313
74454
|
function extractText2(value2) {
|
|
74314
74455
|
if (typeof value2 === "string") return value2;
|
|
74315
74456
|
if (Array.isArray(value2)) return value2.map(extractText2).filter(Boolean).join("\n");
|
|
@@ -75132,10 +75273,10 @@ function createIgnoreMatcher(path2) {
|
|
|
75132
75273
|
const expression = globToRegExp(pattern);
|
|
75133
75274
|
return (candidate) => expression.test(candidate) || expression.test(`${candidate}/`);
|
|
75134
75275
|
}
|
|
75135
|
-
function isIgnored(normalizedPath,
|
|
75136
|
-
if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(
|
|
75276
|
+
function isIgnored(normalizedPath, basename7, isDirectory2, configured) {
|
|
75277
|
+
if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(basename7))
|
|
75137
75278
|
return true;
|
|
75138
|
-
if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(
|
|
75279
|
+
if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(basename7))
|
|
75139
75280
|
return true;
|
|
75140
75281
|
return configured.some((matches) => matches(normalizedPath));
|
|
75141
75282
|
}
|
|
@@ -75742,8 +75883,8 @@ function isWithinDirectory(parent, candidate) {
|
|
|
75742
75883
|
const path2 = (0, import_node_path18.relative)(parent, candidate);
|
|
75743
75884
|
return path2 !== ".." && !path2.startsWith(`..${import_node_path18.sep}`) && !(0, import_node_path18.isAbsolute)(path2);
|
|
75744
75885
|
}
|
|
75745
|
-
async function loadSkillSourceConfig(
|
|
75746
|
-
const configDirectory = (0, import_node_path18.join)(
|
|
75886
|
+
async function loadSkillSourceConfig(homeDirectory2) {
|
|
75887
|
+
const configDirectory = (0, import_node_path18.join)(homeDirectory2, ".alan");
|
|
75747
75888
|
const configPath = (0, import_node_path18.join)(configDirectory, "config.toml");
|
|
75748
75889
|
await (0, import_promises2.mkdir)(configDirectory, { recursive: true, mode: 448 });
|
|
75749
75890
|
let created = false;
|
|
@@ -75759,18 +75900,18 @@ async function loadSkillSourceConfig(homeDirectory) {
|
|
|
75759
75900
|
}
|
|
75760
75901
|
const content = await (0, import_promises2.readFile)(configPath, "utf8");
|
|
75761
75902
|
try {
|
|
75762
|
-
return { state: "ready", config: parseSkillSourceConfig(content,
|
|
75903
|
+
return { state: "ready", config: parseSkillSourceConfig(content, homeDirectory2), created };
|
|
75763
75904
|
} catch (error61) {
|
|
75764
75905
|
return {
|
|
75765
75906
|
state: "invalid",
|
|
75766
|
-
config: parseSkillSourceConfig(DEFAULT_SKILL_CONFIG,
|
|
75907
|
+
config: parseSkillSourceConfig(DEFAULT_SKILL_CONFIG, homeDirectory2),
|
|
75767
75908
|
created: false,
|
|
75768
75909
|
diagnostic: error61 instanceof Error ? error61.message : String(error61)
|
|
75769
75910
|
};
|
|
75770
75911
|
}
|
|
75771
75912
|
}
|
|
75772
|
-
async function resolveSkillScanInput(
|
|
75773
|
-
const loaded = await loadSkillSourceConfig(
|
|
75913
|
+
async function resolveSkillScanInput(homeDirectory2, declared) {
|
|
75914
|
+
const loaded = await loadSkillSourceConfig(homeDirectory2);
|
|
75774
75915
|
if (loaded.state === "invalid") {
|
|
75775
75916
|
throw Object.assign(new Error(`Invalid Skill source configuration: ${loaded.diagnostic}`), {
|
|
75776
75917
|
code: "SKILL_SOURCE_CONFIG_INVALID"
|
|
@@ -75778,7 +75919,7 @@ async function resolveSkillScanInput(homeDirectory, declared) {
|
|
|
75778
75919
|
}
|
|
75779
75920
|
const { config: config2 } = loaded;
|
|
75780
75921
|
if (!config2.enabled) return { ...declared, roots: [], ignoredPaths: config2.ignoredPaths };
|
|
75781
|
-
const draftsPath = (0, import_node_path18.resolve)((0, import_node_path18.join)(
|
|
75922
|
+
const draftsPath = (0, import_node_path18.resolve)((0, import_node_path18.join)(homeDirectory2, ".alan", "skill-sources"));
|
|
75782
75923
|
const enabledProviders = new Set(declared.enabledProviderKinds ?? []);
|
|
75783
75924
|
const configured = [];
|
|
75784
75925
|
for (const source of config2.sources) {
|
|
@@ -75802,7 +75943,7 @@ async function resolveSkillScanInput(homeDirectory, declared) {
|
|
|
75802
75943
|
ignoredPaths: [.../* @__PURE__ */ new Set([...config2.ignoredPaths, ...declared.ignoredPaths ?? []])]
|
|
75803
75944
|
};
|
|
75804
75945
|
}
|
|
75805
|
-
function parseSkillSourceConfig(content,
|
|
75946
|
+
function parseSkillSourceConfig(content, homeDirectory2) {
|
|
75806
75947
|
const parsed = parse5(content);
|
|
75807
75948
|
if (!isRecord4(parsed) || parsed.version !== 1 || !isRecord4(parsed.skills)) {
|
|
75808
75949
|
throw new Error("~/.alan/config.toml must contain version = 1 and a [skills] table");
|
|
@@ -75825,7 +75966,7 @@ function parseSkillSourceConfig(content, homeDirectory) {
|
|
|
75825
75966
|
`skills.sources entry ${index + 1} must contain string path and label values`
|
|
75826
75967
|
);
|
|
75827
75968
|
}
|
|
75828
|
-
const sourcePath = resolveSkillSourcePath(value2.path,
|
|
75969
|
+
const sourcePath = resolveSkillSourcePath(value2.path, homeDirectory2);
|
|
75829
75970
|
const label = value2.label.trim();
|
|
75830
75971
|
if (!label) throw new Error(`skills.sources entry ${index + 1} has an empty label`);
|
|
75831
75972
|
const declarationId = value2.id === void 0 ? stableSourceDeclarationId(sourcePath) : requiredSourceId(value2.id, `skills.sources[${index}].id`);
|
|
@@ -75833,7 +75974,7 @@ function parseSkillSourceConfig(content, homeDirectory) {
|
|
|
75833
75974
|
value2.providers,
|
|
75834
75975
|
`skills.sources[${index}].providers`
|
|
75835
75976
|
);
|
|
75836
|
-
const relativeDirectory = import_node_path18.default.relative(
|
|
75977
|
+
const relativeDirectory = import_node_path18.default.relative(homeDirectory2, sourcePath);
|
|
75837
75978
|
const inferredProviders = providerKindsForUserDirectory(relativeDirectory);
|
|
75838
75979
|
const declaredProviders = value2.providers === void 0 ? inferredProviders : [...new Set(explicitProviders.map((provider) => provider.trim()).filter(Boolean))];
|
|
75839
75980
|
const stale = staleCodexDeclaration(relativeDirectory, label, declaredProviders);
|
|
@@ -75863,14 +76004,14 @@ function requiredSourceId(value2, field) {
|
|
|
75863
76004
|
}
|
|
75864
76005
|
return value2;
|
|
75865
76006
|
}
|
|
75866
|
-
function resolveSkillSourcePath(sourcePath,
|
|
76007
|
+
function resolveSkillSourcePath(sourcePath, homeDirectory2, pathApi = import_node_path18.default) {
|
|
75867
76008
|
const trimmed = sourcePath.trim();
|
|
75868
|
-
if (trimmed === "~") return pathApi.resolve(
|
|
76009
|
+
if (trimmed === "~") return pathApi.resolve(homeDirectory2);
|
|
75869
76010
|
if (trimmed.startsWith("~/") || trimmed.startsWith("~\\")) {
|
|
75870
76011
|
const components = trimmed.slice(2).split(/[\\/]+/).filter(Boolean);
|
|
75871
|
-
return pathApi.resolve(pathApi.join(
|
|
76012
|
+
return pathApi.resolve(pathApi.join(homeDirectory2, ...components));
|
|
75872
76013
|
}
|
|
75873
|
-
return pathApi.isAbsolute(trimmed) ? pathApi.resolve(trimmed) : pathApi.resolve(
|
|
76014
|
+
return pathApi.isAbsolute(trimmed) ? pathApi.resolve(trimmed) : pathApi.resolve(homeDirectory2, trimmed);
|
|
75874
76015
|
}
|
|
75875
76016
|
function optionalBoolean(value2, fallback, field) {
|
|
75876
76017
|
if (value2 === void 0) return fallback;
|
|
@@ -78777,17 +78918,10 @@ var log = {
|
|
|
78777
78918
|
debug: () => {
|
|
78778
78919
|
}
|
|
78779
78920
|
};
|
|
78780
|
-
var
|
|
78781
|
-
|
|
78782
|
-
|
|
78783
|
-
|
|
78784
|
-
cursor: (0, import_node_path23.join)(HOME, ".cursor", "mcp.json"),
|
|
78785
|
-
antigravity: (0, import_node_path23.join)(HOME, ".gemini", "config", "mcp_config.json"),
|
|
78786
|
-
kimi: (0, import_node_path23.join)(HOME, ".kimi", "mcp.json"),
|
|
78787
|
-
opencode: (0, import_node_path23.join)(HOME, ".config", "opencode", "opencode.json"),
|
|
78788
|
-
factory: (0, import_node_path23.join)(HOME, ".factory", "mcp.json"),
|
|
78789
|
-
amp: (0, import_node_path23.join)(HOME, ".config", "amp", "settings.json")
|
|
78790
|
-
};
|
|
78921
|
+
var homeDirectoryOverride;
|
|
78922
|
+
function homeDirectory() {
|
|
78923
|
+
return homeDirectoryOverride ?? (0, import_node_os12.homedir)();
|
|
78924
|
+
}
|
|
78791
78925
|
var MalformedToolConfigError = class extends Error {
|
|
78792
78926
|
};
|
|
78793
78927
|
function parseJsonSafe2(content) {
|
|
@@ -78848,9 +78982,12 @@ function saveMalformedBackup2(path2, content) {
|
|
|
78848
78982
|
}
|
|
78849
78983
|
var claudeAdapter = {
|
|
78850
78984
|
cli: "Claude Code",
|
|
78851
|
-
configPath
|
|
78852
|
-
|
|
78853
|
-
|
|
78985
|
+
get configPath() {
|
|
78986
|
+
return (0, import_node_path23.join)(homeDirectory(), ".claude.json");
|
|
78987
|
+
},
|
|
78988
|
+
get guardDir() {
|
|
78989
|
+
return homeDirectory();
|
|
78990
|
+
},
|
|
78854
78991
|
merge(existing, servers) {
|
|
78855
78992
|
const config2 = parseJsonSafe2(existing);
|
|
78856
78993
|
const mcpServers = config2.mcpServers ?? {};
|
|
@@ -78878,8 +79015,12 @@ var claudeAdapter = {
|
|
|
78878
79015
|
};
|
|
78879
79016
|
var codexAdapter = {
|
|
78880
79017
|
cli: "Codex",
|
|
78881
|
-
configPath
|
|
78882
|
-
|
|
79018
|
+
get configPath() {
|
|
79019
|
+
return (0, import_node_path23.join)(homeDirectory(), ".codex", "config.toml");
|
|
79020
|
+
},
|
|
79021
|
+
get guardDir() {
|
|
79022
|
+
return (0, import_node_path23.join)(homeDirectory(), ".codex");
|
|
79023
|
+
},
|
|
78883
79024
|
merge(existing, servers) {
|
|
78884
79025
|
let config2 = {};
|
|
78885
79026
|
if (existing) {
|
|
@@ -78920,8 +79061,12 @@ var codexAdapter = {
|
|
|
78920
79061
|
};
|
|
78921
79062
|
var cursorAdapter = {
|
|
78922
79063
|
cli: "Cursor",
|
|
78923
|
-
configPath
|
|
78924
|
-
|
|
79064
|
+
get configPath() {
|
|
79065
|
+
return (0, import_node_path23.join)(homeDirectory(), ".cursor", "mcp.json");
|
|
79066
|
+
},
|
|
79067
|
+
get guardDir() {
|
|
79068
|
+
return (0, import_node_path23.join)(homeDirectory(), ".cursor");
|
|
79069
|
+
},
|
|
78925
79070
|
merge(existing, servers) {
|
|
78926
79071
|
const config2 = parseJsonSafe2(existing);
|
|
78927
79072
|
const mcpServers = config2.mcpServers ?? {};
|
|
@@ -78950,8 +79095,12 @@ var cursorAdapter = {
|
|
|
78950
79095
|
function createAntigravityAdapter() {
|
|
78951
79096
|
return {
|
|
78952
79097
|
cli: "Antigravity CLI",
|
|
78953
|
-
configPath
|
|
78954
|
-
|
|
79098
|
+
get configPath() {
|
|
79099
|
+
return (0, import_node_path23.join)(homeDirectory(), ".gemini", "config", "mcp_config.json");
|
|
79100
|
+
},
|
|
79101
|
+
get guardDir() {
|
|
79102
|
+
return (0, import_node_path23.join)(homeDirectory(), ".gemini", "config");
|
|
79103
|
+
},
|
|
78955
79104
|
merge(existing, servers) {
|
|
78956
79105
|
const config2 = parseJsonSafe2(existing);
|
|
78957
79106
|
const mcpServers = config2.mcpServers ?? {};
|
|
@@ -78981,8 +79130,12 @@ function createAntigravityAdapter() {
|
|
|
78981
79130
|
var antigravityAdapter = createAntigravityAdapter();
|
|
78982
79131
|
var kimiAdapter = {
|
|
78983
79132
|
cli: "Kimi CLI",
|
|
78984
|
-
configPath
|
|
78985
|
-
|
|
79133
|
+
get configPath() {
|
|
79134
|
+
return (0, import_node_path23.join)(homeDirectory(), ".kimi", "mcp.json");
|
|
79135
|
+
},
|
|
79136
|
+
get guardDir() {
|
|
79137
|
+
return (0, import_node_path23.join)(homeDirectory(), ".kimi");
|
|
79138
|
+
},
|
|
78986
79139
|
merge(existing, servers) {
|
|
78987
79140
|
const config2 = parseJsonSafe2(existing);
|
|
78988
79141
|
const mcpServers = config2.mcpServers ?? {};
|
|
@@ -79010,8 +79163,12 @@ var kimiAdapter = {
|
|
|
79010
79163
|
};
|
|
79011
79164
|
var opencodeAdapter = {
|
|
79012
79165
|
cli: "OpenCode",
|
|
79013
|
-
configPath
|
|
79014
|
-
|
|
79166
|
+
get configPath() {
|
|
79167
|
+
return (0, import_node_path23.join)(homeDirectory(), ".config", "opencode", "opencode.json");
|
|
79168
|
+
},
|
|
79169
|
+
get guardDir() {
|
|
79170
|
+
return (0, import_node_path23.join)(homeDirectory(), ".config", "opencode");
|
|
79171
|
+
},
|
|
79015
79172
|
merge(existing, servers) {
|
|
79016
79173
|
const config2 = parseJsonSafe2(existing);
|
|
79017
79174
|
const mcp = config2.mcp ?? {};
|
|
@@ -79039,8 +79196,12 @@ var opencodeAdapter = {
|
|
|
79039
79196
|
};
|
|
79040
79197
|
var factoryAdapter = {
|
|
79041
79198
|
cli: "Factory Droid",
|
|
79042
|
-
configPath
|
|
79043
|
-
|
|
79199
|
+
get configPath() {
|
|
79200
|
+
return (0, import_node_path23.join)(homeDirectory(), ".factory", "mcp.json");
|
|
79201
|
+
},
|
|
79202
|
+
get guardDir() {
|
|
79203
|
+
return (0, import_node_path23.join)(homeDirectory(), ".factory");
|
|
79204
|
+
},
|
|
79044
79205
|
merge(existing, servers) {
|
|
79045
79206
|
const config2 = parseJsonSafe2(existing);
|
|
79046
79207
|
const mcpServers = config2.mcpServers ?? {};
|
|
@@ -79075,8 +79236,12 @@ var factoryAdapter = {
|
|
|
79075
79236
|
};
|
|
79076
79237
|
var ampAdapter = {
|
|
79077
79238
|
cli: "Amp",
|
|
79078
|
-
configPath
|
|
79079
|
-
|
|
79239
|
+
get configPath() {
|
|
79240
|
+
return (0, import_node_path23.join)(homeDirectory(), ".config", "amp", "settings.json");
|
|
79241
|
+
},
|
|
79242
|
+
get guardDir() {
|
|
79243
|
+
return (0, import_node_path23.join)(homeDirectory(), ".config", "amp");
|
|
79244
|
+
},
|
|
79080
79245
|
merge(existing, servers) {
|
|
79081
79246
|
const config2 = parseJsonSafe2(existing);
|
|
79082
79247
|
const mcpServers = config2["amp.mcpServers"] ?? {};
|
|
@@ -79182,6 +79347,77 @@ function normalizeAlanRuntimeEntry(actual, expected) {
|
|
|
79182
79347
|
function matchesAlanManagedEntry(actual, expected) {
|
|
79183
79348
|
return entriesMatch(actual, expected) || entriesMatch(normalizeAlanRuntimeEntry(actual, expected), expected);
|
|
79184
79349
|
}
|
|
79350
|
+
var LOCAL_ALAN_MCP_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "0.0.0.0"]);
|
|
79351
|
+
var LEGACY_LOCAL_ALAN_MCP_PORTS = /* @__PURE__ */ new Set(["8400"]);
|
|
79352
|
+
var ALAN_MCP_HOST_SUFFIXES = [".tryalan.ai"];
|
|
79353
|
+
function normalizeMcpPathname(pathname) {
|
|
79354
|
+
const trimmed = pathname.replace(/\/+$/, "");
|
|
79355
|
+
return trimmed.length > 0 ? trimmed : "/";
|
|
79356
|
+
}
|
|
79357
|
+
function urlsShareAlanMcpEndpoint(left, right) {
|
|
79358
|
+
try {
|
|
79359
|
+
const a = new URL(left);
|
|
79360
|
+
const b = new URL(right);
|
|
79361
|
+
return a.origin === b.origin && normalizeMcpPathname(a.pathname) === normalizeMcpPathname(b.pathname);
|
|
79362
|
+
} catch {
|
|
79363
|
+
return left === right;
|
|
79364
|
+
}
|
|
79365
|
+
}
|
|
79366
|
+
function configuredAlanMcpUrlsFromEnv() {
|
|
79367
|
+
const urls = [];
|
|
79368
|
+
for (const raw of [
|
|
79369
|
+
process.env.ALAN_MCP_DESKTOP_URL,
|
|
79370
|
+
process.env.ALAN_MCP_PUBLIC_URL,
|
|
79371
|
+
process.env.ALAN_LOCAL_API_URL
|
|
79372
|
+
]) {
|
|
79373
|
+
const value2 = raw?.trim();
|
|
79374
|
+
if (!value2) continue;
|
|
79375
|
+
try {
|
|
79376
|
+
const parsed = new URL(value2);
|
|
79377
|
+
if (normalizeMcpPathname(parsed.pathname) === "/mcp") {
|
|
79378
|
+
urls.push(parsed.toString());
|
|
79379
|
+
continue;
|
|
79380
|
+
}
|
|
79381
|
+
parsed.pathname = "/mcp";
|
|
79382
|
+
urls.push(parsed.toString());
|
|
79383
|
+
} catch {
|
|
79384
|
+
urls.push(value2.endsWith("/mcp") ? value2 : `${value2.replace(/\/$/, "")}/mcp`);
|
|
79385
|
+
}
|
|
79386
|
+
}
|
|
79387
|
+
return urls;
|
|
79388
|
+
}
|
|
79389
|
+
function extractHttpUrlFromEntry(entry) {
|
|
79390
|
+
if (!entry || typeof entry !== "object") return void 0;
|
|
79391
|
+
const record2 = entry;
|
|
79392
|
+
for (const key of ["url", "serverUrl"]) {
|
|
79393
|
+
const value2 = record2[key];
|
|
79394
|
+
if (typeof value2 === "string" && value2.length > 0) return value2;
|
|
79395
|
+
}
|
|
79396
|
+
for (const value2 of Object.values(record2)) {
|
|
79397
|
+
if (!value2 || typeof value2 !== "object") continue;
|
|
79398
|
+
const nested = extractHttpUrlFromEntry(value2);
|
|
79399
|
+
if (nested) return nested;
|
|
79400
|
+
}
|
|
79401
|
+
return void 0;
|
|
79402
|
+
}
|
|
79403
|
+
function isAlanSelfRegistrationEntry(entry) {
|
|
79404
|
+
const url3 = extractHttpUrlFromEntry(entry);
|
|
79405
|
+
if (!url3) return false;
|
|
79406
|
+
try {
|
|
79407
|
+
const parsed = new URL(url3);
|
|
79408
|
+
if (normalizeMcpPathname(parsed.pathname) !== "/mcp") return false;
|
|
79409
|
+
const host = parsed.hostname.toLowerCase();
|
|
79410
|
+
if (LOCAL_ALAN_MCP_HOSTS.has(host) && LEGACY_LOCAL_ALAN_MCP_PORTS.has(parsed.port)) {
|
|
79411
|
+
return true;
|
|
79412
|
+
}
|
|
79413
|
+
if (ALAN_MCP_HOST_SUFFIXES.some((suffix) => host.endsWith(suffix))) return true;
|
|
79414
|
+
return configuredAlanMcpUrlsFromEnv().some(
|
|
79415
|
+
(configured) => urlsShareAlanMcpEndpoint(configured, url3)
|
|
79416
|
+
);
|
|
79417
|
+
} catch {
|
|
79418
|
+
return false;
|
|
79419
|
+
}
|
|
79420
|
+
}
|
|
79185
79421
|
function hasAlanManagedSignature(entry) {
|
|
79186
79422
|
if (!entry || typeof entry !== "object") return false;
|
|
79187
79423
|
for (const [key, value2] of Object.entries(entry)) {
|
|
@@ -79202,6 +79438,9 @@ function expectedServerEntry(adapter, server) {
|
|
|
79202
79438
|
function isManagedServerList(entries) {
|
|
79203
79439
|
return entries.length === 0 || typeof entries[0] !== "string";
|
|
79204
79440
|
}
|
|
79441
|
+
function isAlanOwnedMcpEntry(entry, desiredEntry, previousEntry) {
|
|
79442
|
+
return hasAlanManagedSignature(entry) || isAlanSelfRegistrationEntry(entry) || matchesAlanManagedEntry(entry, desiredEntry) || previousEntry !== void 0 && matchesAlanManagedEntry(entry, previousEntry);
|
|
79443
|
+
}
|
|
79205
79444
|
function syncMcpToAllClis(servers, oldManagedServers = []) {
|
|
79206
79445
|
const written = [];
|
|
79207
79446
|
const failures = [];
|
|
@@ -79216,6 +79455,7 @@ function syncMcpToAllClis(servers, oldManagedServers = []) {
|
|
|
79216
79455
|
try {
|
|
79217
79456
|
const existing = readFileOr(adapter.configPath);
|
|
79218
79457
|
const previousServers = isManagedServerList(oldManagedServers) ? oldManagedServers : [];
|
|
79458
|
+
const previousNames = isManagedServerList(oldManagedServers) ? oldManagedServers.map((server) => server.name) : oldManagedServers;
|
|
79219
79459
|
const previousByName = new Map(previousServers.map((server) => [server.name, server]));
|
|
79220
79460
|
if (existing) {
|
|
79221
79461
|
for (const server of servers) {
|
|
@@ -79224,21 +79464,20 @@ function syncMcpToAllClis(servers, oldManagedServers = []) {
|
|
|
79224
79464
|
const desiredEntry = expectedServerEntry(adapter, server);
|
|
79225
79465
|
const previous = previousByName.get(server.name);
|
|
79226
79466
|
const previousEntry = previous ? expectedServerEntry(adapter, previous) : void 0;
|
|
79227
|
-
if (!
|
|
79467
|
+
if (!isAlanOwnedMcpEntry(currentEntry, desiredEntry, previousEntry)) {
|
|
79228
79468
|
throw new Error(`an unowned entry already uses the name ${server.name}`);
|
|
79229
79469
|
}
|
|
79230
79470
|
}
|
|
79231
79471
|
}
|
|
79232
79472
|
const currentNames = new Set(servers.map((s) => s.name));
|
|
79233
|
-
const toRemove =
|
|
79473
|
+
const toRemove = previousNames.filter((name) => !currentNames.has(name));
|
|
79234
79474
|
let content;
|
|
79235
79475
|
if (toRemove.length > 0) {
|
|
79236
|
-
const ownedNames = existing ? toRemove.filter(
|
|
79237
|
-
(
|
|
79238
|
-
|
|
79239
|
-
|
|
79240
|
-
|
|
79241
|
-
).map((server) => server.name) : [];
|
|
79476
|
+
const ownedNames = existing ? toRemove.filter((name) => {
|
|
79477
|
+
const entry = serverEntry(adapter, existing, name);
|
|
79478
|
+
const previous = previousByName.get(name);
|
|
79479
|
+
return hasAlanManagedSignature(entry) || isAlanSelfRegistrationEntry(entry) || previous !== void 0 && matchesAlanManagedEntry(entry, expectedServerEntry(adapter, previous));
|
|
79480
|
+
}) : [];
|
|
79242
79481
|
const cleaned = adapter.remove(existing, ownedNames);
|
|
79243
79482
|
content = adapter.merge(cleaned, servers);
|
|
79244
79483
|
} else {
|
|
@@ -79323,7 +79562,9 @@ function inspectAlanMcpPresence(expectedServers = [], candidateNames = DEFAULT_A
|
|
|
79323
79562
|
if (entry === void 0) continue;
|
|
79324
79563
|
const expected = expectedByName.get(name);
|
|
79325
79564
|
const matchesExpected = expected ? matchesAlanManagedEntry(entry, expectedServerEntry(adapter, expected)) : false;
|
|
79326
|
-
if (!hasAlanManagedSignature(entry) && !matchesExpected)
|
|
79565
|
+
if (!hasAlanManagedSignature(entry) && !matchesExpected && !isAlanSelfRegistrationEntry(entry)) {
|
|
79566
|
+
continue;
|
|
79567
|
+
}
|
|
79327
79568
|
foundOnCli = true;
|
|
79328
79569
|
serverNamesFound.add(name);
|
|
79329
79570
|
}
|
|
@@ -79371,7 +79612,8 @@ var McpSyncService = class {
|
|
|
79371
79612
|
managedServerNames;
|
|
79372
79613
|
legacyServerNames;
|
|
79373
79614
|
getStatus() {
|
|
79374
|
-
const
|
|
79615
|
+
const candidateNames = [.../* @__PURE__ */ new Set([...this.managedServerNames, ...this.legacyServerNames])];
|
|
79616
|
+
const presence = inspectAlanMcpPresence([], candidateNames);
|
|
79375
79617
|
return {
|
|
79376
79618
|
configured: presence.configured,
|
|
79377
79619
|
lastSyncAt: null,
|
|
@@ -79425,6 +79667,10 @@ var McpSyncService = class {
|
|
|
79425
79667
|
var import_node_fs22 = require("fs");
|
|
79426
79668
|
var import_node_os13 = require("os");
|
|
79427
79669
|
var import_node_path24 = require("path");
|
|
79670
|
+
var ALAN_HOOK_MARKER = "# alan-native-session-hook";
|
|
79671
|
+
var ALAN_KIMI_HOOKS_START = "# alan-native-session-hooks:start";
|
|
79672
|
+
var ALAN_KIMI_HOOKS_END = "# alan-native-session-hooks:end";
|
|
79673
|
+
var ALAN_OPENCODE_PLUGIN_MARKER = "// alan-native-session-plugin";
|
|
79428
79674
|
var CLAUDE_HOOK_EVENTS = [
|
|
79429
79675
|
"SessionStart",
|
|
79430
79676
|
"UserPromptSubmit",
|
|
@@ -79434,15 +79680,59 @@ var CLAUDE_HOOK_EVENTS = [
|
|
|
79434
79680
|
"SubagentStop",
|
|
79435
79681
|
"SessionEnd"
|
|
79436
79682
|
];
|
|
79437
|
-
var
|
|
79683
|
+
var CODEX_HOOK_EVENTS = [
|
|
79684
|
+
"SessionStart",
|
|
79685
|
+
"UserPromptSubmit",
|
|
79686
|
+
"PostToolUse",
|
|
79687
|
+
"Stop",
|
|
79688
|
+
"SubagentStart",
|
|
79689
|
+
"SubagentStop",
|
|
79690
|
+
"SessionEnd"
|
|
79691
|
+
];
|
|
79692
|
+
var COPILOT_HOOK_EVENTS = [
|
|
79693
|
+
"SessionStart",
|
|
79694
|
+
"UserPromptSubmit",
|
|
79695
|
+
"PostToolUse",
|
|
79696
|
+
"Stop",
|
|
79697
|
+
"SubagentStop",
|
|
79698
|
+
"SessionEnd"
|
|
79699
|
+
];
|
|
79700
|
+
var CURSOR_HOOK_EVENTS = [
|
|
79701
|
+
"sessionStart",
|
|
79702
|
+
"beforeSubmitPrompt",
|
|
79703
|
+
"afterAgentResponse",
|
|
79704
|
+
"stop",
|
|
79705
|
+
"sessionEnd"
|
|
79706
|
+
];
|
|
79707
|
+
var KIMI_HOOK_EVENTS = [
|
|
79708
|
+
"SessionStart",
|
|
79709
|
+
"UserPromptSubmit",
|
|
79710
|
+
"PostToolUse",
|
|
79711
|
+
"Stop",
|
|
79712
|
+
"Interrupt",
|
|
79713
|
+
"SubagentStart",
|
|
79714
|
+
"SubagentStop",
|
|
79715
|
+
"SessionEnd"
|
|
79716
|
+
];
|
|
79717
|
+
var GROK_HOOK_EVENTS = [
|
|
79718
|
+
"SessionStart",
|
|
79719
|
+
"UserPromptSubmit",
|
|
79720
|
+
"PostToolUse",
|
|
79721
|
+
"Stop",
|
|
79722
|
+
"StopFailure",
|
|
79723
|
+
"StopCancelled",
|
|
79724
|
+
"SubagentStart",
|
|
79725
|
+
"SubagentStop",
|
|
79726
|
+
"SessionEnd"
|
|
79727
|
+
];
|
|
79438
79728
|
function shellQuote(value2) {
|
|
79439
79729
|
return `'${value2.replaceAll("'", `'\\''`)}'`;
|
|
79440
79730
|
}
|
|
79441
79731
|
function powershellQuote(value2) {
|
|
79442
79732
|
return `'${value2.replaceAll("'", "''")}'`;
|
|
79443
79733
|
}
|
|
79444
|
-
function
|
|
79445
|
-
|
|
79734
|
+
function hookArgs(input2) {
|
|
79735
|
+
return [
|
|
79446
79736
|
input2.cliEntry,
|
|
79447
79737
|
"hook",
|
|
79448
79738
|
"--config-path",
|
|
@@ -79453,19 +79743,21 @@ function nativeHookCommand(input2) {
|
|
|
79453
79743
|
input2.event,
|
|
79454
79744
|
ALAN_HOOK_MARKER
|
|
79455
79745
|
];
|
|
79456
|
-
|
|
79457
|
-
|
|
79746
|
+
}
|
|
79747
|
+
function checkedEnvironment(environment) {
|
|
79748
|
+
const entries = Object.entries(environment ?? {});
|
|
79749
|
+
for (const [key] of entries) {
|
|
79458
79750
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
79459
79751
|
throw new Error(`Invalid native hook environment variable: ${key}`);
|
|
79460
79752
|
}
|
|
79461
79753
|
}
|
|
79754
|
+
return entries;
|
|
79755
|
+
}
|
|
79756
|
+
function nativeHookCommand(input2) {
|
|
79757
|
+
const args = hookArgs(input2);
|
|
79758
|
+
const environment = checkedEnvironment(input2.environment);
|
|
79462
79759
|
if (environment.length === 0) {
|
|
79463
|
-
return {
|
|
79464
|
-
type: "command",
|
|
79465
|
-
command: input2.nodeExecutable,
|
|
79466
|
-
args,
|
|
79467
|
-
timeout: 5
|
|
79468
|
-
};
|
|
79760
|
+
return { type: "command", command: input2.nodeExecutable, args, timeout: 5 };
|
|
79469
79761
|
}
|
|
79470
79762
|
if ((input2.platform ?? (0, import_node_os13.platform)()) === "win32") {
|
|
79471
79763
|
const environmentPrefix2 = environment.map(([key, value2]) => `$env:${key}=${powershellQuote(value2)}`).join("; ");
|
|
@@ -79486,7 +79778,40 @@ function nativeHookCommand(input2) {
|
|
|
79486
79778
|
timeout: 5
|
|
79487
79779
|
};
|
|
79488
79780
|
}
|
|
79489
|
-
function
|
|
79781
|
+
function nativeShellCommand(runtime, provider, event, platform6 = runtime.platform) {
|
|
79782
|
+
const args = hookArgs({
|
|
79783
|
+
configPath: runtime.configPath,
|
|
79784
|
+
cliEntry: runtime.cliEntry,
|
|
79785
|
+
provider,
|
|
79786
|
+
event
|
|
79787
|
+
});
|
|
79788
|
+
const environment = checkedEnvironment(runtime.environment);
|
|
79789
|
+
if (platform6 === "win32") {
|
|
79790
|
+
const prefix2 = environment.map(([key, value2]) => `$env:${key}=${powershellQuote(value2)}`).join("; ");
|
|
79791
|
+
const command2 = `& ${[runtime.nodeExecutable, ...args].map(powershellQuote).join(" ")}`;
|
|
79792
|
+
return prefix2 ? `${prefix2}; ${command2}` : command2;
|
|
79793
|
+
}
|
|
79794
|
+
const prefix = environment.map(([key, value2]) => `${key}=${shellQuote(value2)}`).join(" ");
|
|
79795
|
+
const command = [runtime.nodeExecutable, ...args].map(shellQuote).join(" ");
|
|
79796
|
+
return prefix ? `${prefix} ${command}` : command;
|
|
79797
|
+
}
|
|
79798
|
+
function resolveRuntime(input2 = {}) {
|
|
79799
|
+
const cliEntry = input2.cliEntry ?? process.argv[1];
|
|
79800
|
+
const configPath = input2.configPath ?? process.env.ALAN_AGENT_CONFIG_PATH;
|
|
79801
|
+
if (!cliEntry) throw new Error("Cannot resolve the alan-agent CLI entrypoint");
|
|
79802
|
+
if (!configPath?.trim()) {
|
|
79803
|
+
throw new Error("Cannot install native hooks without an exact Alan agent config path");
|
|
79804
|
+
}
|
|
79805
|
+
return {
|
|
79806
|
+
configPath,
|
|
79807
|
+
homeDir: input2.homeDir ?? (0, import_node_os13.homedir)(),
|
|
79808
|
+
nodeExecutable: input2.nodeExecutable ?? process.execPath,
|
|
79809
|
+
cliEntry,
|
|
79810
|
+
environment: input2.environment,
|
|
79811
|
+
platform: input2.platform ?? (0, import_node_os13.platform)()
|
|
79812
|
+
};
|
|
79813
|
+
}
|
|
79814
|
+
function readSettings(path2, providerLabel) {
|
|
79490
79815
|
if (!(0, import_node_fs22.existsSync)(path2)) return {};
|
|
79491
79816
|
try {
|
|
79492
79817
|
const value2 = JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8"));
|
|
@@ -79498,78 +79823,363 @@ function readSettings(path2) {
|
|
|
79498
79823
|
const backup = `${path2}.malformed-${Date.now()}.bak`;
|
|
79499
79824
|
(0, import_node_fs22.copyFileSync)(path2, backup);
|
|
79500
79825
|
throw new Error(
|
|
79501
|
-
|
|
79826
|
+
`${providerLabel} settings were malformed and copied to ${backup}: ${error61 instanceof Error ? error61.message : String(error61)}`
|
|
79502
79827
|
);
|
|
79503
79828
|
}
|
|
79504
79829
|
}
|
|
79505
|
-
function
|
|
79830
|
+
function withoutAlanEntries(value2) {
|
|
79506
79831
|
if (!Array.isArray(value2)) return [];
|
|
79507
|
-
return value2.filter((
|
|
79832
|
+
return value2.filter((entry) => !JSON.stringify(entry).includes(ALAN_HOOK_MARKER));
|
|
79508
79833
|
}
|
|
79509
79834
|
function writeSettings(path2, settings) {
|
|
79835
|
+
const serialized = `${JSON.stringify(settings, null, 2)}
|
|
79836
|
+
`;
|
|
79837
|
+
if ((0, import_node_fs22.existsSync)(path2) && (0, import_node_fs22.readFileSync)(path2, "utf8") === serialized) return false;
|
|
79510
79838
|
(0, import_node_fs22.mkdirSync)((0, import_node_path24.dirname)(path2), { recursive: true, mode: 448 });
|
|
79511
79839
|
const temporary = `${path2}.${process.pid}.tmp`;
|
|
79512
|
-
(0, import_node_fs22.writeFileSync)(temporary,
|
|
79513
|
-
`, { mode: 384 });
|
|
79840
|
+
(0, import_node_fs22.writeFileSync)(temporary, serialized, { mode: 384 });
|
|
79514
79841
|
(0, import_node_fs22.renameSync)(temporary, path2);
|
|
79842
|
+
return true;
|
|
79515
79843
|
}
|
|
79516
|
-
function
|
|
79517
|
-
|
|
79518
|
-
|
|
79519
|
-
const
|
|
79520
|
-
|
|
79521
|
-
|
|
79522
|
-
|
|
79523
|
-
|
|
79524
|
-
|
|
79844
|
+
function writeTextFile(path2, content) {
|
|
79845
|
+
if ((0, import_node_fs22.existsSync)(path2) && (0, import_node_fs22.readFileSync)(path2, "utf8") === content) return false;
|
|
79846
|
+
(0, import_node_fs22.mkdirSync)((0, import_node_path24.dirname)(path2), { recursive: true, mode: 448 });
|
|
79847
|
+
const temporary = `${path2}.${process.pid}.tmp`;
|
|
79848
|
+
(0, import_node_fs22.writeFileSync)(temporary, content, { mode: 384 });
|
|
79849
|
+
(0, import_node_fs22.renameSync)(temporary, path2);
|
|
79850
|
+
return true;
|
|
79851
|
+
}
|
|
79852
|
+
function withoutMarkedSection(content, start, end) {
|
|
79853
|
+
const startIndex = content.indexOf(start);
|
|
79854
|
+
const endIndex = content.indexOf(end);
|
|
79855
|
+
if (startIndex < 0 && endIndex < 0) return content;
|
|
79856
|
+
if (startIndex < 0 || endIndex < startIndex) {
|
|
79857
|
+
throw new Error(`Malformed Alan-owned configuration section: ${start}`);
|
|
79858
|
+
}
|
|
79859
|
+
const afterEnd = endIndex + end.length;
|
|
79860
|
+
return `${content.slice(0, startIndex).trimEnd()}
|
|
79861
|
+
${content.slice(afterEnd).trimStart()}`.trim();
|
|
79862
|
+
}
|
|
79863
|
+
function reconcileNestedCommandHooks(input2) {
|
|
79864
|
+
const settings = readSettings(input2.path, input2.providerLabel);
|
|
79865
|
+
const currentHooks = settings.hooks && typeof settings.hooks === "object" && !Array.isArray(settings.hooks) ? settings.hooks : {};
|
|
79866
|
+
const hooks = { ...currentHooks };
|
|
79867
|
+
for (const event of input2.events) {
|
|
79868
|
+
hooks[event] = [...withoutAlanEntries(currentHooks[event]), { hooks: [input2.command(event)] }];
|
|
79869
|
+
}
|
|
79870
|
+
return writeSettings(input2.path, { ...settings, hooks });
|
|
79871
|
+
}
|
|
79872
|
+
function removeNestedCommandHooks(path2, providerLabel) {
|
|
79873
|
+
if (!(0, import_node_fs22.existsSync)(path2)) return false;
|
|
79874
|
+
const settings = readSettings(path2, providerLabel);
|
|
79875
|
+
if (!settings.hooks || typeof settings.hooks !== "object" || Array.isArray(settings.hooks)) {
|
|
79876
|
+
return false;
|
|
79877
|
+
}
|
|
79878
|
+
const hooks = {};
|
|
79879
|
+
let removed = false;
|
|
79880
|
+
for (const [event, groups] of Object.entries(settings.hooks)) {
|
|
79881
|
+
const retained = withoutAlanEntries(groups);
|
|
79882
|
+
if (Array.isArray(groups) && retained.length !== groups.length) removed = true;
|
|
79883
|
+
if (retained.length > 0) hooks[event] = retained;
|
|
79884
|
+
}
|
|
79885
|
+
return removed ? writeSettings(path2, { ...settings, hooks }) : false;
|
|
79886
|
+
}
|
|
79887
|
+
function reconcileClaudeNativeHooks(input2 = {}) {
|
|
79888
|
+
const runtime = resolveRuntime(input2);
|
|
79889
|
+
return reconcileNestedCommandHooks({
|
|
79890
|
+
path: (0, import_node_path24.join)(runtime.homeDir, ".claude", "settings.json"),
|
|
79891
|
+
providerLabel: "Claude",
|
|
79892
|
+
events: CLAUDE_HOOK_EVENTS,
|
|
79893
|
+
command: (event) => ({
|
|
79894
|
+
...nativeHookCommand({
|
|
79895
|
+
...runtime,
|
|
79896
|
+
provider: "claude_cli",
|
|
79897
|
+
event
|
|
79898
|
+
})
|
|
79899
|
+
})
|
|
79900
|
+
});
|
|
79901
|
+
}
|
|
79902
|
+
function removeClaudeNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
|
|
79903
|
+
return removeNestedCommandHooks((0, import_node_path24.join)(homeDir, ".claude", "settings.json"), "Claude");
|
|
79904
|
+
}
|
|
79905
|
+
function reconcileCodexNativeHooks(input2 = {}) {
|
|
79906
|
+
const runtime = resolveRuntime(input2);
|
|
79907
|
+
return reconcileNestedCommandHooks({
|
|
79908
|
+
path: (0, import_node_path24.join)(runtime.homeDir, ".codex", "hooks.json"),
|
|
79909
|
+
providerLabel: "Codex",
|
|
79910
|
+
events: CODEX_HOOK_EVENTS,
|
|
79911
|
+
command: (event) => ({
|
|
79912
|
+
type: "command",
|
|
79913
|
+
command: nativeShellCommand(runtime, "codex_app_server", event, "darwin"),
|
|
79914
|
+
commandWindows: nativeShellCommand(runtime, "codex_app_server", event, "win32"),
|
|
79915
|
+
timeout: event === "SessionEnd" ? 3 : 5
|
|
79916
|
+
})
|
|
79917
|
+
});
|
|
79918
|
+
}
|
|
79919
|
+
function removeCodexNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
|
|
79920
|
+
return removeNestedCommandHooks((0, import_node_path24.join)(homeDir, ".codex", "hooks.json"), "Codex");
|
|
79921
|
+
}
|
|
79922
|
+
function reconcileCopilotNativeHooks(input2 = {}) {
|
|
79923
|
+
const runtime = resolveRuntime(input2);
|
|
79924
|
+
const path2 = (0, import_node_path24.join)(runtime.homeDir, ".copilot", "hooks", "alan-native-session.json");
|
|
79925
|
+
if ((0, import_node_fs22.existsSync)(path2) && !(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_HOOK_MARKER)) {
|
|
79926
|
+
throw new Error(`Refusing to overwrite non-Alan Copilot hook configuration at ${path2}`);
|
|
79525
79927
|
}
|
|
79526
|
-
const
|
|
79928
|
+
const hooks = Object.fromEntries(
|
|
79929
|
+
COPILOT_HOOK_EVENTS.map((event) => [
|
|
79930
|
+
event,
|
|
79931
|
+
[
|
|
79932
|
+
{
|
|
79933
|
+
type: "command",
|
|
79934
|
+
bash: nativeShellCommand(runtime, "copilot_cli", event, "darwin"),
|
|
79935
|
+
powershell: nativeShellCommand(runtime, "copilot_cli", event, "win32"),
|
|
79936
|
+
timeoutSec: event === "SessionEnd" ? 3 : 5
|
|
79937
|
+
}
|
|
79938
|
+
]
|
|
79939
|
+
])
|
|
79940
|
+
);
|
|
79941
|
+
return writeSettings(path2, { version: 1, hooks });
|
|
79942
|
+
}
|
|
79943
|
+
function removeCopilotNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
|
|
79944
|
+
const path2 = (0, import_node_path24.join)(homeDir, ".copilot", "hooks", "alan-native-session.json");
|
|
79945
|
+
if (!(0, import_node_fs22.existsSync)(path2)) return false;
|
|
79946
|
+
if (!(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_HOOK_MARKER)) return false;
|
|
79947
|
+
(0, import_node_fs22.rmSync)(path2);
|
|
79948
|
+
return true;
|
|
79949
|
+
}
|
|
79950
|
+
function reconcileCursorNativeHooks(input2 = {}) {
|
|
79951
|
+
const runtime = resolveRuntime(input2);
|
|
79952
|
+
const path2 = (0, import_node_path24.join)(runtime.homeDir, ".cursor", "hooks.json");
|
|
79953
|
+
const settings = readSettings(path2, "Cursor");
|
|
79527
79954
|
const currentHooks = settings.hooks && typeof settings.hooks === "object" && !Array.isArray(settings.hooks) ? settings.hooks : {};
|
|
79528
79955
|
const hooks = { ...currentHooks };
|
|
79529
|
-
for (const event of
|
|
79956
|
+
for (const event of CURSOR_HOOK_EVENTS) {
|
|
79530
79957
|
hooks[event] = [
|
|
79531
|
-
...
|
|
79958
|
+
...withoutAlanEntries(currentHooks[event]),
|
|
79532
79959
|
{
|
|
79533
|
-
|
|
79534
|
-
|
|
79535
|
-
|
|
79536
|
-
nodeExecutable,
|
|
79537
|
-
cliEntry,
|
|
79538
|
-
environment: input2?.environment,
|
|
79539
|
-
platform: input2?.platform,
|
|
79540
|
-
provider: "claude_cli",
|
|
79541
|
-
event
|
|
79542
|
-
})
|
|
79543
|
-
]
|
|
79960
|
+
type: "command",
|
|
79961
|
+
command: nativeShellCommand(runtime, "cursor_agent_cli", event),
|
|
79962
|
+
timeout: 5
|
|
79544
79963
|
}
|
|
79545
79964
|
];
|
|
79546
79965
|
}
|
|
79547
|
-
|
|
79548
|
-
const previous = (0, import_node_fs22.existsSync)(settingsPath) ? (0, import_node_fs22.readFileSync)(settingsPath, "utf8") : null;
|
|
79549
|
-
const serialized = `${JSON.stringify(next, null, 2)}
|
|
79550
|
-
`;
|
|
79551
|
-
if (previous === serialized) return false;
|
|
79552
|
-
writeSettings(settingsPath, next);
|
|
79553
|
-
return true;
|
|
79966
|
+
return writeSettings(path2, { ...settings, version: settings.version ?? 1, hooks });
|
|
79554
79967
|
}
|
|
79555
|
-
function
|
|
79556
|
-
const
|
|
79557
|
-
if (!(0, import_node_fs22.existsSync)(
|
|
79558
|
-
const settings = readSettings(
|
|
79968
|
+
function removeCursorNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
|
|
79969
|
+
const path2 = (0, import_node_path24.join)(homeDir, ".cursor", "hooks.json");
|
|
79970
|
+
if (!(0, import_node_fs22.existsSync)(path2)) return false;
|
|
79971
|
+
const settings = readSettings(path2, "Cursor");
|
|
79559
79972
|
if (!settings.hooks || typeof settings.hooks !== "object" || Array.isArray(settings.hooks)) {
|
|
79560
79973
|
return false;
|
|
79561
79974
|
}
|
|
79562
79975
|
const hooks = {};
|
|
79563
79976
|
let removed = false;
|
|
79564
|
-
for (const [event,
|
|
79565
|
-
const retained =
|
|
79566
|
-
if (Array.isArray(
|
|
79977
|
+
for (const [event, entries] of Object.entries(settings.hooks)) {
|
|
79978
|
+
const retained = withoutAlanEntries(entries);
|
|
79979
|
+
if (Array.isArray(entries) && retained.length !== entries.length) removed = true;
|
|
79567
79980
|
if (retained.length > 0) hooks[event] = retained;
|
|
79568
79981
|
}
|
|
79569
|
-
|
|
79570
|
-
|
|
79982
|
+
return removed ? writeSettings(path2, { ...settings, hooks }) : false;
|
|
79983
|
+
}
|
|
79984
|
+
function kimiHookSection(runtime) {
|
|
79985
|
+
const hooks = KIMI_HOOK_EVENTS.map(
|
|
79986
|
+
(event) => [
|
|
79987
|
+
"[[hooks]]",
|
|
79988
|
+
`event = ${JSON.stringify(event)}`,
|
|
79989
|
+
`command = ${JSON.stringify(nativeShellCommand(runtime, "kimi_cli", event))}`,
|
|
79990
|
+
`timeout = ${event === "SessionEnd" ? 3 : 5}`
|
|
79991
|
+
].join("\n")
|
|
79992
|
+
).join("\n\n");
|
|
79993
|
+
return `${ALAN_KIMI_HOOKS_START}
|
|
79994
|
+
${hooks}
|
|
79995
|
+
${ALAN_KIMI_HOOKS_END}`;
|
|
79996
|
+
}
|
|
79997
|
+
function reconcileKimiNativeHooks(input2 = {}) {
|
|
79998
|
+
const runtime = resolveRuntime(input2);
|
|
79999
|
+
const path2 = (0, import_node_path24.join)(runtime.homeDir, ".kimi-code", "config.toml");
|
|
80000
|
+
const current = (0, import_node_fs22.existsSync)(path2) ? (0, import_node_fs22.readFileSync)(path2, "utf8") : "";
|
|
80001
|
+
const userContent = withoutMarkedSection(current, ALAN_KIMI_HOOKS_START, ALAN_KIMI_HOOKS_END);
|
|
80002
|
+
const content = `${userContent.trimEnd()}${userContent.trim() ? "\n\n" : ""}${kimiHookSection(runtime)}
|
|
80003
|
+
`;
|
|
80004
|
+
return writeTextFile(path2, content);
|
|
80005
|
+
}
|
|
80006
|
+
function removeKimiNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
|
|
80007
|
+
const path2 = (0, import_node_path24.join)(homeDir, ".kimi-code", "config.toml");
|
|
80008
|
+
if (!(0, import_node_fs22.existsSync)(path2)) return false;
|
|
80009
|
+
const current = (0, import_node_fs22.readFileSync)(path2, "utf8");
|
|
80010
|
+
const content = withoutMarkedSection(current, ALAN_KIMI_HOOKS_START, ALAN_KIMI_HOOKS_END);
|
|
80011
|
+
if (content === current) return false;
|
|
80012
|
+
return writeTextFile(path2, content ? `${content.trimEnd()}
|
|
80013
|
+
` : "");
|
|
80014
|
+
}
|
|
80015
|
+
function reconcileGrokNativeHooks(input2 = {}) {
|
|
80016
|
+
const runtime = resolveRuntime(input2);
|
|
80017
|
+
const path2 = (0, import_node_path24.join)(runtime.homeDir, ".grok", "hooks", "alan-native-session.json");
|
|
80018
|
+
if ((0, import_node_fs22.existsSync)(path2) && !(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_HOOK_MARKER)) {
|
|
80019
|
+
throw new Error(`Refusing to overwrite non-Alan Grok hook configuration at ${path2}`);
|
|
80020
|
+
}
|
|
80021
|
+
return reconcileNestedCommandHooks({
|
|
80022
|
+
path: path2,
|
|
80023
|
+
providerLabel: "Grok",
|
|
80024
|
+
events: GROK_HOOK_EVENTS,
|
|
80025
|
+
command: (event) => ({
|
|
80026
|
+
type: "command",
|
|
80027
|
+
command: nativeShellCommand(runtime, "grok_cli", event),
|
|
80028
|
+
timeout: event === "SessionEnd" ? 3 : 5
|
|
80029
|
+
})
|
|
80030
|
+
});
|
|
80031
|
+
}
|
|
80032
|
+
function removeGrokNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
|
|
80033
|
+
const path2 = (0, import_node_path24.join)(homeDir, ".grok", "hooks", "alan-native-session.json");
|
|
80034
|
+
if (!(0, import_node_fs22.existsSync)(path2)) return false;
|
|
80035
|
+
if (!(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_HOOK_MARKER)) return false;
|
|
80036
|
+
(0, import_node_fs22.rmSync)(path2);
|
|
79571
80037
|
return true;
|
|
79572
80038
|
}
|
|
80039
|
+
function opencodePluginSource(runtime) {
|
|
80040
|
+
const command = [
|
|
80041
|
+
runtime.nodeExecutable,
|
|
80042
|
+
runtime.cliEntry,
|
|
80043
|
+
"hook",
|
|
80044
|
+
"--config-path",
|
|
80045
|
+
runtime.configPath,
|
|
80046
|
+
"--provider",
|
|
80047
|
+
"opencode_cli"
|
|
80048
|
+
];
|
|
80049
|
+
const environment = runtime.environment ?? {};
|
|
80050
|
+
return `${ALAN_OPENCODE_PLUGIN_MARKER}
|
|
80051
|
+
const command = ${JSON.stringify(command)}
|
|
80052
|
+
const environment = ${JSON.stringify(environment)}
|
|
80053
|
+
|
|
80054
|
+
export const AlanNativeSessionPlugin = async ({ directory }) => {
|
|
80055
|
+
const textByPart = new Map()
|
|
80056
|
+
const userPartIdsBySession = new Map()
|
|
80057
|
+
const send = async (event, payload) => {
|
|
80058
|
+
const proc = Bun.spawn({
|
|
80059
|
+
cmd: [...command, "--event", event, ${JSON.stringify(ALAN_HOOK_MARKER)}],
|
|
80060
|
+
env: { ...process.env, ...environment },
|
|
80061
|
+
stdin: "pipe",
|
|
80062
|
+
stdout: "ignore",
|
|
80063
|
+
stderr: "ignore",
|
|
80064
|
+
})
|
|
80065
|
+
proc.stdin.write(JSON.stringify({ ...payload, cwd: payload.cwd ?? directory }))
|
|
80066
|
+
proc.stdin.end()
|
|
80067
|
+
await proc.exited
|
|
80068
|
+
}
|
|
80069
|
+
|
|
80070
|
+
return {
|
|
80071
|
+
"chat.message": async (input, output) => {
|
|
80072
|
+
userPartIdsBySession.set(
|
|
80073
|
+
input.sessionID,
|
|
80074
|
+
new Set(output.parts.map((part) => part.id).filter(Boolean)),
|
|
80075
|
+
)
|
|
80076
|
+
const prompt = output.parts
|
|
80077
|
+
.filter((part) => part.type === "text")
|
|
80078
|
+
.map((part) => part.text)
|
|
80079
|
+
.join("\\n")
|
|
80080
|
+
await send("user_prompt", { session_id: input.sessionID, prompt })
|
|
80081
|
+
},
|
|
80082
|
+
event: async ({ event }) => {
|
|
80083
|
+
if (event.type === "session.created") {
|
|
80084
|
+
await send("session_start", { session_id: event.properties.info.id })
|
|
80085
|
+
return
|
|
80086
|
+
}
|
|
80087
|
+
if (event.type === "session.idle") {
|
|
80088
|
+
await send("stop", { session_id: event.properties.sessionID })
|
|
80089
|
+
return
|
|
80090
|
+
}
|
|
80091
|
+
if (event.type === "session.deleted") {
|
|
80092
|
+
userPartIdsBySession.delete(event.properties.info.id)
|
|
80093
|
+
await send("session_end", { session_id: event.properties.info.id })
|
|
80094
|
+
return
|
|
80095
|
+
}
|
|
80096
|
+
if (event.type === "session.error" && event.properties.sessionID) {
|
|
80097
|
+
await send("stop", {
|
|
80098
|
+
session_id: event.properties.sessionID,
|
|
80099
|
+
error: event.properties.error,
|
|
80100
|
+
})
|
|
80101
|
+
return
|
|
80102
|
+
}
|
|
80103
|
+
if (event.type !== "message.part.updated") return
|
|
80104
|
+
const part = event.properties.part
|
|
80105
|
+
if (part.type !== "text" && part.type !== "reasoning") return
|
|
80106
|
+
if (userPartIdsBySession.get(part.sessionID)?.has(part.id)) return
|
|
80107
|
+
const previous = textByPart.get(part.id) ?? ""
|
|
80108
|
+
const complete = typeof part.text === "string" ? part.text : ""
|
|
80109
|
+
const text = event.properties.delta ?? (complete.startsWith(previous) ? complete.slice(previous.length) : complete)
|
|
80110
|
+
textByPart.set(part.id, complete)
|
|
80111
|
+
if (!text) return
|
|
80112
|
+
await send("transcript_update", {
|
|
80113
|
+
session_id: part.sessionID,
|
|
80114
|
+
source_cursor: part.id + ":" + complete.length,
|
|
80115
|
+
...(part.type === "reasoning" ? { thinking: text } : { transcript_delta: text }),
|
|
80116
|
+
})
|
|
80117
|
+
},
|
|
80118
|
+
}
|
|
80119
|
+
}
|
|
80120
|
+
`;
|
|
80121
|
+
}
|
|
80122
|
+
function reconcileOpencodeNativePlugin(input2 = {}) {
|
|
80123
|
+
const runtime = resolveRuntime(input2);
|
|
80124
|
+
const path2 = (0, import_node_path24.join)(runtime.homeDir, ".config", "opencode", "plugins", "alan-native-session.js");
|
|
80125
|
+
if ((0, import_node_fs22.existsSync)(path2) && !(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_OPENCODE_PLUGIN_MARKER)) {
|
|
80126
|
+
throw new Error(`Refusing to overwrite non-Alan OpenCode plugin at ${path2}`);
|
|
80127
|
+
}
|
|
80128
|
+
const source = opencodePluginSource(runtime);
|
|
80129
|
+
if ((0, import_node_fs22.existsSync)(path2) && (0, import_node_fs22.readFileSync)(path2, "utf8") === source) return false;
|
|
80130
|
+
(0, import_node_fs22.mkdirSync)((0, import_node_path24.dirname)(path2), { recursive: true, mode: 448 });
|
|
80131
|
+
const temporary = `${path2}.${process.pid}.tmp`;
|
|
80132
|
+
(0, import_node_fs22.writeFileSync)(temporary, source, { mode: 384 });
|
|
80133
|
+
(0, import_node_fs22.renameSync)(temporary, path2);
|
|
80134
|
+
return true;
|
|
80135
|
+
}
|
|
80136
|
+
function removeOpencodeNativePlugin(homeDir = (0, import_node_os13.homedir)()) {
|
|
80137
|
+
const path2 = (0, import_node_path24.join)(homeDir, ".config", "opencode", "plugins", "alan-native-session.js");
|
|
80138
|
+
if (!(0, import_node_fs22.existsSync)(path2)) return false;
|
|
80139
|
+
if (!(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_OPENCODE_PLUGIN_MARKER)) return false;
|
|
80140
|
+
(0, import_node_fs22.rmSync)(path2);
|
|
80141
|
+
return true;
|
|
80142
|
+
}
|
|
80143
|
+
function configFileContainsMarker(path2, marker) {
|
|
80144
|
+
if (!(0, import_node_fs22.existsSync)(path2)) return false;
|
|
80145
|
+
try {
|
|
80146
|
+
return (0, import_node_fs22.readFileSync)(path2, "utf8").includes(marker);
|
|
80147
|
+
} catch {
|
|
80148
|
+
return false;
|
|
80149
|
+
}
|
|
80150
|
+
}
|
|
80151
|
+
function inspectNativeHooksConfigured(providerKind, homeDir = (0, import_node_os13.homedir)()) {
|
|
80152
|
+
switch (providerKind) {
|
|
80153
|
+
case "claude_cli":
|
|
80154
|
+
return configFileContainsMarker((0, import_node_path24.join)(homeDir, ".claude", "settings.json"), ALAN_HOOK_MARKER);
|
|
80155
|
+
case "codex_app_server":
|
|
80156
|
+
return configFileContainsMarker((0, import_node_path24.join)(homeDir, ".codex", "hooks.json"), ALAN_HOOK_MARKER);
|
|
80157
|
+
case "copilot_cli":
|
|
80158
|
+
return configFileContainsMarker(
|
|
80159
|
+
(0, import_node_path24.join)(homeDir, ".copilot", "hooks", "alan-native-session.json"),
|
|
80160
|
+
ALAN_HOOK_MARKER
|
|
80161
|
+
);
|
|
80162
|
+
case "cursor_agent_cli":
|
|
80163
|
+
return configFileContainsMarker((0, import_node_path24.join)(homeDir, ".cursor", "hooks.json"), ALAN_HOOK_MARKER);
|
|
80164
|
+
case "kimi_cli":
|
|
80165
|
+
return configFileContainsMarker(
|
|
80166
|
+
(0, import_node_path24.join)(homeDir, ".kimi-code", "config.toml"),
|
|
80167
|
+
ALAN_KIMI_HOOKS_START
|
|
80168
|
+
);
|
|
80169
|
+
case "grok_cli":
|
|
80170
|
+
return configFileContainsMarker(
|
|
80171
|
+
(0, import_node_path24.join)(homeDir, ".grok", "hooks", "alan-native-session.json"),
|
|
80172
|
+
ALAN_HOOK_MARKER
|
|
80173
|
+
);
|
|
80174
|
+
case "opencode_cli":
|
|
80175
|
+
return configFileContainsMarker(
|
|
80176
|
+
(0, import_node_path24.join)(homeDir, ".config", "opencode", "plugins", "alan-native-session.js"),
|
|
80177
|
+
ALAN_OPENCODE_PLUGIN_MARKER
|
|
80178
|
+
);
|
|
80179
|
+
default:
|
|
80180
|
+
return false;
|
|
80181
|
+
}
|
|
80182
|
+
}
|
|
79573
80183
|
|
|
79574
80184
|
// src/integration-cli.ts
|
|
79575
80185
|
function alanMcpServers(apiUrl) {
|
|
@@ -79580,12 +80190,41 @@ function alanMcpServers(apiUrl) {
|
|
|
79580
80190
|
}
|
|
79581
80191
|
};
|
|
79582
80192
|
}
|
|
80193
|
+
function reconcileInstalledNativeHooks(options) {
|
|
80194
|
+
const environment = getDaemonCliEnvironment();
|
|
80195
|
+
const nativeRuntime = {
|
|
80196
|
+
configPath: options.configPath ?? getConfigPath(),
|
|
80197
|
+
nodeExecutable: options.nativeHookRuntime?.executable,
|
|
80198
|
+
cliEntry: options.nativeHookRuntime?.cliEntry,
|
|
80199
|
+
environment: options.nativeHookRuntime?.environment
|
|
80200
|
+
};
|
|
80201
|
+
return [
|
|
80202
|
+
resolveCliExecutable("claude", environment) ? reconcileClaudeNativeHooks(nativeRuntime) : false,
|
|
80203
|
+
resolveCliExecutable("codex", environment) ? reconcileCodexNativeHooks(nativeRuntime) : false,
|
|
80204
|
+
resolveCliExecutable("copilot", environment) ? reconcileCopilotNativeHooks(nativeRuntime) : false,
|
|
80205
|
+
resolveCliExecutable("cursor-agent", environment) ? reconcileCursorNativeHooks(nativeRuntime) : false,
|
|
80206
|
+
resolveCliExecutable("kimi-cli", environment) ? reconcileKimiNativeHooks(nativeRuntime) : false,
|
|
80207
|
+
resolveCliExecutable("grok", environment) ? reconcileGrokNativeHooks(nativeRuntime) : false,
|
|
80208
|
+
resolveCliExecutable("opencode", environment) ? reconcileOpencodeNativePlugin(nativeRuntime) : false
|
|
80209
|
+
].some(Boolean);
|
|
80210
|
+
}
|
|
80211
|
+
function removeNativeHooksOnly() {
|
|
80212
|
+
removeClaudeNativeHooks();
|
|
80213
|
+
removeCodexNativeHooks();
|
|
80214
|
+
removeCopilotNativeHooks();
|
|
80215
|
+
removeCursorNativeHooks();
|
|
80216
|
+
removeKimiNativeHooks();
|
|
80217
|
+
removeGrokNativeHooks();
|
|
80218
|
+
removeOpencodeNativePlugin();
|
|
80219
|
+
}
|
|
79583
80220
|
function runMcpIntegrationCommand(args, options = {}) {
|
|
79584
80221
|
bindConfigPath(args);
|
|
79585
80222
|
const action = args[0] ?? "status";
|
|
79586
80223
|
const config2 = readConfig();
|
|
79587
80224
|
const endpoints = resolveEndpoints(args.slice(1), config2);
|
|
79588
80225
|
const service = new McpSyncService({ enabled: true });
|
|
80226
|
+
const reconcileMcp = options.reconcileMcp ?? true;
|
|
80227
|
+
const reconcileHooks = options.reconcileHooks ?? true;
|
|
79589
80228
|
if (action === "status") {
|
|
79590
80229
|
process.stdout.write(`${JSON.stringify(service.getStatus(), null, 2)}
|
|
79591
80230
|
`);
|
|
@@ -79597,23 +80236,26 @@ function runMcpIntegrationCommand(args, options = {}) {
|
|
|
79597
80236
|
"Alan is not configured. Run `alan-agent login` or `alan-agent setup` first."
|
|
79598
80237
|
);
|
|
79599
80238
|
}
|
|
79600
|
-
|
|
79601
|
-
if (
|
|
79602
|
-
|
|
79603
|
-
|
|
79604
|
-
|
|
79605
|
-
|
|
79606
|
-
|
|
79607
|
-
}) : false;
|
|
80239
|
+
let mcpServersUpdated = false;
|
|
80240
|
+
if (reconcileMcp) {
|
|
80241
|
+
const result = service.syncServers(alanMcpServers(endpoints.apiUrl), endpoints.apiUrl);
|
|
80242
|
+
if (result.errors.length > 0) throw new Error(result.errors.join("; "));
|
|
80243
|
+
mcpServersUpdated = result.mcpServersUpdated;
|
|
80244
|
+
}
|
|
80245
|
+
const hooksUpdated = reconcileHooks ? reconcileInstalledNativeHooks(options) : false;
|
|
79608
80246
|
process.stdout.write(
|
|
79609
|
-
`${
|
|
80247
|
+
`${mcpServersUpdated || hooksUpdated ? "Alan CLI integrations updated" : "Alan CLI integrations already current"}.
|
|
79610
80248
|
`
|
|
79611
80249
|
);
|
|
79612
80250
|
return;
|
|
79613
80251
|
}
|
|
79614
80252
|
if (action === "uninstall") {
|
|
79615
|
-
|
|
79616
|
-
|
|
80253
|
+
if (reconcileMcp) {
|
|
80254
|
+
service.cleanup(toManagedMcpServers(alanMcpServers(endpoints.apiUrl)));
|
|
80255
|
+
}
|
|
80256
|
+
if (reconcileHooks) {
|
|
80257
|
+
removeNativeHooksOnly();
|
|
80258
|
+
}
|
|
79617
80259
|
process.stdout.write("Removed Alan-owned MCP configuration.\n");
|
|
79618
80260
|
return;
|
|
79619
80261
|
}
|
|
@@ -79695,6 +80337,7 @@ function omitUndefined(record2) {
|
|
|
79695
80337
|
// src/native-hook-command.ts
|
|
79696
80338
|
var import_node_crypto19 = require("crypto");
|
|
79697
80339
|
var import_node_fs23 = require("fs");
|
|
80340
|
+
var import_node_os14 = require("os");
|
|
79698
80341
|
var import_node_path25 = require("path");
|
|
79699
80342
|
|
|
79700
80343
|
// src/native-session.ts
|
|
@@ -79727,28 +80370,64 @@ var NATIVE_SESSION_PROVIDER_CAPABILITIES = [
|
|
|
79727
80370
|
command: "codex",
|
|
79728
80371
|
capabilities: {
|
|
79729
80372
|
mcp: true,
|
|
79730
|
-
lifecycleHooks:
|
|
79731
|
-
transcriptDelta:
|
|
79732
|
-
subagents:
|
|
79733
|
-
sessionEnd:
|
|
79734
|
-
state: "
|
|
79735
|
-
reason: "Codex exposes a turn-complete notification, not full lifecycle hooks."
|
|
80373
|
+
lifecycleHooks: true,
|
|
80374
|
+
transcriptDelta: true,
|
|
80375
|
+
subagents: true,
|
|
80376
|
+
sessionEnd: true,
|
|
80377
|
+
state: "supported"
|
|
79736
80378
|
},
|
|
79737
|
-
supportedHookEvents: [
|
|
80379
|
+
supportedHookEvents: [
|
|
80380
|
+
"SessionStart",
|
|
80381
|
+
"UserPromptSubmit",
|
|
80382
|
+
"PostToolUse",
|
|
80383
|
+
"Stop",
|
|
80384
|
+
"SubagentStart",
|
|
80385
|
+
"SubagentStop",
|
|
80386
|
+
"SessionEnd"
|
|
80387
|
+
]
|
|
79738
80388
|
},
|
|
79739
80389
|
{
|
|
79740
80390
|
providerKind: "copilot_cli",
|
|
79741
80391
|
provider: "copilot",
|
|
79742
80392
|
command: "copilot",
|
|
79743
|
-
capabilities:
|
|
79744
|
-
|
|
80393
|
+
capabilities: {
|
|
80394
|
+
mcp: true,
|
|
80395
|
+
lifecycleHooks: true,
|
|
80396
|
+
transcriptDelta: true,
|
|
80397
|
+
subagents: false,
|
|
80398
|
+
sessionEnd: true,
|
|
80399
|
+
state: "supported",
|
|
80400
|
+
reason: "Copilot exposes stable subagent identity only on SubagentStop, so paired subagent lifecycle is not projected."
|
|
80401
|
+
},
|
|
80402
|
+
supportedHookEvents: [
|
|
80403
|
+
"SessionStart",
|
|
80404
|
+
"UserPromptSubmit",
|
|
80405
|
+
"PostToolUse",
|
|
80406
|
+
"Stop",
|
|
80407
|
+
"SubagentStop",
|
|
80408
|
+
"SessionEnd"
|
|
80409
|
+
]
|
|
79745
80410
|
},
|
|
79746
80411
|
{
|
|
79747
80412
|
providerKind: "cursor_agent_cli",
|
|
79748
80413
|
provider: "cursor",
|
|
79749
80414
|
command: "cursor-agent",
|
|
79750
|
-
capabilities:
|
|
79751
|
-
|
|
80415
|
+
capabilities: {
|
|
80416
|
+
mcp: true,
|
|
80417
|
+
lifecycleHooks: true,
|
|
80418
|
+
transcriptDelta: true,
|
|
80419
|
+
subagents: false,
|
|
80420
|
+
sessionEnd: true,
|
|
80421
|
+
state: "supported",
|
|
80422
|
+
reason: "Cursor's subagent stop hook does not expose the stable subagent id from subagent start."
|
|
80423
|
+
},
|
|
80424
|
+
supportedHookEvents: [
|
|
80425
|
+
"sessionStart",
|
|
80426
|
+
"beforeSubmitPrompt",
|
|
80427
|
+
"afterAgentResponse",
|
|
80428
|
+
"stop",
|
|
80429
|
+
"sessionEnd"
|
|
80430
|
+
]
|
|
79752
80431
|
},
|
|
79753
80432
|
{
|
|
79754
80433
|
providerKind: "antigravity_cli",
|
|
@@ -79761,22 +80440,70 @@ var NATIVE_SESSION_PROVIDER_CAPABILITIES = [
|
|
|
79761
80440
|
providerKind: "kimi_cli",
|
|
79762
80441
|
provider: "kimi",
|
|
79763
80442
|
command: "kimi-cli",
|
|
79764
|
-
capabilities:
|
|
79765
|
-
|
|
80443
|
+
capabilities: {
|
|
80444
|
+
mcp: true,
|
|
80445
|
+
lifecycleHooks: true,
|
|
80446
|
+
transcriptDelta: true,
|
|
80447
|
+
subagents: false,
|
|
80448
|
+
sessionEnd: true,
|
|
80449
|
+
state: "supported",
|
|
80450
|
+
reason: "Kimi hooks identify subagents by name but do not expose a stable child session id."
|
|
80451
|
+
},
|
|
80452
|
+
supportedHookEvents: [
|
|
80453
|
+
"SessionStart",
|
|
80454
|
+
"UserPromptSubmit",
|
|
80455
|
+
"PostToolUse",
|
|
80456
|
+
"Stop",
|
|
80457
|
+
"Interrupt",
|
|
80458
|
+
"SubagentStart",
|
|
80459
|
+
"SubagentStop",
|
|
80460
|
+
"SessionEnd"
|
|
80461
|
+
]
|
|
79766
80462
|
},
|
|
79767
80463
|
{
|
|
79768
80464
|
providerKind: "grok_cli",
|
|
79769
80465
|
provider: "grok",
|
|
79770
80466
|
command: "grok",
|
|
79771
|
-
capabilities:
|
|
79772
|
-
|
|
80467
|
+
capabilities: {
|
|
80468
|
+
mcp: true,
|
|
80469
|
+
lifecycleHooks: true,
|
|
80470
|
+
transcriptDelta: false,
|
|
80471
|
+
subagents: false,
|
|
80472
|
+
sessionEnd: true,
|
|
80473
|
+
state: "supported",
|
|
80474
|
+
reason: "Grok supplies the final assistant message on terminal hooks, but not incremental transcript deltas or stable child session ids."
|
|
80475
|
+
},
|
|
80476
|
+
supportedHookEvents: [
|
|
80477
|
+
"SessionStart",
|
|
80478
|
+
"UserPromptSubmit",
|
|
80479
|
+
"PostToolUse",
|
|
80480
|
+
"Stop",
|
|
80481
|
+
"StopFailure",
|
|
80482
|
+
"StopCancelled",
|
|
80483
|
+
"SubagentStart",
|
|
80484
|
+
"SubagentStop",
|
|
80485
|
+
"SessionEnd"
|
|
80486
|
+
]
|
|
79773
80487
|
},
|
|
79774
80488
|
{
|
|
79775
80489
|
providerKind: "opencode_cli",
|
|
79776
80490
|
provider: "opencode",
|
|
79777
80491
|
command: "opencode",
|
|
79778
|
-
capabilities:
|
|
79779
|
-
|
|
80492
|
+
capabilities: {
|
|
80493
|
+
mcp: true,
|
|
80494
|
+
lifecycleHooks: true,
|
|
80495
|
+
transcriptDelta: true,
|
|
80496
|
+
subagents: false,
|
|
80497
|
+
sessionEnd: true,
|
|
80498
|
+
state: "supported",
|
|
80499
|
+
reason: "OpenCode exposes root session and message events; subagent lifecycle is not distinct."
|
|
80500
|
+
},
|
|
80501
|
+
supportedHookEvents: [
|
|
80502
|
+
"session.created",
|
|
80503
|
+
"message.part.updated",
|
|
80504
|
+
"session.idle",
|
|
80505
|
+
"session.deleted"
|
|
80506
|
+
]
|
|
79780
80507
|
},
|
|
79781
80508
|
{
|
|
79782
80509
|
providerKind: "droid_cli",
|
|
@@ -79826,6 +80553,17 @@ function stringField4(payload, ...names) {
|
|
|
79826
80553
|
}
|
|
79827
80554
|
return void 0;
|
|
79828
80555
|
}
|
|
80556
|
+
function firstStringArrayField(payload, ...names) {
|
|
80557
|
+
for (const name of names) {
|
|
80558
|
+
const value2 = payload[name];
|
|
80559
|
+
if (!Array.isArray(value2)) continue;
|
|
80560
|
+
const first = value2.find(
|
|
80561
|
+
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
80562
|
+
);
|
|
80563
|
+
if (first) return first.trim();
|
|
80564
|
+
}
|
|
80565
|
+
return void 0;
|
|
80566
|
+
}
|
|
79829
80567
|
function nonNegativeIntegerField(payload, ...names) {
|
|
79830
80568
|
for (const name of names) {
|
|
79831
80569
|
const value2 = payload[name];
|
|
@@ -79833,19 +80571,77 @@ function nonNegativeIntegerField(payload, ...names) {
|
|
|
79833
80571
|
}
|
|
79834
80572
|
return void 0;
|
|
79835
80573
|
}
|
|
80574
|
+
function resolveCodexSessionIdFromTranscriptPath(transcriptPath) {
|
|
80575
|
+
const fileName = (0, import_node_path25.basename)(transcriptPath);
|
|
80576
|
+
const match = /^rollout-.*-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i.exec(
|
|
80577
|
+
fileName
|
|
80578
|
+
);
|
|
80579
|
+
return match?.[1];
|
|
80580
|
+
}
|
|
80581
|
+
function resolveKimiTranscriptPath(externalSessionId, kimiHomeDir = process.env.KIMI_CODE_HOME?.trim() || (0, import_node_path25.join)((0, import_node_os14.homedir)(), ".kimi-code")) {
|
|
80582
|
+
if ((0, import_node_path25.basename)(externalSessionId) !== externalSessionId) return void 0;
|
|
80583
|
+
const sessionsDir = (0, import_node_path25.join)(kimiHomeDir, "sessions");
|
|
80584
|
+
if (!(0, import_node_fs23.existsSync)(sessionsDir)) return void 0;
|
|
80585
|
+
for (const workspace of (0, import_node_fs23.readdirSync)(sessionsDir, { withFileTypes: true })) {
|
|
80586
|
+
if (!workspace.isDirectory()) continue;
|
|
80587
|
+
const transcriptPath = (0, import_node_path25.join)(
|
|
80588
|
+
sessionsDir,
|
|
80589
|
+
workspace.name,
|
|
80590
|
+
externalSessionId,
|
|
80591
|
+
"agents",
|
|
80592
|
+
"main",
|
|
80593
|
+
"wire.jsonl"
|
|
80594
|
+
);
|
|
80595
|
+
if ((0, import_node_fs23.existsSync)(transcriptPath)) return transcriptPath;
|
|
80596
|
+
}
|
|
80597
|
+
return void 0;
|
|
80598
|
+
}
|
|
80599
|
+
function enrichProviderPayload(provider, payload) {
|
|
80600
|
+
if (provider === "codex_app_server") {
|
|
80601
|
+
const externalSessionId2 = stringField4(
|
|
80602
|
+
payload,
|
|
80603
|
+
"session_id",
|
|
80604
|
+
"sessionId",
|
|
80605
|
+
"thread_id",
|
|
80606
|
+
"threadId"
|
|
80607
|
+
);
|
|
80608
|
+
if (externalSessionId2) return payload;
|
|
80609
|
+
const transcriptPath2 = stringField4(payload, "transcript_path", "transcriptPath");
|
|
80610
|
+
if (!transcriptPath2) return payload;
|
|
80611
|
+
const derivedSessionId = resolveCodexSessionIdFromTranscriptPath(transcriptPath2);
|
|
80612
|
+
return derivedSessionId ? { ...payload, session_id: derivedSessionId } : payload;
|
|
80613
|
+
}
|
|
80614
|
+
if (provider !== "kimi_cli") return payload;
|
|
80615
|
+
const externalSessionId = stringField4(payload, "session_id", "sessionId");
|
|
80616
|
+
if (!externalSessionId || stringField4(payload, "transcript_path", "transcriptPath")) {
|
|
80617
|
+
return payload;
|
|
80618
|
+
}
|
|
80619
|
+
const transcriptPath = resolveKimiTranscriptPath(externalSessionId);
|
|
80620
|
+
return transcriptPath ? { ...payload, transcript_path: transcriptPath } : payload;
|
|
80621
|
+
}
|
|
79836
80622
|
function parseNativeHookEnvelope(input2) {
|
|
79837
80623
|
if (!isNativeSessionProviderKind(input2.provider)) {
|
|
79838
80624
|
throw new Error(`unsupported native session provider: ${input2.provider}`);
|
|
79839
80625
|
}
|
|
79840
|
-
const
|
|
79841
|
-
const
|
|
79842
|
-
const
|
|
80626
|
+
const payload = enrichProviderPayload(input2.provider, input2.payload);
|
|
80627
|
+
const rawHookEvent = input2.hookEvent ?? stringField4(payload, "hook_event_name", "hookEvent", "hookEventName", "type") ?? "notification";
|
|
80628
|
+
const eventType = normalizeHookEvent(rawHookEvent);
|
|
80629
|
+
const cwd = stringField4(payload, "cwd", "working_directory", "workingDirectory") ?? firstStringArrayField(payload, "workspace_roots", "workspaceRoots");
|
|
80630
|
+
const transcriptPath = eventType === "subagent_start" || eventType === "subagent_end" ? stringField4(
|
|
80631
|
+
payload,
|
|
80632
|
+
"agent_transcript_path",
|
|
80633
|
+
"agentTranscriptPath",
|
|
80634
|
+
"transcript_path",
|
|
80635
|
+
"transcriptPath"
|
|
80636
|
+
) : stringField4(payload, "transcript_path", "transcriptPath");
|
|
79843
80637
|
const capability = NATIVE_SESSION_PROVIDER_CAPABILITIES.find(
|
|
79844
80638
|
(candidate) => candidate.providerKind === input2.provider
|
|
79845
80639
|
);
|
|
79846
80640
|
if (!capability) throw new Error(`unsupported native session provider: ${input2.provider}`);
|
|
79847
|
-
const
|
|
79848
|
-
|
|
80641
|
+
const parentSessionId = stringField4(
|
|
80642
|
+
payload,
|
|
80643
|
+
"parent_session_id",
|
|
80644
|
+
"parentSessionId",
|
|
79849
80645
|
"session_id",
|
|
79850
80646
|
"sessionId",
|
|
79851
80647
|
"conversation_id",
|
|
@@ -79853,20 +80649,30 @@ function parseNativeHookEnvelope(input2) {
|
|
|
79853
80649
|
"thread_id",
|
|
79854
80650
|
"threadId"
|
|
79855
80651
|
);
|
|
80652
|
+
const externalSessionId = eventType === "subagent_start" || eventType === "subagent_end" ? stringField4(
|
|
80653
|
+
payload,
|
|
80654
|
+
"agent_id",
|
|
80655
|
+
"agentId",
|
|
80656
|
+
"subagent_id",
|
|
80657
|
+
"subagentId",
|
|
80658
|
+
"task_id",
|
|
80659
|
+
"taskId"
|
|
80660
|
+
) ?? parentSessionId : parentSessionId;
|
|
79856
80661
|
if (!externalSessionId) throw new Error("hook payload is missing a provider session id");
|
|
79857
|
-
const cursor = stringField4(
|
|
80662
|
+
const cursor = stringField4(payload, "source_cursor", "sourceCursor") ?? nonNegativeIntegerField(payload, "byte_offset", "byteOffset")?.toString() ?? nonNegativeIntegerField(payload, "sequence", "seq")?.toString();
|
|
80663
|
+
const providerPayload = capability.providerKind === "cursor_agent_cli" && eventType === "transcript_update" && !transcriptPath && typeof payload.text === "string" ? { ...payload, assistant_response: payload.text } : payload;
|
|
79858
80664
|
return {
|
|
79859
80665
|
schemaVersion: 1,
|
|
79860
80666
|
eventId: (0, import_node_crypto19.randomUUID)(),
|
|
79861
80667
|
provider: capability.provider,
|
|
79862
|
-
eventType
|
|
80668
|
+
eventType,
|
|
79863
80669
|
observedAt: (input2.now ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
79864
80670
|
externalSessionId,
|
|
79865
|
-
|
|
80671
|
+
...(eventType === "subagent_start" || eventType === "subagent_end") && parentSessionId ? { parentExternalSessionId: parentSessionId } : {},
|
|
79866
80672
|
...cwd ? { cwd: (0, import_node_path25.resolve)(cwd) } : {},
|
|
79867
80673
|
...transcriptPath ? { transcriptPath: (0, import_node_path25.resolve)(transcriptPath) } : {},
|
|
79868
80674
|
...cursor ? { sourceCursor: cursor } : {},
|
|
79869
|
-
providerPayload
|
|
80675
|
+
providerPayload
|
|
79870
80676
|
};
|
|
79871
80677
|
}
|
|
79872
80678
|
function normalizeHookEvent(raw) {
|
|
@@ -79875,6 +80681,8 @@ function normalizeHookEvent(raw) {
|
|
|
79875
80681
|
case "session_start":
|
|
79876
80682
|
return "session_start";
|
|
79877
80683
|
case "userpromptsubmit":
|
|
80684
|
+
case "userpromptsubmitted":
|
|
80685
|
+
case "beforesubmitprompt":
|
|
79878
80686
|
case "user_prompt":
|
|
79879
80687
|
return "user_prompt";
|
|
79880
80688
|
case "subagentstart":
|
|
@@ -79887,8 +80695,19 @@ function normalizeHookEvent(raw) {
|
|
|
79887
80695
|
case "session_end":
|
|
79888
80696
|
return "session_end";
|
|
79889
80697
|
case "stop":
|
|
80698
|
+
case "agentstop":
|
|
80699
|
+
case "agent_stop":
|
|
79890
80700
|
case "agent_turn_complete":
|
|
80701
|
+
case "stopfailure":
|
|
80702
|
+
case "stop_failure":
|
|
80703
|
+
case "stopcancelled":
|
|
80704
|
+
case "stop_cancelled":
|
|
80705
|
+
case "interrupt":
|
|
79891
80706
|
return "stop";
|
|
80707
|
+
case "afteragentresponse":
|
|
80708
|
+
case "message.part.updated":
|
|
80709
|
+
case "transcript_update":
|
|
80710
|
+
return "transcript_update";
|
|
79892
80711
|
default:
|
|
79893
80712
|
return "transcript_update";
|
|
79894
80713
|
}
|
|
@@ -79933,21 +80752,34 @@ function runNativeHookCommand(args) {
|
|
|
79933
80752
|
try {
|
|
79934
80753
|
const payload = readBoundedHookPayload();
|
|
79935
80754
|
const enqueued = enqueueNativeHookFromConfig({ args, payload });
|
|
79936
|
-
const hookEvent = argumentValue(args, "--event")
|
|
79937
|
-
|
|
80755
|
+
const hookEvent = argumentValue(args, "--event");
|
|
80756
|
+
const normalizedEvent = normalizeHookEvent(hookEvent ?? "notification");
|
|
80757
|
+
if (enqueued && (normalizedEvent === "user_prompt" || normalizedEvent === "session_start")) {
|
|
79938
80758
|
const providerKind = argumentValue(args, "--provider");
|
|
79939
|
-
const externalSessionId = stringField4(
|
|
80759
|
+
const externalSessionId = stringField4(
|
|
80760
|
+
payload,
|
|
80761
|
+
"session_id",
|
|
80762
|
+
"sessionId",
|
|
80763
|
+
"conversation_id",
|
|
80764
|
+
"conversationId",
|
|
80765
|
+
"thread_id",
|
|
80766
|
+
"threadId"
|
|
80767
|
+
);
|
|
79940
80768
|
const capability = providerKind ? NATIVE_SESSION_PROVIDER_CAPABILITIES.find(
|
|
79941
80769
|
(candidate) => candidate.providerKind === providerKind
|
|
79942
80770
|
) : void 0;
|
|
79943
|
-
|
|
80771
|
+
const shouldInjectLinkingContext = capability && externalSessionId && (capability.providerKind === "claude_cli" || capability.providerKind === "codex_app_server" || capability.providerKind === "kimi_cli" ? normalizedEvent === "user_prompt" : capability.providerKind === "cursor_agent_cli" && normalizedEvent === "session_start");
|
|
80772
|
+
if (shouldInjectLinkingContext && capability && externalSessionId) {
|
|
80773
|
+
const additionalContext = `First call get_native_session_link_status with provider=${capability.provider} and externalSessionId=${externalSessionId}. If status is linked, continue without asking or linking again. If status is syncing, wait briefly and retry the status check. Only when status is pending, ask the user one question: work on an Alan task or continue as a direct session. Resolve a named task with find_records, then call link_native_session. Do not guess a task and do not change task status.`;
|
|
79944
80774
|
process.stdout.write(
|
|
79945
|
-
`${JSON.stringify(
|
|
79946
|
-
|
|
79947
|
-
|
|
79948
|
-
|
|
80775
|
+
`${JSON.stringify(
|
|
80776
|
+
capability.providerKind === "cursor_agent_cli" ? { additional_context: additionalContext } : {
|
|
80777
|
+
hookSpecificOutput: {
|
|
80778
|
+
hookEventName: "UserPromptSubmit",
|
|
80779
|
+
additionalContext
|
|
80780
|
+
}
|
|
79949
80781
|
}
|
|
79950
|
-
|
|
80782
|
+
)}
|
|
79951
80783
|
`
|
|
79952
80784
|
);
|
|
79953
80785
|
}
|
|
@@ -79965,10 +80797,12 @@ function collectNativeIntegrationStatus(args = []) {
|
|
|
79965
80797
|
bindConfigPath(args);
|
|
79966
80798
|
const config2 = readConfig();
|
|
79967
80799
|
const env = getDaemonCliEnvironment();
|
|
80800
|
+
const homeDir = (0, import_node_os14.homedir)();
|
|
79968
80801
|
return NATIVE_SESSION_PROVIDER_CAPABILITIES.map((capability) => ({
|
|
79969
80802
|
provider: capability.providerKind,
|
|
79970
80803
|
command: capability.command,
|
|
79971
80804
|
installed: resolveCliExecutable(capability.command, env) !== null,
|
|
80805
|
+
hooksConfigured: inspectNativeHooksConfigured(capability.providerKind, homeDir),
|
|
79972
80806
|
hookCoverage: capability.capabilities.lifecycleHooks ? "lifecycle" : capability.capabilities.state === "degraded" ? "notification" : "none",
|
|
79973
80807
|
transcriptStreaming: capability.capabilities.transcriptDelta,
|
|
79974
80808
|
inboxReady: Boolean(config2.eventSpoolKey)
|
|
@@ -79992,7 +80826,7 @@ function decodeResumeFallbackContext(encoded) {
|
|
|
79992
80826
|
}
|
|
79993
80827
|
|
|
79994
80828
|
// src/sandbox.ts
|
|
79995
|
-
var
|
|
80829
|
+
var import_node_os15 = require("os");
|
|
79996
80830
|
|
|
79997
80831
|
// src/execution-activity-tracker.ts
|
|
79998
80832
|
var ExecutionActivityTracker = class {
|
|
@@ -80510,6 +81344,9 @@ var WebPresenter = class {
|
|
|
80510
81344
|
id: (0, import_node_crypto20.randomUUID)(),
|
|
80511
81345
|
title: APPLICATION_PROBLEM_TITLES[input2.code],
|
|
80512
81346
|
detail: input2.message,
|
|
81347
|
+
// The schema's slot for the technical cause, so the problem carries it
|
|
81348
|
+
// without putting an SDK error message in front of the person.
|
|
81349
|
+
...input2.diagnostic ? { diagnosticsRef: input2.diagnostic } : {},
|
|
80513
81350
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
80514
81351
|
severity: "terminal",
|
|
80515
81352
|
scope: {
|
|
@@ -81095,9 +81932,10 @@ var WSClient = class {
|
|
|
81095
81932
|
|
|
81096
81933
|
// src/sandbox.ts
|
|
81097
81934
|
var RequiredToolsUnavailableError = class extends Error {
|
|
81098
|
-
constructor(code, message) {
|
|
81935
|
+
constructor(code, message, diagnostic) {
|
|
81099
81936
|
super(message);
|
|
81100
81937
|
this.code = code;
|
|
81938
|
+
this.diagnostic = diagnostic;
|
|
81101
81939
|
this.name = "RequiredToolsUnavailableError";
|
|
81102
81940
|
}
|
|
81103
81941
|
};
|
|
@@ -81285,7 +82123,7 @@ async function runSandbox(config2) {
|
|
|
81285
82123
|
}
|
|
81286
82124
|
const presenter = new WebPresenter(wsClient, config2.sessionId, config2.projectPath);
|
|
81287
82125
|
presenter.setSuppressSessionLifecycle(true);
|
|
81288
|
-
const runtimeSkillManager = await RuntimeSkillManager.open({ homeDirectory: (0,
|
|
82126
|
+
const runtimeSkillManager = await RuntimeSkillManager.open({ homeDirectory: (0, import_node_os15.homedir)() });
|
|
81289
82127
|
let lastProviderSessionId = config2.providerSessionId;
|
|
81290
82128
|
let resumeFallbackContext = config2.resumeFallbackContext;
|
|
81291
82129
|
let activeBackendKind = config2.backendKind || "claude_cli";
|
|
@@ -81370,10 +82208,17 @@ async function runSandbox(config2) {
|
|
|
81370
82208
|
lifecycle.warn("sandbox_agent_mcp_readiness_failed", {
|
|
81371
82209
|
backendKind: activeBackendKind,
|
|
81372
82210
|
code: readiness.code,
|
|
82211
|
+
// The protocol branch cannot describe itself; without this the
|
|
82212
|
+
// event names a category and nothing else.
|
|
82213
|
+
...readiness.diagnostic ? { diagnostic: readiness.diagnostic } : {},
|
|
81373
82214
|
stage: readiness.stage,
|
|
81374
82215
|
retryable: readiness.retryable
|
|
81375
82216
|
});
|
|
81376
|
-
throw new RequiredToolsUnavailableError(
|
|
82217
|
+
throw new RequiredToolsUnavailableError(
|
|
82218
|
+
readiness.code,
|
|
82219
|
+
readiness.message,
|
|
82220
|
+
readiness.diagnostic
|
|
82221
|
+
);
|
|
81377
82222
|
}
|
|
81378
82223
|
} else if (currentRunId ?? config2.runId) {
|
|
81379
82224
|
lifecycle.warn("sandbox_agent_mcp_contract_missing", {
|
|
@@ -81464,7 +82309,11 @@ async function runSandbox(config2) {
|
|
|
81464
82309
|
error: errorMessage
|
|
81465
82310
|
};
|
|
81466
82311
|
if (error61 instanceof RequiredToolsUnavailableError) {
|
|
81467
|
-
presenter.onApplicationError({
|
|
82312
|
+
presenter.onApplicationError({
|
|
82313
|
+
code: error61.code,
|
|
82314
|
+
message: error61.message,
|
|
82315
|
+
...error61.diagnostic ? { diagnostic: error61.diagnostic } : {}
|
|
82316
|
+
});
|
|
81468
82317
|
} else {
|
|
81469
82318
|
presenter.onError(errorMessage, false);
|
|
81470
82319
|
}
|
|
@@ -81574,7 +82423,7 @@ async function runSandbox(config2) {
|
|
|
81574
82423
|
// src/service-manager.ts
|
|
81575
82424
|
var import_node_child_process9 = require("child_process");
|
|
81576
82425
|
var import_node_fs25 = require("fs");
|
|
81577
|
-
var
|
|
82426
|
+
var import_node_os16 = require("os");
|
|
81578
82427
|
var import_node_path26 = require("path");
|
|
81579
82428
|
var SERVICE_LABEL = "ai.tryalan.agent";
|
|
81580
82429
|
var SYSTEMD_UNIT = "alan-agent.service";
|
|
@@ -81767,7 +82616,7 @@ WantedBy=default.target
|
|
|
81767
82616
|
};
|
|
81768
82617
|
}
|
|
81769
82618
|
function currentServicePlan(args, runtime) {
|
|
81770
|
-
const currentPlatform = (0,
|
|
82619
|
+
const currentPlatform = (0, import_node_os16.platform)();
|
|
81771
82620
|
if (currentPlatform !== "darwin" && currentPlatform !== "linux" && currentPlatform !== "win32") {
|
|
81772
82621
|
throw new Error(`Daemon service installation is not supported on ${currentPlatform}`);
|
|
81773
82622
|
}
|
|
@@ -81776,7 +82625,7 @@ function currentServicePlan(args, runtime) {
|
|
|
81776
82625
|
if (!cliEntry) throw new Error("Cannot determine the alan-agent executable path");
|
|
81777
82626
|
return buildDaemonServicePlan({
|
|
81778
82627
|
platform: currentPlatform,
|
|
81779
|
-
homeDir: (0,
|
|
82628
|
+
homeDir: (0, import_node_os16.homedir)(),
|
|
81780
82629
|
nodeExecutable: runtime?.executable ?? process.execPath,
|
|
81781
82630
|
cliEntry: (0, import_node_path26.resolve)(cliEntry),
|
|
81782
82631
|
profile,
|
|
@@ -81813,8 +82662,8 @@ function installDaemonService(args = [], runtime) {
|
|
|
81813
82662
|
}
|
|
81814
82663
|
const plan = currentServicePlan(args, runtime);
|
|
81815
82664
|
if (plan.manifestPath && plan.manifest) {
|
|
81816
|
-
if ((0,
|
|
81817
|
-
(0, import_node_fs25.mkdirSync)((0, import_node_path26.join)((0,
|
|
82665
|
+
if ((0, import_node_os16.platform)() === "darwin") {
|
|
82666
|
+
(0, import_node_fs25.mkdirSync)((0, import_node_path26.join)((0, import_node_os16.homedir)(), ".alan", "agent", "logs"), { recursive: true, mode: 448 });
|
|
81818
82667
|
}
|
|
81819
82668
|
writeManifest(plan.manifestPath, plan.manifest);
|
|
81820
82669
|
}
|
|
@@ -81836,16 +82685,16 @@ function printDaemonServiceStatus(args = []) {
|
|
|
81836
82685
|
|
|
81837
82686
|
// src/skills/skill-cli.ts
|
|
81838
82687
|
var import_promises6 = require("fs/promises");
|
|
81839
|
-
var
|
|
82688
|
+
var import_node_os17 = require("os");
|
|
81840
82689
|
var import_node_path27 = require("path");
|
|
81841
82690
|
async function runSkillsCommand(args) {
|
|
81842
82691
|
const [subcommand, ...options] = args;
|
|
81843
|
-
const
|
|
81844
|
-
const manager = await RuntimeSkillManager.open({ homeDirectory });
|
|
82692
|
+
const homeDirectory2 = option(options, "--home") ?? (0, import_node_os17.homedir)();
|
|
82693
|
+
const manager = await RuntimeSkillManager.open({ homeDirectory: homeDirectory2 });
|
|
81845
82694
|
if (subcommand === "scan") {
|
|
81846
82695
|
const inputPath = option(options, "--input");
|
|
81847
82696
|
const declaredInput = inputPath ? scanSkillsInputSchema.parse(await readProtectedJson(inputPath)) : null;
|
|
81848
|
-
const input2 = declaredInput ? options.includes("--include-configured") ? await resolveSkillScanInput(
|
|
82697
|
+
const input2 = declaredInput ? options.includes("--include-configured") ? await resolveSkillScanInput(homeDirectory2, declaredInput) : declaredInput : await defaultScanInput(homeDirectory2);
|
|
81849
82698
|
const outcome = await manager.scan(input2);
|
|
81850
82699
|
process.stdout.write(`${JSON.stringify(outcome)}
|
|
81851
82700
|
`);
|
|
@@ -81872,8 +82721,8 @@ async function runSkillsCommand(args) {
|
|
|
81872
82721
|
"Usage: alan-agent skills scan [--input <0600-json>] [--include-configured] [--home <path>] | skills reconcile --manifest <0600-json> [--home <path>] | skills publish --input <0600-json> [--home <path>]"
|
|
81873
82722
|
);
|
|
81874
82723
|
}
|
|
81875
|
-
async function defaultScanInput(
|
|
81876
|
-
return resolveSkillScanInput(
|
|
82724
|
+
async function defaultScanInput(homeDirectory2) {
|
|
82725
|
+
return resolveSkillScanInput(homeDirectory2, {
|
|
81877
82726
|
mode: "audit",
|
|
81878
82727
|
reason: "refresh",
|
|
81879
82728
|
enabledProviderKinds: [],
|