@iaforged/context-code 1.2.9 → 1.2.10

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 (172) hide show
  1. package/README.md +119 -119
  2. package/context-bootstrap.js +26 -26
  3. package/dist/src/QueryEngine.js +394 -327
  4. package/dist/src/bridge/bridgeUI.js +1 -1
  5. package/dist/src/buddy/prompt.js +4 -4
  6. package/dist/src/cli/handlers/auth.js +126 -9
  7. package/dist/src/cli/print.js +35 -1
  8. package/dist/src/commands/agent/agent.js +28 -2
  9. package/dist/src/commands/agent/agentStore.js +8 -1
  10. package/dist/src/commands/agent/index.js +1 -1
  11. package/dist/src/commands/bridge-kick.js +9 -9
  12. package/dist/src/commands/commit.js +34 -34
  13. package/dist/src/commands/init-verifiers.js +3 -3
  14. package/dist/src/commands/init.js +88 -88
  15. package/dist/src/commands/insights.js +787 -787
  16. package/dist/src/commands/install.js +19 -19
  17. package/dist/src/commands/login/login.js +21 -12
  18. package/dist/src/commands/logout/logout.js +9 -0
  19. package/dist/src/commands/model/model.js +9 -4
  20. package/dist/src/commands/orchestrate/SwarmUI.js +50 -0
  21. package/dist/src/commands/orchestrate/index.js +2 -2
  22. package/dist/src/commands/orchestrate/orchestrate.js +708 -12
  23. package/dist/src/commands/pr_comments/index.js +33 -33
  24. package/dist/src/commands/profile/index.js +1 -1
  25. package/dist/src/commands/profile/profile.js +52 -3
  26. package/dist/src/commands/provider/index.js +1 -1
  27. package/dist/src/commands/provider/provider.js +117 -45
  28. package/dist/src/commands/resumen/index.js +9 -0
  29. package/dist/src/commands/resumen/resumen.js +29 -0
  30. package/dist/src/commands/security-review.js +190 -190
  31. package/dist/src/commands/swarm-auto/index.js +9 -0
  32. package/dist/src/commands/swarm-auto/swarmAuto.js +111 -0
  33. package/dist/src/commands/swarm-init/index.js +9 -0
  34. package/dist/src/commands/swarm-init/swarmInit.js +72 -0
  35. package/dist/src/commands/team/team.js +39 -6
  36. package/dist/src/commands.js +14 -0
  37. package/dist/src/components/LogoV2/CondensedLogo.js +2 -2
  38. package/dist/src/components/PromptInput/PromptInputQueuedCommands.js +3 -3
  39. package/dist/src/components/agents/agentFileUtils.js +6 -6
  40. package/dist/src/components/permissions/hooks.js +5 -5
  41. package/dist/src/constants/outputStyles.js +83 -83
  42. package/dist/src/core/agents/blueprints.js +58 -0
  43. package/dist/src/core/agents/cliAdapter.js +61 -0
  44. package/dist/src/core/agents/registry.js +93 -0
  45. package/dist/src/core/agents/runtime.js +4 -0
  46. package/dist/src/core/agents/runtime.smoke.js +42 -0
  47. package/dist/src/core/agents/swarm.smoke.js +48 -0
  48. package/dist/src/core/agents/swarmTools.js +38 -0
  49. package/dist/src/core/auth/index.js +2 -0
  50. package/dist/src/core/auth/loginCliAdapter.js +24 -0
  51. package/dist/src/core/auth/loginCore.js +67 -0
  52. package/dist/src/core/auth/logoutCliAdapter.js +34 -0
  53. package/dist/src/core/auth/logoutCore.js +52 -0
  54. package/dist/src/core/auth/preflight.smoke.js +151 -0
  55. package/dist/src/core/index.js +21 -0
  56. package/dist/src/core/mcp/blueprints.js +27 -0
  57. package/dist/src/core/mcp/common.js +14 -0
  58. package/dist/src/core/mcp/runtime.js +67 -0
  59. package/dist/src/core/mcp/runtime.smoke.js +50 -0
  60. package/dist/src/core/mcp/swarmClient.js +40 -0
  61. package/dist/src/core/mcp/swarmSetup.js +43 -0
  62. package/dist/src/core/providers/cliAdapter.js +39 -0
  63. package/dist/src/core/providers/contracts.js +1 -0
  64. package/dist/src/core/providers/index.js +3 -0
  65. package/dist/src/core/providers/llmCore.js +123 -0
  66. package/dist/src/core/providers/providerCore.js +141 -0
  67. package/dist/src/core/providers/providerModelCompatibility.js +98 -0
  68. package/dist/src/core/providers/providerParitySmoke.js +83 -0
  69. package/dist/src/core/providers/providerProfileModelSmoke.js +80 -0
  70. package/dist/src/core/query/contracts.js +1 -0
  71. package/dist/src/core/query/runtime.js +117 -0
  72. package/dist/src/core/query/runtime.smoke.js +39 -0
  73. package/dist/src/core/query/timelineThinking.smoke.js +25 -0
  74. package/dist/src/core/query/wiring.smoke.js +76 -0
  75. package/dist/src/core/skills/cliAdapter.js +38 -0
  76. package/dist/src/core/skills/index.js +52 -0
  77. package/dist/src/core/skills/runtime.smoke.js +53 -0
  78. package/dist/src/core/tasks/runtime.js +205 -0
  79. package/dist/src/core/tasks/runtime.smoke.js +63 -0
  80. package/dist/src/core/tasks/sdkAdapter.js +4 -0
  81. package/dist/src/core/tools/contracts.js +3 -0
  82. package/dist/src/core/tools/fileResolution.js +112 -0
  83. package/dist/src/core/tools/fileResolution.smoke.js +33 -0
  84. package/dist/src/core/tools/filesCore.js +51 -0
  85. package/dist/src/core/tools/filesCore.smoke.js +108 -0
  86. package/dist/src/core/tools/gitCore.js +20 -0
  87. package/dist/src/core/tools/imageParity.smoke.js +36 -0
  88. package/dist/src/core/tools/notebookParity.smoke.js +68 -0
  89. package/dist/src/core/tools/registry.js +22 -0
  90. package/dist/src/core/tools/runtime.smoke.js +32 -0
  91. package/dist/src/core/tools/shellCore.js +60 -0
  92. package/dist/src/core/types/agentContext.js +9 -0
  93. package/dist/src/core/types/auth.js +3 -0
  94. package/dist/src/core/types/command.js +13 -0
  95. package/dist/src/core/types/provider.js +3 -0
  96. package/dist/src/core/types/sdkEvent.js +10 -0
  97. package/dist/src/core/types/swarm.js +1 -0
  98. package/dist/src/cost-tracker.js +3 -3
  99. package/dist/src/hooks/useAwaySummary.js +22 -9
  100. package/dist/src/main.js +32 -2
  101. package/dist/src/screens/REPL.js +9 -0
  102. package/dist/src/services/AgentSummary/agentSummary.js +10 -10
  103. package/dist/src/services/autoDream/autoDream.js +5 -5
  104. package/dist/src/services/autoDream/consolidationPrompt.js +49 -49
  105. package/dist/src/services/compact/prompt.js +238 -238
  106. package/dist/src/services/limits/sessionCounter.js +17 -17
  107. package/dist/src/services/mcp/client.js +27 -1
  108. package/dist/src/services/orchestration/execution/AgentTaskExecutor.js +39 -20
  109. package/dist/src/services/orchestration/execution/OrchestrationExecutionRuntime.js +65 -58
  110. package/dist/src/skills/bundled/loop.js +57 -57
  111. package/dist/src/skills/bundled/remember.js +53 -53
  112. package/dist/src/skills/bundled/simplify.js +49 -49
  113. package/dist/src/skills/bundled/skillify.js +2 -2
  114. package/dist/src/state/onChangeAppState.js +6 -0
  115. package/dist/src/tasks/LocalAgentTask/LocalAgentTask.js +5 -5
  116. package/dist/src/tasks/LocalMainSessionTask.js +5 -5
  117. package/dist/src/tasks/LocalShellTask/LocalShellTask.js +13 -13
  118. package/dist/src/tools/AgentTool/forkSubagent.js +25 -25
  119. package/dist/src/tools/AskUserQuestionTool/prompt.js +29 -29
  120. package/dist/src/tools/BashTool/BashTool.js +27 -2
  121. package/dist/src/tools/BriefTool/prompt.js +14 -14
  122. package/dist/src/tools/EnterPlanModeTool/EnterPlanModeTool.js +12 -12
  123. package/dist/src/tools/EnterPlanModeTool/prompt.js +140 -140
  124. package/dist/src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.js +18 -18
  125. package/dist/src/tools/ExitPlanModeTool/prompt.js +23 -23
  126. package/dist/src/tools/ExitWorktreeTool/prompt.js +29 -29
  127. package/dist/src/tools/FileEditTool/prompt.js +7 -7
  128. package/dist/src/tools/FileReadTool/FileReadTool.js +18 -1
  129. package/dist/src/tools/FileWriteTool/prompt.js +6 -6
  130. package/dist/src/tools/GlobTool/prompt.js +4 -4
  131. package/dist/src/tools/GrepTool/prompt.js +10 -10
  132. package/dist/src/tools/LSPTool/prompt.js +18 -18
  133. package/dist/src/tools/ListMcpResourcesTool/prompt.js +15 -15
  134. package/dist/src/tools/PowerShellTool/PowerShellTool.js +25 -2
  135. package/dist/src/tools/ReadMcpResourceTool/prompt.js +13 -13
  136. package/dist/src/tools/SendMessageTool/prompt.js +36 -36
  137. package/dist/src/tools/SkillTool/prompt.js +21 -21
  138. package/dist/src/tools/SleepTool/prompt.js +10 -10
  139. package/dist/src/tools/TaskCreateTool/prompt.js +41 -41
  140. package/dist/src/tools/TaskGetTool/prompt.js +21 -21
  141. package/dist/src/tools/TaskListTool/prompt.js +30 -30
  142. package/dist/src/tools/TaskOutputTool/TaskOutputTool.js +8 -8
  143. package/dist/src/tools/TaskStopTool/prompt.js +5 -5
  144. package/dist/src/tools/TaskUpdateTool/prompt.js +74 -74
  145. package/dist/src/tools/TodoWriteTool/prompt.js +178 -178
  146. package/dist/src/tools/ToolSearchTool/prompt.js +9 -9
  147. package/dist/src/tools/WebFetchTool/WebFetchTool.js +9 -9
  148. package/dist/src/tools/WebFetchTool/prompt.js +31 -31
  149. package/dist/src/tools/WebSearchTool/prompt.js +26 -26
  150. package/dist/src/utils/agentContext.js +2 -0
  151. package/dist/src/utils/agenticSessionSearch.js +38 -38
  152. package/dist/src/utils/config.js +2 -0
  153. package/dist/src/utils/genericProcessUtils.js +21 -21
  154. package/dist/src/utils/heapDumpService.js +4 -4
  155. package/dist/src/utils/mcpValidation.js +2 -2
  156. package/dist/src/utils/model/modelStrings.js +1 -1
  157. package/dist/src/utils/model/providers.js +5 -0
  158. package/dist/src/utils/orchestration/store/providerAgentStore.js +22 -22
  159. package/dist/src/utils/orchestration/store/providerWorkspaceStore.js +10 -10
  160. package/dist/src/utils/orchestration/store/runStore.js +68 -68
  161. package/dist/src/utils/orchestration/store/teamStore.js +28 -28
  162. package/dist/src/utils/permissions/permissionExplainer.js +6 -6
  163. package/dist/src/utils/permissions/permissionsDb.js +43 -43
  164. package/dist/src/utils/sdkEventQueue.js +2 -0
  165. package/dist/src/utils/secureStorage/sqliteStorage.js +12 -12
  166. package/dist/src/utils/standardMcp/common.js +15 -0
  167. package/dist/src/utils/standardMcp/setup.js +52 -0
  168. package/dist/src/utils/swarm/teammatePromptAddendum.js +10 -10
  169. package/dist/src/utils/task/framework.js +6 -6
  170. package/package.json +1 -1
  171. package/dist/src/commands/usage/index.js +0 -7
  172. package/dist/src/commands/usage/usage.js +0 -5
@@ -149,8 +149,8 @@ function countTasks(tasks) {
149
149
  export async function listOrchestrationRuns() {
150
150
  const db = await getOrchestrationDatabase();
151
151
  return db
152
- .prepare(`SELECT id, team_id, goal, global_orchestrator_agent_id, status, created_at, started_at, finished_at
153
- FROM orchestration_runs
152
+ .prepare(`SELECT id, team_id, goal, global_orchestrator_agent_id, status, created_at, started_at, finished_at
153
+ FROM orchestration_runs
154
154
  ORDER BY created_at DESC, id DESC`)
155
155
  .all()
156
156
  .map(rowToRun)
@@ -159,8 +159,8 @@ export async function listOrchestrationRuns() {
159
159
  export async function getOrchestrationRunById(id) {
160
160
  const db = await getOrchestrationDatabase();
161
161
  const row = db
162
- .prepare(`SELECT id, team_id, goal, global_orchestrator_agent_id, status, created_at, started_at, finished_at
163
- FROM orchestration_runs
162
+ .prepare(`SELECT id, team_id, goal, global_orchestrator_agent_id, status, created_at, started_at, finished_at
163
+ FROM orchestration_runs
164
164
  WHERE id = ?`)
165
165
  .get(id);
166
166
  return rowToRun(row);
@@ -169,8 +169,8 @@ export async function createOrchestrationRun(input) {
169
169
  const db = await getOrchestrationDatabase();
170
170
  const id = randomUUID();
171
171
  const createdAt = nowIso();
172
- db.prepare(`INSERT INTO orchestration_runs (
173
- id, team_id, goal, global_orchestrator_agent_id, status, created_at, started_at, finished_at
172
+ db.prepare(`INSERT INTO orchestration_runs (
173
+ id, team_id, goal, global_orchestrator_agent_id, status, created_at, started_at, finished_at
174
174
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.teamId, 'teamId'), requireText(input.goal, 'goal'), toNullableText(input.globalOrchestratorAgentId), input.status ?? 'planned', createdAt, toNullableText(input.startedAt), toNullableText(input.finishedAt));
175
175
  const created = await getOrchestrationRunById(id);
176
176
  if (!created) {
@@ -184,8 +184,8 @@ export async function updateOrchestrationRun(id, input) {
184
184
  throw new Error(`Orchestration run not found: ${id}`);
185
185
  }
186
186
  const db = await getOrchestrationDatabase();
187
- db.prepare(`UPDATE orchestration_runs
188
- SET goal = ?, global_orchestrator_agent_id = ?, status = ?, started_at = ?, finished_at = ?
187
+ db.prepare(`UPDATE orchestration_runs
188
+ SET goal = ?, global_orchestrator_agent_id = ?, status = ?, started_at = ?, finished_at = ?
189
189
  WHERE id = ?`).run(input.goal === undefined ? existing.goal : requireText(input.goal, 'goal'), input.globalOrchestratorAgentId === undefined
190
190
  ? existing.globalOrchestratorAgentId
191
191
  : toNullableText(input.globalOrchestratorAgentId), input.status ?? existing.status, input.startedAt === undefined ? existing.startedAt : toNullableText(input.startedAt), input.finishedAt === undefined ? existing.finishedAt : toNullableText(input.finishedAt), id);
@@ -198,9 +198,9 @@ export async function updateOrchestrationRun(id, input) {
198
198
  export async function listOrchestrationTasks(runId) {
199
199
  const db = await getOrchestrationDatabase();
200
200
  return db
201
- .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
202
- FROM orchestration_tasks
203
- WHERE run_id = ?
201
+ .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
202
+ FROM orchestration_tasks
203
+ WHERE run_id = ?
204
204
  ORDER BY created_at, id`)
205
205
  .all(requireText(runId, 'runId'))
206
206
  .map(rowToTask)
@@ -209,8 +209,8 @@ export async function listOrchestrationTasks(runId) {
209
209
  export async function getOrchestrationTaskById(id) {
210
210
  const db = await getOrchestrationDatabase();
211
211
  const row = db
212
- .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
213
- FROM orchestration_tasks
212
+ .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
213
+ FROM orchestration_tasks
214
214
  WHERE id = ?`)
215
215
  .get(requireText(id, 'id'));
216
216
  return rowToTask(row);
@@ -218,9 +218,9 @@ export async function getOrchestrationTaskById(id) {
218
218
  export async function listOrchestrationTasksByTeamUnit(runId, teamUnitId) {
219
219
  const db = await getOrchestrationDatabase();
220
220
  return db
221
- .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
222
- FROM orchestration_tasks
223
- WHERE run_id = ? AND team_unit_id = ?
221
+ .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
222
+ FROM orchestration_tasks
223
+ WHERE run_id = ? AND team_unit_id = ?
224
224
  ORDER BY created_at, id`)
225
225
  .all(requireText(runId, 'runId'), requireText(teamUnitId, 'teamUnitId'))
226
226
  .map(rowToTask)
@@ -229,9 +229,9 @@ export async function listOrchestrationTasksByTeamUnit(runId, teamUnitId) {
229
229
  export async function listOrchestrationTasksByAgent(runId, agentId) {
230
230
  const db = await getOrchestrationDatabase();
231
231
  return db
232
- .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
233
- FROM orchestration_tasks
234
- WHERE run_id = ? AND assigned_agent_id = ?
232
+ .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
233
+ FROM orchestration_tasks
234
+ WHERE run_id = ? AND assigned_agent_id = ?
235
235
  ORDER BY created_at, id`)
236
236
  .all(requireText(runId, 'runId'), requireText(agentId, 'agentId'))
237
237
  .map(rowToTask)
@@ -240,9 +240,9 @@ export async function listOrchestrationTasksByAgent(runId, agentId) {
240
240
  export async function listOrchestrationMessages(runId) {
241
241
  const db = await getOrchestrationDatabase();
242
242
  return db
243
- .prepare(`SELECT id, run_id, task_id, from_agent_id, to_agent_id, message_type, content, created_at
244
- FROM orchestration_messages
245
- WHERE run_id = ?
243
+ .prepare(`SELECT id, run_id, task_id, from_agent_id, to_agent_id, message_type, content, created_at
244
+ FROM orchestration_messages
245
+ WHERE run_id = ?
246
246
  ORDER BY created_at, id`)
247
247
  .all(requireText(runId, 'runId'))
248
248
  .map(rowToMessage)
@@ -251,9 +251,9 @@ export async function listOrchestrationMessages(runId) {
251
251
  export async function listOrchestrationMessagesByTask(taskId) {
252
252
  const db = await getOrchestrationDatabase();
253
253
  return db
254
- .prepare(`SELECT id, run_id, task_id, from_agent_id, to_agent_id, message_type, content, created_at
255
- FROM orchestration_messages
256
- WHERE task_id = ?
254
+ .prepare(`SELECT id, run_id, task_id, from_agent_id, to_agent_id, message_type, content, created_at
255
+ FROM orchestration_messages
256
+ WHERE task_id = ?
257
257
  ORDER BY created_at, id`)
258
258
  .all(requireText(taskId, 'taskId'))
259
259
  .map(rowToMessage)
@@ -262,10 +262,10 @@ export async function listOrchestrationMessagesByTask(taskId) {
262
262
  export async function listOrchestrationMessagesByTeamUnit(runId, teamUnitId) {
263
263
  const db = await getOrchestrationDatabase();
264
264
  return db
265
- .prepare(`SELECT messages.id, messages.run_id, messages.task_id, messages.from_agent_id, messages.to_agent_id, messages.message_type, messages.content, messages.created_at
266
- FROM orchestration_messages AS messages
267
- INNER JOIN orchestration_tasks AS tasks ON tasks.id = messages.task_id
268
- WHERE messages.run_id = ? AND tasks.team_unit_id = ?
265
+ .prepare(`SELECT messages.id, messages.run_id, messages.task_id, messages.from_agent_id, messages.to_agent_id, messages.message_type, messages.content, messages.created_at
266
+ FROM orchestration_messages AS messages
267
+ INNER JOIN orchestration_tasks AS tasks ON tasks.id = messages.task_id
268
+ WHERE messages.run_id = ? AND tasks.team_unit_id = ?
269
269
  ORDER BY messages.created_at, messages.id`)
270
270
  .all(requireText(runId, 'runId'), requireText(teamUnitId, 'teamUnitId'))
271
271
  .map(rowToMessage)
@@ -275,8 +275,8 @@ export async function createOrchestrationTask(input) {
275
275
  const db = await getOrchestrationDatabase();
276
276
  const id = randomUUID();
277
277
  const createdAt = nowIso();
278
- db.prepare(`INSERT INTO orchestration_tasks (
279
- id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
278
+ db.prepare(`INSERT INTO orchestration_tasks (
279
+ id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
280
280
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.runId, 'runId'), toNullableText(input.parentTaskId), requireText(input.scopeType, 'scopeType'), toNullableText(input.teamUnitId ?? input.teamDomainId), toNullableText(input.assignedAgentId), requireText(input.title, 'title'), requireText(input.instructions, 'instructions'), input.status ?? 'pending', toNullableText(input.resultSummary), createdAt, toNullableText(input.finishedAt));
281
281
  const created = (await listOrchestrationTasks(input.runId)).find(task => task.id === id);
282
282
  if (!created) {
@@ -287,16 +287,16 @@ export async function createOrchestrationTask(input) {
287
287
  export async function updateOrchestrationTask(id, input) {
288
288
  const db = await getOrchestrationDatabase();
289
289
  const row = db
290
- .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
291
- FROM orchestration_tasks
290
+ .prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
291
+ FROM orchestration_tasks
292
292
  WHERE id = ?`)
293
293
  .get(id);
294
294
  const existing = rowToTask(row);
295
295
  if (!existing) {
296
296
  throw new Error(`Orchestration task not found: ${id}`);
297
297
  }
298
- db.prepare(`UPDATE orchestration_tasks
299
- SET parent_task_id = ?, scope_type = ?, team_unit_id = ?, assigned_agent_id = ?, title = ?, instructions = ?, status = ?, result_summary = ?, finished_at = ?
298
+ db.prepare(`UPDATE orchestration_tasks
299
+ SET parent_task_id = ?, scope_type = ?, team_unit_id = ?, assigned_agent_id = ?, title = ?, instructions = ?, status = ?, result_summary = ?, finished_at = ?
300
300
  WHERE id = ?`).run(input.parentTaskId === undefined ? existing.parentTaskId : toNullableText(input.parentTaskId), input.scopeType === undefined ? existing.scopeType : requireText(input.scopeType, 'scopeType'), input.teamUnitId === undefined && input.teamDomainId === undefined
301
301
  ? existing.teamUnitId
302
302
  : toNullableText(input.teamUnitId ?? input.teamDomainId), input.assignedAgentId === undefined ? existing.assignedAgentId : toNullableText(input.assignedAgentId), input.title === undefined ? existing.title : requireText(input.title, 'title'), input.instructions === undefined ? existing.instructions : requireText(input.instructions, 'instructions'), input.status ?? existing.status, input.resultSummary === undefined ? existing.resultSummary : toNullableText(input.resultSummary), input.finishedAt === undefined ? existing.finishedAt : toNullableText(input.finishedAt), id);
@@ -310,12 +310,12 @@ export async function createOrchestrationMessage(input) {
310
310
  const db = await getOrchestrationDatabase();
311
311
  const id = randomUUID();
312
312
  const createdAt = nowIso();
313
- db.prepare(`INSERT INTO orchestration_messages (
314
- id, run_id, task_id, from_agent_id, to_agent_id, message_type, content, created_at
313
+ db.prepare(`INSERT INTO orchestration_messages (
314
+ id, run_id, task_id, from_agent_id, to_agent_id, message_type, content, created_at
315
315
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.runId, 'runId'), toNullableText(input.taskId), toNullableText(input.fromAgentId), toNullableText(input.toAgentId), requireText(input.messageType, 'messageType'), requireText(input.content, 'content'), createdAt);
316
316
  const row = db
317
- .prepare(`SELECT id, run_id, task_id, from_agent_id, to_agent_id, message_type, content, created_at
318
- FROM orchestration_messages
317
+ .prepare(`SELECT id, run_id, task_id, from_agent_id, to_agent_id, message_type, content, created_at
318
+ FROM orchestration_messages
319
319
  WHERE id = ?`)
320
320
  .get(id);
321
321
  const created = rowToMessage(row);
@@ -328,12 +328,12 @@ export async function createOrchestrationTaskResult(input) {
328
328
  const db = await getOrchestrationDatabase();
329
329
  const id = randomUUID();
330
330
  const createdAt = nowIso();
331
- db.prepare(`INSERT INTO orchestration_task_results (
332
- id, run_id, task_id, agent_id, result_type, status, summary, content, metadata_json, created_at
331
+ db.prepare(`INSERT INTO orchestration_task_results (
332
+ id, run_id, task_id, agent_id, result_type, status, summary, content, metadata_json, created_at
333
333
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.runId, 'runId'), requireText(input.taskId, 'taskId'), toNullableText(input.agentId), input.resultType?.trim() || 'output', input.status ?? 'submitted', toNullableText(input.summary), toNullableText(input.content), toNullableText(input.metadataJson), createdAt);
334
334
  const row = db
335
- .prepare(`SELECT id, run_id, task_id, agent_id, result_type, status, summary, content, metadata_json, created_at
336
- FROM orchestration_task_results
335
+ .prepare(`SELECT id, run_id, task_id, agent_id, result_type, status, summary, content, metadata_json, created_at
336
+ FROM orchestration_task_results
337
337
  WHERE id = ?`)
338
338
  .get(id);
339
339
  const created = rowToTaskResult(row);
@@ -345,9 +345,9 @@ export async function createOrchestrationTaskResult(input) {
345
345
  export async function listOrchestrationTaskResults(taskId) {
346
346
  const db = await getOrchestrationDatabase();
347
347
  return db
348
- .prepare(`SELECT id, run_id, task_id, agent_id, result_type, status, summary, content, metadata_json, created_at
349
- FROM orchestration_task_results
350
- WHERE task_id = ?
348
+ .prepare(`SELECT id, run_id, task_id, agent_id, result_type, status, summary, content, metadata_json, created_at
349
+ FROM orchestration_task_results
350
+ WHERE task_id = ?
351
351
  ORDER BY created_at, id`)
352
352
  .all(requireText(taskId, 'taskId'))
353
353
  .map(rowToTaskResult)
@@ -356,9 +356,9 @@ export async function listOrchestrationTaskResults(taskId) {
356
356
  export async function listOrchestrationTaskResultsByRun(runId) {
357
357
  const db = await getOrchestrationDatabase();
358
358
  return db
359
- .prepare(`SELECT id, run_id, task_id, agent_id, result_type, status, summary, content, metadata_json, created_at
360
- FROM orchestration_task_results
361
- WHERE run_id = ?
359
+ .prepare(`SELECT id, run_id, task_id, agent_id, result_type, status, summary, content, metadata_json, created_at
360
+ FROM orchestration_task_results
361
+ WHERE run_id = ?
362
362
  ORDER BY created_at, id`)
363
363
  .all(requireText(runId, 'runId'))
364
364
  .map(rowToTaskResult)
@@ -367,10 +367,10 @@ export async function listOrchestrationTaskResultsByRun(runId) {
367
367
  export async function listOrchestrationTaskResultsByTeamUnit(runId, teamUnitId) {
368
368
  const db = await getOrchestrationDatabase();
369
369
  return db
370
- .prepare(`SELECT results.id, results.run_id, results.task_id, results.agent_id, results.result_type, results.status, results.summary, results.content, results.metadata_json, results.created_at
371
- FROM orchestration_task_results AS results
372
- INNER JOIN orchestration_tasks AS tasks ON tasks.id = results.task_id
373
- WHERE results.run_id = ? AND tasks.team_unit_id = ?
370
+ .prepare(`SELECT results.id, results.run_id, results.task_id, results.agent_id, results.result_type, results.status, results.summary, results.content, results.metadata_json, results.created_at
371
+ FROM orchestration_task_results AS results
372
+ INNER JOIN orchestration_tasks AS tasks ON tasks.id = results.task_id
373
+ WHERE results.run_id = ? AND tasks.team_unit_id = ?
374
374
  ORDER BY results.created_at, results.id`)
375
375
  .all(requireText(runId, 'runId'), requireText(teamUnitId, 'teamUnitId'))
376
376
  .map(rowToTaskResult)
@@ -382,15 +382,15 @@ export async function upsertOrchestrationTeamReport(input) {
382
382
  const teamUnitId = requireText(input.teamUnitId ?? input.teamDomainId, 'teamUnitId');
383
383
  const existing = await getOrchestrationTeamReport(input.runId, teamUnitId);
384
384
  if (existing) {
385
- db.prepare(`UPDATE orchestration_team_reports
386
- SET local_orchestrator_agent_id = ?, status = ?, summary = ?, blockers = ?, output = ?, metrics_json = ?, updated_at = ?, submitted_at = ?
385
+ db.prepare(`UPDATE orchestration_team_reports
386
+ SET local_orchestrator_agent_id = ?, status = ?, summary = ?, blockers = ?, output = ?, metrics_json = ?, updated_at = ?, submitted_at = ?
387
387
  WHERE id = ?`).run(input.localOrchestratorAgentId === undefined
388
388
  ? existing.localOrchestratorAgentId
389
389
  : toNullableText(input.localOrchestratorAgentId), input.status ?? existing.status, requireText(input.summary, 'summary'), input.blockers === undefined ? existing.blockers : toNullableText(input.blockers), input.output === undefined ? existing.output : toNullableText(input.output), input.metricsJson === undefined ? existing.metricsJson : toNullableText(input.metricsJson), now, input.submittedAt === undefined ? existing.submittedAt : toNullableText(input.submittedAt), existing.id);
390
390
  }
391
391
  else {
392
- db.prepare(`INSERT INTO orchestration_team_reports (
393
- id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at
392
+ db.prepare(`INSERT INTO orchestration_team_reports (
393
+ id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at
394
394
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(randomUUID(), requireText(input.runId, 'runId'), teamUnitId, toNullableText(input.localOrchestratorAgentId), input.status ?? 'submitted', requireText(input.summary, 'summary'), toNullableText(input.blockers), toNullableText(input.output), toNullableText(input.metricsJson), now, now, toNullableText(input.submittedAt));
395
395
  }
396
396
  const saved = await getOrchestrationTeamReport(input.runId, teamUnitId);
@@ -402,8 +402,8 @@ export async function upsertOrchestrationTeamReport(input) {
402
402
  export async function getOrchestrationTeamReport(runId, teamUnitId) {
403
403
  const db = await getOrchestrationDatabase();
404
404
  const row = db
405
- .prepare(`SELECT id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at
406
- FROM orchestration_team_reports
405
+ .prepare(`SELECT id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at
406
+ FROM orchestration_team_reports
407
407
  WHERE run_id = ? AND team_unit_id = ?`)
408
408
  .get(requireText(runId, 'runId'), requireText(teamUnitId, 'teamUnitId'));
409
409
  return rowToTeamReport(row);
@@ -411,9 +411,9 @@ export async function getOrchestrationTeamReport(runId, teamUnitId) {
411
411
  export async function listOrchestrationTeamReports(runId) {
412
412
  const db = await getOrchestrationDatabase();
413
413
  return db
414
- .prepare(`SELECT id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at
415
- FROM orchestration_team_reports
416
- WHERE run_id = ?
414
+ .prepare(`SELECT id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at
415
+ FROM orchestration_team_reports
416
+ WHERE run_id = ?
417
417
  ORDER BY updated_at, id`)
418
418
  .all(requireText(runId, 'runId'))
419
419
  .map(rowToTeamReport)
@@ -424,13 +424,13 @@ export async function upsertOrchestrationRunReport(input) {
424
424
  const now = nowIso();
425
425
  const existing = await getOrchestrationRunReport(input.runId);
426
426
  if (existing) {
427
- db.prepare(`UPDATE orchestration_run_reports
428
- SET status = ?, summary = ?, output = ?, risks = ?, next_steps = ?, metrics_json = ?, updated_at = ?, submitted_at = ?
427
+ db.prepare(`UPDATE orchestration_run_reports
428
+ SET status = ?, summary = ?, output = ?, risks = ?, next_steps = ?, metrics_json = ?, updated_at = ?, submitted_at = ?
429
429
  WHERE id = ?`).run(input.status ?? existing.status, requireText(input.summary, 'summary'), input.output === undefined ? existing.output : toNullableText(input.output), input.risks === undefined ? existing.risks : toNullableText(input.risks), input.nextSteps === undefined ? existing.nextSteps : toNullableText(input.nextSteps), input.metricsJson === undefined ? existing.metricsJson : toNullableText(input.metricsJson), now, input.submittedAt === undefined ? existing.submittedAt : toNullableText(input.submittedAt), existing.id);
430
430
  }
431
431
  else {
432
- db.prepare(`INSERT INTO orchestration_run_reports (
433
- id, run_id, status, summary, output, risks, next_steps, metrics_json, created_at, updated_at, submitted_at
432
+ db.prepare(`INSERT INTO orchestration_run_reports (
433
+ id, run_id, status, summary, output, risks, next_steps, metrics_json, created_at, updated_at, submitted_at
434
434
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(randomUUID(), requireText(input.runId, 'runId'), input.status ?? 'submitted', requireText(input.summary, 'summary'), toNullableText(input.output), toNullableText(input.risks), toNullableText(input.nextSteps), toNullableText(input.metricsJson), now, now, toNullableText(input.submittedAt));
435
435
  }
436
436
  const saved = await getOrchestrationRunReport(input.runId);
@@ -442,8 +442,8 @@ export async function upsertOrchestrationRunReport(input) {
442
442
  export async function getOrchestrationRunReport(runId) {
443
443
  const db = await getOrchestrationDatabase();
444
444
  const row = db
445
- .prepare(`SELECT id, run_id, status, summary, output, risks, next_steps, metrics_json, created_at, updated_at, submitted_at
446
- FROM orchestration_run_reports
445
+ .prepare(`SELECT id, run_id, status, summary, output, risks, next_steps, metrics_json, created_at, updated_at, submitted_at
446
+ FROM orchestration_run_reports
447
447
  WHERE run_id = ?`)
448
448
  .get(requireText(runId, 'runId'));
449
449
  return rowToRunReport(row);
@@ -82,8 +82,8 @@ function resolvePriority(value, fallback = 0) {
82
82
  async function getTeamRowById(id) {
83
83
  const db = await getOrchestrationDatabase();
84
84
  const row = db
85
- .prepare(`SELECT id, name, description, global_orchestrator_agent_id, is_enabled, created_at, updated_at
86
- FROM teams
85
+ .prepare(`SELECT id, name, description, global_orchestrator_agent_id, is_enabled, created_at, updated_at
86
+ FROM teams
87
87
  WHERE id = ?`)
88
88
  .get(id);
89
89
  return rowToTeam(row);
@@ -91,8 +91,8 @@ async function getTeamRowById(id) {
91
91
  async function getTeamUnitRowById(id) {
92
92
  const db = await getOrchestrationDatabase();
93
93
  const row = db
94
- .prepare(`SELECT id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at
95
- FROM team_units
94
+ .prepare(`SELECT id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at
95
+ FROM team_units
96
96
  WHERE id = ?`)
97
97
  .get(id);
98
98
  return rowToTeamUnit(row);
@@ -100,8 +100,8 @@ async function getTeamUnitRowById(id) {
100
100
  async function getTeamUnitMemberRowById(id) {
101
101
  const db = await getOrchestrationDatabase();
102
102
  const row = db
103
- .prepare(`SELECT id, team_unit_id, agent_id, duty, priority, created_at, updated_at
104
- FROM team_unit_members
103
+ .prepare(`SELECT id, team_unit_id, agent_id, duty, priority, created_at, updated_at
104
+ FROM team_unit_members
105
105
  WHERE id = ?`)
106
106
  .get(id);
107
107
  return rowToTeamUnitMember(row);
@@ -109,8 +109,8 @@ async function getTeamUnitMemberRowById(id) {
109
109
  export async function listTeams() {
110
110
  const db = await getOrchestrationDatabase();
111
111
  return db
112
- .prepare(`SELECT id, name, description, global_orchestrator_agent_id, is_enabled, created_at, updated_at
113
- FROM teams
112
+ .prepare(`SELECT id, name, description, global_orchestrator_agent_id, is_enabled, created_at, updated_at
113
+ FROM teams
114
114
  ORDER BY name, created_at, id`)
115
115
  .all()
116
116
  .map(rowToTeam)
@@ -122,8 +122,8 @@ export async function getTeamById(id) {
122
122
  export async function getTeamByName(name) {
123
123
  const db = await getOrchestrationDatabase();
124
124
  const row = db
125
- .prepare(`SELECT id, name, description, global_orchestrator_agent_id, is_enabled, created_at, updated_at
126
- FROM teams
125
+ .prepare(`SELECT id, name, description, global_orchestrator_agent_id, is_enabled, created_at, updated_at
126
+ FROM teams
127
127
  WHERE name = ?`)
128
128
  .get(requireText(name, 'name'));
129
129
  return rowToTeam(row);
@@ -133,8 +133,8 @@ export async function createTeam(input) {
133
133
  const id = randomUUID();
134
134
  const name = requireText(input.name, 'name');
135
135
  const now = nowIso();
136
- db.prepare(`INSERT INTO teams (
137
- id, name, description, global_orchestrator_agent_id, is_enabled, created_at, updated_at
136
+ db.prepare(`INSERT INTO teams (
137
+ id, name, description, global_orchestrator_agent_id, is_enabled, created_at, updated_at
138
138
  ) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(id, name, toNullableText(input.description), toNullableText(input.globalOrchestratorAgentId), toDbBoolean(resolveBoolean(input.isEnabled, true)), now, now);
139
139
  const created = await getTeamById(id);
140
140
  if (!created) {
@@ -156,8 +156,8 @@ export async function updateTeam(id, input) {
156
156
  ? existing.globalOrchestratorAgentId
157
157
  : toNullableText(input.globalOrchestratorAgentId);
158
158
  const isEnabled = resolveBoolean(input.isEnabled, existing.isEnabled);
159
- db.prepare(`UPDATE teams
160
- SET name = ?, description = ?, global_orchestrator_agent_id = ?, is_enabled = ?, updated_at = ?
159
+ db.prepare(`UPDATE teams
160
+ SET name = ?, description = ?, global_orchestrator_agent_id = ?, is_enabled = ?, updated_at = ?
161
161
  WHERE id = ?`).run(name, description, globalOrchestratorAgentId, toDbBoolean(isEnabled), nowIso(), id);
162
162
  const updated = await getTeamRowById(id);
163
163
  if (!updated) {
@@ -178,9 +178,9 @@ export async function deleteTeam(id) {
178
178
  export async function listTeamUnits(teamId) {
179
179
  const db = await getOrchestrationDatabase();
180
180
  return db
181
- .prepare(`SELECT id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at
182
- FROM team_units
183
- WHERE team_id = ?
181
+ .prepare(`SELECT id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at
182
+ FROM team_units
183
+ WHERE team_id = ?
184
184
  ORDER BY unit_name, created_at, id`)
185
185
  .all(requireText(teamId, 'teamId'))
186
186
  .map(rowToTeamUnit)
@@ -200,8 +200,8 @@ export async function createTeamUnit(input) {
200
200
  const db = await getOrchestrationDatabase();
201
201
  const id = randomUUID();
202
202
  const now = nowIso();
203
- db.prepare(`INSERT INTO team_units (
204
- id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at
203
+ db.prepare(`INSERT INTO team_units (
204
+ id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at
205
205
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.teamId, 'teamId'), requireText(input.unitName, 'unitName'), toNullableText(input.workspaceId), toNullableText(input.localOrchestratorAgentId), toNullableText(input.leadAgentId), resolveSelectionMode(input.selectionMode), toDbBoolean(resolveBoolean(input.required, false)), now, now);
206
206
  const created = await getTeamUnitById(id);
207
207
  if (!created) {
@@ -229,8 +229,8 @@ export async function updateTeamUnit(id, input) {
229
229
  ? existing.selectionMode
230
230
  : resolveSelectionMode(input.selectionMode, existing.selectionMode);
231
231
  const required = resolveBoolean(input.required, existing.required);
232
- db.prepare(`UPDATE team_units
233
- SET unit_name = ?, workspace_id = ?, local_orchestrator_agent_id = ?, lead_agent_id = ?, selection_mode = ?, required = ?, updated_at = ?
232
+ db.prepare(`UPDATE team_units
233
+ SET unit_name = ?, workspace_id = ?, local_orchestrator_agent_id = ?, lead_agent_id = ?, selection_mode = ?, required = ?, updated_at = ?
234
234
  WHERE id = ?`).run(unitName, workspaceId, localOrchestratorAgentId, leadAgentId, selectionMode, toDbBoolean(required), nowIso(), id);
235
235
  const updated = await getTeamUnitRowById(id);
236
236
  if (!updated) {
@@ -251,9 +251,9 @@ export async function deleteTeamUnit(id) {
251
251
  export async function listTeamUnitMembers(teamUnitId) {
252
252
  const db = await getOrchestrationDatabase();
253
253
  return db
254
- .prepare(`SELECT id, team_unit_id, agent_id, duty, priority, created_at, updated_at
255
- FROM team_unit_members
256
- WHERE team_unit_id = ?
254
+ .prepare(`SELECT id, team_unit_id, agent_id, duty, priority, created_at, updated_at
255
+ FROM team_unit_members
256
+ WHERE team_unit_id = ?
257
257
  ORDER BY priority DESC, created_at, id`)
258
258
  .all(requireText(teamUnitId, 'teamUnitId'))
259
259
  .map(rowToTeamUnitMember)
@@ -269,8 +269,8 @@ export async function createTeamUnitMember(input) {
269
269
  const db = await getOrchestrationDatabase();
270
270
  const id = randomUUID();
271
271
  const now = nowIso();
272
- db.prepare(`INSERT INTO team_unit_members (
273
- id, team_unit_id, agent_id, duty, priority, created_at, updated_at
272
+ db.prepare(`INSERT INTO team_unit_members (
273
+ id, team_unit_id, agent_id, duty, priority, created_at, updated_at
274
274
  ) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.teamUnitId, 'teamUnitId'), requireText(input.agentId, 'agentId'), toNullableText(input.duty), resolvePriority(input.priority), now, now);
275
275
  const created = await getTeamUnitMemberById(id);
276
276
  if (!created) {
@@ -286,8 +286,8 @@ export async function updateTeamUnitMember(id, input) {
286
286
  const db = await getOrchestrationDatabase();
287
287
  const duty = input.duty === undefined ? existing.duty : toNullableText(input.duty);
288
288
  const priority = resolvePriority(input.priority, existing.priority);
289
- db.prepare(`UPDATE team_unit_members
290
- SET duty = ?, priority = ?, updated_at = ?
289
+ db.prepare(`UPDATE team_unit_members
290
+ SET duty = ?, priority = ?, updated_at = ?
291
291
  WHERE id = ?`).run(duty, priority, nowIso(), id);
292
292
  const updated = await getTeamUnitMemberRowById(id);
293
293
  if (!updated) {
@@ -117,12 +117,12 @@ export async function generatePermissionExplanation({ toolName, toolInput, toolD
117
117
  const conversationContext = messages?.length
118
118
  ? extractConversationContext(messages)
119
119
  : '';
120
- const userPrompt = `Tool: ${toolName}
121
- ${toolDescription ? `Description: ${toolDescription}\n` : ''}
122
- Input:
123
- ${formattedInput}
124
- ${conversationContext ? `\nRecent conversation context:\n${conversationContext}` : ''}
125
-
120
+ const userPrompt = `Tool: ${toolName}
121
+ ${toolDescription ? `Description: ${toolDescription}\n` : ''}
122
+ Input:
123
+ ${formattedInput}
124
+ ${conversationContext ? `\nRecent conversation context:\n${conversationContext}` : ''}
125
+
126
126
  Explain this command in context.`;
127
127
  const model = getMainLoopModel();
128
128
  // Use sideQuery with forced tool choice for guaranteed structured output
@@ -19,12 +19,12 @@ export async function upsertPermissionRule(scope, scopePath, toolName, behavior,
19
19
  const db = (await ProviderProfilesDb.get()).db;
20
20
  const now = new Date().toISOString();
21
21
  const id = randomUUID();
22
- db.prepare(`
23
- INSERT INTO permission_rules (id, scope, scope_path, tool_name, behavior, created_at, expires_at)
24
- VALUES (?, ?, ?, ?, ?, ?, ?)
25
- ON CONFLICT(scope, scope_path, tool_name) DO UPDATE SET
26
- behavior = excluded.behavior,
27
- expires_at = excluded.expires_at
22
+ db.prepare(`
23
+ INSERT INTO permission_rules (id, scope, scope_path, tool_name, behavior, created_at, expires_at)
24
+ VALUES (?, ?, ?, ?, ?, ?, ?)
25
+ ON CONFLICT(scope, scope_path, tool_name) DO UPDATE SET
26
+ behavior = excluded.behavior,
27
+ expires_at = excluded.expires_at
28
28
  `).run(id, scope, scopePath ?? null, toolName, behavior, now, expiresAt ?? null);
29
29
  return { id, scope, scopePath: scopePath ?? null, toolName, behavior, createdAt: now, expiresAt: expiresAt ?? null };
30
30
  }
@@ -35,10 +35,10 @@ export async function upsertPermissionRule(scope, scopePath, toolName, behavior,
35
35
  export async function getPermissionRules(scope, scopePath) {
36
36
  const db = (await ProviderProfilesDb.get()).db;
37
37
  const now = new Date().toISOString();
38
- let sql = `
39
- SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at
40
- FROM permission_rules
41
- WHERE (expires_at IS NULL OR expires_at > ?)
38
+ let sql = `
39
+ SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at
40
+ FROM permission_rules
41
+ WHERE (expires_at IS NULL OR expires_at > ?)
42
42
  `;
43
43
  const params = [now];
44
44
  if (scope !== undefined) {
@@ -70,24 +70,24 @@ export async function findPermissionRule(toolName, projectPath, directoryPath) {
70
70
  }
71
71
  scopes.push({ scope: 'global', path: null });
72
72
  for (const { scope, path } of scopes) {
73
- const row = db.prepare(`
74
- SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at
75
- FROM permission_rules
76
- WHERE tool_name = ? AND scope = ? AND scope_path IS ?
77
- AND (expires_at IS NULL OR expires_at > ?)
78
- LIMIT 1
73
+ const row = db.prepare(`
74
+ SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at
75
+ FROM permission_rules
76
+ WHERE tool_name = ? AND scope = ? AND scope_path IS ?
77
+ AND (expires_at IS NULL OR expires_at > ?)
78
+ LIMIT 1
79
79
  `).get(toolName, scope, path, now);
80
80
  if (row) {
81
81
  return rowToPermissionRule(row);
82
82
  }
83
83
  // Also check wildcard patterns — e.g. tool_name = 'Bash(find:*)'
84
84
  // matches the query for 'Bash(find:/some/path)'
85
- const wildcardRows = db.prepare(`
86
- SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at
87
- FROM permission_rules
88
- WHERE scope = ? AND scope_path IS ?
89
- AND (expires_at IS NULL OR expires_at > ?)
90
- ORDER BY created_at DESC
85
+ const wildcardRows = db.prepare(`
86
+ SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at
87
+ FROM permission_rules
88
+ WHERE scope = ? AND scope_path IS ?
89
+ AND (expires_at IS NULL OR expires_at > ?)
90
+ ORDER BY created_at DESC
91
91
  `).all(scope, path, now);
92
92
  for (const wRow of wildcardRows) {
93
93
  const pattern = String(wRow.tool_name ?? '');
@@ -137,12 +137,12 @@ export async function setPermissionMode(scope, mode, scopePath) {
137
137
  const db = (await ProviderProfilesDb.get()).db;
138
138
  const now = new Date().toISOString();
139
139
  const id = randomUUID();
140
- db.prepare(`
141
- INSERT INTO permission_mode_config (id, scope, scope_path, mode, updated_at)
142
- VALUES (?, ?, ?, ?, ?)
143
- ON CONFLICT(scope, scope_path) DO UPDATE SET
144
- mode = excluded.mode,
145
- updated_at = excluded.updated_at
140
+ db.prepare(`
141
+ INSERT INTO permission_mode_config (id, scope, scope_path, mode, updated_at)
142
+ VALUES (?, ?, ?, ?, ?)
143
+ ON CONFLICT(scope, scope_path) DO UPDATE SET
144
+ mode = excluded.mode,
145
+ updated_at = excluded.updated_at
146
146
  `).run(id, scope, scopePath ?? null, mode, now);
147
147
  }
148
148
  /**
@@ -151,17 +151,17 @@ export async function setPermissionMode(scope, mode, scopePath) {
151
151
  export async function getEffectivePermissionMode(projectPath) {
152
152
  const db = (await ProviderProfilesDb.get()).db;
153
153
  if (projectPath) {
154
- const projectRow = db.prepare(`
155
- SELECT mode FROM permission_mode_config
156
- WHERE scope = 'project' AND scope_path = ?
154
+ const projectRow = db.prepare(`
155
+ SELECT mode FROM permission_mode_config
156
+ WHERE scope = 'project' AND scope_path = ?
157
157
  `).get(projectPath);
158
158
  if (projectRow?.mode) {
159
159
  return projectRow.mode;
160
160
  }
161
161
  }
162
- const globalRow = db.prepare(`
163
- SELECT mode FROM permission_mode_config
164
- WHERE scope = 'global' AND scope_path IS NULL
162
+ const globalRow = db.prepare(`
163
+ SELECT mode FROM permission_mode_config
164
+ WHERE scope = 'global' AND scope_path IS NULL
165
165
  `).get();
166
166
  return globalRow?.mode ?? 'default';
167
167
  }
@@ -170,10 +170,10 @@ export async function getEffectivePermissionMode(projectPath) {
170
170
  */
171
171
  export async function getAllPermissionModes() {
172
172
  const db = (await ProviderProfilesDb.get()).db;
173
- const rows = db.prepare(`
174
- SELECT id, scope, scope_path, mode, updated_at
175
- FROM permission_mode_config
176
- ORDER BY scope, scope_path
173
+ const rows = db.prepare(`
174
+ SELECT id, scope, scope_path, mode, updated_at
175
+ FROM permission_mode_config
176
+ ORDER BY scope, scope_path
177
177
  `).all();
178
178
  return rows.map(row => ({
179
179
  id: String(row.id ?? ''),
@@ -192,11 +192,11 @@ export async function getAllPermissionModes() {
192
192
  export async function addTrustedDirectory(path, trustLevel = 'full') {
193
193
  const db = (await ProviderProfilesDb.get()).db;
194
194
  const now = new Date().toISOString();
195
- db.prepare(`
196
- INSERT INTO trusted_directories (path, trust_level, created_at)
197
- VALUES (?, ?, ?)
198
- ON CONFLICT(path) DO UPDATE SET
199
- trust_level = excluded.trust_level
195
+ db.prepare(`
196
+ INSERT INTO trusted_directories (path, trust_level, created_at)
197
+ VALUES (?, ?, ?)
198
+ ON CONFLICT(path) DO UPDATE SET
199
+ trust_level = excluded.trust_level
200
200
  `).run(path, trustLevel, now);
201
201
  }
202
202
  /**
@@ -1,8 +1,10 @@
1
1
  import { randomUUID } from 'crypto';
2
2
  import { getIsNonInteractiveSession, getSessionId } from '../bootstrap/state.js';
3
+ import { recordSdkEvent } from '../core/tasks/sdkAdapter.js';
3
4
  const MAX_QUEUE_SIZE = 1000;
4
5
  const queue = [];
5
6
  export function enqueueSdkEvent(event) {
7
+ recordSdkEvent(event);
6
8
  // SDK events are only consumed (drained) in headless/streaming mode.
7
9
  // In TUI mode they would accumulate up to the cap and never be read.
8
10
  if (!getIsNonInteractiveSession()) {