@grackle-ai/plugin-core 0.96.3

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 (122) hide show
  1. package/dist/codespace-handlers.d.ts +6 -0
  2. package/dist/codespace-handlers.d.ts.map +1 -0
  3. package/dist/codespace-handlers.js +66 -0
  4. package/dist/codespace-handlers.js.map +1 -0
  5. package/dist/cron-phase.d.ts +46 -0
  6. package/dist/cron-phase.d.ts.map +1 -0
  7. package/dist/cron-phase.js +88 -0
  8. package/dist/cron-phase.js.map +1 -0
  9. package/dist/dispatch-phase.d.ts +46 -0
  10. package/dist/dispatch-phase.d.ts.map +1 -0
  11. package/dist/dispatch-phase.js +99 -0
  12. package/dist/dispatch-phase.js.map +1 -0
  13. package/dist/environment-handlers.d.ts +16 -0
  14. package/dist/environment-handlers.d.ts.map +1 -0
  15. package/dist/environment-handlers.js +255 -0
  16. package/dist/environment-handlers.js.map +1 -0
  17. package/dist/environment-reconciliation.d.ts +35 -0
  18. package/dist/environment-reconciliation.d.ts.map +1 -0
  19. package/dist/environment-reconciliation.js +74 -0
  20. package/dist/environment-reconciliation.js.map +1 -0
  21. package/dist/escalation-handlers.d.ts +8 -0
  22. package/dist/escalation-handlers.d.ts.map +1 -0
  23. package/dist/escalation-handlers.js +60 -0
  24. package/dist/escalation-handlers.js.map +1 -0
  25. package/dist/finding-handlers.d.ts +8 -0
  26. package/dist/finding-handlers.d.ts.map +1 -0
  27. package/dist/finding-handlers.js +38 -0
  28. package/dist/finding-handlers.js.map +1 -0
  29. package/dist/grpc-proto-converters.d.ts +31 -0
  30. package/dist/grpc-proto-converters.d.ts.map +1 -0
  31. package/dist/grpc-proto-converters.js +222 -0
  32. package/dist/grpc-proto-converters.js.map +1 -0
  33. package/dist/grpc-service.d.ts +21 -0
  34. package/dist/grpc-service.d.ts.map +1 -0
  35. package/dist/grpc-service.js +50 -0
  36. package/dist/grpc-service.js.map +1 -0
  37. package/dist/grpc-shared.d.ts +22 -0
  38. package/dist/grpc-shared.d.ts.map +1 -0
  39. package/dist/grpc-shared.js +68 -0
  40. package/dist/grpc-shared.js.map +1 -0
  41. package/dist/index.d.ts +20 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +20 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/knowledge-handlers.d.ts +12 -0
  46. package/dist/knowledge-handlers.d.ts.map +1 -0
  47. package/dist/knowledge-handlers.js +149 -0
  48. package/dist/knowledge-handlers.js.map +1 -0
  49. package/dist/lifecycle-cleanup.d.ts +13 -0
  50. package/dist/lifecycle-cleanup.d.ts.map +1 -0
  51. package/dist/lifecycle-cleanup.js +35 -0
  52. package/dist/lifecycle-cleanup.js.map +1 -0
  53. package/dist/lifecycle.d.ts +28 -0
  54. package/dist/lifecycle.d.ts.map +1 -0
  55. package/dist/lifecycle.js +132 -0
  56. package/dist/lifecycle.js.map +1 -0
  57. package/dist/orphan-phase.d.ts +27 -0
  58. package/dist/orphan-phase.d.ts.map +1 -0
  59. package/dist/orphan-phase.js +69 -0
  60. package/dist/orphan-phase.js.map +1 -0
  61. package/dist/persona-handlers.d.ts +12 -0
  62. package/dist/persona-handlers.d.ts.map +1 -0
  63. package/dist/persona-handlers.js +156 -0
  64. package/dist/persona-handlers.js.map +1 -0
  65. package/dist/root-task-boot.d.ts +67 -0
  66. package/dist/root-task-boot.d.ts.map +1 -0
  67. package/dist/root-task-boot.js +234 -0
  68. package/dist/root-task-boot.js.map +1 -0
  69. package/dist/schedule-expression.d.ts +43 -0
  70. package/dist/schedule-expression.d.ts.map +1 -0
  71. package/dist/schedule-expression.js +105 -0
  72. package/dist/schedule-expression.js.map +1 -0
  73. package/dist/schedule-handlers.d.ts +12 -0
  74. package/dist/schedule-handlers.d.ts.map +1 -0
  75. package/dist/schedule-handlers.js +122 -0
  76. package/dist/schedule-handlers.js.map +1 -0
  77. package/dist/session-handlers.d.ts +40 -0
  78. package/dist/session-handlers.d.ts.map +1 -0
  79. package/dist/session-handlers.js +610 -0
  80. package/dist/session-handlers.js.map +1 -0
  81. package/dist/settings-handlers.d.ts +10 -0
  82. package/dist/settings-handlers.d.ts.map +1 -0
  83. package/dist/settings-handlers.js +80 -0
  84. package/dist/settings-handlers.js.map +1 -0
  85. package/dist/signals/escalation-auto.d.ts +20 -0
  86. package/dist/signals/escalation-auto.d.ts.map +1 -0
  87. package/dist/signals/escalation-auto.js +126 -0
  88. package/dist/signals/escalation-auto.js.map +1 -0
  89. package/dist/signals/orphan-reparent.d.ts +31 -0
  90. package/dist/signals/orphan-reparent.d.ts.map +1 -0
  91. package/dist/signals/orphan-reparent.js +175 -0
  92. package/dist/signals/orphan-reparent.js.map +1 -0
  93. package/dist/signals/sigchld.d.ts +12 -0
  94. package/dist/signals/sigchld.d.ts.map +1 -0
  95. package/dist/signals/sigchld.js +177 -0
  96. package/dist/signals/sigchld.js.map +1 -0
  97. package/dist/task-handlers.d.ts +22 -0
  98. package/dist/task-handlers.d.ts.map +1 -0
  99. package/dist/task-handlers.js +517 -0
  100. package/dist/task-handlers.js.map +1 -0
  101. package/dist/test-utils/integration-setup.d.ts +11 -0
  102. package/dist/test-utils/integration-setup.d.ts.map +1 -0
  103. package/dist/test-utils/integration-setup.js +26 -0
  104. package/dist/test-utils/integration-setup.js.map +1 -0
  105. package/dist/test-utils/mock-database.d.ts +152 -0
  106. package/dist/test-utils/mock-database.d.ts.map +1 -0
  107. package/dist/test-utils/mock-database.js +169 -0
  108. package/dist/test-utils/mock-database.js.map +1 -0
  109. package/dist/token-handlers.d.ts +12 -0
  110. package/dist/token-handlers.d.ts.map +1 -0
  111. package/dist/token-handlers.js +85 -0
  112. package/dist/token-handlers.js.map +1 -0
  113. package/dist/tsdoc-metadata.json +11 -0
  114. package/dist/utils/format-gh-error.d.ts +6 -0
  115. package/dist/utils/format-gh-error.d.ts.map +1 -0
  116. package/dist/utils/format-gh-error.js +30 -0
  117. package/dist/utils/format-gh-error.js.map +1 -0
  118. package/dist/workspace-handlers.d.ts +16 -0
  119. package/dist/workspace-handlers.d.ts.map +1 -0
  120. package/dist/workspace-handlers.js +146 -0
  121. package/dist/workspace-handlers.js.map +1 -0
  122. package/package.json +60 -0
@@ -0,0 +1,517 @@
1
+ import { ConnectError, Code } from "@connectrpc/connect";
2
+ import { create } from "@bufbuild/protobuf";
3
+ import { grackle, powerline } from "@grackle-ai/common";
4
+ import { DEFAULT_MCP_PORT, SESSION_STATUS, TERMINAL_SESSION_STATUSES, END_REASON, TASK_STATUS, ROOT_TASK_ID, ROOT_TASK_INITIAL_PROMPT, MAX_TASK_DEPTH, LOGS_DIR, taskStatusToString, } from "@grackle-ai/common";
5
+ import { envRegistry, sessionStore, taskStore, workspaceStore, personaStore, settingsStore, dispatchQueueStore, grackleHome, slugify, safeParseJsonArray } from "@grackle-ai/database";
6
+ import { v4 as uuid } from "uuid";
7
+ import { join } from "node:path";
8
+ import { adapterManager } from "@grackle-ai/core";
9
+ import { streamHub } from "@grackle-ai/core";
10
+ import { streamRegistry } from "@grackle-ai/core";
11
+ import { tokenPush } from "@grackle-ai/core";
12
+ import { emit } from "@grackle-ai/core";
13
+ import { processEventStream } from "@grackle-ai/core";
14
+ import { processorRegistry } from "@grackle-ai/core";
15
+ import { logger } from "@grackle-ai/core";
16
+ import { getTraceId } from "@grackle-ai/core";
17
+ import { resolvePersona, buildOrchestratorContext, SystemPromptBuilder, buildTaskPrompt } from "@grackle-ai/prompt";
18
+ import { toPersonaResolveInput, buildOrchestratorContextInput } from "@grackle-ai/core";
19
+ import { createScopedToken, loadOrCreateApiKey } from "@grackle-ai/auth";
20
+ import { cleanupLifecycleStream, ensureLifecycleStream } from "./lifecycle.js";
21
+ import { ensureAsyncDeliveryListener } from "@grackle-ai/core";
22
+ import { ensureStdinStream } from "@grackle-ai/core";
23
+ import { computeTaskStatus } from "@grackle-ai/core";
24
+ import { transferAllPipeSubscriptions } from "./signals/orphan-reparent.js";
25
+ import { taskRowToProto, sessionRowToProto } from "./grpc-proto-converters.js";
26
+ import { validatePipeInputs, toDialableHost, resolveAncestorEnvironmentId } from "./grpc-shared.js";
27
+ import { personaMcpServersToJson } from "@grackle-ai/core";
28
+ import { hasCapacity, checkBudget } from "@grackle-ai/core";
29
+ /** List tasks, optionally filtered by workspace, search query, or status. */
30
+ export async function listTasks(req) {
31
+ const rows = taskStore.listTasks(req.workspaceId || undefined, {
32
+ search: req.search || undefined,
33
+ status: req.status || undefined,
34
+ });
35
+ const childIdsMap = taskStore.buildChildIdsMap(rows);
36
+ // Batch-fetch sessions for all tasks and group by taskId
37
+ const taskIds = rows.map((r) => r.id);
38
+ const allSessions = sessionStore.listSessionsByTaskIds(taskIds);
39
+ const sessionsByTask = new Map();
40
+ for (const s of allSessions) {
41
+ const arr = sessionsByTask.get(s.taskId) ?? [];
42
+ arr.push(s);
43
+ sessionsByTask.set(s.taskId, arr);
44
+ }
45
+ return create(grackle.TaskListSchema, {
46
+ tasks: rows.map((r) => {
47
+ const taskSessions = sessionsByTask.get(r.id) ?? [];
48
+ const { status, latestSessionId } = computeTaskStatus(r.status, taskSessions);
49
+ return taskRowToProto(r, childIdsMap.get(r.id) ?? [], status, latestSessionId);
50
+ }),
51
+ });
52
+ }
53
+ /** Create a new task. */
54
+ export async function createTask(req) {
55
+ if (!req.title) {
56
+ throw new ConnectError("title is required", Code.InvalidArgument);
57
+ }
58
+ const workspaceId = req.workspaceId || undefined;
59
+ let workspace;
60
+ if (workspaceId) {
61
+ workspace = workspaceStore.getWorkspace(workspaceId);
62
+ if (!workspace) {
63
+ throw new ConnectError(`Workspace not found: ${workspaceId}`, Code.NotFound);
64
+ }
65
+ }
66
+ // Validate parent task if specified
67
+ if (req.parentTaskId) {
68
+ const parent = taskStore.getTask(req.parentTaskId);
69
+ if (!parent) {
70
+ throw new ConnectError(`Parent task not found: ${req.parentTaskId}`, Code.NotFound);
71
+ }
72
+ if (!parent.canDecompose) {
73
+ throw new ConnectError(`Parent task "${parent.title}" (${req.parentTaskId}) does not have decomposition rights`, Code.FailedPrecondition);
74
+ }
75
+ if (parent.depth + 1 > MAX_TASK_DEPTH) {
76
+ throw new ConnectError(`Task depth would exceed maximum of ${MAX_TASK_DEPTH}`, Code.FailedPrecondition);
77
+ }
78
+ }
79
+ if ((req.tokenBudget ?? 0) < 0 || (req.costBudgetMillicents ?? 0) < 0) {
80
+ throw new ConnectError("Budget values must be >= 0", Code.InvalidArgument);
81
+ }
82
+ const id = uuid().slice(0, 8);
83
+ taskStore.createTask(id, workspaceId, req.title, req.description, [...req.dependsOn], workspace ? slugify(workspace.name) : "", req.parentTaskId,
84
+ // Default to false (no decomposition rights) unless explicitly granted.
85
+ // Orchestrator/root processes that need fork() must opt in.
86
+ req.canDecompose ?? false, req.defaultPersonaId ?? "", req.tokenBudget ?? 0, req.costBudgetMillicents ?? 0);
87
+ const row = taskStore.getTask(id);
88
+ emit("task.created", { taskId: id, workspaceId: req.workspaceId });
89
+ logger.info({ taskId: id, workspaceId: req.workspaceId }, "Task created");
90
+ return taskRowToProto(row);
91
+ }
92
+ /** Get a task by ID with computed status. */
93
+ export async function getTask(req) {
94
+ const row = taskStore.getTask(req.id);
95
+ if (!row) {
96
+ throw new ConnectError(`Task not found: ${req.id}`, Code.NotFound);
97
+ }
98
+ const taskSessions = sessionStore.listSessionsForTask(req.id);
99
+ const { status, latestSessionId } = computeTaskStatus(row.status, taskSessions);
100
+ return taskRowToProto(row, undefined, status, latestSessionId);
101
+ }
102
+ /** Update task fields or late-bind a session to a task. */
103
+ export async function updateTask(req) {
104
+ const existing = taskStore.getTask(req.id);
105
+ if (!existing) {
106
+ throw new ConnectError(`Task not found: ${req.id}`, Code.NotFound);
107
+ }
108
+ let reqStatus = existing.status;
109
+ if (req.status !== grackle.TaskStatus.UNSPECIFIED) {
110
+ if (req.id === ROOT_TASK_ID) {
111
+ throw new ConnectError("Cannot change the status of the system task", Code.PermissionDenied);
112
+ }
113
+ const converted = taskStatusToString(req.status);
114
+ if (!converted) {
115
+ throw new ConnectError(`Unknown task status enum value: ${req.status}`, Code.InvalidArgument);
116
+ }
117
+ reqStatus = converted;
118
+ }
119
+ taskStore.updateTask(req.id, req.title !== "" ? req.title : existing.title, req.description !== "" ? req.description : existing.description, reqStatus, req.dependsOn.length > 0
120
+ ? [...req.dependsOn]
121
+ : safeParseJsonArray(existing.dependsOn), req.defaultPersonaId);
122
+ // Update budget fields if explicitly set in the request (proto3 optional presence)
123
+ if ((req.tokenBudget !== undefined && req.tokenBudget < 0) || (req.costBudgetMillicents !== undefined && req.costBudgetMillicents < 0)) {
124
+ throw new ConnectError("Budget values must be >= 0", Code.InvalidArgument);
125
+ }
126
+ if (req.tokenBudget !== undefined || req.costBudgetMillicents !== undefined) {
127
+ taskStore.updateTaskBudget(req.id, req.tokenBudget ?? existing.tokenBudget, req.costBudgetMillicents ?? existing.costBudgetMillicents);
128
+ }
129
+ // Late-bind: associate an existing session with this task
130
+ if (req.sessionId !== "") {
131
+ const session = sessionStore.getSession(req.sessionId);
132
+ if (!session) {
133
+ throw new ConnectError(`Session not found: ${req.sessionId}`, Code.NotFound);
134
+ }
135
+ if (TERMINAL_SESSION_STATUSES.has(session.status)) {
136
+ throw new ConnectError(`Cannot bind terminal session ${req.sessionId} (status: ${session.status})`, Code.FailedPrecondition);
137
+ }
138
+ // Verify the processor exists before mutating DB state to avoid partial updates
139
+ if (!processorRegistry.get(req.sessionId)) {
140
+ throw new ConnectError(`No active event processor for session ${req.sessionId}`, Code.FailedPrecondition);
141
+ }
142
+ sessionStore.setSessionTask(req.sessionId, req.id);
143
+ processorRegistry.lateBind(req.sessionId, req.id, existing.workspaceId || undefined);
144
+ emit("task.started", { taskId: req.id, sessionId: req.sessionId, workspaceId: existing.workspaceId || "" });
145
+ }
146
+ emit("task.updated", { taskId: req.id, workspaceId: existing.workspaceId || "" });
147
+ logger.info({ taskId: req.id }, "Task updated");
148
+ const row = taskStore.getTask(req.id);
149
+ const taskSessions = sessionStore.listSessionsForTask(req.id);
150
+ const { status, latestSessionId } = computeTaskStatus(row.status, taskSessions);
151
+ return taskRowToProto(row, undefined, status, latestSessionId);
152
+ }
153
+ /** Start a task by spawning a new agent session. */
154
+ export async function startTask(req) {
155
+ const task = taskStore.getTask(req.taskId);
156
+ if (!task) {
157
+ throw new ConnectError(`Task not found: ${req.taskId}`, Code.NotFound);
158
+ }
159
+ {
160
+ const taskSessions = sessionStore.listSessionsForTask(req.taskId);
161
+ const { status: effectiveStatus } = computeTaskStatus(task.status, taskSessions);
162
+ if (req.taskId === ROOT_TASK_ID) {
163
+ // Root task is always re-startable unless actively working
164
+ if (effectiveStatus === TASK_STATUS.WORKING) {
165
+ throw new ConnectError("System is already running", Code.FailedPrecondition);
166
+ }
167
+ }
168
+ else if (![TASK_STATUS.NOT_STARTED, TASK_STATUS.FAILED].includes(effectiveStatus)) {
169
+ throw new ConnectError(`Task ${req.taskId} cannot be started (status: ${effectiveStatus})`, Code.FailedPrecondition);
170
+ }
171
+ }
172
+ if (!taskStore.areDependenciesMet(req.taskId)) {
173
+ throw new ConnectError(`Task ${req.taskId} has unmet dependencies`, Code.FailedPrecondition);
174
+ }
175
+ // ── Pre-spawn budget check ──
176
+ const budgetResult = checkBudget(req.taskId, task.workspaceId || undefined);
177
+ if (budgetResult) {
178
+ throw new ConnectError(`Budget exceeded (${budgetResult.scope} ${budgetResult.reason}): ${budgetResult.message}`, Code.ResourceExhausted);
179
+ }
180
+ const workspace = task.workspaceId ? workspaceStore.getWorkspace(task.workspaceId) : undefined;
181
+ if (task.workspaceId && !workspace) {
182
+ throw new ConnectError(`Workspace not found: ${task.workspaceId}`, Code.NotFound);
183
+ }
184
+ const environmentId = req.environmentId
185
+ || resolveAncestorEnvironmentId(task.parentTaskId)
186
+ || workspace?.environmentId
187
+ || "";
188
+ if (!environmentId) {
189
+ throw new ConnectError("No environment specified for task, ancestor, or workspace", Code.FailedPrecondition);
190
+ }
191
+ const conn = adapterManager.getConnection(environmentId);
192
+ if (!conn) {
193
+ throw new ConnectError(`Environment ${environmentId} not connected`, Code.FailedPrecondition);
194
+ }
195
+ // Resolve persona via cascade (request → task → workspace → app default)
196
+ let resolved;
197
+ try {
198
+ resolved = resolvePersona(req.personaId, task.defaultPersonaId, workspace?.defaultPersonaId || "", settingsStore.getSetting("default_persona_id") || undefined, (id) => toPersonaResolveInput(personaStore.getPersona(id)));
199
+ }
200
+ catch (err) {
201
+ throw new ConnectError(err.message, Code.FailedPrecondition);
202
+ }
203
+ // Validate pipe inputs before creating the session
204
+ validatePipeInputs(req.pipe, req.parentSessionId);
205
+ const taskPipeMode = req.pipe;
206
+ // ── Concurrency gate (hybrid fast-path) ──────────────────
207
+ // Pipe-mode tasks bypass the queue because the parent agent is waiting
208
+ // synchronously for the child session to start.
209
+ if (!taskPipeMode) {
210
+ const concurrencyDeps = {
211
+ countActiveForEnvironment: sessionStore.countActiveForEnvironment,
212
+ getEnvironment: (id) => envRegistry.getEnvironment(id),
213
+ getSetting: settingsStore.getSetting,
214
+ };
215
+ if (!hasCapacity(environmentId, concurrencyDeps)) {
216
+ dispatchQueueStore.enqueue({
217
+ id: uuid(),
218
+ taskId: task.id,
219
+ environmentId,
220
+ personaId: resolved.personaId,
221
+ notes: req.notes || "",
222
+ });
223
+ logger.info({ taskId: task.id, environmentId }, "Task queued (environment at capacity)");
224
+ throw new ConnectError("Environment at capacity; task queued for dispatch", Code.ResourceExhausted);
225
+ }
226
+ // If this task was previously enqueued but we now have capacity,
227
+ // remove the stale queue entry to prevent duplicate dispatch.
228
+ dispatchQueueStore.dequeue(task.id);
229
+ }
230
+ const env = envRegistry.getEnvironment(environmentId);
231
+ const sessionId = uuid();
232
+ const { runtime, model, maxTurns, systemPrompt } = resolved;
233
+ const logPath = join(grackleHome, LOGS_DIR, sessionId);
234
+ // Root task always starts with the hardcoded greeting prompt; user messages
235
+ // are sent as follow-ups via sendInput. Other tasks use buildTaskPrompt.
236
+ const taskPrompt = task.id === ROOT_TASK_ID
237
+ ? ROOT_TASK_INITIAL_PROMPT
238
+ : buildTaskPrompt(task.title, task.description, req.notes);
239
+ const isOrchestrator = task.canDecompose && task.depth <= 1 && !!task.workspaceId;
240
+ const orchestratorCtx = isOrchestrator
241
+ ? buildOrchestratorContext(buildOrchestratorContextInput(task.workspaceId, workspace ? { name: workspace.name, description: workspace.description, repoUrl: workspace.repoUrl } : undefined))
242
+ : undefined;
243
+ const systemContext = new SystemPromptBuilder({
244
+ task: { title: task.title, description: task.description, notes: task.id === ROOT_TASK_ID ? "" : (req.notes || "") },
245
+ taskId: task.id,
246
+ canDecompose: task.canDecompose,
247
+ personaPrompt: systemPrompt,
248
+ taskDepth: task.depth,
249
+ workpad: task.workpad || undefined,
250
+ ...orchestratorCtx,
251
+ ...(orchestratorCtx && { triggerMode: "fresh" }),
252
+ }).build();
253
+ sessionStore.createSession(sessionId, environmentId, runtime, task.title, model, logPath, task.id, resolved.personaId, req.parentSessionId || "", // parentSessionId
254
+ taskPipeMode || "");
255
+ emit("task.started", { taskId: task.id, sessionId, workspaceId: task.workspaceId || "" });
256
+ // Re-push stored tokens + provider credentials (scoped to runtime) so they're fresh for this session.
257
+ // For local envs, skip file tokens — the PowerLine is on the same machine.
258
+ await tokenPush.refreshTokensForTask(environmentId, runtime, env?.adapterType === "local" ? { excludeFileTokens: true } : undefined);
259
+ const mcpServersJson = personaMcpServersToJson(resolved.mcpServers, resolved.personaId);
260
+ const useWorktrees = workspace?.useWorktrees ?? false;
261
+ if (!useWorktrees) {
262
+ logger.warn({ taskId: task.id, workspaceId: task.workspaceId, branch: task.branch }, "Worktrees disabled for workspace — agent will work in main checkout. Concurrent tasks on the same environment may conflict.");
263
+ }
264
+ const taskMcpPort = parseInt(process.env.GRACKLE_MCP_PORT || String(DEFAULT_MCP_PORT), 10);
265
+ const taskMcpDialHost = toDialableHost(process.env.GRACKLE_HOST || "127.0.0.1");
266
+ const taskMcpUrl = `http://${taskMcpDialHost}:${taskMcpPort}/mcp`;
267
+ const taskMcpToken = createScopedToken({ sub: task.id, pid: task.workspaceId || "", per: resolved.personaId, sid: sessionId }, loadOrCreateApiKey(grackleHome));
268
+ const powerlineReq = create(powerline.SpawnRequestSchema, {
269
+ sessionId,
270
+ runtime,
271
+ prompt: taskPrompt,
272
+ model,
273
+ maxTurns,
274
+ branch: task.branch,
275
+ workingDirectory: task.branch
276
+ ? (workspace?.workingDirectory || process.env.GRACKLE_WORKTREE_BASE || "/workspace")
277
+ : "",
278
+ useWorktrees,
279
+ systemContext,
280
+ workspaceId: task.workspaceId ?? undefined,
281
+ taskId: task.id,
282
+ mcpServersJson,
283
+ mcpUrl: taskMcpUrl,
284
+ mcpToken: taskMcpToken,
285
+ scriptContent: resolved.type === "script" ? resolved.script : "",
286
+ pipe: req.pipe,
287
+ });
288
+ // Create lifecycle stream for the task session
289
+ const taskLifecycleStream = streamRegistry.createStream(`lifecycle:${sessionId}`);
290
+ const taskSpawnerId = req.parentSessionId || "__server__";
291
+ streamRegistry.subscribe(taskLifecycleStream.id, taskSpawnerId, "rw", "detach", true);
292
+ streamRegistry.subscribe(taskLifecycleStream.id, sessionId, "rw", "detach", false);
293
+ // Create stdin stream — routes human input through the stream-registry
294
+ ensureStdinStream(sessionId);
295
+ // Set up IPC pipe stream (optional)
296
+ let taskPipeFd = 0;
297
+ if (taskPipeMode && taskPipeMode !== "detach" && req.parentSessionId) {
298
+ const ipcStream = streamRegistry.createStream(`pipe:${sessionId}`);
299
+ const parentSub = streamRegistry.subscribe(ipcStream.id, req.parentSessionId, "rw", taskPipeMode === "sync" ? "sync" : "async", true);
300
+ streamRegistry.subscribe(ipcStream.id, sessionId, "rw", "async", false);
301
+ taskPipeFd = parentSub.fd;
302
+ if (taskPipeMode === "async") {
303
+ ensureAsyncDeliveryListener(req.parentSessionId); // parent receives child messages
304
+ ensureAsyncDeliveryListener(sessionId); // child receives parent messages
305
+ }
306
+ }
307
+ processEventStream(conn.client.spawn(powerlineReq), {
308
+ sessionId,
309
+ logPath,
310
+ workspaceId: task.workspaceId ?? undefined,
311
+ taskId: task.id,
312
+ systemContext,
313
+ prompt: taskPrompt,
314
+ traceId: getTraceId(),
315
+ });
316
+ logger.info({ taskId: task.id, sessionId, workspaceId: task.workspaceId }, "Task started");
317
+ const row = sessionStore.getSession(sessionId);
318
+ const taskProto = sessionRowToProto(row);
319
+ taskProto.pipeFd = taskPipeFd;
320
+ return taskProto;
321
+ }
322
+ /** Mark a task as complete and clean up active sessions. */
323
+ export async function completeTask(req) {
324
+ if (req.id === ROOT_TASK_ID) {
325
+ throw new ConnectError("Cannot complete the system task", Code.PermissionDenied);
326
+ }
327
+ const task = taskStore.getTask(req.id);
328
+ if (!task) {
329
+ throw new ConnectError(`Task not found: ${req.id}`, Code.NotFound);
330
+ }
331
+ taskStore.markTaskComplete(task.id, TASK_STATUS.COMPLETE);
332
+ // Transfer ALL pipe fds from this task's sessions to the grandparent BEFORE
333
+ // closing sessions — once sessions are cleaned up, their subscriptions are gone.
334
+ // Always transfer regardless of orphaned tasks: ipc_spawn creates child sessions
335
+ // (not tasks), so pipe subs exist even when getOrphanedTasks returns empty.
336
+ const grandparentId = task.parentTaskId || ROOT_TASK_ID;
337
+ transferAllPipeSubscriptions(task.id, grandparentId);
338
+ // Close lifecycle FDs for any active sessions — cascades to STOPPED via orphan callback
339
+ const activeSessions = sessionStore.getActiveSessionsForTask(req.id);
340
+ for (const activeSession of activeSessions) {
341
+ cleanupLifecycleStream(activeSession.id);
342
+ const subs = streamRegistry.getSubscriptionsForSession(activeSession.id);
343
+ for (const sub of subs) {
344
+ streamRegistry.unsubscribe(sub.id);
345
+ }
346
+ }
347
+ // Check for newly unblocked tasks
348
+ if (task.workspaceId) {
349
+ const unblocked = taskStore.checkAndUnblock(task.workspaceId);
350
+ for (const t of unblocked) {
351
+ streamHub.publish(create(grackle.SessionEventSchema, {
352
+ sessionId: "",
353
+ type: grackle.EventType.SYSTEM,
354
+ timestamp: new Date().toISOString(),
355
+ content: JSON.stringify({
356
+ type: "task_unblocked",
357
+ taskId: t.id,
358
+ title: t.title,
359
+ }),
360
+ raw: "",
361
+ }));
362
+ }
363
+ }
364
+ emit("task.completed", { taskId: task.id, workspaceId: task.workspaceId || "" });
365
+ logger.info({ taskId: task.id }, "Task completed");
366
+ const row = taskStore.getTask(task.id);
367
+ const taskSessions = sessionStore.listSessionsForTask(task.id);
368
+ const { status, latestSessionId } = computeTaskStatus(row.status, taskSessions);
369
+ return taskRowToProto(row, undefined, status, latestSessionId);
370
+ }
371
+ /** Set the workpad JSON for a task. */
372
+ export async function setWorkpad(req) {
373
+ const task = taskStore.getTask(req.taskId);
374
+ if (!task) {
375
+ throw new ConnectError(`Task not found: ${req.taskId}`, Code.NotFound);
376
+ }
377
+ // Validate workpad is a valid JSON object
378
+ try {
379
+ const parsed = JSON.parse(req.workpad);
380
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
381
+ throw new ConnectError("Workpad must be a JSON object", Code.InvalidArgument);
382
+ }
383
+ }
384
+ catch (err) {
385
+ if (err instanceof ConnectError) {
386
+ throw err;
387
+ }
388
+ throw new ConnectError("Workpad must be valid JSON", Code.InvalidArgument);
389
+ }
390
+ const MAX_WORKPAD_BYTES = 64 * 1024; // 64 KB
391
+ const workpadBytes = Buffer.byteLength(req.workpad, "utf8");
392
+ if (workpadBytes > MAX_WORKPAD_BYTES) {
393
+ throw new ConnectError(`Workpad exceeds maximum size of ${MAX_WORKPAD_BYTES} bytes`, Code.InvalidArgument);
394
+ }
395
+ taskStore.setWorkpad(req.taskId, req.workpad);
396
+ const row = taskStore.getTask(req.taskId);
397
+ const taskSessions = sessionStore.listSessionsForTask(req.taskId);
398
+ const { status, latestSessionId } = computeTaskStatus(row.status, taskSessions);
399
+ return taskRowToProto(row, undefined, status, latestSessionId);
400
+ }
401
+ /** Resume the latest session for a task. */
402
+ export async function resumeTask(req) {
403
+ const task = taskStore.getTask(req.id);
404
+ if (!task) {
405
+ throw new ConnectError(`Task not found: ${req.id}`, Code.NotFound);
406
+ }
407
+ const latestSession = sessionStore.getLatestSessionForTask(req.id);
408
+ if (!latestSession) {
409
+ throw new ConnectError(`Task ${req.id} has no sessions to resume`, Code.FailedPrecondition);
410
+ }
411
+ if (![SESSION_STATUS.STOPPED, SESSION_STATUS.SUSPENDED].includes(latestSession.status)) {
412
+ throw new ConnectError(`Latest session ${latestSession.id} is not resumable (status: ${latestSession.status})`, Code.FailedPrecondition);
413
+ }
414
+ if (!latestSession.runtimeSessionId) {
415
+ throw new ConnectError(`Latest session ${latestSession.id} has no runtime session ID — cannot resume`, Code.FailedPrecondition);
416
+ }
417
+ const conn = adapterManager.getConnection(latestSession.environmentId);
418
+ if (!conn) {
419
+ throw new ConnectError(`Environment ${latestSession.environmentId} not connected`, Code.FailedPrecondition);
420
+ }
421
+ const powerlineReq = create(powerline.ResumeRequestSchema, {
422
+ sessionId: latestSession.id,
423
+ runtimeSessionId: latestSession.runtimeSessionId,
424
+ runtime: latestSession.runtime,
425
+ });
426
+ const logPath = latestSession.logPath || join(grackleHome, LOGS_DIR, latestSession.id);
427
+ // Initiate the stream before mutating the DB. If resume() throws
428
+ // synchronously the DB is never touched, so no rollback is needed.
429
+ const resumeStream = conn.client.resume(powerlineReq);
430
+ // Reset session DB row to RUNNING (clears endedAt, error, etc.)
431
+ sessionStore.reanimateSession(latestSession.id);
432
+ // Re-create lifecycle stream if it was deleted during kill/stop
433
+ const resumeSpawnerId = latestSession.parentSessionId || "__server__";
434
+ ensureLifecycleStream(latestSession.id, resumeSpawnerId);
435
+ processEventStream(resumeStream, {
436
+ sessionId: latestSession.id,
437
+ logPath,
438
+ workspaceId: task.workspaceId ?? undefined,
439
+ taskId: task.id,
440
+ traceId: getTraceId(),
441
+ });
442
+ emit("task.started", { taskId: task.id, sessionId: latestSession.id, workspaceId: task.workspaceId || "" });
443
+ logger.info({ taskId: task.id, sessionId: latestSession.id }, "Task resumed");
444
+ const row = sessionStore.getSession(latestSession.id);
445
+ return sessionRowToProto(row);
446
+ }
447
+ /** Stop a task by terminating all its active sessions. */
448
+ export async function stopTask(req) {
449
+ const task = taskStore.getTask(req.id);
450
+ if (!task) {
451
+ throw new ConnectError(`Task not found: ${req.id}`, Code.NotFound);
452
+ }
453
+ // Terminate all active sessions for this task using the fd-closure pattern
454
+ const activeSessions = sessionStore.getActiveSessionsForTask(req.id);
455
+ for (const activeSession of activeSessions) {
456
+ cleanupLifecycleStream(activeSession.id);
457
+ const subs = streamRegistry.getSubscriptionsForSession(activeSession.id);
458
+ for (const sub of subs) {
459
+ streamRegistry.unsubscribe(sub.id);
460
+ }
461
+ const current = sessionStore.getSession(activeSession.id);
462
+ if (current && !TERMINAL_SESSION_STATUSES.has(current.status)) {
463
+ sessionStore.updateSession(activeSession.id, SESSION_STATUS.STOPPED, undefined, undefined, END_REASON.INTERRUPTED);
464
+ streamHub.publish(create(grackle.SessionEventSchema, {
465
+ sessionId: activeSession.id,
466
+ type: grackle.EventType.STATUS,
467
+ timestamp: new Date().toISOString(),
468
+ content: END_REASON.INTERRUPTED,
469
+ raw: "",
470
+ }));
471
+ }
472
+ }
473
+ // Mark task complete
474
+ taskStore.markTaskComplete(req.id, TASK_STATUS.COMPLETE);
475
+ // Check for newly unblocked tasks
476
+ if (task.workspaceId) {
477
+ taskStore.checkAndUnblock(task.workspaceId);
478
+ }
479
+ emit("task.completed", { taskId: task.id, workspaceId: task.workspaceId || "" });
480
+ logger.info({ taskId: req.id }, "Task stopped");
481
+ const updated = taskStore.getTask(req.id);
482
+ const taskSessions = sessionStore.listSessionsForTask(req.id);
483
+ const { status, latestSessionId } = computeTaskStatus(updated.status, taskSessions);
484
+ return taskRowToProto(updated, undefined, status, latestSessionId);
485
+ }
486
+ /** Delete a task and all its sessions. */
487
+ export async function deleteTask(req) {
488
+ if (req.id === ROOT_TASK_ID) {
489
+ throw new ConnectError("Cannot delete the system task", Code.PermissionDenied);
490
+ }
491
+ const task = taskStore.getTask(req.id);
492
+ if (!task) {
493
+ throw new ConnectError(`Task not found: ${req.id}`, Code.NotFound);
494
+ }
495
+ const children = taskStore.getChildren(req.id);
496
+ if (children.length > 0) {
497
+ throw new ConnectError("Cannot delete task with children. Delete children first.", Code.FailedPrecondition);
498
+ }
499
+ // Terminate all active sessions via lifecycle cleanup before deleting the task
500
+ const activeSessions = sessionStore.getActiveSessionsForTask(req.id);
501
+ for (const activeSession of activeSessions) {
502
+ cleanupLifecycleStream(activeSession.id);
503
+ const subs = streamRegistry.getSubscriptionsForSession(activeSession.id);
504
+ for (const sub of subs) {
505
+ streamRegistry.unsubscribe(sub.id);
506
+ }
507
+ }
508
+ const changes = taskStore.deleteTask(req.id);
509
+ if (changes === 0) {
510
+ logger.error({ taskId: req.id }, "deleteTask returned 0 changes despite task existing");
511
+ throw new ConnectError(`Failed to delete task ${req.id}: no rows affected`, Code.Internal);
512
+ }
513
+ emit("task.deleted", { taskId: req.id, workspaceId: task.workspaceId || "" });
514
+ logger.info({ taskId: req.id }, "Task deleted");
515
+ return create(grackle.EmptySchema, {});
516
+ }
517
+ //# sourceMappingURL=task-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-handlers.js","sourceRoot":"","sources":["../src/task-handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Initialize an in-memory SQLite database with all tables and seed data.
3
+ * Call once in `beforeAll`.
4
+ */
5
+ export declare function initTestDatabase(): void;
6
+ /**
7
+ * Extract the service handler map for the Grackle service.
8
+ * Uses the {@link createDefaultCollector} to get all built-in handlers.
9
+ */
10
+ export declare function getHandlers(): Record<string, (...args: unknown[]) => unknown>;
11
+ //# sourceMappingURL=integration-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-setup.d.ts","sourceRoot":"","sources":["../../src/test-utils/integration-setup.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAE7E"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Shared setup for gRPC handler integration tests.
3
+ *
4
+ * Provides an in-memory SQLite database (real stores, no database mocks)
5
+ * and a helper to extract handler methods via {@link createDefaultCollector}.
6
+ */
7
+ import { openDatabase, initDatabase, sqlite, seedDatabase } from "@grackle-ai/database";
8
+ import { grackle } from "@grackle-ai/common";
9
+ import { createDefaultCollector } from "../grpc-service.js";
10
+ /**
11
+ * Initialize an in-memory SQLite database with all tables and seed data.
12
+ * Call once in `beforeAll`.
13
+ */
14
+ export function initTestDatabase() {
15
+ openDatabase(":memory:");
16
+ initDatabase();
17
+ seedDatabase(sqlite);
18
+ }
19
+ /**
20
+ * Extract the service handler map for the Grackle service.
21
+ * Uses the {@link createDefaultCollector} to get all built-in handlers.
22
+ */
23
+ export function getHandlers() {
24
+ return createDefaultCollector().getHandlers(grackle.Grackle);
25
+ }
26
+ //# sourceMappingURL=integration-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-setup.js","sourceRoot":"","sources":["../../src/test-utils/integration-setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,YAAY,CAAC,UAAU,CAAC,CAAC;IACzB,YAAY,EAAE,CAAC;IACf,YAAY,CAAC,MAAO,CAAC,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,sBAAsB,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAoD,CAAC;AAClH,CAAC"}