@grackle-ai/server 0.41.1 → 0.43.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 (42) hide show
  1. package/dist/db.d.ts.map +1 -1
  2. package/dist/db.js +55 -1
  3. package/dist/db.js.map +1 -1
  4. package/dist/event-processor.js +4 -4
  5. package/dist/event-processor.js.map +1 -1
  6. package/dist/grpc-service.d.ts.map +1 -1
  7. package/dist/grpc-service.js +43 -36
  8. package/dist/grpc-service.js.map +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +3 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/log-writer.d.ts +8 -0
  13. package/dist/log-writer.d.ts.map +1 -1
  14. package/dist/log-writer.js +12 -0
  15. package/dist/log-writer.js.map +1 -1
  16. package/dist/processor-registry.d.ts +2 -2
  17. package/dist/processor-registry.d.ts.map +1 -1
  18. package/dist/processor-registry.js.map +1 -1
  19. package/dist/reanimate-agent.js +1 -1
  20. package/dist/reanimate-agent.js.map +1 -1
  21. package/dist/schema.d.ts +1 -1
  22. package/dist/schema.d.ts.map +1 -1
  23. package/dist/schema.js +0 -1
  24. package/dist/schema.js.map +1 -1
  25. package/dist/settings-store.d.ts.map +1 -1
  26. package/dist/settings-store.js +1 -0
  27. package/dist/settings-store.js.map +1 -1
  28. package/dist/signals/sigchld.d.ts +7 -0
  29. package/dist/signals/sigchld.d.ts.map +1 -0
  30. package/dist/signals/sigchld.js +163 -0
  31. package/dist/signals/sigchld.js.map +1 -0
  32. package/dist/signals/signal-delivery.d.ts +14 -0
  33. package/dist/signals/signal-delivery.d.ts.map +1 -0
  34. package/dist/signals/signal-delivery.js +167 -0
  35. package/dist/signals/signal-delivery.js.map +1 -0
  36. package/dist/task-store.d.ts +5 -5
  37. package/dist/task-store.d.ts.map +1 -1
  38. package/dist/task-store.js +24 -12
  39. package/dist/task-store.js.map +1 -1
  40. package/dist/ws-bridge.js +40 -36
  41. package/dist/ws-bridge.js.map +1 -1
  42. package/package.json +9 -7
@@ -0,0 +1,167 @@
1
+ import { create } from "@bufbuild/protobuf";
2
+ import { grackle, powerline, SESSION_STATUS } from "@grackle-ai/common";
3
+ import * as sessionStore from "../session-store.js";
4
+ import * as adapterManager from "../adapter-manager.js";
5
+ import { reanimateAgent } from "../reanimate-agent.js";
6
+ import * as streamHub from "../stream-hub.js";
7
+ import * as logWriter from "../log-writer.js";
8
+ import { logger } from "../logger.js";
9
+ /** Timeout (ms) to wait for a reanimated session to reach IDLE. */
10
+ const REANIMATE_IDLE_TIMEOUT_MS = 60_000;
11
+ /** Statuses considered active (the agent can accept input). */
12
+ const ACTIVE_STATUSES = new Set([
13
+ SESSION_STATUS.IDLE,
14
+ SESSION_STATUS.RUNNING,
15
+ SESSION_STATUS.PENDING,
16
+ ]);
17
+ /**
18
+ * Deliver a signal message to a task's agent session.
19
+ *
20
+ * Active session (IDLE/RUNNING/PENDING) → sendInput bypassing the IDLE guard.
21
+ * Dead session (COMPLETED/FAILED/INTERRUPTED) → reanimate + wait for IDLE + sendInput.
22
+ * No session at all → log warning, return false.
23
+ *
24
+ * @param taskId - Target task whose session should receive the signal.
25
+ * @param signalType - Signal kind for logging (e.g. "sigchld").
26
+ * @param message - The text content to deliver as user input.
27
+ * @returns true if the message was sent, false otherwise.
28
+ */
29
+ export async function deliverSignalToTask(taskId, signalType, message) {
30
+ // ── 1. Try an active session ──────────────────────────────
31
+ const activeSessions = sessionStore.getActiveSessionsForTask(taskId);
32
+ if (activeSessions.length > 0) {
33
+ const session = activeSessions[0];
34
+ return await sendInputToSession(session.id, session.environmentId, message, signalType);
35
+ }
36
+ // ── 2. Try reanimating the latest terminal session ────────
37
+ const latest = sessionStore.getLatestSessionForTask(taskId);
38
+ if (!latest) {
39
+ logger.warn({ taskId, signalType }, "No session exists for task — signal dropped");
40
+ return false;
41
+ }
42
+ if (ACTIVE_STATUSES.has(latest.status)) {
43
+ // Should not happen (getActiveSessionsForTask would have found it),
44
+ // but handle it defensively.
45
+ return await sendInputToSession(latest.id, latest.environmentId, message, signalType);
46
+ }
47
+ if (!latest.runtimeSessionId) {
48
+ logger.warn({ taskId, sessionId: latest.id, signalType }, "Latest session has no runtimeSessionId — cannot reanimate, signal dropped");
49
+ return false;
50
+ }
51
+ // Subscribe to the session stream BEFORE reanimating so we don't miss
52
+ // the waiting_input event if the runtime reaches IDLE quickly (e.g. stub).
53
+ const idleWaiter = waitForSessionIdle(latest.id, REANIMATE_IDLE_TIMEOUT_MS);
54
+ try {
55
+ reanimateAgent(latest.id);
56
+ }
57
+ catch (err) {
58
+ idleWaiter.cancel();
59
+ logger.error({ err, taskId, sessionId: latest.id, signalType }, "Failed to reanimate session for signal delivery");
60
+ return false;
61
+ }
62
+ // Wait for the reanimated session to reach IDLE
63
+ const reachedIdle = await idleWaiter.promise;
64
+ if (!reachedIdle) {
65
+ logger.error({ taskId, sessionId: latest.id, signalType }, "Reanimated session did not reach IDLE within timeout — signal dropped");
66
+ return false;
67
+ }
68
+ return await sendInputToSession(latest.id, latest.environmentId, message, signalType);
69
+ }
70
+ /**
71
+ * Send input text to a session via its environment's PowerLine connection.
72
+ * Bypasses the server-side IDLE guard — the agent runtime accepts input at any
73
+ * time and picks it up at the next turn boundary.
74
+ */
75
+ async function sendInputToSession(sessionId, environmentId, text, signalType) {
76
+ const conn = adapterManager.getConnection(environmentId);
77
+ if (!conn) {
78
+ logger.error({ sessionId, environmentId, signalType }, "Environment not connected — signal delivery failed");
79
+ return false;
80
+ }
81
+ try {
82
+ // Record the signal as a user_input event in the session log and stream,
83
+ // matching the pattern used by the WS bridge for regular user input.
84
+ const session = sessionStore.getSession(sessionId);
85
+ const userInputEvent = create(grackle.SessionEventSchema, {
86
+ sessionId,
87
+ type: grackle.EventType.USER_INPUT,
88
+ timestamp: new Date().toISOString(),
89
+ content: text,
90
+ });
91
+ if (session?.logPath) {
92
+ // Ensure the stream is open before writing — the session may still be
93
+ // PENDING and processEventStream may not have called initLog yet.
94
+ logWriter.ensureLogInitialized(session.logPath);
95
+ logWriter.writeEvent(session.logPath, userInputEvent);
96
+ }
97
+ streamHub.publish(userInputEvent);
98
+ await conn.client.sendInput(create(powerline.InputMessageSchema, { sessionId, text }));
99
+ logger.info({ sessionId, signalType }, "Signal delivered to session");
100
+ return true;
101
+ }
102
+ catch (err) {
103
+ logger.error({ err, sessionId, signalType }, "sendInput failed during signal delivery");
104
+ return false;
105
+ }
106
+ }
107
+ /**
108
+ * Begin watching for a session to reach IDLE status via StreamHub events.
109
+ * Subscribes immediately so events are captured even before the caller starts
110
+ * the session (e.g. via reanimateAgent).
111
+ */
112
+ function waitForSessionIdle(sessionId, timeoutMs) {
113
+ const stream = streamHub.createStream(sessionId);
114
+ let timer;
115
+ const promise = (async () => {
116
+ // Check DB after subscribing to close the race window.
117
+ const current = sessionStore.getSession(sessionId);
118
+ if (current?.status === SESSION_STATUS.IDLE) {
119
+ stream.cancel();
120
+ return true;
121
+ }
122
+ try {
123
+ return await Promise.race([
124
+ (async () => {
125
+ for await (const event of stream) {
126
+ // Only inspect status events — other event types (text, tool_use, etc.)
127
+ // can have arbitrary content that might accidentally match status strings.
128
+ if (event.type !== grackle.EventType.STATUS) {
129
+ continue;
130
+ }
131
+ // "waiting_input" is the runtime status that maps to IDLE in the session store.
132
+ if (event.content === "waiting_input") {
133
+ return true;
134
+ }
135
+ // If the session hit a terminal state, stop waiting
136
+ if (["completed", "failed", "killed", "interrupted"].includes(event.content)) {
137
+ return false;
138
+ }
139
+ }
140
+ return false;
141
+ })(),
142
+ new Promise((resolve) => {
143
+ timer = setTimeout(() => {
144
+ stream.cancel();
145
+ resolve(false);
146
+ }, timeoutMs);
147
+ }),
148
+ ]);
149
+ }
150
+ finally {
151
+ if (timer !== undefined) {
152
+ clearTimeout(timer);
153
+ }
154
+ stream.cancel();
155
+ }
156
+ })();
157
+ return {
158
+ promise,
159
+ cancel: () => {
160
+ stream.cancel();
161
+ if (timer !== undefined) {
162
+ clearTimeout(timer);
163
+ }
164
+ },
165
+ };
166
+ }
167
+ //# sourceMappingURL=signal-delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-delivery.js","sourceRoot":"","sources":["../../src/signals/signal-delivery.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { type TaskRow } from "./schema.js";
2
2
  import type { TaskStatus } from "@grackle-ai/common";
3
3
  export type { TaskRow };
4
4
  /** Insert a new task with auto-generated branch name and sort order. */
5
- export declare function createTask(id: string, projectId: string, title: string, description: string, dependsOn: string[], projectSlug: string, parentTaskId?: string, canDecompose?: boolean, defaultPersonaId?: string): void;
5
+ export declare function createTask(id: string, projectId: string | undefined, title: string, description: string, dependsOn: string[], projectSlug: string, parentTaskId?: string, canDecompose?: boolean, defaultPersonaId?: string): void;
6
6
  /** Retrieve a single task by ID. */
7
7
  export declare function getTask(id: string): TaskRow | undefined;
8
8
  /** Options for filtering the task list. */
@@ -12,8 +12,8 @@ export interface ListTasksOptions {
12
12
  /** Exact match filter on task status (e.g. "not_started", "in_progress"). */
13
13
  status?: string;
14
14
  }
15
- /** Return tasks for a project, with optional search/status filters, ordered by sort_order then created_at. */
16
- export declare function listTasks(projectId: string, options?: ListTasksOptions): TaskRow[];
15
+ /** Return tasks for a project (or all tasks when projectId is omitted), with optional search/status filters, ordered by sort_order then created_at. */
16
+ export declare function listTasks(projectId?: string, options?: ListTasksOptions): TaskRow[];
17
17
  /** Update multiple task fields at once. */
18
18
  export declare function updateTask(id: string, title: string, description: string, status: string, dependsOn: string[], defaultPersonaId?: string): void;
19
19
  /** Update only the dependsOn array of a task. */
@@ -28,9 +28,9 @@ export declare function markTaskComplete(id: string, status?: "complete" | "fail
28
28
  /** Delete a task by ID. Returns the number of rows affected. */
29
29
  export declare function deleteTask(id: string): number;
30
30
  /** Return all not_started tasks whose dependencies are fully met. */
31
- export declare function getUnblockedTasks(projectId: string): TaskRow[];
31
+ export declare function getUnblockedTasks(projectId?: string): TaskRow[];
32
32
  /** Alias for getUnblockedTasks — check which pending tasks are now unblocked. */
33
- export declare function checkAndUnblock(projectId: string): TaskRow[];
33
+ export declare function checkAndUnblock(projectId?: string): TaskRow[];
34
34
  /** Check whether all dependencies of a task are in "complete" status. */
35
35
  export declare function areDependenciesMet(taskId: string): boolean;
36
36
  /** Build a map from parentTaskId to child IDs from a pre-fetched list of rows. Avoids N+1 queries. */
@@ -1 +1 @@
1
- {"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../src/task-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAKrD,YAAY,EAAE,OAAO,EAAE,CAAC;AAExB,wEAAwE;AACxE,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAAW,EACzB,YAAY,CAAC,EAAE,OAAO,EACtB,gBAAgB,GAAE,MAAW,GAC5B,IAAI,CAgDN;AAED,oCAAoC;AACpC,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAEvD;AAED,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,mHAAmH;IACnH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,8GAA8G;AAC9G,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,EAAE,CA+BlF;AAED,2CAA2C;AAC3C,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EAAE,EACnB,gBAAgB,CAAC,EAAE,MAAM,GACxB,IAAI,CAeN;AAED,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAQtE;AAED,mCAAmC;AACnC,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAQrE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,EACV,MAAM,GAAE,UAAU,GAAG,QAAqB,GACzC,IAAI,CASN;AAED,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,CAe9D;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,CAE5D;AAED,yEAAyE;AACzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAa1D;AAID,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAavE;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAOrD;AAED,2HAA2H;AAC3H,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CA0BxD;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAYtD;AAED,kDAAkD;AAClD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO3E"}
1
+ {"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../src/task-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAKrD,YAAY,EAAE,OAAO,EAAE,CAAC;AAExB,wEAAwE;AACxE,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAAW,EACzB,YAAY,CAAC,EAAE,OAAO,EACtB,gBAAgB,GAAE,MAAW,GAC5B,IAAI,CAsDN;AAED,oCAAoC;AACpC,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAEvD;AAED,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,mHAAmH;IACnH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,uJAAuJ;AACvJ,wBAAgB,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,EAAE,CAqCnF;AAED,2CAA2C;AAC3C,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EAAE,EACnB,gBAAgB,CAAC,EAAE,MAAM,GACxB,IAAI,CAeN;AAED,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAQtE;AAED,mCAAmC;AACnC,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAQrE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,EACV,MAAM,GAAE,UAAU,GAAG,QAAqB,GACzC,IAAI,CASN;AAED,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,CAe/D;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,CAE7D;AAED,yEAAyE;AACzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAa1D;AAID,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAavE;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAOrD;AAED,2HAA2H;AAC3H,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CA0BxD;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAYtD;AAED,kDAAkD;AAClD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO3E"}
@@ -24,21 +24,27 @@ export function createTask(id, projectId, title, description, dependsOn, project
24
24
  branch = `${parent.branch}/${slugify(title)}`;
25
25
  }
26
26
  else {
27
- branch = `${projectSlug}/${slugify(title)}`;
27
+ const prefix = projectSlug || "task";
28
+ branch = `${prefix}/${slugify(title)}`;
28
29
  }
29
30
  // Derive canDecompose when not explicitly set: root=true, child=false
30
31
  const resolvedCanDecompose = canDecompose ?? !parentTaskId;
31
32
  const depsJson = JSON.stringify(dependsOn);
32
- const maxRow = db
33
+ const sortOrderConditions = [];
34
+ if (projectId) {
35
+ sortOrderConditions.push(eq(tasks.projectId, projectId));
36
+ }
37
+ const maxRowQuery = db
33
38
  .select({ maxOrder: sql `max(sort_order)` })
34
- .from(tasks)
35
- .where(eq(tasks.projectId, projectId))
36
- .get();
39
+ .from(tasks);
40
+ const maxRow = sortOrderConditions.length > 0
41
+ ? maxRowQuery.where(and(...sortOrderConditions)).get()
42
+ : maxRowQuery.get();
37
43
  const sortOrder = (maxRow?.maxOrder ?? -1) + 1;
38
44
  db.insert(tasks)
39
45
  .values({
40
46
  id,
41
- projectId,
47
+ projectId: projectId || null,
42
48
  title,
43
49
  description,
44
50
  branch,
@@ -59,9 +65,12 @@ export function getTask(id) {
59
65
  function escapeLikePattern(value) {
60
66
  return value.replace(/[%_\\]/g, (ch) => `\\${ch}`);
61
67
  }
62
- /** Return tasks for a project, with optional search/status filters, ordered by sort_order then created_at. */
68
+ /** Return tasks for a project (or all tasks when projectId is omitted), with optional search/status filters, ordered by sort_order then created_at. */
63
69
  export function listTasks(projectId, options) {
64
- const conditions = [eq(tasks.projectId, projectId)];
70
+ const conditions = [];
71
+ if (projectId) {
72
+ conditions.push(eq(tasks.projectId, projectId));
73
+ }
65
74
  if (options?.status) {
66
75
  // Normalize legacy status aliases (e.g. "in_progress" → "working")
67
76
  const canonical = taskStatusToString(taskStatusToEnum(options.status));
@@ -78,10 +87,13 @@ export function listTasks(projectId, options) {
78
87
  const pattern = `%${escaped}%`;
79
88
  conditions.push(or(sql `${tasks.title} LIKE ${pattern} ESCAPE '\\'`, sql `${tasks.description} LIKE ${pattern} ESCAPE '\\'`));
80
89
  }
81
- return db
90
+ const query = db
82
91
  .select()
83
- .from(tasks)
84
- .where(and(...conditions))
92
+ .from(tasks);
93
+ const filtered = conditions.length > 0
94
+ ? query.where(and(...conditions))
95
+ : query;
96
+ return filtered
85
97
  .orderBy(asc(tasks.sortOrder), asc(tasks.createdAt))
86
98
  .all();
87
99
  }
@@ -209,7 +221,7 @@ export function getDescendants(taskId) {
209
221
  if (!task) {
210
222
  return [];
211
223
  }
212
- const allRows = listTasks(task.projectId);
224
+ const allRows = listTasks(task.projectId || undefined);
213
225
  const childIdsMap = buildChildIdsMap(allRows);
214
226
  const rowById = new Map(allRows.map((r) => [r.id, r]));
215
227
  const result = [];
@@ -1 +1 @@
1
- {"version":3,"file":"task-store.js","sourceRoot":"","sources":["../src/task-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"task-store.js","sourceRoot":"","sources":["../src/task-store.ts"],"names":[],"mappings":"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"}
package/dist/ws-bridge.js CHANGED
@@ -174,12 +174,12 @@ async function autoProvisionEnvironment(ws, environmentId, env, logContext) {
174
174
  * string for failures that need the caller to surface to the client.
175
175
  */
176
176
  async function startTaskSession(ws, task, options) {
177
- const project = projectStore.getProject(task.projectId);
178
- if (!project) {
177
+ const project = task.projectId ? projectStore.getProject(task.projectId) : undefined;
178
+ if (task.projectId && !project) {
179
179
  logger.warn({ taskId: task.id }, "startTaskSession failed: project not found");
180
180
  return `Project not found: ${task.projectId}`;
181
181
  }
182
- const environmentId = options?.environmentId || project.defaultEnvironmentId;
182
+ const environmentId = options?.environmentId || project?.defaultEnvironmentId || "";
183
183
  const env = envRegistry.getEnvironment(environmentId);
184
184
  if (!env) {
185
185
  logger.warn({ taskId: task.id, environmentId }, "startTaskSession failed: environment not found");
@@ -194,7 +194,7 @@ async function startTaskSession(ws, task, options) {
194
194
  // Resolve persona via cascade (request → task → project → app default)
195
195
  let resolved;
196
196
  try {
197
- resolved = resolvePersona(options?.personaId || "", task.defaultPersonaId, project.defaultPersonaId);
197
+ resolved = resolvePersona(options?.personaId || "", task.defaultPersonaId, project?.defaultPersonaId || "");
198
198
  }
199
199
  catch (err) {
200
200
  return err.message;
@@ -211,7 +211,7 @@ async function startTaskSession(ws, task, options) {
211
211
  emit("task.started", {
212
212
  taskId: freshTask.id,
213
213
  sessionId,
214
- projectId: freshTask.projectId,
214
+ projectId: freshTask.projectId || "",
215
215
  });
216
216
  // Re-push stored tokens + provider credentials (scoped to runtime) so they're fresh for this session.
217
217
  // For local envs, skip file tokens — the PowerLine is on the same machine.
@@ -233,7 +233,8 @@ async function startTaskSession(ws, task, options) {
233
233
  const mcpPort = parseInt(process.env.GRACKLE_MCP_PORT || String(DEFAULT_MCP_PORT), 10);
234
234
  const mcpDialHost = toDialableHost(process.env.GRACKLE_HOST || "127.0.0.1");
235
235
  const mcpUrl = `http://${mcpDialHost}:${mcpPort}/mcp`;
236
- const mcpToken = createScopedToken({ sub: freshTask.id, pid: freshTask.projectId, per: resolved.personaId, sid: sessionId }, loadOrCreateApiKey());
236
+ const mcpToken = createScopedToken({ sub: freshTask.id, pid: freshTask.projectId || "", per: resolved.personaId, sid: sessionId }, loadOrCreateApiKey());
237
+ const useWorktrees = project?.useWorktrees ?? false;
237
238
  const powerlineReq = create(powerline.SpawnRequestSchema, {
238
239
  sessionId,
239
240
  runtime,
@@ -241,11 +242,11 @@ async function startTaskSession(ws, task, options) {
241
242
  model,
242
243
  maxTurns,
243
244
  branch: freshTask.branch,
244
- worktreeBasePath: freshTask.branch
245
- ? (project.worktreeBasePath || process.env.GRACKLE_WORKTREE_BASE || "/workspace")
245
+ worktreeBasePath: freshTask.branch && useWorktrees
246
+ ? (project?.worktreeBasePath || process.env.GRACKLE_WORKTREE_BASE || "/workspace")
246
247
  : "",
247
248
  systemContext,
248
- projectId: freshTask.projectId,
249
+ projectId: freshTask.projectId ?? undefined,
249
250
  taskId: freshTask.id,
250
251
  mcpServersJson,
251
252
  mcpUrl,
@@ -254,7 +255,7 @@ async function startTaskSession(ws, task, options) {
254
255
  processEventStream(conn.client.spawn(powerlineReq), {
255
256
  sessionId,
256
257
  logPath,
257
- projectId: freshTask.projectId,
258
+ projectId: freshTask.projectId ?? undefined,
258
259
  taskId: freshTask.id,
259
260
  });
260
261
  return undefined;
@@ -529,7 +530,7 @@ async function handleMessage(ws, msg, subscriptions) {
529
530
  if (session.taskId) {
530
531
  const task = taskStore.getTask(session.taskId);
531
532
  if (task) {
532
- emit("task.updated", { taskId: task.id, projectId: task.projectId });
533
+ emit("task.updated", { taskId: task.id, projectId: task.projectId || "" });
533
534
  }
534
535
  }
535
536
  break;
@@ -716,7 +717,7 @@ async function handleMessage(ws, msg, subscriptions) {
716
717
  });
717
718
  return;
718
719
  }
719
- personaStore.updatePersona(updatePersonaId, msg.payload?.name || existingPersona.name, msg.payload?.description || existingPersona.description, msg.payload?.systemPrompt || existingPersona.systemPrompt, msg.payload?.toolConfig || existingPersona.toolConfig, msg.payload?.runtime || existingPersona.runtime, msg.payload?.model || existingPersona.model, msg.payload?.maxTurns || existingPersona.maxTurns, msg.payload?.mcpServers || existingPersona.mcpServers);
720
+ personaStore.updatePersona(updatePersonaId, msg.payload?.name ?? existingPersona.name, msg.payload?.description ?? existingPersona.description, msg.payload?.systemPrompt ?? existingPersona.systemPrompt, msg.payload?.toolConfig ?? existingPersona.toolConfig, msg.payload?.runtime ?? existingPersona.runtime, msg.payload?.model ?? existingPersona.model, msg.payload?.maxTurns ?? existingPersona.maxTurns, msg.payload?.mcpServers ?? existingPersona.mcpServers);
720
721
  emit("persona.updated", { personaId: updatePersonaId });
721
722
  break;
722
723
  }
@@ -768,9 +769,7 @@ async function handleMessage(ws, msg, subscriptions) {
768
769
  }
769
770
  // ─── Tasks ─────────────────────────────────────────────
770
771
  case "list_tasks": {
771
- const projectId = msg.payload?.projectId;
772
- if (!projectId)
773
- return;
772
+ const projectId = msg.payload?.projectId || undefined;
774
773
  const rows = taskStore.listTasks(projectId, {
775
774
  search: msg.payload?.search || undefined,
776
775
  status: msg.payload?.status || undefined,
@@ -794,7 +793,7 @@ async function handleMessage(ws, msg, subscriptions) {
794
793
  const computed = computeTaskStatus(r.status, taskSessions);
795
794
  return {
796
795
  id: r.id,
797
- projectId: r.projectId,
796
+ projectId: r.projectId ?? undefined,
798
797
  title: r.title,
799
798
  description: r.description,
800
799
  status: computed.status,
@@ -815,25 +814,28 @@ async function handleMessage(ws, msg, subscriptions) {
815
814
  break;
816
815
  }
817
816
  case "create_task": {
818
- const projectId = msg.payload?.projectId;
817
+ const projectId = msg.payload?.projectId || undefined;
819
818
  const title = msg.payload?.title;
820
819
  const requestId = typeof msg.payload?.requestId === "string"
821
820
  ? msg.payload.requestId
822
821
  : "";
823
- if (!projectId || !title) {
822
+ if (!title) {
824
823
  sendWs(ws, {
825
824
  type: "create_task_error",
826
- payload: { message: "projectId and title required", requestId },
825
+ payload: { message: "title required", requestId },
827
826
  });
828
827
  return;
829
828
  }
830
- const project = projectStore.getProject(projectId);
831
- if (!project) {
832
- sendWs(ws, {
833
- type: "create_task_error",
834
- payload: { message: `Project not found: ${projectId}`, requestId },
835
- });
836
- return;
829
+ let project;
830
+ if (projectId) {
831
+ project = projectStore.getProject(projectId);
832
+ if (!project) {
833
+ sendWs(ws, {
834
+ type: "create_task_error",
835
+ payload: { message: `Project not found: ${projectId}`, requestId },
836
+ });
837
+ return;
838
+ }
837
839
  }
838
840
  const parentTaskId = msg.payload?.parentTaskId || "";
839
841
  const rawCanDecompose = msg.payload?.canDecompose;
@@ -842,7 +844,7 @@ async function handleMessage(ws, msg, subscriptions) {
842
844
  const canDecompose = typeof rawCanDecompose === "boolean" ? rawCanDecompose : false;
843
845
  try {
844
846
  const id = uuid().slice(0, 8);
845
- taskStore.createTask(id, projectId, title, msg.payload?.description || "", msg.payload?.dependsOn || [], slugify(project.name), parentTaskId, canDecompose, msg.payload?.defaultPersonaId || "");
847
+ taskStore.createTask(id, projectId, title, msg.payload?.description || "", msg.payload?.dependsOn || [], project ? slugify(project.name) : "", parentTaskId, canDecompose, msg.payload?.defaultPersonaId || "");
846
848
  emit("task.created", { taskId: id, projectId, requestId });
847
849
  }
848
850
  catch (error) {
@@ -891,13 +893,13 @@ async function handleMessage(ws, msg, subscriptions) {
891
893
  }
892
894
  sessionStore.setSessionTask(lateBindSessionId, updateTaskId);
893
895
  try {
894
- processorRegistry.lateBind(lateBindSessionId, updateTaskId, existingTask.projectId);
896
+ processorRegistry.lateBind(lateBindSessionId, updateTaskId, existingTask.projectId || undefined);
895
897
  }
896
898
  catch (err) {
897
899
  sendWs(ws, { type: "error", payload: { message: String(err) } });
898
900
  return;
899
901
  }
900
- emit("task.started", { taskId: updateTaskId, sessionId: lateBindSessionId, projectId: existingTask.projectId });
902
+ emit("task.started", { taskId: updateTaskId, sessionId: lateBindSessionId, projectId: existingTask.projectId || "" });
901
903
  break;
902
904
  }
903
905
  // Only allow editing not_started tasks (non-late-bind path)
@@ -926,7 +928,7 @@ async function handleMessage(ws, msg, subscriptions) {
926
928
  ? msg.payload.defaultPersonaId
927
929
  : undefined;
928
930
  taskStore.updateTask(updateTaskId, updatedTitle, updatedDescription, existingTask.status, updatedDependsOn, updatedDefaultPersonaId);
929
- emit("task.updated", { taskId: updateTaskId, projectId: existingTask.projectId });
931
+ emit("task.updated", { taskId: updateTaskId, projectId: existingTask.projectId || "" });
930
932
  break;
931
933
  }
932
934
  case "start_task": {
@@ -977,7 +979,7 @@ async function handleMessage(ws, msg, subscriptions) {
977
979
  return;
978
980
  taskStore.markTaskComplete(taskId, TASK_STATUS.COMPLETE);
979
981
  const task = taskStore.getTask(taskId);
980
- const unblocked = task ? taskStore.checkAndUnblock(task.projectId) : [];
982
+ const unblocked = task?.projectId ? taskStore.checkAndUnblock(task.projectId) : [];
981
983
  sendWs(ws, {
982
984
  type: "task_completed",
983
985
  payload: {
@@ -986,7 +988,7 @@ async function handleMessage(ws, msg, subscriptions) {
986
988
  },
987
989
  });
988
990
  if (task) {
989
- emit("task.completed", { taskId, projectId: task.projectId });
991
+ emit("task.completed", { taskId, projectId: task.projectId || "" });
990
992
  }
991
993
  break;
992
994
  }
@@ -1036,10 +1038,10 @@ async function handleMessage(ws, msg, subscriptions) {
1036
1038
  processEventStream(conn.client.resume(powerlineReq), {
1037
1039
  sessionId: latestSession.id,
1038
1040
  logPath,
1039
- projectId: task.projectId,
1041
+ projectId: task.projectId ?? undefined,
1040
1042
  taskId: task.id,
1041
1043
  });
1042
- emit("task.started", { taskId: task.id, sessionId: latestSession.id, projectId: task.projectId });
1044
+ emit("task.started", { taskId: task.id, sessionId: latestSession.id, projectId: task.projectId || "" });
1043
1045
  break;
1044
1046
  }
1045
1047
  case "delete_task": {
@@ -1088,7 +1090,7 @@ async function handleMessage(ws, msg, subscriptions) {
1088
1090
  sendWs(ws, { type: "error", payload: { message: `Failed to delete task ${taskId}: no rows affected` } });
1089
1091
  return;
1090
1092
  }
1091
- emit("task.deleted", { taskId, projectId: deletedTask.projectId });
1093
+ emit("task.deleted", { taskId, projectId: deletedTask.projectId || "" });
1092
1094
  break;
1093
1095
  }
1094
1096
  // ─── Task Sessions ─────────────────────────────────────
@@ -1170,7 +1172,9 @@ async function handleMessage(ws, msg, subscriptions) {
1170
1172
  });
1171
1173
  return;
1172
1174
  }
1173
- const environmentId = projectStore.getProject(task.projectId)?.defaultEnvironmentId;
1175
+ const environmentId = task.projectId
1176
+ ? projectStore.getProject(task.projectId)?.defaultEnvironmentId
1177
+ : undefined;
1174
1178
  if (!environmentId) {
1175
1179
  sendWs(ws, {
1176
1180
  type: "task_diff",