@grackle-ai/core 0.92.3 → 0.94.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.
Files changed (59) hide show
  1. package/dist/concurrency.d.ts +34 -0
  2. package/dist/concurrency.d.ts.map +1 -0
  3. package/dist/concurrency.js +41 -0
  4. package/dist/concurrency.js.map +1 -0
  5. package/dist/dispatch-phase.d.ts +44 -0
  6. package/dist/dispatch-phase.d.ts.map +1 -0
  7. package/dist/dispatch-phase.js +84 -0
  8. package/dist/dispatch-phase.js.map +1 -0
  9. package/dist/environment-handlers.d.ts.map +1 -1
  10. package/dist/environment-handlers.js +17 -5
  11. package/dist/environment-handlers.js.map +1 -1
  12. package/dist/grpc-proto-converters.d.ts +6 -2
  13. package/dist/grpc-proto-converters.d.ts.map +1 -1
  14. package/dist/grpc-proto-converters.js +11 -3
  15. package/dist/grpc-proto-converters.js.map +1 -1
  16. package/dist/index.d.ts +10 -5
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +8 -6
  19. package/dist/index.js.map +1 -1
  20. package/dist/lifecycle.d.ts +10 -9
  21. package/dist/lifecycle.d.ts.map +1 -1
  22. package/dist/lifecycle.js +18 -21
  23. package/dist/lifecycle.js.map +1 -1
  24. package/dist/root-task-boot.d.ts +12 -3
  25. package/dist/root-task-boot.d.ts.map +1 -1
  26. package/dist/root-task-boot.js +80 -45
  27. package/dist/root-task-boot.js.map +1 -1
  28. package/dist/signals/escalation-auto.d.ts +9 -8
  29. package/dist/signals/escalation-auto.d.ts.map +1 -1
  30. package/dist/signals/escalation-auto.js +21 -25
  31. package/dist/signals/escalation-auto.js.map +1 -1
  32. package/dist/signals/orphan-reparent.d.ts +9 -8
  33. package/dist/signals/orphan-reparent.d.ts.map +1 -1
  34. package/dist/signals/orphan-reparent.js +21 -25
  35. package/dist/signals/orphan-reparent.js.map +1 -1
  36. package/dist/signals/sigchld.d.ts +9 -4
  37. package/dist/signals/sigchld.d.ts.map +1 -1
  38. package/dist/signals/sigchld.js +23 -26
  39. package/dist/signals/sigchld.js.map +1 -1
  40. package/dist/stream-registry.d.ts +14 -2
  41. package/dist/stream-registry.d.ts.map +1 -1
  42. package/dist/stream-registry.js +22 -0
  43. package/dist/stream-registry.js.map +1 -1
  44. package/dist/subscriber-types.d.ts +25 -0
  45. package/dist/subscriber-types.d.ts.map +1 -0
  46. package/dist/subscriber-types.js +11 -0
  47. package/dist/subscriber-types.js.map +1 -0
  48. package/dist/task-handlers.d.ts.map +1 -1
  49. package/dist/task-handlers.js +26 -1
  50. package/dist/task-handlers.js.map +1 -1
  51. package/dist/test-utils/mock-database.d.ts +11 -0
  52. package/dist/test-utils/mock-database.d.ts.map +1 -1
  53. package/dist/test-utils/mock-database.js +11 -0
  54. package/dist/test-utils/mock-database.js.map +1 -1
  55. package/dist/workspace-handlers.d.ts +4 -0
  56. package/dist/workspace-handlers.d.ts.map +1 -1
  57. package/dist/workspace-handlers.js +51 -2
  58. package/dist/workspace-handlers.js.map +1 -1
  59. package/package.json +7 -7
package/dist/lifecycle.js CHANGED
@@ -17,22 +17,20 @@ import { sessionStore, taskStore } from "@grackle-ai/database";
17
17
  import * as streamRegistry from "./stream-registry.js";
18
18
  import * as adapterManager from "./adapter-manager.js";
19
19
  import * as streamHub from "./stream-hub.js";
20
- import { emit } from "./event-bus.js";
21
20
  import { reanimateAgent } from "./reanimate-agent.js";
22
21
  import { logger } from "./logger.js";
23
- /** Whether the lifecycle manager has been initialized. */
24
- let initialized = false;
25
22
  /**
26
- * Initialize the lifecycle manager. Registers the orphan callback on the
27
- * stream-registry so that sessions auto-stop when all fds are closed.
28
- * Idempotent safe to call multiple times.
23
+ * Create the lifecycle manager subscriber.
24
+ *
25
+ * Registers orphan and revival callbacks on the stream-registry so that
26
+ * sessions auto-stop when all fds are closed and auto-reanimate when
27
+ * a new fd is opened.
28
+ *
29
+ * @param ctx - Plugin context providing event-bus access.
30
+ * @returns A Disposable that unregisters both callbacks.
29
31
  */
30
- export function initLifecycleManager() {
31
- if (initialized) {
32
- return;
33
- }
34
- initialized = true;
35
- streamRegistry.onSessionOrphaned((sessionId) => {
32
+ export function createLifecycleSubscriber(ctx) {
33
+ const unsubOrphan = streamRegistry.onSessionOrphaned((sessionId) => {
36
34
  const session = sessionStore.getSession(sessionId);
37
35
  if (!session) {
38
36
  return;
@@ -83,14 +81,14 @@ export function initLifecycleManager() {
83
81
  if (session.taskId) {
84
82
  const task = taskStore.getTask(session.taskId);
85
83
  if (task) {
86
- emit("task.updated", { taskId: task.id, workspaceId: task.workspaceId || "" });
84
+ ctx.emit("task.updated", { taskId: task.id, workspaceId: task.workspaceId || "" });
87
85
  }
88
86
  }
89
87
  });
90
88
  // ── Auto-reanimate: when an external session subscribes to a lifecycle
91
89
  // stream whose session is stopped, automatically restart it. This is the
92
90
  // "open() IS reanimate" model from the streams IPC spec.
93
- streamRegistry.onSessionRevived((targetSessionId, _subscriberSessionId) => {
91
+ const unsubRevived = streamRegistry.onSessionRevived((targetSessionId, _subscriberSessionId) => {
94
92
  const session = sessionStore.getSession(targetSessionId);
95
93
  if (!session) {
96
94
  return;
@@ -125,6 +123,12 @@ export function initLifecycleManager() {
125
123
  }
126
124
  });
127
125
  logger.info("Lifecycle manager initialized");
126
+ return {
127
+ dispose() {
128
+ unsubOrphan();
129
+ unsubRevived();
130
+ },
131
+ };
128
132
  }
129
133
  /**
130
134
  * Clean up lifecycle stream for a session. Deletes the stream and all its
@@ -162,11 +166,4 @@ export function ensureLifecycleStream(sessionId, spawnerId) {
162
166
  streamRegistry.subscribe(stream.id, spawnerId, "rw", "detach", true);
163
167
  streamRegistry.subscribe(stream.id, sessionId, "rw", "detach", false);
164
168
  }
165
- /**
166
- * Reset module state. For testing only.
167
- * @internal
168
- */
169
- export function _resetForTesting() {
170
- initialized = false;
171
- }
172
169
  //# sourceMappingURL=lifecycle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import type { TaskRow, SessionRow, EnvironmentRow } from "@grackle-ai/database";
18
18
  import type { TaskStatusResult } from "./compute-task-status.js";
19
+ import type { Disposable, PluginContext } from "./subscriber-types.js";
19
20
  /** Dependencies injected into the root task boot module for testability. */
20
21
  export interface RootTaskBootDeps {
21
22
  /** Look up a task by ID. */
@@ -45,14 +46,22 @@ export interface RootTaskBootDeps {
45
46
  * event subscriptions. Each call checks whether the root task needs starting
46
47
  * and applies reanimate-first + exponential backoff logic.
47
48
  *
49
+ * Each call creates independent backoff state (not shared across calls).
50
+ *
48
51
  * @param deps - Injected dependencies for testability.
49
52
  * @returns An async function to call on each `environment.changed` event.
50
53
  */
51
54
  export declare function createRootTaskBoot(deps: RootTaskBootDeps): () => Promise<void>;
52
55
  /**
53
- * Reset in-memory backoff state. For use in tests only.
56
+ * Create the root task boot subscriber.
57
+ *
58
+ * Creates independent backoff state (not shared with other factory calls)
59
+ * and subscribes to `environment.changed` and `setting.changed` events.
60
+ * Returns a Disposable that unsubscribes the handler.
54
61
  *
55
- * @internal
62
+ * @param ctx - Plugin context providing event-bus access.
63
+ * @param deps - Injected dependencies for testability.
64
+ * @returns A Disposable that unsubscribes the handler.
56
65
  */
57
- export declare function _resetForTesting(): void;
66
+ export declare function createRootTaskBootSubscriber(ctx: PluginContext, deps: RootTaskBootDeps): Disposable;
58
67
  //# sourceMappingURL=root-task-boot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-task-boot.d.ts","sourceRoot":"","sources":["../src/root-task-boot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAsBjE,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B;IAC5B,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,GAAG,SAAS,CAAC;IAC7C,oCAAoC;IACpC,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,CAAC,EAAE,CAAC;IAC3F,kEAAkE;IAClE,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;IACpE,0EAA0E;IAC1E,iBAAiB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,CAAC,EAAE,KAAK,gBAAgB,CAAC;IAC3H,8DAA8D;IAC9D,6BAA6B,EAAE,MAAM,cAAc,GAAG,SAAS,CAAC;IAChE,mGAAmG;IACnG,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACvH,mFAAmF;IACnF,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,UAAU,CAAC;IAClD,oGAAoG;IACpG,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;CAC7B;AA6BD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAiB9E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
1
+ {"version":3,"file":"root-task-boot.d.ts","sourceRoot":"","sources":["../src/root-task-boot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAqBvE,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B;IAC5B,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,GAAG,SAAS,CAAC;IAC7C,oCAAoC;IACpC,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,CAAC,EAAE,CAAC;IAC3F,kEAAkE;IAClE,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;IACpE,0EAA0E;IAC1E,iBAAiB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,CAAC,EAAE,KAAK,gBAAgB,CAAC;IAC3H,8DAA8D;IAC9D,6BAA6B,EAAE,MAAM,cAAc,GAAG,SAAS,CAAC;IAChE,mGAAmG;IACnG,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACvH,mFAAmF;IACnF,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,UAAU,CAAC;IAClD,oGAAoG;IACpG,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;CAC7B;AA4BD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAE9E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,GAAG,UAAU,CAuBnG"}
@@ -28,7 +28,7 @@ const BOOT_MAX_FAILURES = 10;
28
28
  /** Minimum time a session must survive (ms) to be considered stable and reset backoff. */
29
29
  const BOOT_STABLE_THRESHOLD_MS = 30_000;
30
30
  // ─── State ──────────────────────────────────────────────────
31
- let state = createInitialState();
31
+ /** Create a fresh backoff state. */
32
32
  function createInitialState() {
33
33
  return {
34
34
  failures: 0,
@@ -45,39 +45,74 @@ function createInitialState() {
45
45
  * event subscriptions. Each call checks whether the root task needs starting
46
46
  * and applies reanimate-first + exponential backoff logic.
47
47
  *
48
+ * Each call creates independent backoff state (not shared across calls).
49
+ *
48
50
  * @param deps - Injected dependencies for testability.
49
51
  * @returns An async function to call on each `environment.changed` event.
50
52
  */
51
53
  export function createRootTaskBoot(deps) {
54
+ return createRootTaskBootHandler(deps, createInitialState());
55
+ }
56
+ /**
57
+ * Create the root task boot subscriber.
58
+ *
59
+ * Creates independent backoff state (not shared with other factory calls)
60
+ * and subscribes to `environment.changed` and `setting.changed` events.
61
+ * Returns a Disposable that unsubscribes the handler.
62
+ *
63
+ * @param ctx - Plugin context providing event-bus access.
64
+ * @param deps - Injected dependencies for testability.
65
+ * @returns A Disposable that unsubscribes the handler.
66
+ */
67
+ export function createRootTaskBootSubscriber(ctx, deps) {
68
+ const bootState = createInitialState();
69
+ const tryBoot = createRootTaskBootHandler(deps, bootState);
70
+ const unsubscribe = ctx.subscribe((event) => {
71
+ if (event.type === "environment.changed") {
72
+ tryBoot().catch(() => { });
73
+ }
74
+ // Also try when onboarding completes — the environment is already
75
+ // connected but boot was deferred until the user chose a runtime.
76
+ if (event.type === "setting.changed") {
77
+ const payload = event.payload;
78
+ if (payload.key === "onboarding_completed" && payload.value === "true") {
79
+ tryBoot().catch(() => { });
80
+ }
81
+ }
82
+ });
83
+ return {
84
+ dispose() {
85
+ unsubscribe();
86
+ },
87
+ };
88
+ }
89
+ // ─── Internal ───────────────────────────────────────────────
90
+ /**
91
+ * Create an async boot handler that uses the given backoff state.
92
+ * Shared implementation for both {@link createRootTaskBoot} and
93
+ * {@link createRootTaskBootSubscriber}.
94
+ */
95
+ function createRootTaskBootHandler(deps, s) {
52
96
  return async () => {
53
97
  // Guard: prevent concurrent boot attempts
54
- if (state.inProgress) {
98
+ if (s.inProgress) {
55
99
  return;
56
100
  }
57
- state.inProgress = true;
101
+ s.inProgress = true;
58
102
  try {
59
- await attemptBoot(deps);
103
+ await attemptBoot(deps, s);
60
104
  }
61
105
  catch (err) {
62
- recordFailure();
106
+ recordFailure(s);
63
107
  logger.warn({ err }, "Root task boot failed with unexpected exception");
64
108
  }
65
109
  finally {
66
- state.inProgress = false; // eslint-disable-line require-atomic-updates -- single-threaded, flag guards re-entry
110
+ s.inProgress = false; // eslint-disable-line require-atomic-updates -- single-threaded, flag guards re-entry
67
111
  }
68
112
  };
69
113
  }
70
- /**
71
- * Reset in-memory backoff state. For use in tests only.
72
- *
73
- * @internal
74
- */
75
- export function _resetForTesting() {
76
- state = createInitialState();
77
- }
78
- // ─── Internal ───────────────────────────────────────────────
79
114
  /** Core boot logic — separated from the guard/error wrapper for clarity. */
80
- async function attemptBoot(deps) {
115
+ async function attemptBoot(deps, s) {
81
116
  // 0. Don't auto-start before onboarding — the user hasn't chosen their
82
117
  // runtime yet, so the root task would launch with the default "claude-code".
83
118
  if (deps.isOnboarded && !deps.isOnboarded()) {
@@ -92,28 +127,28 @@ async function attemptBoot(deps) {
92
127
  const sessions = deps.listSessionsForTask(ROOT_TASK_ID);
93
128
  const { status } = deps.computeTaskStatus(rootTask.status, sessions);
94
129
  if (status === TASK_STATUS.WORKING) {
95
- checkStabilityReset();
130
+ checkStabilityReset(s);
96
131
  return;
97
132
  }
98
133
  // 2b. Crash-loop detection: if we recently started a session but the task
99
134
  // is no longer working before the stability threshold, count it as a failure.
100
135
  // This catches the case where startTaskSession succeeded but the session
101
136
  // crashed shortly after (the main crash-loop scenario from issue #959).
102
- if (state.lastSessionStartedAt > 0) {
103
- const sinceLastStart = Date.now() - state.lastSessionStartedAt;
137
+ if (s.lastSessionStartedAt > 0) {
138
+ const sinceLastStart = Date.now() - s.lastSessionStartedAt;
104
139
  if (sinceLastStart < BOOT_STABLE_THRESHOLD_MS) {
105
140
  // Session crashed before reaching stability — record as failure
106
- if (state.lastFailureAt < state.lastSessionStartedAt) {
141
+ if (s.lastFailureAt < s.lastSessionStartedAt) {
107
142
  // Only record once per start (guard against multiple environment.changed events)
108
- recordFailure();
109
- logger.info({ survivedMs: sinceLastStart, failures: state.failures }, "Root task session crashed before stability threshold — recording failure");
143
+ recordFailure(s);
144
+ logger.info({ survivedMs: sinceLastStart, failures: s.failures }, "Root task session crashed before stability threshold — recording failure");
110
145
  }
111
146
  }
112
147
  else {
113
148
  // Session survived past stability threshold but is now stopped — reset backoff
114
- resetBackoff(sinceLastStart);
149
+ resetBackoff(s, sinceLastStart);
115
150
  }
116
- state.lastSessionStartedAt = 0;
151
+ s.lastSessionStartedAt = 0;
117
152
  }
118
153
  // 3. Find connected environment
119
154
  const connectedEnv = deps.findFirstConnectedEnvironment();
@@ -121,16 +156,16 @@ async function attemptBoot(deps) {
121
156
  return;
122
157
  }
123
158
  // 4. Check backoff
124
- if (state.failures >= BOOT_MAX_FAILURES) {
159
+ if (s.failures >= BOOT_MAX_FAILURES) {
125
160
  // Log only once when the threshold is first reached to avoid spam
126
- if (state.failures === BOOT_MAX_FAILURES) {
127
- logger.error({ failures: state.failures }, "Root task boot exhausted all retries (%d failures) — giving up until server restart", state.failures);
161
+ if (s.failures === BOOT_MAX_FAILURES) {
162
+ logger.error({ failures: s.failures }, "Root task boot exhausted all retries (%d failures) — giving up until server restart", s.failures);
128
163
  }
129
164
  return;
130
165
  }
131
- if (state.failures > 0) {
132
- const delay = Math.min(BOOT_INITIAL_DELAY_MS * Math.pow(BOOT_BACKOFF_MULTIPLIER, state.failures - 1), BOOT_MAX_DELAY_MS);
133
- const elapsed = Date.now() - state.lastFailureAt;
166
+ if (s.failures > 0) {
167
+ const delay = Math.min(BOOT_INITIAL_DELAY_MS * Math.pow(BOOT_BACKOFF_MULTIPLIER, s.failures - 1), BOOT_MAX_DELAY_MS);
168
+ const elapsed = Date.now() - s.lastFailureAt;
134
169
  if (elapsed < delay) {
135
170
  return; // backoff not elapsed yet
136
171
  }
@@ -155,45 +190,45 @@ async function attemptBoot(deps) {
155
190
  notes: ROOT_TASK_INITIAL_PROMPT,
156
191
  });
157
192
  if (err) {
158
- recordFailure();
193
+ recordFailure(s);
159
194
  logger.warn({ err }, "Root task auto-start failed");
160
195
  return;
161
196
  }
162
197
  logger.info({ environmentId: connectedEnv.id }, "Root task auto-started (fresh spawn)");
163
198
  }
164
199
  // 7. Track session start time for stability detection
165
- state.lastSessionStartedAt = Date.now(); // eslint-disable-line require-atomic-updates -- single-threaded
200
+ s.lastSessionStartedAt = Date.now(); // eslint-disable-line require-atomic-updates -- single-threaded
166
201
  }
167
202
  /** Record a boot failure: increment counter and timestamp. */
168
- function recordFailure() {
169
- state.failures++;
170
- state.lastFailureAt = Date.now();
203
+ function recordFailure(s) {
204
+ s.failures++;
205
+ s.lastFailureAt = Date.now();
171
206
  }
172
207
  /**
173
208
  * If the root task has been WORKING long enough (past the stability threshold),
174
209
  * reset the backoff counter. Called when we detect the task is already running.
175
210
  */
176
- function checkStabilityReset() {
177
- if (state.failures === 0) {
211
+ function checkStabilityReset(s) {
212
+ if (s.failures === 0) {
178
213
  return;
179
214
  }
180
- if (state.lastSessionStartedAt > 0) {
181
- const elapsed = Date.now() - state.lastSessionStartedAt;
215
+ if (s.lastSessionStartedAt > 0) {
216
+ const elapsed = Date.now() - s.lastSessionStartedAt;
182
217
  if (elapsed >= BOOT_STABLE_THRESHOLD_MS) {
183
- resetBackoff(elapsed);
218
+ resetBackoff(s, elapsed);
184
219
  }
185
220
  }
186
221
  else {
187
222
  // Task is WORKING but we didn't start it (e.g., session recovery
188
223
  // reanimated it externally). Begin tracking stability from now so
189
224
  // backoff can eventually reset — otherwise MAX_FAILURES is permanent.
190
- state.lastSessionStartedAt = Date.now();
225
+ s.lastSessionStartedAt = Date.now();
191
226
  }
192
227
  }
193
228
  /** Zero out the backoff state after a session has proven stable. */
194
- function resetBackoff(survivedMs) {
195
- logger.info({ survivedMs, previousFailures: state.failures }, "Root task session stable — resetting backoff");
196
- state.failures = 0;
197
- state.lastFailureAt = 0;
229
+ function resetBackoff(s, survivedMs) {
230
+ logger.info({ survivedMs, previousFailures: s.failures }, "Root task session stable — resetting backoff");
231
+ s.failures = 0;
232
+ s.lastFailureAt = 0;
198
233
  }
199
234
  //# sourceMappingURL=root-task-boot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-task-boot.js","sourceRoot":"","sources":["../src/root-task-boot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"root-task-boot.js","sourceRoot":"","sources":["../src/root-task-boot.ts"],"names":[],"mappings":"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"}
@@ -6,14 +6,15 @@
6
6
  * This is the safety net for simple topologies where there is no orchestrator
7
7
  * to explicitly call `escalate_to_human`.
8
8
  */
9
+ import type { Disposable, PluginContext } from "../subscriber-types.js";
9
10
  /**
10
- * Initialize the auto-escalation event-bus subscriber.
11
- * Idempotent — safe to call multiple times.
12
- */
13
- export declare function initEscalationAutoSubscriber(): void;
14
- /**
15
- * Reset module state. For use in tests only.
16
- * @internal
11
+ * Create the auto-escalation event-bus subscriber.
12
+ *
13
+ * Watches for standalone (parentless, non-ROOT) tasks whose latest session
14
+ * goes IDLE and automatically creates an escalation.
15
+ *
16
+ * @param ctx - Plugin context providing event-bus access.
17
+ * @returns A Disposable that unsubscribes and clears dedup state.
17
18
  */
18
- export declare function _resetForTesting(): void;
19
+ export declare function createEscalationAutoSubscriber(ctx: PluginContext): Disposable;
19
20
  //# sourceMappingURL=escalation-auto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"escalation-auto.d.ts","sourceRoot":"","sources":["../../src/signals/escalation-auto.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CA2BnD;AAmGD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC"}
1
+ {"version":3,"file":"escalation-auto.d.ts","sourceRoot":"","sources":["../../src/signals/escalation-auto.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAKxE;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,CAgC7E"}
@@ -7,7 +7,6 @@
7
7
  * to explicitly call `escalate_to_human`.
8
8
  */
9
9
  import { SESSION_STATUS, ROOT_TASK_ID } from "@grackle-ai/common";
10
- import { subscribe } from "../event-bus.js";
11
10
  import { taskStore, sessionStore, escalationStore } from "@grackle-ai/database";
12
11
  import { readLastTextEntry } from "../log-writer.js";
13
12
  import { routeEscalation } from "../notification-router.js";
@@ -15,20 +14,19 @@ import { logger } from "../logger.js";
15
14
  import { ulid } from "ulid";
16
15
  /** How long (ms) to remember a delivered notification before allowing re-delivery. */
17
16
  const DEDUP_TTL_MS = 3_600_000; // 1 hour
18
- /** Track delivered notifications to prevent duplicates: key -> delivery timestamp. */
19
- const delivered = new Map();
20
- /** Whether the subscriber has been initialized. */
21
- let initialized = false;
22
17
  /**
23
- * Initialize the auto-escalation event-bus subscriber.
24
- * Idempotent — safe to call multiple times.
18
+ * Create the auto-escalation event-bus subscriber.
19
+ *
20
+ * Watches for standalone (parentless, non-ROOT) tasks whose latest session
21
+ * goes IDLE and automatically creates an escalation.
22
+ *
23
+ * @param ctx - Plugin context providing event-bus access.
24
+ * @returns A Disposable that unsubscribes and clears dedup state.
25
25
  */
26
- export function initEscalationAutoSubscriber() {
27
- if (initialized) {
28
- return;
29
- }
30
- initialized = true;
31
- subscribe((event) => {
26
+ export function createEscalationAutoSubscriber(ctx) {
27
+ /** Track delivered notifications to prevent duplicates: key -> delivery timestamp. */
28
+ const delivered = new Map();
29
+ const unsubscribe = ctx.subscribe((event) => {
32
30
  if (event.type !== "task.updated") {
33
31
  return;
34
32
  }
@@ -39,7 +37,7 @@ export function initEscalationAutoSubscriber() {
39
37
  // Fire-and-forget async handler — errors are logged, never thrown
40
38
  (async () => {
41
39
  try {
42
- await handleTaskUpdated(taskId);
40
+ await handleTaskUpdated(delivered, taskId);
43
41
  }
44
42
  catch (err) {
45
43
  logger.error({ err, taskId }, "Escalation auto-detect handler error");
@@ -47,12 +45,18 @@ export function initEscalationAutoSubscriber() {
47
45
  })().catch(() => { });
48
46
  });
49
47
  logger.info("Escalation auto-detect subscriber initialized");
48
+ return {
49
+ dispose() {
50
+ unsubscribe();
51
+ delivered.clear();
52
+ },
53
+ };
50
54
  }
51
55
  /**
52
56
  * Handle a task.updated event: check if the task is a standalone root task
53
57
  * whose latest session has gone IDLE, and if so, auto-escalate.
54
58
  */
55
- async function handleTaskUpdated(taskId) {
59
+ async function handleTaskUpdated(delivered, taskId) {
56
60
  const task = taskStore.getTask(taskId);
57
61
  if (!task) {
58
62
  return;
@@ -81,7 +85,7 @@ async function handleTaskUpdated(taskId) {
81
85
  return;
82
86
  }
83
87
  // Prune expired entries to prevent unbounded growth
84
- pruneDelivered(now);
88
+ pruneDelivered(delivered, now);
85
89
  // Extract the last text message from the session log
86
90
  const logPath = latestSession.logPath || undefined;
87
91
  const lastEntry = logPath ? readLastTextEntry(logPath) : undefined;
@@ -112,19 +116,11 @@ async function handleTaskUpdated(taskId) {
112
116
  logger.info({ taskId, escalationId, title: task.title }, "Auto-escalation created for idle standalone task");
113
117
  }
114
118
  /** Remove dedup entries older than DEDUP_TTL_MS. */
115
- function pruneDelivered(now) {
119
+ function pruneDelivered(delivered, now) {
116
120
  for (const [key, timestamp] of delivered) {
117
121
  if (now - timestamp >= DEDUP_TTL_MS) {
118
122
  delivered.delete(key);
119
123
  }
120
124
  }
121
125
  }
122
- /**
123
- * Reset module state. For use in tests only.
124
- * @internal
125
- */
126
- export function _resetForTesting() {
127
- delivered.clear();
128
- initialized = false;
129
- }
130
126
  //# sourceMappingURL=escalation-auto.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"escalation-auto.js","sourceRoot":"","sources":["../../src/signals/escalation-auto.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"escalation-auto.js","sourceRoot":"","sources":["../../src/signals/escalation-auto.ts"],"names":[],"mappings":"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"}
@@ -6,11 +6,17 @@
6
6
  * detects orphan conditions, and reparents children to the grandparent.
7
7
  * The root task (PID 1) is the ultimate adopter.
8
8
  */
9
+ import type { Disposable, PluginContext } from "../subscriber-types.js";
9
10
  /**
10
- * Initialize the orphan reparenting event-bus subscriber.
11
- * Idempotent — safe to call multiple times.
11
+ * Create the orphan reparenting event-bus subscriber.
12
+ *
13
+ * Watches for parent tasks reaching terminal state and reparents their
14
+ * non-terminal children to the grandparent (or root task as ultimate adopter).
15
+ *
16
+ * @param ctx - Plugin context providing event-bus access.
17
+ * @returns A Disposable that unsubscribes and clears dedup state.
12
18
  */
13
- export declare function initOrphanReparentSubscriber(): void;
19
+ export declare function createOrphanReparentSubscriber(ctx: PluginContext): Disposable;
14
20
  /**
15
21
  * Transfer ALL pipe subscriptions from a dead parent's sessions to the
16
22
  * grandparent's active session. Called once per parent death (not per child).
@@ -22,9 +28,4 @@ export declare function initOrphanReparentSubscriber(): void;
22
28
  * killSessionAndCleanup() before sessions are cleaned up.
23
29
  */
24
30
  export declare function transferAllPipeSubscriptions(deadParentTaskId: string, grandparentTaskId: string): void;
25
- /**
26
- * Reset module state. For testing only.
27
- * @internal
28
- */
29
- export declare function _resetForTesting(): void;
30
31
  //# sourceMappingURL=orphan-reparent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"orphan-reparent.d.ts","sourceRoot":"","sources":["../../src/signals/orphan-reparent.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAyBH;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CA8BnD;AA2FD;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,gBAAgB,EAAE,MAAM,EACxB,iBAAiB,EAAE,MAAM,GACxB,IAAI,CAsDN;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC"}
1
+ {"version":3,"file":"orphan-reparent.d.ts","sourceRoot":"","sources":["../../src/signals/orphan-reparent.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAWxE;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,CAmC7E;AA+FD;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,gBAAgB,EAAE,MAAM,EACxB,iBAAiB,EAAE,MAAM,GACxB,IAAI,CAsDN"}