@grackle-ai/server 0.91.3 → 0.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Register all built-in environment adapters (Docker, Local, SSH, Codespace)
3
+ * with the adapter manager, injecting shared server dependencies.
4
+ */
5
+ export declare function registerAllAdapters(): void;
6
+ //# sourceMappingURL=adapter-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../src/adapter-registry.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAY1C"}
@@ -0,0 +1,22 @@
1
+ import { registerAdapter, exec, logger } from "@grackle-ai/core";
2
+ import { credentialProviders } from "@grackle-ai/database";
3
+ import { DockerAdapter } from "@grackle-ai/adapter-docker";
4
+ import { LocalAdapter } from "@grackle-ai/adapter-local";
5
+ import { SshAdapter } from "@grackle-ai/adapter-ssh";
6
+ import { CodespaceAdapter } from "@grackle-ai/adapter-codespace";
7
+ /**
8
+ * Register all built-in environment adapters (Docker, Local, SSH, Codespace)
9
+ * with the adapter manager, injecting shared server dependencies.
10
+ */
11
+ export function registerAllAdapters() {
12
+ const adapterDeps = {
13
+ exec,
14
+ logger,
15
+ isGitHubProviderEnabled: () => credentialProviders.getCredentialProviders().github !== "off",
16
+ };
17
+ registerAdapter(new DockerAdapter(adapterDeps));
18
+ registerAdapter(new LocalAdapter());
19
+ registerAdapter(new SshAdapter(adapterDeps));
20
+ registerAdapter(new CodespaceAdapter(adapterDeps));
21
+ }
22
+ //# sourceMappingURL=adapter-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../src/adapter-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,WAAW,GAAG;QAClB,IAAI;QACJ,MAAM;QACN,uBAAuB,EAAE,GAAY,EAAE,CACrC,mBAAmB,CAAC,sBAAsB,EAAE,CAAC,MAAM,KAAK,KAAK;KAChE,CAAC;IAEF,eAAe,CAAC,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;IAChD,eAAe,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC;IACpC,eAAe,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7C,eAAe,CAAC,IAAI,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Open the database, verify integrity, run schema migrations, seed defaults,
3
+ * start the WAL checkpoint timer, and reset all environment statuses.
4
+ *
5
+ * Environment statuses are reset because in-memory connections are lost on
6
+ * server restart — every environment starts as "disconnected".
7
+ */
8
+ export declare function initializeDatabase(): void;
9
+ //# sourceMappingURL=database-init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-init.d.ts","sourceRoot":"","sources":["../src/database-init.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAOzC"}
@@ -0,0 +1,17 @@
1
+ import { openDatabase, checkDatabaseIntegrity, initDatabase, seedDatabase, sqlite, startWalCheckpointTimer, envRegistry, } from "@grackle-ai/database";
2
+ /**
3
+ * Open the database, verify integrity, run schema migrations, seed defaults,
4
+ * start the WAL checkpoint timer, and reset all environment statuses.
5
+ *
6
+ * Environment statuses are reset because in-memory connections are lost on
7
+ * server restart — every environment starts as "disconnected".
8
+ */
9
+ export function initializeDatabase() {
10
+ openDatabase();
11
+ checkDatabaseIntegrity();
12
+ initDatabase();
13
+ seedDatabase(sqlite);
14
+ startWalCheckpointTimer();
15
+ envRegistry.resetAllStatuses();
16
+ }
17
+ //# sourceMappingURL=database-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-init.js","sourceRoot":"","sources":["../src/database-init.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAAE,sBAAsB,EAAE,YAAY,EAClD,YAAY,EAAE,MAAM,EAAE,uBAAuB,EAAE,WAAW,GAC3D,MAAM,sBAAsB,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB;IAChC,YAAY,EAAE,CAAC;IACf,sBAAsB,EAAE,CAAC;IACzB,YAAY,EAAE,CAAC;IACf,YAAY,CAAC,MAAO,CAAC,CAAC;IACtB,uBAAuB,EAAE,CAAC;IAC1B,WAAW,CAAC,gBAAgB,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Wire all event subscribers (SIGCHLD, escalation, orphan reparent, lifecycle)
3
+ * and optionally the root task auto-boot handler.
4
+ *
5
+ * The root task boot is wired to `environment.changed` and `setting.changed`
6
+ * (onboarding completion) events, using a reanimate-first strategy with
7
+ * exponential backoff.
8
+ *
9
+ * @param options.skipRootAutostart - When true, skip wiring the root task boot
10
+ * (used in E2E tests where the root session would conflict with test sessions).
11
+ */
12
+ export declare function wireEventSubscribers(options: {
13
+ skipRootAutostart: boolean;
14
+ }): void;
15
+ //# sourceMappingURL=event-subscribers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-subscribers.d.ts","sourceRoot":"","sources":["../src/event-subscribers.ts"],"names":[],"mappings":"AASA;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,iBAAiB,EAAE,OAAO,CAAC;CAC5B,GAAG,IAAI,CAuCP"}
@@ -0,0 +1,49 @@
1
+ import { initSigchldSubscriber, initEscalationAutoSubscriber, initOrphanReparentSubscriber, initLifecycleManager, createRootTaskBoot, subscribe, computeTaskStatus, findFirstConnectedEnvironment, startTaskSession, reanimateAgent, } from "@grackle-ai/core";
2
+ import { taskStore, sessionStore, settingsStore } from "@grackle-ai/database";
3
+ /**
4
+ * Wire all event subscribers (SIGCHLD, escalation, orphan reparent, lifecycle)
5
+ * and optionally the root task auto-boot handler.
6
+ *
7
+ * The root task boot is wired to `environment.changed` and `setting.changed`
8
+ * (onboarding completion) events, using a reanimate-first strategy with
9
+ * exponential backoff.
10
+ *
11
+ * @param options.skipRootAutostart - When true, skip wiring the root task boot
12
+ * (used in E2E tests where the root session would conflict with test sessions).
13
+ */
14
+ export function wireEventSubscribers(options) {
15
+ // Wire SIGCHLD: notify parent tasks when child sessions reach terminal status
16
+ initSigchldSubscriber();
17
+ // Wire escalation auto-detection: notify human when standalone tasks go idle
18
+ initEscalationAutoSubscriber();
19
+ // Wire orphan reparenting: reparent non-terminal children when parent task completes/fails
20
+ initOrphanReparentSubscriber();
21
+ // Wire lifecycle manager: auto-hibernate sessions when all fds are closed
22
+ initLifecycleManager();
23
+ if (!options.skipRootAutostart) {
24
+ const tryBootRootTask = createRootTaskBoot({
25
+ getTask: taskStore.getTask,
26
+ listSessionsForTask: sessionStore.listSessionsForTask,
27
+ getLatestSessionForTask: sessionStore.getLatestSessionForTask,
28
+ computeTaskStatus,
29
+ findFirstConnectedEnvironment,
30
+ startTaskSession,
31
+ reanimateAgent,
32
+ isOnboarded: () => settingsStore.getSetting("onboarding_completed") === "true",
33
+ });
34
+ subscribe((event) => {
35
+ if (event.type === "environment.changed") {
36
+ tryBootRootTask().catch(() => { });
37
+ }
38
+ // Also try when onboarding completes — the environment is already
39
+ // connected but boot was deferred until the user chose a runtime.
40
+ if (event.type === "setting.changed") {
41
+ const payload = event.payload;
42
+ if (payload.key === "onboarding_completed" && payload.value === "true") {
43
+ tryBootRootTask().catch(() => { });
44
+ }
45
+ }
46
+ });
47
+ }
48
+ }
49
+ //# sourceMappingURL=event-subscribers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-subscribers.js","sourceRoot":"","sources":["../src/event-subscribers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EAAE,4BAA4B,EACnD,4BAA4B,EAAE,oBAAoB,EAClD,kBAAkB,EAAE,SAAS,EAC7B,iBAAiB,EAAE,6BAA6B,EAChD,gBAAgB,EAAE,cAAc,GACjC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAEpC;IACC,8EAA8E;IAC9E,qBAAqB,EAAE,CAAC;IAExB,6EAA6E;IAC7E,4BAA4B,EAAE,CAAC;IAE/B,2FAA2F;IAC3F,4BAA4B,EAAE,CAAC;IAE/B,0EAA0E;IAC1E,oBAAoB,EAAE,CAAC;IAEvB,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,eAAe,GAAG,kBAAkB,CAAC;YACzC,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,mBAAmB,EAAE,YAAY,CAAC,mBAAmB;YACrD,uBAAuB,EAAE,YAAY,CAAC,uBAAuB;YAC7D,iBAAiB;YACjB,6BAA6B;YAC7B,gBAAgB;YAChB,cAAc;YACd,WAAW,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,sBAAsB,CAAC,KAAK,MAAM;SAC/E,CAAC,CAAC;QAEH,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YAClB,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;gBACzC,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAuB,CAAC,CAAC,CAAC;YACzD,CAAC;YACD,kEAAkE;YAClE,kEAAkE;YAClE,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBACrC,MAAM,OAAO,GAAG,KAAK,CAAC,OAA2C,CAAC;gBAClE,IAAI,OAAO,CAAC,GAAG,KAAK,sBAAsB,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;oBACvE,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAuB,CAAC,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
package/dist/index.js CHANGED
@@ -2,144 +2,50 @@ import { connectNodeAdapter } from "@connectrpc/connect-node";
2
2
  import { ConnectError, Code } from "@connectrpc/connect";
3
3
  import http2 from "node:http2";
4
4
  import { randomUUID } from "node:crypto";
5
- import { registerGrackleRoutes, registerAdapter, startHeartbeat, getAdapter, setConnection, removeConnection, listConnections, initSigchldSubscriber, initEscalationAutoSubscriber, initLifecycleManager, emit, subscribe, startTaskSession, reanimateAgent, pushToEnv, attemptReconnects, resetReconnectState, parseAdapterConfig, isKnowledgeEnabled, initKnowledge, neo4jHealthCheck, createKnowledgeHealthPhase, getKnowledgeReadinessCheck, computeTaskStatus, ReconciliationManager, createCronPhase, createOrphanPhase, findFirstConnectedEnvironment, lifecycleCleanupPhase, createEnvironmentReconciliationPhase, createRootTaskBoot, initOrphanReparentSubscriber, logger, exec, detectLanIp, runWithTrace, isValidTraceId, wrapAsyncIterableWithTrace, } from "@grackle-ai/core";
6
- import { envRegistry, sessionStore, workspaceStore, taskStore, scheduleStore, personaStore, settingsStore, openDatabase, initDatabase, sqlite, seedDatabase, credentialProviders, grackleHome, checkDatabaseIntegrity, startWalCheckpointTimer, stopWalCheckpointTimer } from "@grackle-ai/database";
7
- import { DockerAdapter } from "@grackle-ai/adapter-docker";
8
- import { LocalAdapter } from "@grackle-ai/adapter-local";
9
- import { SshAdapter } from "@grackle-ai/adapter-ssh";
10
- import { CodespaceAdapter } from "@grackle-ai/adapter-codespace";
11
- import { closeAllTunnels, reconnectOrProvision } from "@grackle-ai/adapter-sdk";
12
- import { ROOT_TASK_ID, DEFAULT_WORKSPACE_ID } from "@grackle-ai/common";
5
+ import { registerGrackleRoutes, startHeartbeat, getAdapter, setConnection, removeConnection, emit, pushToEnv, attemptReconnects, resetReconnectState, parseAdapterConfig, isKnowledgeEnabled, initKnowledge, getKnowledgeReadinessCheck, ReconciliationManager, logger, exec, detectLanIp, runWithTrace, isValidTraceId, wrapAsyncIterableWithTrace, } from "@grackle-ai/core";
6
+ import { envRegistry, sessionStore, settingsStore, personaStore, workspaceStore, taskStore, sqlite, grackleHome } from "@grackle-ai/database";
7
+ import { reconnectOrProvision } from "@grackle-ai/adapter-sdk";
13
8
  import { LocalPowerLineManager } from "./local-powerline-manager.js";
14
9
  import { registerCrashHandlers } from "./crash-handler.js";
15
10
  import { resolveServerConfig } from "./config.js";
16
11
  import { createMcpServer } from "@grackle-ai/mcp";
17
- import { loadOrCreateApiKey, verifyApiKey, setAuthLogger, generatePairingCode, startSessionCleanup, stopSessionCleanup, startPairingCleanup, stopPairingCleanup, startOAuthCleanup, stopOAuthCleanup, } from "@grackle-ai/auth";
12
+ import { loadOrCreateApiKey, verifyApiKey, setAuthLogger, generatePairingCode, startSessionCleanup, startPairingCleanup, startOAuthCleanup, } from "@grackle-ai/auth";
18
13
  import { createWebServer, isWildcardAddress } from "@grackle-ai/web-server";
19
14
  import { createRequire } from "node:module";
15
+ import { initializeDatabase } from "./database-init.js";
16
+ import { registerAllAdapters } from "./adapter-registry.js";
17
+ import { bootstrapLocalEnvironment } from "./local-environment.js";
18
+ import { createReconciliationPhases } from "./reconciliation-setup.js";
19
+ import { wireEventSubscribers } from "./event-subscribers.js";
20
+ import { createShutdown } from "./shutdown.js";
20
21
  /** Require function for loading optional native modules (qrcode). */
21
22
  const esmRequire = createRequire(import.meta.url);
22
- /** Manager for local PowerLine lifecycle (start, stop, auto-restart). */
23
- let localPowerLineManager;
24
23
  async function main() {
24
+ // Initialized to a no-op so server error handlers that fire before createShutdown()
25
+ // don't throw. Replaced with the real shutdown function after all servers are created.
26
+ let shutdown = async () => { };
25
27
  // Resolve and validate all server configuration from env vars (fail fast on invalid values)
26
28
  const config = resolveServerConfig();
27
29
  logger.info({ config }, "Server configuration resolved");
28
30
  // Open the database, verify integrity, run schema migrations, then seed defaults
29
- openDatabase();
30
- checkDatabaseIntegrity();
31
- initDatabase();
32
- seedDatabase(sqlite);
33
- startWalCheckpointTimer();
34
- // Reset all environment statuses on startup — in-memory connections are lost
35
- envRegistry.resetAllStatuses();
31
+ initializeDatabase();
36
32
  // Configure auth logger to use the server's pino instance
37
33
  setAuthLogger(logger);
38
34
  // Load (or generate) the API key on startup
39
35
  const apiKey = loadOrCreateApiKey(grackleHome);
40
- // Register adapters with server dependencies injected
41
- const adapterDeps = {
42
- exec,
43
- logger,
44
- isGitHubProviderEnabled: () => credentialProviders.getCredentialProviders().github !== "off",
45
- };
46
- registerAdapter(new DockerAdapter(adapterDeps));
47
- registerAdapter(new LocalAdapter());
48
- registerAdapter(new SshAdapter(adapterDeps));
49
- registerAdapter(new CodespaceAdapter(adapterDeps));
50
- // --- Auto-start local PowerLine ---
51
- const skipLocalPowerLine = config.skipLocalPowerline;
52
- const powerlinePort = config.powerlinePort;
53
- const plBindHost = config.host;
54
- if (skipLocalPowerLine) {
55
- logger.info("Skipping local PowerLine auto-start (GRACKLE_SKIP_LOCAL_POWERLINE=1)");
56
- }
57
- else
58
- try {
59
- // Ensure the "local" environment exists in the database
60
- let localEnv = envRegistry.getEnvironment("local");
61
- const adapterConfig = JSON.stringify({ port: powerlinePort, host: plBindHost });
62
- if (localEnv) {
63
- // Update the adapter config to match the current port/host
64
- envRegistry.updateAdapterConfig("local", adapterConfig);
65
- localEnv = envRegistry.getEnvironment("local");
66
- }
67
- else {
68
- envRegistry.addEnvironment("local", "Local", "local", adapterConfig);
69
- localEnv = envRegistry.getEnvironment("local");
70
- }
71
- // Sync: keep the local environment's defaultRuntime in sync with the
72
- // app-level default persona's runtime so bootstrap pre-installs the
73
- // correct runtime packages (fixes #1031).
74
- const defaultPersonaId = settingsStore.getSetting("default_persona_id") || "";
75
- const defaultPersona = defaultPersonaId ? personaStore.getPersona(defaultPersonaId) : undefined;
76
- if (defaultPersona?.runtime && localEnv.defaultRuntime !== defaultPersona.runtime) {
77
- const previousRuntime = localEnv.defaultRuntime;
78
- envRegistry.updateDefaultRuntime("local", defaultPersona.runtime);
79
- localEnv = envRegistry.getEnvironment("local");
80
- logger.info({ from: previousRuntime, to: defaultPersona.runtime }, "Synced local environment defaultRuntime with default persona");
81
- }
82
- // Seed: ensure the default workspace exists (tied to the local environment).
83
- // The system task needs a workspace to resolve an environment for execution.
84
- const defaultWorkspace = workspaceStore.getWorkspace(DEFAULT_WORKSPACE_ID);
85
- if (!defaultWorkspace) {
86
- workspaceStore.createWorkspace(DEFAULT_WORKSPACE_ID, "Default", "", "", "local", false);
87
- logger.info("Created default workspace for local environment");
88
- }
89
- else if (defaultWorkspace.environmentId !== "local") {
90
- logger.warn({ workspaceId: DEFAULT_WORKSPACE_ID, environmentId: defaultWorkspace.environmentId }, "Default workspace is not bound to local environment; skipping system task association");
91
- }
92
- // Backfill: assign the default workspace to the system task if it has none.
93
- const systemTask = taskStore.getTask(ROOT_TASK_ID);
94
- const resolvedDefault = workspaceStore.getWorkspace(DEFAULT_WORKSPACE_ID);
95
- if (systemTask && !systemTask.workspaceId && resolvedDefault?.environmentId === "local") {
96
- taskStore.setTaskWorkspace(ROOT_TASK_ID, DEFAULT_WORKSPACE_ID);
97
- logger.info("Assigned default workspace to system task");
98
- }
99
- // Spawn the PowerLine child process with auto-restart on crash
100
- localPowerLineManager = new LocalPowerLineManager({
101
- port: powerlinePort,
102
- host: plBindHost,
103
- token: localEnv.powerlineToken,
104
- onStatusChange: (status) => {
105
- envRegistry.updateEnvironmentStatus("local", status);
106
- emit("environment.changed", {});
107
- },
108
- onRestarted: () => {
109
- resetReconnectState("local");
110
- },
111
- });
112
- await localPowerLineManager.start();
113
- // Auto-provision: connect the local adapter
114
- const localAdapter = getAdapter("local");
115
- const config = parseAdapterConfig(localEnv.adapterConfig);
116
- envRegistry.updateEnvironmentStatus("local", "connecting");
117
- emit("environment.changed", {});
118
- for await (const event of reconnectOrProvision("local", localAdapter, config, localEnv.powerlineToken, !!localEnv.bootstrapped)) {
119
- logger.info({ stage: event.stage, progress: event.progress }, "Local env: %s", event.message);
120
- }
121
- const conn = await localAdapter.connect("local", config, localEnv.powerlineToken);
122
- setConnection("local", conn);
123
- // Push env-var tokens only — file tokens would just overwrite local credential
124
- // files (e.g. ~/.claude/credentials.json) with their own content.
125
- await pushToEnv("local", { excludeFileTokens: true });
126
- envRegistry.updateEnvironmentStatus("local", "connected");
127
- envRegistry.markBootstrapped("local");
128
- emit("environment.changed", {});
129
- logger.info({ port: powerlinePort }, "Local environment auto-connected");
130
- }
131
- catch (err) {
132
- // Clean up the PowerLine child if it started but provisioning/connection failed
133
- const failedManager = localPowerLineManager;
134
- localPowerLineManager = undefined;
135
- if (failedManager) {
136
- await failedManager.stop();
137
- }
138
- envRegistry.updateEnvironmentStatus("local", "error");
139
- emit("environment.changed", {});
140
- logger.error({ err, port: powerlinePort }, "Failed to start local PowerLine — local environment will not be available. Is port %d in use?", powerlinePort);
141
- // Non-fatal: server continues without local env (remote envs still work)
142
- }
36
+ // Register all built-in environment adapters
37
+ registerAllAdapters();
38
+ // Bootstrap the local environment (PowerLine + provisioning)
39
+ const { powerLineManager: localPowerLineManager } = await bootstrapLocalEnvironment({
40
+ powerlinePort: config.powerlinePort,
41
+ bindHost: config.host,
42
+ skipLocalPowerline: config.skipLocalPowerline,
43
+ }, {
44
+ envRegistry, settingsStore, personaStore, workspaceStore, taskStore,
45
+ getAdapter, parseAdapterConfig, setConnection, pushToEnv,
46
+ reconnectOrProvision, emit, resetReconnectState, logger,
47
+ createPowerLineManager: (opts) => new LocalPowerLineManager(opts),
48
+ });
143
49
  // Non-blocking startup diagnostic: check gh CLI availability
144
50
  const GH_CHECK_TIMEOUT_MS = 5_000;
145
51
  exec("gh", ["version"], { timeout: GH_CHECK_TIMEOUT_MS })
@@ -180,45 +86,7 @@ async function main() {
180
86
  startSessionCleanup();
181
87
  startOAuthCleanup();
182
88
  // --- Reconciliation Manager ---
183
- const cronPhase = createCronPhase({
184
- getDueSchedules: scheduleStore.getDueSchedules,
185
- advanceSchedule: scheduleStore.advanceSchedule,
186
- createTask: taskStore.createTask,
187
- setTaskScheduleId: taskStore.setTaskScheduleId,
188
- startTaskSession,
189
- emit,
190
- findFirstConnectedEnvironment,
191
- getPersona: personaStore.getPersona,
192
- getTask: taskStore.getTask,
193
- setScheduleEnabled: scheduleStore.setScheduleEnabled,
194
- isEnvironmentConnected: (id) => {
195
- const env = envRegistry.getEnvironment(id);
196
- return env?.status === "connected";
197
- },
198
- });
199
- const orphanPhase = createOrphanPhase({
200
- listAllTasks: () => {
201
- const workspaces = workspaceStore.listWorkspaces();
202
- const allTasks = [];
203
- for (const ws of workspaces) {
204
- allTasks.push(...taskStore.listTasks(ws.id));
205
- }
206
- return allTasks;
207
- },
208
- reparentTask: (taskId, newParentTaskId) => taskStore.reparentTask(taskId, newParentTaskId),
209
- emit,
210
- });
211
- const environmentReconciliationPhase = createEnvironmentReconciliationPhase({
212
- listEnvironments: envRegistry.listEnvironments,
213
- listConnectionIds: () => new Set(listConnections().keys()),
214
- updateEnvironmentStatus: envRegistry.updateEnvironmentStatus,
215
- removeConnection,
216
- emit,
217
- });
218
- const reconciliationPhases = [cronPhase, lifecycleCleanupPhase, orphanPhase, environmentReconciliationPhase];
219
- if (isKnowledgeEnabled()) {
220
- reconciliationPhases.push(createKnowledgeHealthPhase({ healthCheck: neo4jHealthCheck }));
221
- }
89
+ const reconciliationPhases = createReconciliationPhases();
222
90
  const reconciliationManager = new ReconciliationManager(reconciliationPhases);
223
91
  reconciliationManager.start();
224
92
  // --- gRPC server (HTTP/2) ---
@@ -296,43 +164,8 @@ async function main() {
296
164
  };
297
165
  },
298
166
  });
299
- // Wire SIGCHLD: notify parent tasks when child sessions reach terminal status
300
- initSigchldSubscriber();
301
- // Wire escalation auto-detection: notify human when standalone tasks go idle
302
- initEscalationAutoSubscriber();
303
- // Wire orphan reparenting: reparent non-terminal children when parent task completes/fails
304
- initOrphanReparentSubscriber();
305
- // Wire lifecycle manager: auto-hibernate sessions when all fds are closed
306
- initLifecycleManager();
307
- // Auto-start the root task (process 1) when any environment connects.
308
- // Uses reanimate-first strategy with exponential backoff (issue #959).
309
- // Skipped in E2E tests where the root task session would conflict with test sessions.
310
- // Also deferred until onboarding is complete so the user's runtime choice is respected (#1031).
311
- if (!config.skipRootAutostart) {
312
- const tryBootRootTask = createRootTaskBoot({
313
- getTask: taskStore.getTask,
314
- listSessionsForTask: sessionStore.listSessionsForTask,
315
- getLatestSessionForTask: sessionStore.getLatestSessionForTask,
316
- computeTaskStatus,
317
- findFirstConnectedEnvironment,
318
- startTaskSession,
319
- reanimateAgent,
320
- isOnboarded: () => settingsStore.getSetting("onboarding_completed") === "true",
321
- });
322
- subscribe((event) => {
323
- if (event.type === "environment.changed") {
324
- tryBootRootTask().catch(() => { });
325
- }
326
- // Also try when onboarding completes — the environment is already
327
- // connected but boot was deferred until the user chose a runtime.
328
- if (event.type === "setting.changed") {
329
- const payload = event.payload;
330
- if (payload.key === "onboarding_completed" && payload.value === "true") {
331
- tryBootRootTask().catch(() => { });
332
- }
333
- }
334
- });
335
- }
167
+ // Wire event subscribers (SIGCHLD, escalation, orphan reparent, lifecycle, root task boot)
168
+ wireEventSubscribers({ skipRootAutostart: config.skipRootAutostart });
336
169
  webServer.on("error", (err) => {
337
170
  if (err.code === "EADDRINUSE") {
338
171
  logger.fatal({ port: webPort }, "Port %d is already in use. Is another Grackle server running?", webPort);
@@ -403,65 +236,15 @@ async function main() {
403
236
  mcpServer.listen(mcpPort, bindHost, () => {
404
237
  logger.info({ port: mcpPort, host: bindHost }, "MCP server on http://%s:%d/mcp", urlHost, mcpPort);
405
238
  });
406
- // Graceful shutdown with a hard timeout so upgraded WS connections don't block exit.
407
- const SHUTDOWN_TIMEOUT_MS = 5_000;
408
- async function shutdown() {
409
- logger.info("Shutting down...");
410
- stopWalCheckpointTimer();
411
- stopPairingCleanup();
412
- stopSessionCleanup();
413
- stopOAuthCleanup();
414
- await reconciliationManager.stop();
415
- const forceExit = setTimeout(() => {
416
- logger.warn("Shutdown timed out, forcing exit");
417
- process.exit(1);
418
- }, SHUTDOWN_TIMEOUT_MS);
419
- // Stop the local PowerLine child process first
420
- const plManager = localPowerLineManager;
421
- localPowerLineManager = undefined;
422
- if (plManager) {
423
- await plManager.stop();
424
- }
425
- if (knowledgeCleanup) {
426
- try {
427
- await knowledgeCleanup();
428
- }
429
- catch (err) {
430
- logger.error({ err }, "Error while shutting down knowledge graph");
431
- }
432
- }
433
- await closeAllTunnels();
434
- await new Promise((resolve) => {
435
- grpcServer.close((err) => {
436
- if (err) {
437
- logger.error({ err }, "Error while closing gRPC server");
438
- }
439
- resolve();
440
- });
441
- });
442
- await new Promise((resolve) => {
443
- webServer.close((err) => {
444
- if (err) {
445
- logger.error({ err }, "Error while closing web server");
446
- }
447
- resolve();
448
- });
449
- });
450
- await new Promise((resolve) => {
451
- mcpServer.close((err) => {
452
- if (err) {
453
- logger.error({ err }, "Error while closing MCP server");
454
- }
455
- resolve();
456
- });
457
- });
458
- // Final WAL checkpoint (TRUNCATE) to fully flush pending writes before exit
459
- if (sqlite) {
460
- sqlite.pragma("wal_checkpoint(TRUNCATE)");
461
- }
462
- clearTimeout(forceExit);
463
- process.exit(process.exitCode || 0);
464
- }
239
+ // --- Graceful shutdown ---
240
+ shutdown = createShutdown({
241
+ grpcServer,
242
+ webServer,
243
+ mcpServer,
244
+ reconciliationManager,
245
+ localPowerLineManager,
246
+ knowledgeCleanup,
247
+ });
465
248
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
466
249
  process.on("SIGINT", shutdown);
467
250
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import type { EnvironmentStatus } from "@grackle-ai/common";
2
+ import type { EnvironmentAdapter, PowerLineConnection, ProvisionEvent } from "@grackle-ai/adapter-sdk";
3
+ import type { envRegistry as envRegistryModule, taskStore as taskStoreModule, workspaceStore as workspaceStoreModule } from "@grackle-ai/database";
4
+ import type { emit as emitFn } from "@grackle-ai/core";
5
+ import type { LocalPowerLineManager } from "./local-powerline-manager.js";
6
+ /** Result of the local environment bootstrap. */
7
+ export interface LocalEnvironmentResult {
8
+ /** The PowerLine manager if startup succeeded, undefined otherwise. */
9
+ powerLineManager?: LocalPowerLineManager;
10
+ }
11
+ /** Minimal logger interface for dependency injection. */
12
+ interface Logger {
13
+ info: (...args: unknown[]) => void;
14
+ warn: (...args: unknown[]) => void;
15
+ error: (...args: unknown[]) => void;
16
+ }
17
+ /** Injected dependencies for the local environment bootstrap. */
18
+ export interface LocalEnvironmentDeps {
19
+ /** Environment registry (database module namespace). */
20
+ envRegistry: Pick<typeof envRegistryModule, "getEnvironment" | "updateAdapterConfig" | "addEnvironment" | "updateEnvironmentStatus" | "markBootstrapped" | "updateDefaultRuntime">;
21
+ settingsStore: {
22
+ getSetting: (key: string) => string | undefined;
23
+ };
24
+ personaStore: {
25
+ getPersona: (id: string) => {
26
+ runtime: string;
27
+ } | undefined;
28
+ };
29
+ /** Workspace store (database module namespace). */
30
+ workspaceStore: Pick<typeof workspaceStoreModule, "getWorkspace" | "createWorkspace">;
31
+ /** Task store (database module namespace). */
32
+ taskStore: Pick<typeof taskStoreModule, "getTask" | "setTaskWorkspace">;
33
+ getAdapter: (type: string) => EnvironmentAdapter | undefined;
34
+ parseAdapterConfig: (raw: string) => Record<string, unknown>;
35
+ setConnection: (envId: string, conn: PowerLineConnection) => void;
36
+ pushToEnv: (envId: string, opts?: {
37
+ excludeFileTokens: boolean;
38
+ }) => Promise<void>;
39
+ reconnectOrProvision: (envId: string, adapter: EnvironmentAdapter, config: Record<string, unknown>, token: string, bootstrapped: boolean) => AsyncGenerator<ProvisionEvent>;
40
+ emit: typeof emitFn;
41
+ resetReconnectState: (envId: string) => void;
42
+ logger: Logger;
43
+ createPowerLineManager: (opts: {
44
+ port: number;
45
+ host: string;
46
+ token: string;
47
+ onStatusChange: (status: EnvironmentStatus) => void;
48
+ onRestarted: () => void;
49
+ }) => LocalPowerLineManager;
50
+ }
51
+ /** Options for bootstrapping the local environment. */
52
+ interface LocalEnvironmentOptions {
53
+ /** Port the PowerLine should listen on. */
54
+ powerlinePort: number;
55
+ /** Host the PowerLine should bind to. */
56
+ bindHost: string;
57
+ /** Skip auto-starting the local PowerLine process. */
58
+ skipLocalPowerline: boolean;
59
+ }
60
+ /**
61
+ * Bootstrap the local environment: create/update the DB record, sync runtime
62
+ * with the default persona, seed the default workspace, start the PowerLine
63
+ * child process, provision, and connect.
64
+ *
65
+ * This is a non-fatal operation — if anything fails, the error is logged and
66
+ * the server continues without a local environment (remote envs still work).
67
+ *
68
+ * @param options - Port, host, and skip flag.
69
+ * @param deps - Injected dependencies for testability.
70
+ * @returns The PowerLine manager if startup succeeded.
71
+ */
72
+ export declare function bootstrapLocalEnvironment(options: LocalEnvironmentOptions, deps: LocalEnvironmentDeps): Promise<LocalEnvironmentResult>;
73
+ export {};
74
+ //# sourceMappingURL=local-environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-environment.d.ts","sourceRoot":"","sources":["../src/local-environment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ import { ROOT_TASK_ID, DEFAULT_WORKSPACE_ID } from "@grackle-ai/common";
2
+ /**
3
+ * Bootstrap the local environment: create/update the DB record, sync runtime
4
+ * with the default persona, seed the default workspace, start the PowerLine
5
+ * child process, provision, and connect.
6
+ *
7
+ * This is a non-fatal operation — if anything fails, the error is logged and
8
+ * the server continues without a local environment (remote envs still work).
9
+ *
10
+ * @param options - Port, host, and skip flag.
11
+ * @param deps - Injected dependencies for testability.
12
+ * @returns The PowerLine manager if startup succeeded.
13
+ */
14
+ export async function bootstrapLocalEnvironment(options, deps) {
15
+ const { powerlinePort, bindHost, skipLocalPowerline } = options;
16
+ const { envRegistry, settingsStore, personaStore, workspaceStore, taskStore, logger } = deps;
17
+ if (skipLocalPowerline) {
18
+ logger.info("Skipping local PowerLine auto-start (GRACKLE_SKIP_LOCAL_POWERLINE=1)");
19
+ return {};
20
+ }
21
+ let manager;
22
+ try {
23
+ // Ensure the "local" environment exists in the database
24
+ let localEnv;
25
+ const adapterConfig = JSON.stringify({ port: powerlinePort, host: bindHost });
26
+ const existing = envRegistry.getEnvironment("local");
27
+ if (existing) {
28
+ // Update the adapter config to match the current port/host
29
+ envRegistry.updateAdapterConfig("local", adapterConfig);
30
+ localEnv = envRegistry.getEnvironment("local");
31
+ }
32
+ else {
33
+ envRegistry.addEnvironment("local", "Local", "local", adapterConfig);
34
+ localEnv = envRegistry.getEnvironment("local");
35
+ }
36
+ // Sync: keep the local environment's defaultRuntime in sync with the
37
+ // app-level default persona's runtime so bootstrap pre-installs the
38
+ // correct runtime packages (fixes #1031).
39
+ const defaultPersonaId = settingsStore.getSetting("default_persona_id") || "";
40
+ const defaultPersona = defaultPersonaId ? personaStore.getPersona(defaultPersonaId) : undefined;
41
+ if (defaultPersona?.runtime && localEnv.defaultRuntime !== defaultPersona.runtime) {
42
+ const previousRuntime = localEnv.defaultRuntime;
43
+ envRegistry.updateDefaultRuntime("local", defaultPersona.runtime);
44
+ localEnv = envRegistry.getEnvironment("local");
45
+ logger.info({ from: previousRuntime, to: defaultPersona.runtime }, "Synced local environment defaultRuntime with default persona");
46
+ }
47
+ // Seed: ensure the default workspace exists (tied to the local environment).
48
+ const defaultWorkspace = workspaceStore.getWorkspace(DEFAULT_WORKSPACE_ID);
49
+ if (!defaultWorkspace) {
50
+ workspaceStore.createWorkspace(DEFAULT_WORKSPACE_ID, "Default", "", "", "local", false);
51
+ logger.info("Created default workspace for local environment");
52
+ }
53
+ else if (defaultWorkspace.environmentId !== "local") {
54
+ logger.warn({ workspaceId: DEFAULT_WORKSPACE_ID, environmentId: defaultWorkspace.environmentId }, "Default workspace is not bound to local environment; skipping system task association");
55
+ }
56
+ // Backfill: assign the default workspace to the system task if it has none.
57
+ const systemTask = taskStore.getTask(ROOT_TASK_ID);
58
+ const resolvedDefault = workspaceStore.getWorkspace(DEFAULT_WORKSPACE_ID);
59
+ if (systemTask && !systemTask.workspaceId && resolvedDefault?.environmentId === "local") {
60
+ taskStore.setTaskWorkspace(ROOT_TASK_ID, DEFAULT_WORKSPACE_ID);
61
+ logger.info("Assigned default workspace to system task");
62
+ }
63
+ // Spawn the PowerLine child process with auto-restart on crash
64
+ manager = deps.createPowerLineManager({
65
+ port: powerlinePort,
66
+ host: bindHost,
67
+ token: localEnv.powerlineToken,
68
+ onStatusChange: (status) => {
69
+ envRegistry.updateEnvironmentStatus("local", status);
70
+ deps.emit("environment.changed", {});
71
+ },
72
+ onRestarted: () => {
73
+ deps.resetReconnectState("local");
74
+ },
75
+ });
76
+ await manager.start();
77
+ // Auto-provision: connect the local adapter
78
+ const localAdapter = deps.getAdapter("local");
79
+ const config = deps.parseAdapterConfig(localEnv.adapterConfig);
80
+ envRegistry.updateEnvironmentStatus("local", "connecting");
81
+ deps.emit("environment.changed", {});
82
+ for await (const event of deps.reconnectOrProvision("local", localAdapter, config, localEnv.powerlineToken, !!localEnv.bootstrapped)) {
83
+ logger.info({ stage: event.stage, progress: event.progress }, "Local env: %s", event.message);
84
+ }
85
+ const conn = await localAdapter.connect("local", config, localEnv.powerlineToken);
86
+ deps.setConnection("local", conn);
87
+ // Push env-var tokens only — file tokens would just overwrite local credential
88
+ // files (e.g. ~/.claude/credentials.json) with their own content.
89
+ await deps.pushToEnv("local", { excludeFileTokens: true });
90
+ envRegistry.updateEnvironmentStatus("local", "connected");
91
+ envRegistry.markBootstrapped("local");
92
+ deps.emit("environment.changed", {});
93
+ logger.info({ port: powerlinePort }, "Local environment auto-connected");
94
+ return { powerLineManager: manager };
95
+ }
96
+ catch (err) {
97
+ // Clean up the PowerLine child if it started but provisioning/connection failed
98
+ if (manager) {
99
+ try {
100
+ await manager.stop();
101
+ }
102
+ catch (stopErr) {
103
+ logger.warn({ err: stopErr, port: powerlinePort }, "Failed to stop local PowerLine during cleanup");
104
+ }
105
+ }
106
+ envRegistry.updateEnvironmentStatus("local", "error");
107
+ deps.emit("environment.changed", {});
108
+ logger.error({ err, port: powerlinePort }, "Failed to start local PowerLine — local environment will not be available. Is port %d in use?", powerlinePort);
109
+ // Non-fatal: server continues without local env (remote envs still work)
110
+ return {};
111
+ }
112
+ }
113
+ //# sourceMappingURL=local-environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-environment.js","sourceRoot":"","sources":["../src/local-environment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ReconciliationPhase } from "@grackle-ai/core";
2
+ /**
3
+ * Assemble the ordered list of reconciliation phases for the server.
4
+ *
5
+ * Returns cron, lifecycle-cleanup, orphan-reparent, and environment-reconciliation
6
+ * phases. When the knowledge subsystem is enabled, a knowledge-health phase is
7
+ * appended.
8
+ *
9
+ * @returns An array of phases to pass to {@link ReconciliationManager}.
10
+ */
11
+ export declare function createReconciliationPhases(): ReconciliationPhase[];
12
+ //# sourceMappingURL=reconciliation-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciliation-setup.d.ts","sourceRoot":"","sources":["../src/reconciliation-setup.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAK5D;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,IAAI,mBAAmB,EAAE,CAiDlE"}
@@ -0,0 +1,54 @@
1
+ import { createCronPhase, createOrphanPhase, lifecycleCleanupPhase, createEnvironmentReconciliationPhase, listConnections, removeConnection, isKnowledgeEnabled, createKnowledgeHealthPhase, neo4jHealthCheck, startTaskSession, emit, findFirstConnectedEnvironment, } from "@grackle-ai/core";
2
+ import { scheduleStore, taskStore, workspaceStore, personaStore, envRegistry, } from "@grackle-ai/database";
3
+ /**
4
+ * Assemble the ordered list of reconciliation phases for the server.
5
+ *
6
+ * Returns cron, lifecycle-cleanup, orphan-reparent, and environment-reconciliation
7
+ * phases. When the knowledge subsystem is enabled, a knowledge-health phase is
8
+ * appended.
9
+ *
10
+ * @returns An array of phases to pass to {@link ReconciliationManager}.
11
+ */
12
+ export function createReconciliationPhases() {
13
+ const cronPhase = createCronPhase({
14
+ getDueSchedules: scheduleStore.getDueSchedules,
15
+ advanceSchedule: scheduleStore.advanceSchedule,
16
+ createTask: taskStore.createTask,
17
+ setTaskScheduleId: taskStore.setTaskScheduleId,
18
+ startTaskSession,
19
+ emit,
20
+ findFirstConnectedEnvironment,
21
+ getPersona: personaStore.getPersona,
22
+ getTask: taskStore.getTask,
23
+ setScheduleEnabled: scheduleStore.setScheduleEnabled,
24
+ isEnvironmentConnected: (id) => {
25
+ const env = envRegistry.getEnvironment(id);
26
+ return env?.status === "connected";
27
+ },
28
+ });
29
+ const orphanPhase = createOrphanPhase({
30
+ listAllTasks: () => {
31
+ const workspaces = workspaceStore.listWorkspaces();
32
+ const allTasks = [];
33
+ for (const ws of workspaces) {
34
+ allTasks.push(...taskStore.listTasks(ws.id));
35
+ }
36
+ return allTasks;
37
+ },
38
+ reparentTask: (taskId, newParentTaskId) => taskStore.reparentTask(taskId, newParentTaskId),
39
+ emit,
40
+ });
41
+ const environmentReconciliationPhase = createEnvironmentReconciliationPhase({
42
+ listEnvironments: envRegistry.listEnvironments,
43
+ listConnectionIds: () => new Set(listConnections().keys()),
44
+ updateEnvironmentStatus: envRegistry.updateEnvironmentStatus,
45
+ removeConnection,
46
+ emit,
47
+ });
48
+ const phases = [cronPhase, lifecycleCleanupPhase, orphanPhase, environmentReconciliationPhase];
49
+ if (isKnowledgeEnabled()) {
50
+ phases.push(createKnowledgeHealthPhase({ healthCheck: neo4jHealthCheck }));
51
+ }
52
+ return phases;
53
+ }
54
+ //# sourceMappingURL=reconciliation-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciliation-setup.js","sourceRoot":"","sources":["../src/reconciliation-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAAE,iBAAiB,EAAE,qBAAqB,EACzD,oCAAoC,EAAE,eAAe,EAAE,gBAAgB,EACvE,kBAAkB,EAAE,0BAA0B,EAAE,gBAAgB,EAChE,gBAAgB,EAAE,IAAI,EAAE,6BAA6B,GACtD,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,GACpE,MAAM,sBAAsB,CAAC;AAE9B;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B;IACxC,MAAM,SAAS,GAAG,eAAe,CAAC;QAChC,eAAe,EAAE,aAAa,CAAC,eAAe;QAC9C,eAAe,EAAE,aAAa,CAAC,eAAe;QAC9C,UAAU,EAAE,SAAS,CAAC,UAAU;QAChC,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;QAC9C,gBAAgB;QAChB,IAAI;QACJ,6BAA6B;QAC7B,UAAU,EAAE,YAAY,CAAC,UAAU;QACnC,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,kBAAkB,EAAE,aAAa,CAAC,kBAAkB;QACpD,sBAAsB,EAAE,CAAC,EAAU,EAAW,EAAE;YAC9C,MAAM,GAAG,GAAG,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;YAC3C,OAAO,GAAG,EAAE,MAAM,KAAK,WAAW,CAAC;QACrC,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,iBAAiB,CAAC;QACpC,YAAY,EAAE,GAAG,EAAE;YACjB,MAAM,UAAU,GAAG,cAAc,CAAC,cAAc,EAAE,CAAC;YACnD,MAAM,QAAQ,GAA6D,EAAE,CAAC;YAC9E,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,YAAY,EAAE,CAAC,MAAc,EAAE,eAAuB,EAAE,EAAE,CACxD,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,eAAe,CAAC;QACjD,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,8BAA8B,GAAG,oCAAoC,CAAC;QAC1E,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;QAC9C,iBAAiB,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,CAAC;QAC1D,uBAAuB,EAAE,WAAW,CAAC,uBAAuB;QAC5D,gBAAgB;QAChB,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,MAAM,GAA0B,CAAC,SAAS,EAAE,qBAAqB,EAAE,WAAW,EAAE,8BAA8B,CAAC,CAAC;IAEtH,IAAI,kBAAkB,EAAE,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CACT,0BAA0B,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,35 @@
1
+ /** Minimal server interface — only the `.close()` method is needed for shutdown. */
2
+ interface Closeable {
3
+ close: (cb: (err?: Error) => void) => void;
4
+ }
5
+ /** Resources that must be cleaned up during graceful shutdown. */
6
+ export interface ShutdownContext {
7
+ /** The HTTP/2 gRPC server. */
8
+ grpcServer: Closeable;
9
+ /** The HTTP/1.1 web + WebSocket server. */
10
+ webServer: Closeable;
11
+ /** The HTTP/1.1 MCP server. */
12
+ mcpServer: Closeable;
13
+ /** The reconciliation manager (cron, orphan, lifecycle phases). */
14
+ reconciliationManager: {
15
+ stop: () => Promise<void>;
16
+ };
17
+ /** The local PowerLine child-process manager, if running. */
18
+ localPowerLineManager?: {
19
+ stop: () => Promise<void>;
20
+ };
21
+ /** Optional knowledge graph cleanup function. */
22
+ knowledgeCleanup?: () => Promise<void>;
23
+ }
24
+ /**
25
+ * Create a graceful shutdown function that closes all server resources.
26
+ *
27
+ * The returned function stops timers, closes servers, flushes the WAL, and
28
+ * exits the process. A hard timeout forces exit if shutdown hangs.
29
+ *
30
+ * @param context - All resources that need cleanup.
31
+ * @returns An async shutdown function suitable for SIGINT/SIGTERM handlers.
32
+ */
33
+ export declare function createShutdown(context: ShutdownContext): () => Promise<void>;
34
+ export {};
35
+ //# sourceMappingURL=shutdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"AAQA,oFAAoF;AACpF,UAAU,SAAS;IACjB,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI,KAAK,IAAI,CAAC;CAC5C;AAED,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,UAAU,EAAE,SAAS,CAAC;IACtB,2CAA2C;IAC3C,SAAS,EAAE,SAAS,CAAC;IACrB,+BAA+B;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,mEAAmE;IACnE,qBAAqB,EAAE;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;IACrD,6DAA6D;IAC7D,qBAAqB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;IACtD,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAmE5E"}
@@ -0,0 +1,78 @@
1
+ import { logger } from "@grackle-ai/core";
2
+ import { sqlite, stopWalCheckpointTimer } from "@grackle-ai/database";
3
+ import { stopPairingCleanup, stopSessionCleanup, stopOAuthCleanup } from "@grackle-ai/auth";
4
+ import { closeAllTunnels } from "@grackle-ai/adapter-sdk";
5
+ /** Hard timeout (ms) so upgraded WS connections don't block exit. */
6
+ const SHUTDOWN_TIMEOUT_MS = 5_000;
7
+ /**
8
+ * Create a graceful shutdown function that closes all server resources.
9
+ *
10
+ * The returned function stops timers, closes servers, flushes the WAL, and
11
+ * exits the process. A hard timeout forces exit if shutdown hangs.
12
+ *
13
+ * @param context - All resources that need cleanup.
14
+ * @returns An async shutdown function suitable for SIGINT/SIGTERM handlers.
15
+ */
16
+ export function createShutdown(context) {
17
+ return async function shutdown() {
18
+ logger.info("Shutting down...");
19
+ stopWalCheckpointTimer();
20
+ stopPairingCleanup();
21
+ stopSessionCleanup();
22
+ stopOAuthCleanup();
23
+ await context.reconciliationManager.stop();
24
+ const forceExit = setTimeout(() => {
25
+ logger.warn("Shutdown timed out, forcing exit");
26
+ process.exit(1);
27
+ }, SHUTDOWN_TIMEOUT_MS);
28
+ // Stop the local PowerLine child process first
29
+ if (context.localPowerLineManager) {
30
+ await context.localPowerLineManager.stop();
31
+ }
32
+ if (context.knowledgeCleanup) {
33
+ try {
34
+ await context.knowledgeCleanup();
35
+ }
36
+ catch (err) {
37
+ logger.error({ err }, "Error while shutting down knowledge graph");
38
+ }
39
+ }
40
+ await closeAllTunnels();
41
+ await new Promise((resolve) => {
42
+ context.grpcServer.close((err) => {
43
+ if (err) {
44
+ logger.error({ err }, "Error while closing gRPC server");
45
+ }
46
+ resolve();
47
+ });
48
+ });
49
+ await new Promise((resolve) => {
50
+ context.webServer.close((err) => {
51
+ if (err) {
52
+ logger.error({ err }, "Error while closing web server");
53
+ }
54
+ resolve();
55
+ });
56
+ });
57
+ await new Promise((resolve) => {
58
+ context.mcpServer.close((err) => {
59
+ if (err) {
60
+ logger.error({ err }, "Error while closing MCP server");
61
+ }
62
+ resolve();
63
+ });
64
+ });
65
+ // Final WAL checkpoint (TRUNCATE) to fully flush pending writes before exit
66
+ if (sqlite) {
67
+ try {
68
+ sqlite.pragma("wal_checkpoint(TRUNCATE)");
69
+ }
70
+ catch (err) {
71
+ logger.error({ err }, "Error during final WAL checkpoint");
72
+ }
73
+ }
74
+ clearTimeout(forceExit);
75
+ process.exit(process.exitCode || 0);
76
+ };
77
+ }
78
+ //# sourceMappingURL=shutdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grackle-ai/server",
3
- "version": "0.91.3",
3
+ "version": "0.92.0",
4
4
  "description": "Grackle server orchestrator — spawns and wires core (gRPC), web-server (HTTP), MCP, and PowerLine",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,18 +31,18 @@
31
31
  "@connectrpc/connect-node": "^2.0.0",
32
32
  "pino": "^10.3.1",
33
33
  "qrcode": "^1.5.4",
34
- "@grackle-ai/adapter-codespace": "0.91.3",
35
- "@grackle-ai/adapter-docker": "0.91.3",
36
- "@grackle-ai/adapter-local": "0.91.3",
37
- "@grackle-ai/adapter-sdk": "0.91.3",
38
- "@grackle-ai/adapter-ssh": "0.91.3",
39
- "@grackle-ai/auth": "0.91.3",
40
- "@grackle-ai/core": "0.91.3",
41
- "@grackle-ai/database": "0.91.3",
42
- "@grackle-ai/common": "0.91.3",
43
- "@grackle-ai/mcp": "0.91.3",
44
- "@grackle-ai/web-server": "0.91.3",
45
- "@grackle-ai/powerline": "0.91.3"
34
+ "@grackle-ai/adapter-codespace": "0.92.0",
35
+ "@grackle-ai/adapter-docker": "0.92.0",
36
+ "@grackle-ai/adapter-local": "0.92.0",
37
+ "@grackle-ai/adapter-ssh": "0.92.0",
38
+ "@grackle-ai/adapter-sdk": "0.92.0",
39
+ "@grackle-ai/auth": "0.92.0",
40
+ "@grackle-ai/common": "0.92.0",
41
+ "@grackle-ai/powerline": "0.92.0",
42
+ "@grackle-ai/database": "0.92.0",
43
+ "@grackle-ai/web-server": "0.92.0",
44
+ "@grackle-ai/mcp": "0.92.0",
45
+ "@grackle-ai/core": "0.92.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@rushstack/heft": "1.2.7",