@agimon-ai/doompi-task 0.0.1-alpha.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 (190) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  4. package/dist/commands.cjs +2 -0
  5. package/dist/commands.cjs.map +1 -0
  6. package/dist/commands.d.cts +14 -0
  7. package/dist/commands.d.cts.map +1 -0
  8. package/dist/commands.d.mts +14 -0
  9. package/dist/commands.d.mts.map +1 -0
  10. package/dist/commands.mjs +2 -0
  11. package/dist/commands.mjs.map +1 -0
  12. package/dist/config.cjs +2 -0
  13. package/dist/config.cjs.map +1 -0
  14. package/dist/config.d.cts +38 -0
  15. package/dist/config.d.cts.map +1 -0
  16. package/dist/config.d.mts +38 -0
  17. package/dist/config.d.mts.map +1 -0
  18. package/dist/config.mjs +2 -0
  19. package/dist/config.mjs.map +1 -0
  20. package/dist/delegation/manager.cjs +5 -0
  21. package/dist/delegation/manager.cjs.map +1 -0
  22. package/dist/delegation/manager.d.cts +189 -0
  23. package/dist/delegation/manager.d.cts.map +1 -0
  24. package/dist/delegation/manager.d.mts +189 -0
  25. package/dist/delegation/manager.d.mts.map +1 -0
  26. package/dist/delegation/manager.mjs +5 -0
  27. package/dist/delegation/manager.mjs.map +1 -0
  28. package/dist/extension.cjs +3 -0
  29. package/dist/extension.cjs.map +1 -0
  30. package/dist/extension.d.cts +12 -0
  31. package/dist/extension.d.cts.map +1 -0
  32. package/dist/extension.d.mts +12 -0
  33. package/dist/extension.d.mts.map +1 -0
  34. package/dist/extension.mjs +3 -0
  35. package/dist/extension.mjs.map +1 -0
  36. package/dist/extensions/doom.cjs +2 -0
  37. package/dist/extensions/doom.cjs.map +1 -0
  38. package/dist/extensions/doom.d.cts +6 -0
  39. package/dist/extensions/doom.d.cts.map +1 -0
  40. package/dist/extensions/doom.d.mts +7 -0
  41. package/dist/extensions/doom.d.mts.map +1 -0
  42. package/dist/extensions/doom.mjs +2 -0
  43. package/dist/extensions/doom.mjs.map +1 -0
  44. package/dist/extensions/pi.cjs +2 -0
  45. package/dist/extensions/pi.cjs.map +1 -0
  46. package/dist/extensions/pi.d.cts +2 -0
  47. package/dist/extensions/pi.d.mts +2 -0
  48. package/dist/extensions/pi.mjs +2 -0
  49. package/dist/extensions/pi.mjs.map +1 -0
  50. package/dist/index.cjs +1 -0
  51. package/dist/index.d.cts +15 -0
  52. package/dist/index.d.mts +15 -0
  53. package/dist/index.mjs +1 -0
  54. package/dist/logSinkTelemetry.cjs +2 -0
  55. package/dist/logSinkTelemetry.cjs.map +1 -0
  56. package/dist/logSinkTelemetry.d.cts +51 -0
  57. package/dist/logSinkTelemetry.d.cts.map +1 -0
  58. package/dist/logSinkTelemetry.d.mts +51 -0
  59. package/dist/logSinkTelemetry.d.mts.map +1 -0
  60. package/dist/logSinkTelemetry.mjs +2 -0
  61. package/dist/logSinkTelemetry.mjs.map +1 -0
  62. package/dist/store/invariants.cjs +2 -0
  63. package/dist/store/invariants.cjs.map +1 -0
  64. package/dist/store/invariants.d.cts +14 -0
  65. package/dist/store/invariants.d.cts.map +1 -0
  66. package/dist/store/invariants.d.mts +14 -0
  67. package/dist/store/invariants.d.mts.map +1 -0
  68. package/dist/store/invariants.mjs +2 -0
  69. package/dist/store/invariants.mjs.map +1 -0
  70. package/dist/store/paths.cjs +2 -0
  71. package/dist/store/paths.cjs.map +1 -0
  72. package/dist/store/paths.d.cts +23 -0
  73. package/dist/store/paths.d.cts.map +1 -0
  74. package/dist/store/paths.d.mts +23 -0
  75. package/dist/store/paths.d.mts.map +1 -0
  76. package/dist/store/paths.mjs +2 -0
  77. package/dist/store/paths.mjs.map +1 -0
  78. package/dist/store/processLiveness.cjs +2 -0
  79. package/dist/store/processLiveness.cjs.map +1 -0
  80. package/dist/store/processLiveness.d.cts +12 -0
  81. package/dist/store/processLiveness.d.cts.map +1 -0
  82. package/dist/store/processLiveness.d.mts +12 -0
  83. package/dist/store/processLiveness.d.mts.map +1 -0
  84. package/dist/store/processLiveness.mjs +2 -0
  85. package/dist/store/processLiveness.mjs.map +1 -0
  86. package/dist/store/reconcile.cjs +2 -0
  87. package/dist/store/reconcile.cjs.map +1 -0
  88. package/dist/store/reconcile.d.cts +34 -0
  89. package/dist/store/reconcile.d.cts.map +1 -0
  90. package/dist/store/reconcile.d.mts +34 -0
  91. package/dist/store/reconcile.d.mts.map +1 -0
  92. package/dist/store/reconcile.mjs +2 -0
  93. package/dist/store/reconcile.mjs.map +1 -0
  94. package/dist/store/reducer.cjs +3 -0
  95. package/dist/store/reducer.cjs.map +1 -0
  96. package/dist/store/reducer.d.cts +72 -0
  97. package/dist/store/reducer.d.cts.map +1 -0
  98. package/dist/store/reducer.d.mts +72 -0
  99. package/dist/store/reducer.d.mts.map +1 -0
  100. package/dist/store/reducer.mjs +3 -0
  101. package/dist/store/reducer.mjs.map +1 -0
  102. package/dist/store/taskGraph.cjs +2 -0
  103. package/dist/store/taskGraph.cjs.map +1 -0
  104. package/dist/store/taskGraph.d.cts +25 -0
  105. package/dist/store/taskGraph.d.cts.map +1 -0
  106. package/dist/store/taskGraph.d.mts +25 -0
  107. package/dist/store/taskGraph.d.mts.map +1 -0
  108. package/dist/store/taskGraph.mjs +2 -0
  109. package/dist/store/taskGraph.mjs.map +1 -0
  110. package/dist/store/taskStore.cjs +2 -0
  111. package/dist/store/taskStore.cjs.map +1 -0
  112. package/dist/store/taskStore.d.cts +77 -0
  113. package/dist/store/taskStore.d.cts.map +1 -0
  114. package/dist/store/taskStore.d.mts +77 -0
  115. package/dist/store/taskStore.d.mts.map +1 -0
  116. package/dist/store/taskStore.mjs +2 -0
  117. package/dist/store/taskStore.mjs.map +1 -0
  118. package/dist/store/types.cjs +2 -0
  119. package/dist/store/types.cjs.map +1 -0
  120. package/dist/store/types.d.cts +165 -0
  121. package/dist/store/types.d.cts.map +1 -0
  122. package/dist/store/types.d.mts +165 -0
  123. package/dist/store/types.d.mts.map +1 -0
  124. package/dist/store/types.mjs +2 -0
  125. package/dist/store/types.mjs.map +1 -0
  126. package/dist/tool/promptGuidelines.cjs +2 -0
  127. package/dist/tool/promptGuidelines.cjs.map +1 -0
  128. package/dist/tool/promptGuidelines.d.cts +5 -0
  129. package/dist/tool/promptGuidelines.d.cts.map +1 -0
  130. package/dist/tool/promptGuidelines.d.mts +5 -0
  131. package/dist/tool/promptGuidelines.d.mts.map +1 -0
  132. package/dist/tool/promptGuidelines.mjs +2 -0
  133. package/dist/tool/promptGuidelines.mjs.map +1 -0
  134. package/dist/tool/responseEnvelope.cjs +6 -0
  135. package/dist/tool/responseEnvelope.cjs.map +1 -0
  136. package/dist/tool/responseEnvelope.d.cts +39 -0
  137. package/dist/tool/responseEnvelope.d.cts.map +1 -0
  138. package/dist/tool/responseEnvelope.d.mts +39 -0
  139. package/dist/tool/responseEnvelope.d.mts.map +1 -0
  140. package/dist/tool/responseEnvelope.mjs +6 -0
  141. package/dist/tool/responseEnvelope.mjs.map +1 -0
  142. package/dist/tool/schema.cjs +2 -0
  143. package/dist/tool/schema.cjs.map +1 -0
  144. package/dist/tool/schema.d.cts +86 -0
  145. package/dist/tool/schema.d.cts.map +1 -0
  146. package/dist/tool/schema.d.mts +86 -0
  147. package/dist/tool/schema.d.mts.map +1 -0
  148. package/dist/tool/schema.mjs +2 -0
  149. package/dist/tool/schema.mjs.map +1 -0
  150. package/dist/tool/taskTool.cjs +3 -0
  151. package/dist/tool/taskTool.cjs.map +1 -0
  152. package/dist/tool/taskTool.d.cts +17 -0
  153. package/dist/tool/taskTool.d.cts.map +1 -0
  154. package/dist/tool/taskTool.d.mts +17 -0
  155. package/dist/tool/taskTool.d.mts.map +1 -0
  156. package/dist/tool/taskTool.mjs +3 -0
  157. package/dist/tool/taskTool.mjs.map +1 -0
  158. package/dist/tui/format.cjs +4 -0
  159. package/dist/tui/format.cjs.map +1 -0
  160. package/dist/tui/format.d.cts +62 -0
  161. package/dist/tui/format.d.cts.map +1 -0
  162. package/dist/tui/format.d.mts +62 -0
  163. package/dist/tui/format.d.mts.map +1 -0
  164. package/dist/tui/format.mjs +4 -0
  165. package/dist/tui/format.mjs.map +1 -0
  166. package/dist/tui/selectors.cjs +2 -0
  167. package/dist/tui/selectors.cjs.map +1 -0
  168. package/dist/tui/selectors.d.cts +45 -0
  169. package/dist/tui/selectors.d.cts.map +1 -0
  170. package/dist/tui/selectors.d.mts +45 -0
  171. package/dist/tui/selectors.d.mts.map +1 -0
  172. package/dist/tui/selectors.mjs +2 -0
  173. package/dist/tui/selectors.mjs.map +1 -0
  174. package/dist/tui/taskOverlay.cjs +2 -0
  175. package/dist/tui/taskOverlay.cjs.map +1 -0
  176. package/dist/tui/taskOverlay.d.cts +38 -0
  177. package/dist/tui/taskOverlay.d.cts.map +1 -0
  178. package/dist/tui/taskOverlay.d.mts +38 -0
  179. package/dist/tui/taskOverlay.d.mts.map +1 -0
  180. package/dist/tui/taskOverlay.mjs +2 -0
  181. package/dist/tui/taskOverlay.mjs.map +1 -0
  182. package/dist/tui/taskSpace.cjs +5 -0
  183. package/dist/tui/taskSpace.cjs.map +1 -0
  184. package/dist/tui/taskSpace.d.cts +61 -0
  185. package/dist/tui/taskSpace.d.cts.map +1 -0
  186. package/dist/tui/taskSpace.d.mts +61 -0
  187. package/dist/tui/taskSpace.d.mts.map +1 -0
  188. package/dist/tui/taskSpace.mjs +5 -0
  189. package/dist/tui/taskSpace.mjs.map +1 -0
  190. package/package.json +185 -0
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require("../delegation/manager.cjs");let e=require("@agimon-ai/doompi-extension-contracts/subagent-tool"),t=require("typebox");const n=[`upsert`,`list`,`get`,`delete`,`clear`,`assign`,`cancel`],r=[`pending`,`in_progress`,`completed`,`failed`,`deleted`],i=[`fresh`,`fork`],a={upsert:[`action`,`tasks`],list:[`action`,`status`,`includeDeleted`],get:[`action`,`id`],delete:[`action`,`id`],clear:[`action`],assign:[`action`,`id`,`agent`,`inlineAgent`,`instructions`,`relevantFiles`,`priorFindings`,`model`,`context`],cancel:[`action`,`id`]};function o(e,t){return a[e].includes(t)}const s=t.Type.Union([t.Type.Integer(),t.Type.String()]),c=t.Type.Object({id:t.Type.Optional(t.Type.Integer({description:`Existing task id to change. Omit to create a new task. An entry with an id never creates: if the id is unknown, only that entry fails.`})),ref:t.Type.Optional(t.Type.String({description:`Temporary name for a task created by this entry, so a LATER entry in the same tasks[] can list it in blockedBy before its real id exists. Must start with a letter. Scoped to this one call and never stored; the response reports which real id it became.`})),subject:t.Type.Optional(t.Type.String({description:`Short imperative subject line (e.g. 'Research existing tool'). Required when the entry has no id; on an entry with an id it renames the task.`})),description:t.Type.Optional(t.Type.String({description:`Long-form task detail. This becomes the brief handed to the subagent when the task is assigned.`})),activeForm:t.Type.Optional(t.Type.String({description:`Present-continuous spinner label shown while status is in_progress (e.g. 'writing tests')`})),status:t.Type.Optional(t.Type.String({enum:[...r],description:`Starting status for a new entry (default pending; deleted is rejected), or the target status for an entry with an id, where the transition must be legal.`})),blockedBy:t.Type.Optional(t.Type.Array(s,{description:`Dependencies for a NEW entry (one with no id): this task is blocked by each target. A number is an existing task id; a string is the ref of a task created by an EARLIER entry in this same array. Use addBlockedBy / removeBlockedBy on an entry that has an id.`})),addBlockedBy:t.Type.Optional(t.Type.Array(s,{description:`Dependencies to add, for an entry with an id. Task ids, or refs declared by an earlier entry. Additive merge — do not resend the full array.`})),removeBlockedBy:t.Type.Optional(t.Type.Array(s,{description:`Dependencies to remove, for an entry with an id. Additive merge — do not resend the full array.`})),owner:t.Type.Optional(t.Type.String({description:`Owner label for this task. assign sets this to the subagent name automatically.`})),metadata:t.Type.Optional(t.Type.Record(t.Type.String(),t.Type.Unknown(),{description:`Arbitrary metadata merged into the task; pass null as a value to delete that key`}))},{additionalProperties:!1}),l=t.Type.Object({action:t.Type.String({enum:[...n],description:`upsert (create new tasks and change existing ones, one or many per call), list, get, delete (tombstone), clear (close/reset the list), assign (delegate to a subagent), cancel (stop a delegated run)`}),tasks:t.Type.Optional(t.Type.Array(c,{minItems:1,description:`upsert only. One entry per task: an entry with an id changes that task, an entry without an id creates one. Entries apply in array order, so a later entry can depend on an earlier one by ref. Each entry succeeds or fails on its own: the ones that succeed are committed and the ones that fail are reported by their array index.`})),id:t.Type.Optional(t.Type.Integer({description:`Task id, for get, delete, assign and cancel. upsert does not accept this field — put the id inside the tasks[] entry you want to change.`})),status:t.Type.Optional(t.Type.String({enum:[...r],description:`list only: return just the tasks in this status. To SET a status, use upsert with the task id inside tasks[].`})),includeDeleted:t.Type.Optional(t.Type.Boolean({description:`If true, list returns deleted (tombstoned) tasks as well. Default: false.`})),agent:t.Type.Optional(t.Type.String({description:`Name of the subagent to delegate this task to (required for assign)`})),inlineAgent:t.Type.Optional(e.InlineAgentSchema),instructions:t.Type.Optional(t.Type.String({description:`Extra instructions appended to the delegated brief (assign only)`})),relevantFiles:t.Type.Optional(t.Type.Array(t.Type.String(),{description:`Files you have ALREADY read or located that the subagent should open first (assign only). Paths relative to the working directory. A child starts with none of your context and otherwise spends most of its run rediscovering the repo. Send only files you actually looked at — a guessed path costs the child more than an omitted one. At most 12; extras are dropped.`})),priorFindings:t.Type.Optional(t.Type.String({description:`What you already established about this task and the subagent should not re-derive (assign only): symbol names, call sites, the approach you chose, what you already ruled out. Facts you discovered, not directives — put directives in instructions. Keep it to a few lines; it is truncated past ~1500 characters.`})),model:t.Type.Optional(t.Type.String({description:`Model override for the delegated run (assign only)`})),context:t.Type.Optional(t.Type.String({enum:[...i],description:`Subagent starting context (assign only): 'fresh' starts clean, 'fork' inherits this conversation. If omitted, uses the agent default, then fresh.`}))});exports.COMMAND_NAME=`tasks`,exports.ERR_REQUIRES_INTERACTIVE=`/tasks requires interactive mode`,exports.MSG_NO_TASKS=`No tasks yet. Ask the agent to add some!`,exports.MSG_UPSERT_FIELD_MISPLACED=`Per-task fields belong inside each tasks[] entry, not at the top level: {"action":"upsert","tasks":[{"id":3,"status":"completed"}]}.`,exports.TASK_ACTIONS=n,exports.TASK_ACTION_FIELDS=a,exports.TASK_CONTEXTS=i,exports.TASK_STATUSES=r,exports.TOOL_LABEL=`Task`,exports.TOOL_NAME=`task`,exports.TaskItemSchema=c,exports.TaskParamsSchema=l,exports.taskActionAcceptsField=o;
2
+ //# sourceMappingURL=schema.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.cjs","names":["Type","InlineAgentSchema"],"sources":["../../src/tool/schema.ts"],"sourcesContent":["import { InlineAgentSchema } from '@agimon-ai/doompi-extension-contracts/subagent-tool';\nimport { type Static, Type } from 'typebox';\nimport { MAX_BRIEF_FILES } from '../delegation/manager.ts';\nimport type { TaskAction } from '../store/types.ts';\n\nexport const TASK_ACTIONS = ['upsert', 'list', 'get', 'delete', 'clear', 'assign', 'cancel'] as const;\nexport const TASK_STATUSES = ['pending', 'in_progress', 'completed', 'failed', 'deleted'] as const;\nexport const TASK_CONTEXTS = ['fresh', 'fork'] as const;\n\nexport const TOOL_NAME = 'task';\nexport const TOOL_LABEL = 'Task';\nexport const COMMAND_NAME = 'tasks';\n\nexport const ERR_REQUIRES_INTERACTIVE = '/tasks requires interactive mode';\nexport const MSG_NO_TASKS = 'No tasks yet. Ask the agent to add some!';\n\n/**\n * Which top-level fields each action accepts.\n *\n * The params object is flat and shared across every action, so the schema alone\n * cannot express \"upsert has no top-level id\". That gap matters: a call like\n * `{\"action\":\"upsert\",\"id\":3,\"tasks\":[{\"status\":\"completed\"}]}` would otherwise\n * silently create a duplicate task, because the entry itself carries no id.\n */\nexport const TASK_ACTION_FIELDS = {\n upsert: ['action', 'tasks'],\n list: ['action', 'status', 'includeDeleted'],\n get: ['action', 'id'],\n delete: ['action', 'id'],\n clear: ['action'],\n assign: [\n 'action',\n 'id',\n 'agent',\n 'inlineAgent',\n 'instructions',\n 'relevantFiles',\n 'priorFindings',\n 'model',\n 'context',\n ],\n cancel: ['action', 'id'],\n} as const satisfies Record<TaskAction, readonly string[]>;\n\nexport function taskActionAcceptsField(action: TaskAction, field: string): boolean {\n return (TASK_ACTION_FIELDS[action] as readonly string[]).includes(field);\n}\n\n/** Correction hint appended when a per-task field lands at the top level. */\nexport const MSG_UPSERT_FIELD_MISPLACED =\n 'Per-task fields belong inside each tasks[] entry, not at the top level: {\"action\":\"upsert\",\"tasks\":[{\"id\":3,\"status\":\"completed\"}]}.';\n\n/**\n * A dependency target: an existing task id, or the `ref` of a task created\n * earlier in the same call.\n */\nconst DepTokenSchema = Type.Union([Type.Integer(), Type.String()]);\n\n/**\n * One entry of an upsert. `additionalProperties: false` is load-bearing: pi\n * validates tool arguments against this schema before `execute` runs, so a\n * stray `{\"action\":\"update\"}` inside an entry is rejected at the boundary.\n */\nexport const TaskItemSchema = Type.Object(\n {\n id: Type.Optional(\n Type.Integer({\n description:\n 'Existing task id to change. Omit to create a new task. An entry with an id never creates: if the id is unknown, only that entry fails.',\n }),\n ),\n ref: Type.Optional(\n Type.String({\n description:\n 'Temporary name for a task created by this entry, so a LATER entry in the same tasks[] can list it in blockedBy before its real id exists. Must start with a letter. Scoped to this one call and never stored; the response reports which real id it became.',\n }),\n ),\n subject: Type.Optional(\n Type.String({\n description:\n \"Short imperative subject line (e.g. 'Research existing tool'). Required when the entry has no id; on an entry with an id it renames the task.\",\n }),\n ),\n description: Type.Optional(\n Type.String({\n description: 'Long-form task detail. This becomes the brief handed to the subagent when the task is assigned.',\n }),\n ),\n activeForm: Type.Optional(\n Type.String({\n description: \"Present-continuous spinner label shown while status is in_progress (e.g. 'writing tests')\",\n }),\n ),\n status: Type.Optional(\n Type.String({\n enum: [...TASK_STATUSES],\n description:\n 'Starting status for a new entry (default pending; deleted is rejected), or the target status for an entry with an id, where the transition must be legal.',\n }),\n ),\n blockedBy: Type.Optional(\n Type.Array(DepTokenSchema, {\n description:\n 'Dependencies for a NEW entry (one with no id): this task is blocked by each target. A number is an existing task id; a string is the ref of a task created by an EARLIER entry in this same array. Use addBlockedBy / removeBlockedBy on an entry that has an id.',\n }),\n ),\n addBlockedBy: Type.Optional(\n Type.Array(DepTokenSchema, {\n description:\n 'Dependencies to add, for an entry with an id. Task ids, or refs declared by an earlier entry. Additive merge — do not resend the full array.',\n }),\n ),\n removeBlockedBy: Type.Optional(\n Type.Array(DepTokenSchema, {\n description: 'Dependencies to remove, for an entry with an id. Additive merge — do not resend the full array.',\n }),\n ),\n owner: Type.Optional(\n Type.String({ description: 'Owner label for this task. assign sets this to the subagent name automatically.' }),\n ),\n metadata: Type.Optional(\n Type.Record(Type.String(), Type.Unknown(), {\n description: 'Arbitrary metadata merged into the task; pass null as a value to delete that key',\n }),\n ),\n },\n { additionalProperties: false },\n);\n\n/**\n * Tool parameters. Every `description` doubles as LLM-facing prompt copy, so\n * wording changes here change model behaviour.\n */\nexport const TaskParamsSchema = Type.Object({\n action: Type.String({\n enum: [...TASK_ACTIONS],\n description:\n 'upsert (create new tasks and change existing ones, one or many per call), list, get, delete (tombstone), clear (close/reset the list), assign (delegate to a subagent), cancel (stop a delegated run)',\n }),\n tasks: Type.Optional(\n Type.Array(TaskItemSchema, {\n minItems: 1,\n description:\n 'upsert only. One entry per task: an entry with an id changes that task, an entry without an id creates one. Entries apply in array order, so a later entry can depend on an earlier one by ref. Each entry succeeds or fails on its own: the ones that succeed are committed and the ones that fail are reported by their array index.',\n }),\n ),\n id: Type.Optional(\n Type.Integer({\n description:\n 'Task id, for get, delete, assign and cancel. upsert does not accept this field — put the id inside the tasks[] entry you want to change.',\n }),\n ),\n status: Type.Optional(\n Type.String({\n enum: [...TASK_STATUSES],\n description:\n 'list only: return just the tasks in this status. To SET a status, use upsert with the task id inside tasks[].',\n }),\n ),\n includeDeleted: Type.Optional(\n Type.Boolean({\n description: 'If true, list returns deleted (tombstoned) tasks as well. Default: false.',\n }),\n ),\n agent: Type.Optional(\n Type.String({\n description: 'Name of the subagent to delegate this task to (required for assign)',\n }),\n ),\n inlineAgent: Type.Optional(InlineAgentSchema),\n instructions: Type.Optional(\n Type.String({\n description: 'Extra instructions appended to the delegated brief (assign only)',\n }),\n ),\n relevantFiles: Type.Optional(\n Type.Array(Type.String(), {\n description: `Files you have ALREADY read or located that the subagent should open first (assign only). Paths relative to the working directory. A child starts with none of your context and otherwise spends most of its run rediscovering the repo. Send only files you actually looked at — a guessed path costs the child more than an omitted one. At most ${MAX_BRIEF_FILES}; extras are dropped.`,\n }),\n ),\n priorFindings: Type.Optional(\n Type.String({\n description:\n 'What you already established about this task and the subagent should not re-derive (assign only): symbol names, call sites, the approach you chose, what you already ruled out. Facts you discovered, not directives — put directives in instructions. Keep it to a few lines; it is truncated past ~1500 characters.',\n }),\n ),\n model: Type.Optional(Type.String({ description: 'Model override for the delegated run (assign only)' })),\n context: Type.Optional(\n Type.String({\n enum: [...TASK_CONTEXTS],\n description:\n \"Subagent starting context (assign only): 'fresh' starts clean, 'fork' inherits this conversation. If omitted, uses the agent default, then fresh.\",\n }),\n ),\n});\n\nexport type TaskItemParams = Static<typeof TaskItemSchema>;\nexport type TaskParams = Static<typeof TaskParamsSchema>;\n"],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import { TaskAction } from "../store/types.cjs";
2
+ import { Static, Type } from "typebox";
3
+ //#region src/tool/schema.d.ts
4
+ declare const TASK_ACTIONS: readonly ["upsert", "list", "get", "delete", "clear", "assign", "cancel"];
5
+ declare const TASK_STATUSES: readonly ["pending", "in_progress", "completed", "failed", "deleted"];
6
+ declare const TASK_CONTEXTS: readonly ["fresh", "fork"];
7
+ declare const TOOL_NAME = "task";
8
+ declare const TOOL_LABEL = "Task";
9
+ declare const COMMAND_NAME = "tasks";
10
+ declare const ERR_REQUIRES_INTERACTIVE = "/tasks requires interactive mode";
11
+ declare const MSG_NO_TASKS = "No tasks yet. Ask the agent to add some!";
12
+ /**
13
+ * Which top-level fields each action accepts.
14
+ *
15
+ * The params object is flat and shared across every action, so the schema alone
16
+ * cannot express "upsert has no top-level id". That gap matters: a call like
17
+ * `{"action":"upsert","id":3,"tasks":[{"status":"completed"}]}` would otherwise
18
+ * silently create a duplicate task, because the entry itself carries no id.
19
+ */
20
+ declare const TASK_ACTION_FIELDS: {
21
+ readonly upsert: readonly ["action", "tasks"];
22
+ readonly list: readonly ["action", "status", "includeDeleted"];
23
+ readonly get: readonly ["action", "id"];
24
+ readonly delete: readonly ["action", "id"];
25
+ readonly clear: readonly ["action"];
26
+ readonly assign: readonly ["action", "id", "agent", "inlineAgent", "instructions", "relevantFiles", "priorFindings", "model", "context"];
27
+ readonly cancel: readonly ["action", "id"];
28
+ };
29
+ declare function taskActionAcceptsField(action: TaskAction, field: string): boolean;
30
+ /** Correction hint appended when a per-task field lands at the top level. */
31
+ declare const MSG_UPSERT_FIELD_MISPLACED = "Per-task fields belong inside each tasks[] entry, not at the top level: {\"action\":\"upsert\",\"tasks\":[{\"id\":3,\"status\":\"completed\"}]}.";
32
+ /**
33
+ * One entry of an upsert. `additionalProperties: false` is load-bearing: pi
34
+ * validates tool arguments against this schema before `execute` runs, so a
35
+ * stray `{"action":"update"}` inside an entry is rejected at the boundary.
36
+ */
37
+ declare const TaskItemSchema: Type.TObject<{
38
+ id: Type.TOptional<Type.TInteger>;
39
+ ref: Type.TOptional<Type.TString>;
40
+ subject: Type.TOptional<Type.TString>;
41
+ description: Type.TOptional<Type.TString>;
42
+ activeForm: Type.TOptional<Type.TString>;
43
+ status: Type.TOptional<Type.TString>;
44
+ blockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
45
+ addBlockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
46
+ removeBlockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
47
+ owner: Type.TOptional<Type.TString>;
48
+ metadata: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
49
+ }>;
50
+ /**
51
+ * Tool parameters. Every `description` doubles as LLM-facing prompt copy, so
52
+ * wording changes here change model behaviour.
53
+ */
54
+ declare const TaskParamsSchema: Type.TObject<{
55
+ action: Type.TString;
56
+ tasks: Type.TOptional<Type.TArray<Type.TObject<{
57
+ id: Type.TOptional<Type.TInteger>;
58
+ ref: Type.TOptional<Type.TString>;
59
+ subject: Type.TOptional<Type.TString>;
60
+ description: Type.TOptional<Type.TString>;
61
+ activeForm: Type.TOptional<Type.TString>;
62
+ status: Type.TOptional<Type.TString>;
63
+ blockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
64
+ addBlockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
65
+ removeBlockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
66
+ owner: Type.TOptional<Type.TString>;
67
+ metadata: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
68
+ }>>>;
69
+ id: Type.TOptional<Type.TInteger>;
70
+ status: Type.TOptional<Type.TString>;
71
+ includeDeleted: Type.TOptional<Type.TBoolean>;
72
+ agent: Type.TOptional<Type.TString>;
73
+ inlineAgent: Type.TOptional<Type.TObject<{
74
+ systemPrompt: Type.TString;
75
+ }>>;
76
+ instructions: Type.TOptional<Type.TString>;
77
+ relevantFiles: Type.TOptional<Type.TArray<Type.TString>>;
78
+ priorFindings: Type.TOptional<Type.TString>;
79
+ model: Type.TOptional<Type.TString>;
80
+ context: Type.TOptional<Type.TString>;
81
+ }>;
82
+ type TaskItemParams = Static<typeof TaskItemSchema>;
83
+ type TaskParams = Static<typeof TaskParamsSchema>;
84
+ //#endregion
85
+ export { COMMAND_NAME, ERR_REQUIRES_INTERACTIVE, MSG_NO_TASKS, MSG_UPSERT_FIELD_MISPLACED, TASK_ACTIONS, TASK_ACTION_FIELDS, TASK_CONTEXTS, TASK_STATUSES, TOOL_LABEL, TOOL_NAME, TaskItemParams, TaskItemSchema, TaskParams, TaskParamsSchema, taskActionAcceptsField };
86
+ //# sourceMappingURL=schema.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.cts","names":[],"sources":["../../src/tool/schema.ts"],"mappings":";;;cAKa;cACA;cACA;cAEA;cACA;cACA;cAEA;cACA;;;;;;;;;cAUA;;;;;;;;;iBAoBG,uBAAuB,QAAQ,YAAY;;cAK9C;;;;;;cAcA,gBAAc,KAAA;;;;;;;;;;;;;;;;;cAsEd,kBAAgB,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+DjB,iBAAiB,cAAc;KAC/B,aAAa,cAAc"}
@@ -0,0 +1,86 @@
1
+ import { TaskAction } from "../store/types.mjs";
2
+ import { Static, Type } from "typebox";
3
+ //#region src/tool/schema.d.ts
4
+ declare const TASK_ACTIONS: readonly ["upsert", "list", "get", "delete", "clear", "assign", "cancel"];
5
+ declare const TASK_STATUSES: readonly ["pending", "in_progress", "completed", "failed", "deleted"];
6
+ declare const TASK_CONTEXTS: readonly ["fresh", "fork"];
7
+ declare const TOOL_NAME = "task";
8
+ declare const TOOL_LABEL = "Task";
9
+ declare const COMMAND_NAME = "tasks";
10
+ declare const ERR_REQUIRES_INTERACTIVE = "/tasks requires interactive mode";
11
+ declare const MSG_NO_TASKS = "No tasks yet. Ask the agent to add some!";
12
+ /**
13
+ * Which top-level fields each action accepts.
14
+ *
15
+ * The params object is flat and shared across every action, so the schema alone
16
+ * cannot express "upsert has no top-level id". That gap matters: a call like
17
+ * `{"action":"upsert","id":3,"tasks":[{"status":"completed"}]}` would otherwise
18
+ * silently create a duplicate task, because the entry itself carries no id.
19
+ */
20
+ declare const TASK_ACTION_FIELDS: {
21
+ readonly upsert: readonly ["action", "tasks"];
22
+ readonly list: readonly ["action", "status", "includeDeleted"];
23
+ readonly get: readonly ["action", "id"];
24
+ readonly delete: readonly ["action", "id"];
25
+ readonly clear: readonly ["action"];
26
+ readonly assign: readonly ["action", "id", "agent", "inlineAgent", "instructions", "relevantFiles", "priorFindings", "model", "context"];
27
+ readonly cancel: readonly ["action", "id"];
28
+ };
29
+ declare function taskActionAcceptsField(action: TaskAction, field: string): boolean;
30
+ /** Correction hint appended when a per-task field lands at the top level. */
31
+ declare const MSG_UPSERT_FIELD_MISPLACED = "Per-task fields belong inside each tasks[] entry, not at the top level: {\"action\":\"upsert\",\"tasks\":[{\"id\":3,\"status\":\"completed\"}]}.";
32
+ /**
33
+ * One entry of an upsert. `additionalProperties: false` is load-bearing: pi
34
+ * validates tool arguments against this schema before `execute` runs, so a
35
+ * stray `{"action":"update"}` inside an entry is rejected at the boundary.
36
+ */
37
+ declare const TaskItemSchema: Type.TObject<{
38
+ id: Type.TOptional<Type.TInteger>;
39
+ ref: Type.TOptional<Type.TString>;
40
+ subject: Type.TOptional<Type.TString>;
41
+ description: Type.TOptional<Type.TString>;
42
+ activeForm: Type.TOptional<Type.TString>;
43
+ status: Type.TOptional<Type.TString>;
44
+ blockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
45
+ addBlockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
46
+ removeBlockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
47
+ owner: Type.TOptional<Type.TString>;
48
+ metadata: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
49
+ }>;
50
+ /**
51
+ * Tool parameters. Every `description` doubles as LLM-facing prompt copy, so
52
+ * wording changes here change model behaviour.
53
+ */
54
+ declare const TaskParamsSchema: Type.TObject<{
55
+ action: Type.TString;
56
+ tasks: Type.TOptional<Type.TArray<Type.TObject<{
57
+ id: Type.TOptional<Type.TInteger>;
58
+ ref: Type.TOptional<Type.TString>;
59
+ subject: Type.TOptional<Type.TString>;
60
+ description: Type.TOptional<Type.TString>;
61
+ activeForm: Type.TOptional<Type.TString>;
62
+ status: Type.TOptional<Type.TString>;
63
+ blockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
64
+ addBlockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
65
+ removeBlockedBy: Type.TOptional<Type.TArray<Type.TUnion<[Type.TInteger, Type.TString]>>>;
66
+ owner: Type.TOptional<Type.TString>;
67
+ metadata: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
68
+ }>>>;
69
+ id: Type.TOptional<Type.TInteger>;
70
+ status: Type.TOptional<Type.TString>;
71
+ includeDeleted: Type.TOptional<Type.TBoolean>;
72
+ agent: Type.TOptional<Type.TString>;
73
+ inlineAgent: Type.TOptional<Type.TObject<{
74
+ systemPrompt: Type.TString;
75
+ }>>;
76
+ instructions: Type.TOptional<Type.TString>;
77
+ relevantFiles: Type.TOptional<Type.TArray<Type.TString>>;
78
+ priorFindings: Type.TOptional<Type.TString>;
79
+ model: Type.TOptional<Type.TString>;
80
+ context: Type.TOptional<Type.TString>;
81
+ }>;
82
+ type TaskItemParams = Static<typeof TaskItemSchema>;
83
+ type TaskParams = Static<typeof TaskParamsSchema>;
84
+ //#endregion
85
+ export { COMMAND_NAME, ERR_REQUIRES_INTERACTIVE, MSG_NO_TASKS, MSG_UPSERT_FIELD_MISPLACED, TASK_ACTIONS, TASK_ACTION_FIELDS, TASK_CONTEXTS, TASK_STATUSES, TOOL_LABEL, TOOL_NAME, TaskItemParams, TaskItemSchema, TaskParams, TaskParamsSchema, taskActionAcceptsField };
86
+ //# sourceMappingURL=schema.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.mts","names":[],"sources":["../../src/tool/schema.ts"],"mappings":";;;cAKa;cACA;cACA;cAEA;cACA;cACA;cAEA;cACA;;;;;;;;;cAUA;;;;;;;;;iBAoBG,uBAAuB,QAAQ,YAAY;;cAK9C;;;;;;cAcA,gBAAc,KAAA;;;;;;;;;;;;;;;;;cAsEd,kBAAgB,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+DjB,iBAAiB,cAAc;KAC/B,aAAa,cAAc"}
@@ -0,0 +1,2 @@
1
+ import"../delegation/manager.mjs";import{InlineAgentSchema as e}from"@agimon-ai/doompi-extension-contracts/subagent-tool";import{Type as t}from"typebox";const n=[`upsert`,`list`,`get`,`delete`,`clear`,`assign`,`cancel`],r=[`pending`,`in_progress`,`completed`,`failed`,`deleted`],i=[`fresh`,`fork`],a=`task`,o=`Task`,s=`tasks`,c=`/tasks requires interactive mode`,l=`No tasks yet. Ask the agent to add some!`,u={upsert:[`action`,`tasks`],list:[`action`,`status`,`includeDeleted`],get:[`action`,`id`],delete:[`action`,`id`],clear:[`action`],assign:[`action`,`id`,`agent`,`inlineAgent`,`instructions`,`relevantFiles`,`priorFindings`,`model`,`context`],cancel:[`action`,`id`]};function d(e,t){return u[e].includes(t)}const f=`Per-task fields belong inside each tasks[] entry, not at the top level: {"action":"upsert","tasks":[{"id":3,"status":"completed"}]}.`,p=t.Union([t.Integer(),t.String()]),m=t.Object({id:t.Optional(t.Integer({description:`Existing task id to change. Omit to create a new task. An entry with an id never creates: if the id is unknown, only that entry fails.`})),ref:t.Optional(t.String({description:`Temporary name for a task created by this entry, so a LATER entry in the same tasks[] can list it in blockedBy before its real id exists. Must start with a letter. Scoped to this one call and never stored; the response reports which real id it became.`})),subject:t.Optional(t.String({description:`Short imperative subject line (e.g. 'Research existing tool'). Required when the entry has no id; on an entry with an id it renames the task.`})),description:t.Optional(t.String({description:`Long-form task detail. This becomes the brief handed to the subagent when the task is assigned.`})),activeForm:t.Optional(t.String({description:`Present-continuous spinner label shown while status is in_progress (e.g. 'writing tests')`})),status:t.Optional(t.String({enum:[...r],description:`Starting status for a new entry (default pending; deleted is rejected), or the target status for an entry with an id, where the transition must be legal.`})),blockedBy:t.Optional(t.Array(p,{description:`Dependencies for a NEW entry (one with no id): this task is blocked by each target. A number is an existing task id; a string is the ref of a task created by an EARLIER entry in this same array. Use addBlockedBy / removeBlockedBy on an entry that has an id.`})),addBlockedBy:t.Optional(t.Array(p,{description:`Dependencies to add, for an entry with an id. Task ids, or refs declared by an earlier entry. Additive merge — do not resend the full array.`})),removeBlockedBy:t.Optional(t.Array(p,{description:`Dependencies to remove, for an entry with an id. Additive merge — do not resend the full array.`})),owner:t.Optional(t.String({description:`Owner label for this task. assign sets this to the subagent name automatically.`})),metadata:t.Optional(t.Record(t.String(),t.Unknown(),{description:`Arbitrary metadata merged into the task; pass null as a value to delete that key`}))},{additionalProperties:!1}),h=t.Object({action:t.String({enum:[...n],description:`upsert (create new tasks and change existing ones, one or many per call), list, get, delete (tombstone), clear (close/reset the list), assign (delegate to a subagent), cancel (stop a delegated run)`}),tasks:t.Optional(t.Array(m,{minItems:1,description:`upsert only. One entry per task: an entry with an id changes that task, an entry without an id creates one. Entries apply in array order, so a later entry can depend on an earlier one by ref. Each entry succeeds or fails on its own: the ones that succeed are committed and the ones that fail are reported by their array index.`})),id:t.Optional(t.Integer({description:`Task id, for get, delete, assign and cancel. upsert does not accept this field — put the id inside the tasks[] entry you want to change.`})),status:t.Optional(t.String({enum:[...r],description:`list only: return just the tasks in this status. To SET a status, use upsert with the task id inside tasks[].`})),includeDeleted:t.Optional(t.Boolean({description:`If true, list returns deleted (tombstoned) tasks as well. Default: false.`})),agent:t.Optional(t.String({description:`Name of the subagent to delegate this task to (required for assign)`})),inlineAgent:t.Optional(e),instructions:t.Optional(t.String({description:`Extra instructions appended to the delegated brief (assign only)`})),relevantFiles:t.Optional(t.Array(t.String(),{description:`Files you have ALREADY read or located that the subagent should open first (assign only). Paths relative to the working directory. A child starts with none of your context and otherwise spends most of its run rediscovering the repo. Send only files you actually looked at — a guessed path costs the child more than an omitted one. At most 12; extras are dropped.`})),priorFindings:t.Optional(t.String({description:`What you already established about this task and the subagent should not re-derive (assign only): symbol names, call sites, the approach you chose, what you already ruled out. Facts you discovered, not directives — put directives in instructions. Keep it to a few lines; it is truncated past ~1500 characters.`})),model:t.Optional(t.String({description:`Model override for the delegated run (assign only)`})),context:t.Optional(t.String({enum:[...i],description:`Subagent starting context (assign only): 'fresh' starts clean, 'fork' inherits this conversation. If omitted, uses the agent default, then fresh.`}))});export{s as COMMAND_NAME,c as ERR_REQUIRES_INTERACTIVE,l as MSG_NO_TASKS,f as MSG_UPSERT_FIELD_MISPLACED,n as TASK_ACTIONS,u as TASK_ACTION_FIELDS,i as TASK_CONTEXTS,r as TASK_STATUSES,o as TOOL_LABEL,a as TOOL_NAME,m as TaskItemSchema,h as TaskParamsSchema,d as taskActionAcceptsField};
2
+ //# sourceMappingURL=schema.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.mjs","names":[],"sources":["../../src/tool/schema.ts"],"sourcesContent":["import { InlineAgentSchema } from '@agimon-ai/doompi-extension-contracts/subagent-tool';\nimport { type Static, Type } from 'typebox';\nimport { MAX_BRIEF_FILES } from '../delegation/manager.ts';\nimport type { TaskAction } from '../store/types.ts';\n\nexport const TASK_ACTIONS = ['upsert', 'list', 'get', 'delete', 'clear', 'assign', 'cancel'] as const;\nexport const TASK_STATUSES = ['pending', 'in_progress', 'completed', 'failed', 'deleted'] as const;\nexport const TASK_CONTEXTS = ['fresh', 'fork'] as const;\n\nexport const TOOL_NAME = 'task';\nexport const TOOL_LABEL = 'Task';\nexport const COMMAND_NAME = 'tasks';\n\nexport const ERR_REQUIRES_INTERACTIVE = '/tasks requires interactive mode';\nexport const MSG_NO_TASKS = 'No tasks yet. Ask the agent to add some!';\n\n/**\n * Which top-level fields each action accepts.\n *\n * The params object is flat and shared across every action, so the schema alone\n * cannot express \"upsert has no top-level id\". That gap matters: a call like\n * `{\"action\":\"upsert\",\"id\":3,\"tasks\":[{\"status\":\"completed\"}]}` would otherwise\n * silently create a duplicate task, because the entry itself carries no id.\n */\nexport const TASK_ACTION_FIELDS = {\n upsert: ['action', 'tasks'],\n list: ['action', 'status', 'includeDeleted'],\n get: ['action', 'id'],\n delete: ['action', 'id'],\n clear: ['action'],\n assign: [\n 'action',\n 'id',\n 'agent',\n 'inlineAgent',\n 'instructions',\n 'relevantFiles',\n 'priorFindings',\n 'model',\n 'context',\n ],\n cancel: ['action', 'id'],\n} as const satisfies Record<TaskAction, readonly string[]>;\n\nexport function taskActionAcceptsField(action: TaskAction, field: string): boolean {\n return (TASK_ACTION_FIELDS[action] as readonly string[]).includes(field);\n}\n\n/** Correction hint appended when a per-task field lands at the top level. */\nexport const MSG_UPSERT_FIELD_MISPLACED =\n 'Per-task fields belong inside each tasks[] entry, not at the top level: {\"action\":\"upsert\",\"tasks\":[{\"id\":3,\"status\":\"completed\"}]}.';\n\n/**\n * A dependency target: an existing task id, or the `ref` of a task created\n * earlier in the same call.\n */\nconst DepTokenSchema = Type.Union([Type.Integer(), Type.String()]);\n\n/**\n * One entry of an upsert. `additionalProperties: false` is load-bearing: pi\n * validates tool arguments against this schema before `execute` runs, so a\n * stray `{\"action\":\"update\"}` inside an entry is rejected at the boundary.\n */\nexport const TaskItemSchema = Type.Object(\n {\n id: Type.Optional(\n Type.Integer({\n description:\n 'Existing task id to change. Omit to create a new task. An entry with an id never creates: if the id is unknown, only that entry fails.',\n }),\n ),\n ref: Type.Optional(\n Type.String({\n description:\n 'Temporary name for a task created by this entry, so a LATER entry in the same tasks[] can list it in blockedBy before its real id exists. Must start with a letter. Scoped to this one call and never stored; the response reports which real id it became.',\n }),\n ),\n subject: Type.Optional(\n Type.String({\n description:\n \"Short imperative subject line (e.g. 'Research existing tool'). Required when the entry has no id; on an entry with an id it renames the task.\",\n }),\n ),\n description: Type.Optional(\n Type.String({\n description: 'Long-form task detail. This becomes the brief handed to the subagent when the task is assigned.',\n }),\n ),\n activeForm: Type.Optional(\n Type.String({\n description: \"Present-continuous spinner label shown while status is in_progress (e.g. 'writing tests')\",\n }),\n ),\n status: Type.Optional(\n Type.String({\n enum: [...TASK_STATUSES],\n description:\n 'Starting status for a new entry (default pending; deleted is rejected), or the target status for an entry with an id, where the transition must be legal.',\n }),\n ),\n blockedBy: Type.Optional(\n Type.Array(DepTokenSchema, {\n description:\n 'Dependencies for a NEW entry (one with no id): this task is blocked by each target. A number is an existing task id; a string is the ref of a task created by an EARLIER entry in this same array. Use addBlockedBy / removeBlockedBy on an entry that has an id.',\n }),\n ),\n addBlockedBy: Type.Optional(\n Type.Array(DepTokenSchema, {\n description:\n 'Dependencies to add, for an entry with an id. Task ids, or refs declared by an earlier entry. Additive merge — do not resend the full array.',\n }),\n ),\n removeBlockedBy: Type.Optional(\n Type.Array(DepTokenSchema, {\n description: 'Dependencies to remove, for an entry with an id. Additive merge — do not resend the full array.',\n }),\n ),\n owner: Type.Optional(\n Type.String({ description: 'Owner label for this task. assign sets this to the subagent name automatically.' }),\n ),\n metadata: Type.Optional(\n Type.Record(Type.String(), Type.Unknown(), {\n description: 'Arbitrary metadata merged into the task; pass null as a value to delete that key',\n }),\n ),\n },\n { additionalProperties: false },\n);\n\n/**\n * Tool parameters. Every `description` doubles as LLM-facing prompt copy, so\n * wording changes here change model behaviour.\n */\nexport const TaskParamsSchema = Type.Object({\n action: Type.String({\n enum: [...TASK_ACTIONS],\n description:\n 'upsert (create new tasks and change existing ones, one or many per call), list, get, delete (tombstone), clear (close/reset the list), assign (delegate to a subagent), cancel (stop a delegated run)',\n }),\n tasks: Type.Optional(\n Type.Array(TaskItemSchema, {\n minItems: 1,\n description:\n 'upsert only. One entry per task: an entry with an id changes that task, an entry without an id creates one. Entries apply in array order, so a later entry can depend on an earlier one by ref. Each entry succeeds or fails on its own: the ones that succeed are committed and the ones that fail are reported by their array index.',\n }),\n ),\n id: Type.Optional(\n Type.Integer({\n description:\n 'Task id, for get, delete, assign and cancel. upsert does not accept this field — put the id inside the tasks[] entry you want to change.',\n }),\n ),\n status: Type.Optional(\n Type.String({\n enum: [...TASK_STATUSES],\n description:\n 'list only: return just the tasks in this status. To SET a status, use upsert with the task id inside tasks[].',\n }),\n ),\n includeDeleted: Type.Optional(\n Type.Boolean({\n description: 'If true, list returns deleted (tombstoned) tasks as well. Default: false.',\n }),\n ),\n agent: Type.Optional(\n Type.String({\n description: 'Name of the subagent to delegate this task to (required for assign)',\n }),\n ),\n inlineAgent: Type.Optional(InlineAgentSchema),\n instructions: Type.Optional(\n Type.String({\n description: 'Extra instructions appended to the delegated brief (assign only)',\n }),\n ),\n relevantFiles: Type.Optional(\n Type.Array(Type.String(), {\n description: `Files you have ALREADY read or located that the subagent should open first (assign only). Paths relative to the working directory. A child starts with none of your context and otherwise spends most of its run rediscovering the repo. Send only files you actually looked at — a guessed path costs the child more than an omitted one. At most ${MAX_BRIEF_FILES}; extras are dropped.`,\n }),\n ),\n priorFindings: Type.Optional(\n Type.String({\n description:\n 'What you already established about this task and the subagent should not re-derive (assign only): symbol names, call sites, the approach you chose, what you already ruled out. Facts you discovered, not directives — put directives in instructions. Keep it to a few lines; it is truncated past ~1500 characters.',\n }),\n ),\n model: Type.Optional(Type.String({ description: 'Model override for the delegated run (assign only)' })),\n context: Type.Optional(\n Type.String({\n enum: [...TASK_CONTEXTS],\n description:\n \"Subagent starting context (assign only): 'fresh' starts clean, 'fork' inherits this conversation. If omitted, uses the agent default, then fresh.\",\n }),\n ),\n});\n\nexport type TaskItemParams = Static<typeof TaskItemSchema>;\nexport type TaskParams = Static<typeof TaskParamsSchema>;\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../logSinkTelemetry.cjs"),t=require("./schema.cjs"),n=require("../store/reducer.cjs"),r=require("../tui/format.cjs"),i=require("./responseEnvelope.cjs"),a=require("./promptGuidelines.cjs"),o=`Manage a shared task list to track multi-step progress, and delegate tasks to subagents`,s=new Set([`upsert`,`list`,`get`,`delete`,`clear`]);var c=class extends Error{};function l(e,t){return new c([`Task ${e} failed: ${t}`,``,`Options:`,`- List the task board and inspect the current ids, states, and blockers.`,`- Correct the arguments or state conflict, then retry once.`,`- Ask the user before cancelling work or changing dependencies to recover.`].join(`
2
+ `))}function u(e,n){let r=Object.keys(n).filter(r=>n[r]!==void 0&&!t.taskActionAcceptsField(e,r));if(r.length===0)return;let i=e===`upsert`?` ${t.MSG_UPSERT_FIELD_MISPLACED}`:``;throw l(e,`${e} does not accept ${r.join(`, `)}.${i}`)}async function d(e,t,r){let{document:a,value:o}=await e.mutate(e=>{let i=n.applyTaskMutation(e,t,r);return{...n.isCommittingOp(i.op)?{document:i.document}:{},value:i}});if(o.op.kind===`error`)throw l(t,o.op.message);if(o.op.kind===`upsert`&&o.op.applied===0)throw l(t,i.formatUpsertFailureText(o.op));return i.buildToolResult(t,r,a,o.op)}function f(n,f){let{store:p,delegation:m}=f;n.registerTool({name:t.TOOL_NAME,label:t.TOOL_LABEL,description:`Manage a shared task list for tracking multi-step progress, and delegate tasks to subagents. Actions: upsert (write tasks — a tasks[] array where an entry with an id changes that task and an entry without an id creates one, so one call can capture a whole plan), list, get, delete (tombstone), clear (close/reset the list), assign (hand the task to a named subagent that works it in the background), cancel (stop a delegated run). upsert applies each entry independently: successes are committed and failures are reported by array index, and an entry can depend on a task created by an earlier entry in the same call via a ref. Batch when writing a plan down; report progress one task at a time. Status: pending → in_progress → completed, plus failed and a deleted tombstone. The list is shared within the current session tree, including delegated subagents, while unrelated sessions start empty. Session stores persist until retention cleanup.`,promptSnippet:o,promptGuidelines:a.DEFAULT_PROMPT_GUIDELINES,parameters:t.TaskParamsSchema,async execute(t,n,r,a,o){let h=n.action,g=n;try{if(u(h,g),s.has(h)){let e=await d(p,h,g);return f.onChange?.(),e}let e;if(h===`assign`?(a?.(i.buildTextResult(h,g,p.snapshot,`Delegating task #${g.id??`unknown`}...`)),e=await m.assign(g.id??NaN,{agent:g.agent,inlineAgent:g.inlineAgent,instructions:g.instructions,relevantFiles:g.relevantFiles,priorFindings:g.priorFindings,model:g.model,context:g.context,signal:r})):(a?.(i.buildTextResult(h,g,p.snapshot,`Requesting cancellation for task #${g.id??`unknown`}...`)),e=await m.cancel(g.id??NaN)),f.onChange?.(),!e.ok)throw l(h,e.message);return i.buildTextResult(h,g,p.snapshot,e.message,void 0)}catch(t){throw f.report?.error(e.TASK_EVENT.toolFailed,t,{"tool.action":h,...g.id===void 0?{}:{"task.id":g.id}}),t instanceof c?t:l(h,t instanceof Error?t.message:String(t))}},renderCall(e,t,n){return r.renderTaskCall(e,t,p.snapshot.tasks)},renderResult(e,t,n,i){return r.renderTaskResult(e,t,n)}})}exports.DEFAULT_PROMPT_GUIDELINES=a.DEFAULT_PROMPT_GUIDELINES,exports.DEFAULT_PROMPT_SNIPPET=o,exports.registerTaskTool=f;
3
+ //# sourceMappingURL=taskTool.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskTool.cjs","names":["taskActionAcceptsField","MSG_UPSERT_FIELD_MISPLACED","applyTaskMutation","isCommittingOp","formatUpsertFailureText","buildToolResult","TOOL_NAME","TOOL_LABEL","DEFAULT_PROMPT_GUIDELINES","TaskParamsSchema","buildTextResult","TASK_EVENT","renderTaskCall","renderTaskResult"],"sources":["../../src/tool/taskTool.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport type { DelegationManager, DelegationOutcome } from '../delegation/manager.ts';\nimport { TASK_EVENT, type TaskFailureReporter } from '../logSinkTelemetry.ts';\nimport { applyTaskMutation, isCommittingOp, type ReducerAction } from '../store/reducer.ts';\nimport type { TaskStore } from '../store/taskStore.ts';\nimport type { TaskAction, TaskMutationParams } from '../store/types.ts';\nimport { renderTaskCall, renderTaskResult } from '../tui/format.ts';\nimport { buildTextResult, buildToolResult, formatUpsertFailureText, type ToolResult } from './responseEnvelope.ts';\nimport {\n MSG_UPSERT_FIELD_MISPLACED,\n TOOL_LABEL,\n TOOL_NAME,\n TaskParamsSchema,\n taskActionAcceptsField,\n} from './schema.ts';\nimport { DEFAULT_PROMPT_GUIDELINES } from './promptGuidelines.ts';\nexport { DEFAULT_PROMPT_GUIDELINES } from './promptGuidelines.ts';\n\nexport const DEFAULT_PROMPT_SNIPPET =\n 'Manage a shared task list to track multi-step progress, and delegate tasks to subagents';\n\nexport interface TaskToolDependencies {\n store: TaskStore;\n delegation: DelegationManager;\n onChange?: () => void;\n report?: TaskFailureReporter;\n}\n\nconst ACTION_ATTRIBUTE = 'tool.action';\nconst TASK_ID_ATTRIBUTE = 'task.id';\n\nconst REDUCER_ACTIONS = new Set<TaskAction>(['upsert', 'list', 'get', 'delete', 'clear']);\n\nclass TaskToolExecutionError extends Error {}\n\nfunction actionableTaskError(action: TaskAction, message: string): TaskToolExecutionError {\n return new TaskToolExecutionError(\n [\n `Task ${action} failed: ${message}`,\n '',\n 'Options:',\n '- List the task board and inspect the current ids, states, and blockers.',\n '- Correct the arguments or state conflict, then retry once.',\n '- Ask the user before cancelling work or changing dependencies to recover.',\n ].join('\\n'),\n );\n}\n\n/**\n * Reject a field that belongs to a different action.\n *\n * The params schema is flat and shared across every action, so this is the only\n * place `{\"action\":\"upsert\",\"id\":3}` can be caught — and it must be, because\n * the entry it carries has no id and would silently create a duplicate task.\n */\nfunction rejectStrayFields(action: TaskAction, params: TaskMutationParams): void {\n const stray = Object.keys(params).filter((key) => params[key] !== undefined && !taskActionAcceptsField(action, key));\n if (stray.length === 0) return;\n const hint = action === 'upsert' ? ` ${MSG_UPSERT_FIELD_MISPLACED}` : '';\n throw actionableTaskError(action, `${action} does not accept ${stray.join(', ')}.${hint}`);\n}\n\n/** Run an action through the reducer, persisting only when it produced a change. */\nasync function executeReducerAction(\n store: TaskStore,\n action: ReducerAction,\n params: TaskMutationParams,\n): Promise<ToolResult> {\n const { document, value } = await store.mutate((current) => {\n const result = applyTaskMutation(current, action, params);\n return {\n ...(isCommittingOp(result.op) ? { document: result.document } : {}),\n value: result,\n };\n });\n if (value.op.kind === 'error') throw actionableTaskError(action, value.op.message);\n // An upsert that applied nothing is a failed call: it wrote nothing and left\n // `rev` alone, so it must not read to the model as a success. A batch where\n // some entries landed returns normally — that is what partial apply means.\n if (value.op.kind === 'upsert' && value.op.applied === 0) {\n throw actionableTaskError(action, formatUpsertFailureText(value.op));\n }\n // `document` is the committed document, so `details.rev` matches what landed\n // on disk; `value.document` is the pre-write copy and lags by one.\n return buildToolResult(action, params, document, value.op);\n}\n\nexport function registerTaskTool(pi: ExtensionAPI, dependencies: TaskToolDependencies): void {\n const { store, delegation } = dependencies;\n\n pi.registerTool({\n name: TOOL_NAME,\n label: TOOL_LABEL,\n description:\n 'Manage a shared task list for tracking multi-step progress, and delegate tasks to subagents. Actions: upsert (write tasks — a tasks[] array where an entry with an id changes that task and an entry without an id creates one, so one call can capture a whole plan), list, get, delete (tombstone), clear (close/reset the list), assign (hand the task to a named subagent that works it in the background), cancel (stop a delegated run). upsert applies each entry independently: successes are committed and failures are reported by array index, and an entry can depend on a task created by an earlier entry in the same call via a ref. Batch when writing a plan down; report progress one task at a time. Status: pending → in_progress → completed, plus failed and a deleted tombstone. The list is shared within the current session tree, including delegated subagents, while unrelated sessions start empty. Session stores persist until retention cleanup.',\n promptSnippet: DEFAULT_PROMPT_SNIPPET,\n promptGuidelines: DEFAULT_PROMPT_GUIDELINES,\n parameters: TaskParamsSchema,\n\n async execute(_toolCallId, params, signal, onUpdate, _ctx) {\n const action = params.action as TaskAction;\n const mutationParams = params as TaskMutationParams;\n\n try {\n rejectStrayFields(action, mutationParams);\n if (REDUCER_ACTIONS.has(action)) {\n const result = await executeReducerAction(store, action as ReducerAction, mutationParams);\n dependencies.onChange?.();\n return result;\n }\n\n let outcome: DelegationOutcome;\n if (action === 'assign') {\n onUpdate?.(\n buildTextResult(\n action,\n mutationParams,\n store.snapshot,\n `Delegating task #${mutationParams.id ?? 'unknown'}...`,\n ),\n );\n outcome = await delegation.assign(mutationParams.id ?? Number.NaN, {\n agent: mutationParams.agent,\n inlineAgent: mutationParams.inlineAgent,\n instructions: mutationParams.instructions,\n relevantFiles: mutationParams.relevantFiles,\n priorFindings: mutationParams.priorFindings,\n model: mutationParams.model,\n context: mutationParams.context,\n signal,\n });\n } else {\n onUpdate?.(\n buildTextResult(\n action,\n mutationParams,\n store.snapshot,\n `Requesting cancellation for task #${mutationParams.id ?? 'unknown'}...`,\n ),\n );\n outcome = await delegation.cancel(mutationParams.id ?? Number.NaN);\n }\n\n dependencies.onChange?.();\n if (!outcome.ok) throw actionableTaskError(action, outcome.message);\n return buildTextResult(action, mutationParams, store.snapshot, outcome.message, undefined);\n } catch (error) {\n // Rethrown so pi still renders the failure to the model; recorded\n // because this is where a store fault becomes visible to the user.\n dependencies.report?.error(TASK_EVENT.toolFailed, error, {\n [ACTION_ATTRIBUTE]: action,\n ...(mutationParams.id === undefined ? {} : { [TASK_ID_ATTRIBUTE]: mutationParams.id }),\n });\n if (error instanceof TaskToolExecutionError) throw error;\n throw actionableTaskError(action, error instanceof Error ? error.message : String(error));\n }\n },\n\n // Render hooks receive no session identity, so they read the store snapshot\n // that the executing session last loaded. That is the foreground session's\n // own view, which is exactly what its transcript should show.\n renderCall(args, theme, _context) {\n return renderTaskCall(args as never, theme, store.snapshot.tasks);\n },\n\n renderResult(result, options, theme, _context) {\n return renderTaskResult(result, options, theme);\n },\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { TaskFailureReporter } from "../logSinkTelemetry.cjs";
2
+ import { TaskStore } from "../store/taskStore.cjs";
3
+ import { DelegationManager } from "../delegation/manager.cjs";
4
+ import { DEFAULT_PROMPT_GUIDELINES } from "./promptGuidelines.cjs";
5
+ import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
6
+ //#region src/tool/taskTool.d.ts
7
+ declare const DEFAULT_PROMPT_SNIPPET = "Manage a shared task list to track multi-step progress, and delegate tasks to subagents";
8
+ interface TaskToolDependencies {
9
+ store: TaskStore;
10
+ delegation: DelegationManager;
11
+ onChange?: () => void;
12
+ report?: TaskFailureReporter;
13
+ }
14
+ declare function registerTaskTool(pi: ExtensionAPI, dependencies: TaskToolDependencies): void;
15
+ //#endregion
16
+ export { DEFAULT_PROMPT_GUIDELINES, DEFAULT_PROMPT_SNIPPET, TaskToolDependencies, registerTaskTool };
17
+ //# sourceMappingURL=taskTool.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskTool.d.cts","names":[],"sources":["../../src/tool/taskTool.ts"],"mappings":";;;;;;cAkBa;UAGI;EACf,OAAO;EACP,YAAY;EACZ;EACA,SAAS;;iBA8DK,iBAAiB,IAAI,cAAc,cAAc"}
@@ -0,0 +1,17 @@
1
+ import { TaskFailureReporter } from "../logSinkTelemetry.mjs";
2
+ import { TaskStore } from "../store/taskStore.mjs";
3
+ import { DelegationManager } from "../delegation/manager.mjs";
4
+ import { DEFAULT_PROMPT_GUIDELINES } from "./promptGuidelines.mjs";
5
+ import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
6
+ //#region src/tool/taskTool.d.ts
7
+ declare const DEFAULT_PROMPT_SNIPPET = "Manage a shared task list to track multi-step progress, and delegate tasks to subagents";
8
+ interface TaskToolDependencies {
9
+ store: TaskStore;
10
+ delegation: DelegationManager;
11
+ onChange?: () => void;
12
+ report?: TaskFailureReporter;
13
+ }
14
+ declare function registerTaskTool(pi: ExtensionAPI, dependencies: TaskToolDependencies): void;
15
+ //#endregion
16
+ export { DEFAULT_PROMPT_GUIDELINES, DEFAULT_PROMPT_SNIPPET, TaskToolDependencies, registerTaskTool };
17
+ //# sourceMappingURL=taskTool.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskTool.d.mts","names":[],"sources":["../../src/tool/taskTool.ts"],"mappings":";;;;;;cAkBa;UAGI;EACf,OAAO;EACP,YAAY;EACZ;EACA,SAAS;;iBA8DK,iBAAiB,IAAI,cAAc,cAAc"}
@@ -0,0 +1,3 @@
1
+ import{TASK_EVENT as e}from"../logSinkTelemetry.mjs";import{MSG_UPSERT_FIELD_MISPLACED as t,TOOL_LABEL as n,TOOL_NAME as r,TaskParamsSchema as i,taskActionAcceptsField as a}from"./schema.mjs";import{applyTaskMutation as o,isCommittingOp as s}from"../store/reducer.mjs";import{renderTaskCall as c,renderTaskResult as l}from"../tui/format.mjs";import{buildTextResult as u,buildToolResult as d,formatUpsertFailureText as f}from"./responseEnvelope.mjs";import{DEFAULT_PROMPT_GUIDELINES as p}from"./promptGuidelines.mjs";const m=`Manage a shared task list to track multi-step progress, and delegate tasks to subagents`,h=new Set([`upsert`,`list`,`get`,`delete`,`clear`]);var g=class extends Error{};function _(e,t){return new g([`Task ${e} failed: ${t}`,``,`Options:`,`- List the task board and inspect the current ids, states, and blockers.`,`- Correct the arguments or state conflict, then retry once.`,`- Ask the user before cancelling work or changing dependencies to recover.`].join(`
2
+ `))}function v(e,n){let r=Object.keys(n).filter(t=>n[t]!==void 0&&!a(e,t));if(r.length===0)return;let i=e===`upsert`?` ${t}`:``;throw _(e,`${e} does not accept ${r.join(`, `)}.${i}`)}async function y(e,t,n){let{document:r,value:i}=await e.mutate(e=>{let r=o(e,t,n);return{...s(r.op)?{document:r.document}:{},value:r}});if(i.op.kind===`error`)throw _(t,i.op.message);if(i.op.kind===`upsert`&&i.op.applied===0)throw _(t,f(i.op));return d(t,n,r,i.op)}function b(t,a){let{store:o,delegation:s}=a;t.registerTool({name:r,label:n,description:`Manage a shared task list for tracking multi-step progress, and delegate tasks to subagents. Actions: upsert (write tasks — a tasks[] array where an entry with an id changes that task and an entry without an id creates one, so one call can capture a whole plan), list, get, delete (tombstone), clear (close/reset the list), assign (hand the task to a named subagent that works it in the background), cancel (stop a delegated run). upsert applies each entry independently: successes are committed and failures are reported by array index, and an entry can depend on a task created by an earlier entry in the same call via a ref. Batch when writing a plan down; report progress one task at a time. Status: pending → in_progress → completed, plus failed and a deleted tombstone. The list is shared within the current session tree, including delegated subagents, while unrelated sessions start empty. Session stores persist until retention cleanup.`,promptSnippet:m,promptGuidelines:p,parameters:i,async execute(t,n,r,i,c){let l=n.action,d=n;try{if(v(l,d),h.has(l)){let e=await y(o,l,d);return a.onChange?.(),e}let e;if(l===`assign`?(i?.(u(l,d,o.snapshot,`Delegating task #${d.id??`unknown`}...`)),e=await s.assign(d.id??NaN,{agent:d.agent,inlineAgent:d.inlineAgent,instructions:d.instructions,relevantFiles:d.relevantFiles,priorFindings:d.priorFindings,model:d.model,context:d.context,signal:r})):(i?.(u(l,d,o.snapshot,`Requesting cancellation for task #${d.id??`unknown`}...`)),e=await s.cancel(d.id??NaN)),a.onChange?.(),!e.ok)throw _(l,e.message);return u(l,d,o.snapshot,e.message,void 0)}catch(t){throw a.report?.error(e.toolFailed,t,{"tool.action":l,...d.id===void 0?{}:{"task.id":d.id}}),t instanceof g?t:_(l,t instanceof Error?t.message:String(t))}},renderCall(e,t,n){return c(e,t,o.snapshot.tasks)},renderResult(e,t,n,r){return l(e,t,n)}})}export{p as DEFAULT_PROMPT_GUIDELINES,m as DEFAULT_PROMPT_SNIPPET,b as registerTaskTool};
3
+ //# sourceMappingURL=taskTool.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskTool.mjs","names":[],"sources":["../../src/tool/taskTool.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport type { DelegationManager, DelegationOutcome } from '../delegation/manager.ts';\nimport { TASK_EVENT, type TaskFailureReporter } from '../logSinkTelemetry.ts';\nimport { applyTaskMutation, isCommittingOp, type ReducerAction } from '../store/reducer.ts';\nimport type { TaskStore } from '../store/taskStore.ts';\nimport type { TaskAction, TaskMutationParams } from '../store/types.ts';\nimport { renderTaskCall, renderTaskResult } from '../tui/format.ts';\nimport { buildTextResult, buildToolResult, formatUpsertFailureText, type ToolResult } from './responseEnvelope.ts';\nimport {\n MSG_UPSERT_FIELD_MISPLACED,\n TOOL_LABEL,\n TOOL_NAME,\n TaskParamsSchema,\n taskActionAcceptsField,\n} from './schema.ts';\nimport { DEFAULT_PROMPT_GUIDELINES } from './promptGuidelines.ts';\nexport { DEFAULT_PROMPT_GUIDELINES } from './promptGuidelines.ts';\n\nexport const DEFAULT_PROMPT_SNIPPET =\n 'Manage a shared task list to track multi-step progress, and delegate tasks to subagents';\n\nexport interface TaskToolDependencies {\n store: TaskStore;\n delegation: DelegationManager;\n onChange?: () => void;\n report?: TaskFailureReporter;\n}\n\nconst ACTION_ATTRIBUTE = 'tool.action';\nconst TASK_ID_ATTRIBUTE = 'task.id';\n\nconst REDUCER_ACTIONS = new Set<TaskAction>(['upsert', 'list', 'get', 'delete', 'clear']);\n\nclass TaskToolExecutionError extends Error {}\n\nfunction actionableTaskError(action: TaskAction, message: string): TaskToolExecutionError {\n return new TaskToolExecutionError(\n [\n `Task ${action} failed: ${message}`,\n '',\n 'Options:',\n '- List the task board and inspect the current ids, states, and blockers.',\n '- Correct the arguments or state conflict, then retry once.',\n '- Ask the user before cancelling work or changing dependencies to recover.',\n ].join('\\n'),\n );\n}\n\n/**\n * Reject a field that belongs to a different action.\n *\n * The params schema is flat and shared across every action, so this is the only\n * place `{\"action\":\"upsert\",\"id\":3}` can be caught — and it must be, because\n * the entry it carries has no id and would silently create a duplicate task.\n */\nfunction rejectStrayFields(action: TaskAction, params: TaskMutationParams): void {\n const stray = Object.keys(params).filter((key) => params[key] !== undefined && !taskActionAcceptsField(action, key));\n if (stray.length === 0) return;\n const hint = action === 'upsert' ? ` ${MSG_UPSERT_FIELD_MISPLACED}` : '';\n throw actionableTaskError(action, `${action} does not accept ${stray.join(', ')}.${hint}`);\n}\n\n/** Run an action through the reducer, persisting only when it produced a change. */\nasync function executeReducerAction(\n store: TaskStore,\n action: ReducerAction,\n params: TaskMutationParams,\n): Promise<ToolResult> {\n const { document, value } = await store.mutate((current) => {\n const result = applyTaskMutation(current, action, params);\n return {\n ...(isCommittingOp(result.op) ? { document: result.document } : {}),\n value: result,\n };\n });\n if (value.op.kind === 'error') throw actionableTaskError(action, value.op.message);\n // An upsert that applied nothing is a failed call: it wrote nothing and left\n // `rev` alone, so it must not read to the model as a success. A batch where\n // some entries landed returns normally — that is what partial apply means.\n if (value.op.kind === 'upsert' && value.op.applied === 0) {\n throw actionableTaskError(action, formatUpsertFailureText(value.op));\n }\n // `document` is the committed document, so `details.rev` matches what landed\n // on disk; `value.document` is the pre-write copy and lags by one.\n return buildToolResult(action, params, document, value.op);\n}\n\nexport function registerTaskTool(pi: ExtensionAPI, dependencies: TaskToolDependencies): void {\n const { store, delegation } = dependencies;\n\n pi.registerTool({\n name: TOOL_NAME,\n label: TOOL_LABEL,\n description:\n 'Manage a shared task list for tracking multi-step progress, and delegate tasks to subagents. Actions: upsert (write tasks — a tasks[] array where an entry with an id changes that task and an entry without an id creates one, so one call can capture a whole plan), list, get, delete (tombstone), clear (close/reset the list), assign (hand the task to a named subagent that works it in the background), cancel (stop a delegated run). upsert applies each entry independently: successes are committed and failures are reported by array index, and an entry can depend on a task created by an earlier entry in the same call via a ref. Batch when writing a plan down; report progress one task at a time. Status: pending → in_progress → completed, plus failed and a deleted tombstone. The list is shared within the current session tree, including delegated subagents, while unrelated sessions start empty. Session stores persist until retention cleanup.',\n promptSnippet: DEFAULT_PROMPT_SNIPPET,\n promptGuidelines: DEFAULT_PROMPT_GUIDELINES,\n parameters: TaskParamsSchema,\n\n async execute(_toolCallId, params, signal, onUpdate, _ctx) {\n const action = params.action as TaskAction;\n const mutationParams = params as TaskMutationParams;\n\n try {\n rejectStrayFields(action, mutationParams);\n if (REDUCER_ACTIONS.has(action)) {\n const result = await executeReducerAction(store, action as ReducerAction, mutationParams);\n dependencies.onChange?.();\n return result;\n }\n\n let outcome: DelegationOutcome;\n if (action === 'assign') {\n onUpdate?.(\n buildTextResult(\n action,\n mutationParams,\n store.snapshot,\n `Delegating task #${mutationParams.id ?? 'unknown'}...`,\n ),\n );\n outcome = await delegation.assign(mutationParams.id ?? Number.NaN, {\n agent: mutationParams.agent,\n inlineAgent: mutationParams.inlineAgent,\n instructions: mutationParams.instructions,\n relevantFiles: mutationParams.relevantFiles,\n priorFindings: mutationParams.priorFindings,\n model: mutationParams.model,\n context: mutationParams.context,\n signal,\n });\n } else {\n onUpdate?.(\n buildTextResult(\n action,\n mutationParams,\n store.snapshot,\n `Requesting cancellation for task #${mutationParams.id ?? 'unknown'}...`,\n ),\n );\n outcome = await delegation.cancel(mutationParams.id ?? Number.NaN);\n }\n\n dependencies.onChange?.();\n if (!outcome.ok) throw actionableTaskError(action, outcome.message);\n return buildTextResult(action, mutationParams, store.snapshot, outcome.message, undefined);\n } catch (error) {\n // Rethrown so pi still renders the failure to the model; recorded\n // because this is where a store fault becomes visible to the user.\n dependencies.report?.error(TASK_EVENT.toolFailed, error, {\n [ACTION_ATTRIBUTE]: action,\n ...(mutationParams.id === undefined ? {} : { [TASK_ID_ATTRIBUTE]: mutationParams.id }),\n });\n if (error instanceof TaskToolExecutionError) throw error;\n throw actionableTaskError(action, error instanceof Error ? error.message : String(error));\n }\n },\n\n // Render hooks receive no session identity, so they read the store snapshot\n // that the executing session last loaded. That is the foreground session's\n // own view, which is exactly what its transcript should show.\n renderCall(args, theme, _context) {\n return renderTaskCall(args as never, theme, store.snapshot.tasks);\n },\n\n renderResult(result, options, theme, _context) {\n return renderTaskResult(result, options, theme);\n },\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../delegation/manager.cjs");let t=require("@earendil-works/pi-tui"),n=require("@agimon-ai/doompi-ui/theme");const r={pending:`○`,in_progress:`◐`,completed:`●`,failed:`✗`,deleted:`⊘`},i={pending:`dim`,in_progress:`warning`,completed:`success`,failed:`error`,deleted:`muted`},a={pending:`pending`,in_progress:`in progress`,completed:`completed`,failed:`failed`,deleted:`deleted`},o={...r,completed:`✓`,deleted:r.failed},s={...i,deleted:`error`},c=1e3,l={upsert:`✎`,delete:`×`,get:`›`,list:`☰`,clear:`∅`,assign:`⇒`,cancel:`⊗`};function u(e){return e.length===0?l.upsert:e.every(e=>e.id===void 0)?`+`:e.every(e=>e.id!==void 0)?`→`:l.upsert}function d(e,t){return t.fg(s[e],o[e])}function f(e){let t=Math.max(0,Math.floor(e/1e3)),n=t%60,r=Math.floor(t/60);if(r<60)return r===0?`${n}s`:`${r}m${String(n).padStart(2,`0`)}s`;let i=r%60;return`${Math.floor(r/60)}h${String(i).padStart(2,`0`)}m${String(n).padStart(2,`0`)}s`}function p(e){let t=Math.max(0,Math.round(e));return t<c?String(t):t<1e4?`${(t/c).toFixed(1)}k`:`${Math.round(t/c)}k`}function m(t,r,i,a,o=Date.now()){let s=t.status===`in_progress`?`accent`:t.status===`completed`||t.status===`deleted`?`muted`:`text`,c=r.fg(s,t.subject);(t.status===`completed`||t.status===`deleted`)&&(c=r.strikethrough(c));let l=d(t.status,r);i&&(l+=` ${r.fg(`dim`,`#${t.id}`)}`),l+=` ${c}`;let u=t.delegation?.agent;if(u&&t.delegation?.state===`running`){let i=[];a&&(i.push(r.fg(`muted`,`[${f(e.DelegationManager.elapsedMs(a,o))}]`)),a.tokens!==void 0&&i.push(r.fg(`muted`,`[${p(a.tokens)}]`))),i.push(r.fg((0,n.agentIdentityColor)(t.delegation.runId??t.delegation.requestId),`[${u}]`)),l+=` ${i.join(``)}`,a?.currentTool&&(l+=` ${r.fg(`muted`,`· ${a.currentTool}`)}`)}else u&&(l+=` ${r.fg(`muted`,`[${u}]`)}`);return t.status===`in_progress`&&t.activeForm&&(l+=` ${r.fg(`muted`,`(${t.activeForm})`)}`),t.blockedBy?.length&&(l+=` ${r.fg(`muted`,`⛓ ${t.blockedBy.map(e=>`#${e}`).join(`,`)}`)}`),l}function h(e,t){let n=e.status===`in_progress`&&e.activeForm?` (${e.activeForm})`:``,r=e.delegation?.agent?` [${e.delegation.agent}]`:``,i=e.blockedBy?.length?` ⛓ ${e.blockedBy.map(e=>`#${e}`).join(`,`)}`:``;return` ${t} #${e.id} ${e.subject}${n}${r}${i}`}function g(e,n,r){let i=e.action===`upsert`?e.tasks??[]:[],o=e.action===`upsert`?u(i):l[e.action]??e.action,s=n.fg(`toolTitle`,n.bold(`task `))+n.fg(`muted`,o);if(e.action===`upsert`){if(i.length===1){let e=i[0];if(e.id===void 0)e.subject&&(s+=` ${n.fg(`dim`,e.subject)}`);else{let t=r.find(t=>t.id===e.id)?.subject??e.subject??`#${e.id}`;s+=` ${n.fg(`accent`,t)}`}}else i.length>1&&(s+=` ${n.fg(`dim`,`${i.length} tasks`)}`)}else if(e.action===`assign`&&e.id!==void 0){let t=r.find(t=>t.id===e.id)?.subject??`#${e.id}`;s+=` ${n.fg(`accent`,t)}`,e.agent&&(s+=` ${n.fg(`muted`,`→ ${e.agent}`)}`)}else if((e.action===`get`||e.action===`delete`||e.action===`cancel`)&&e.id!==void 0){let t=r.find(t=>t.id===e.id)?.subject??`#${e.id}`;s+=` ${n.fg(`accent`,t)}`}else e.action===`list`&&e.status&&(s+=` ${n.fg(`muted`,a[e.status])}`);return new t.Text(s,0,0)}var _=class{rows;constructor(e){this.rows=e}invalidate(){}render(e){return this.rows.map(({left:n,right:r})=>{if(r===void 0||r.length===0)return(0,t.truncateToWidth)(n,e);let i=(0,t.visibleWidth)(r),a=e-i-2;if(a<=0)return(0,t.truncateToWidth)(n,e);let o=(0,t.truncateToWidth)(n,a),s=Math.max(2,e-(0,t.visibleWidth)(o)-i);return o+` `.repeat(s)+r})}};function v(e){return(e.content??[]).map(e=>e.text??``).join(``)}function y(e){return e.split(`
2
+ `).filter(e=>e.trim().length>0)}function b(e){let t=e.params,n=e.tasks;return t.includeDeleted!==!0&&(n=n.filter(e=>e.status!==`deleted`)),t.status&&(n=n.filter(e=>e.status===t.status)),n}function x(e){let t=e.params;if(t.id!==void 0)return e.tasks.find(e=>e.id===t.id)}function S(e){return(e.upsert?.applied??[]).flatMap(t=>e.tasks.find(e=>e.id===t)??[])}function C(e,n,r){let o=e.details;if(n.isPartial){let n=y(v(e)).at(-1)??`working`;return new t.Text(r.fg(`warning`,`◐`)+r.fg(`dim`,` ${n}`),0,0)}if(e.isError===!0||o?.error!==void 0){let i=y(o?.error??v(e));if(i.length<=1)return new t.Text(r.fg(`error`,`✗`)+r.fg(`dim`,i[0]?` ${i[0]}`:``),0,0);let a=n.expanded?i:i.slice(0,8);return new t.Text([...a.map(e=>r.fg(`toolOutput`,e)),r.fg(`error`,`✗`)].join(`
3
+ `),0,0)}if(!o)return new t.Text(r.fg(`success`,`✓`),0,0);let s=e=>({left:m(e,r,!0),right:r.fg(i[e.status],a[e.status])});if(o.action===`list`){let e=b(o),t=n.expanded?e:e.slice(0,8),i=t.map(s),a=e.length===0?`no tasks`:`${e.length} task${e.length===1?``:`s`}`;return e.length>t.length&&(a+=` · ctrl+o`),i.push({left:r.fg(`success`,`✓`)+r.fg(`dim`,` ${a}`)}),new _(i)}if(o.action===`clear`)return new t.Text(r.fg(`success`,`✓`)+r.fg(`dim`,` cleared`),0,0);if(o.action===`upsert`){let e=S(o),t=o.upsert?.failed??0;if(e.length===1&&t===0)return new _([s(e[0])]);let i=n.expanded?e:e.slice(0,8),a=i.map(s),c=`${e.length} applied`;t>0&&(c+=` · ${t} failed`),e.length>i.length&&(c+=` · ctrl+o`);let l=t>0?r.fg(`warning`,`!`):r.fg(`success`,`✓`);return a.push({left:l+r.fg(`dim`,` ${c}`)}),new _(a)}let c=x(o);return c?new _([s(c)]):new t.Text(r.fg(`success`,`✓`),0,0)}exports.ACTION_GLYPH=l,exports.JustifiedRows=_,exports.STATUS_COLOR=i,exports.STATUS_GLYPH=r,exports.STATUS_LABEL=a,exports.formatCommandTaskLine=h,exports.formatElapsedMs=f,exports.formatOverlayTaskLine=m,exports.formatTokenCount=p,exports.overlayStatusGlyph=d,exports.renderTaskCall=g,exports.renderTaskResult=C;
4
+ //# sourceMappingURL=format.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.cjs","names":["DelegationManager","agentIdentityColor","Text","truncateToWidth","visibleWidth"],"sources":["../../src/tui/format.ts"],"sourcesContent":["import type { Theme } from '@earendil-works/pi-coding-agent';\nimport { type Component, Text, truncateToWidth, visibleWidth } from '@earendil-works/pi-tui';\nimport { agentIdentityColor } from '@agimon-ai/doompi-ui/theme';\nimport { DelegationManager, type DelegationProgress } from '../delegation/manager.ts';\nimport type {\n Task,\n TaskAction,\n TaskDetails,\n TaskItemMutation,\n TaskMutationParams,\n TaskStatus,\n} from '../store/types.ts';\n\nexport const STATUS_GLYPH: Record<TaskStatus, string> = {\n pending: '○',\n in_progress: '◐',\n completed: '●',\n failed: '✗',\n deleted: '⊘',\n};\n\ntype TaskStatusColor = 'dim' | 'warning' | 'success' | 'error' | 'muted';\n\nexport const STATUS_COLOR: Record<TaskStatus, TaskStatusColor> = {\n pending: 'dim',\n in_progress: 'warning',\n completed: 'success',\n failed: 'error',\n deleted: 'muted',\n};\n\nexport const STATUS_LABEL: Record<TaskStatus, string> = {\n pending: 'pending',\n in_progress: 'in progress',\n completed: 'completed',\n failed: 'failed',\n deleted: 'deleted',\n};\n\nconst OVERLAY_STATUS_GLYPH: Record<TaskStatus, string> = {\n ...STATUS_GLYPH,\n completed: '✓',\n deleted: STATUS_GLYPH.failed,\n};\n\nconst OVERLAY_STATUS_COLOR: Record<TaskStatus, TaskStatusColor> = {\n ...STATUS_COLOR,\n deleted: 'error',\n};\nconst MILLISECONDS_PER_SECOND = 1000;\nconst SECONDS_PER_MINUTE = 60;\nconst MINUTES_PER_HOUR = 60;\nconst TOKENS_PER_KILO = 1000;\nconst TOKEN_DECIMAL_LIMIT = 10_000;\n\nexport const ACTION_GLYPH: Record<TaskAction, string> = {\n upsert: '✎',\n delete: '×',\n get: '›',\n list: '☰',\n clear: '∅',\n assign: '⇒',\n cancel: '⊗',\n};\n\n/**\n * `upsert` is two operations behind one name, so a homogeneous batch narrows to\n * the glyph the operator already reads: `+` means new work appeared, `→` means\n * work moved. A mixed batch keeps the neutral write glyph.\n */\nconst UPSERT_CREATE_GLYPH = '+';\nconst UPSERT_UPDATE_GLYPH = '→';\n\nfunction upsertGlyph(items: readonly TaskItemMutation[]): string {\n if (items.length === 0) return ACTION_GLYPH.upsert;\n if (items.every((item) => item.id === undefined)) return UPSERT_CREATE_GLYPH;\n if (items.every((item) => item.id !== undefined)) return UPSERT_UPDATE_GLYPH;\n return ACTION_GLYPH.upsert;\n}\n\nexport function overlayStatusGlyph(status: TaskStatus, theme: Theme): string {\n return theme.fg(OVERLAY_STATUS_COLOR[status], OVERLAY_STATUS_GLYPH[status]);\n}\n\nexport function formatElapsedMs(durationMs: number): string {\n const totalSeconds = Math.max(0, Math.floor(durationMs / MILLISECONDS_PER_SECOND));\n const seconds = totalSeconds % SECONDS_PER_MINUTE;\n const totalMinutes = Math.floor(totalSeconds / SECONDS_PER_MINUTE);\n if (totalMinutes < MINUTES_PER_HOUR) {\n return totalMinutes === 0 ? `${seconds}s` : `${totalMinutes}m${String(seconds).padStart(2, '0')}s`;\n }\n const minutes = totalMinutes % MINUTES_PER_HOUR;\n const hours = Math.floor(totalMinutes / MINUTES_PER_HOUR);\n return `${hours}h${String(minutes).padStart(2, '0')}m${String(seconds).padStart(2, '0')}s`;\n}\n\nexport function formatTokenCount(tokens: number): string {\n const count = Math.max(0, Math.round(tokens));\n if (count < TOKENS_PER_KILO) return String(count);\n if (count < TOKEN_DECIMAL_LIMIT) return `${(count / TOKENS_PER_KILO).toFixed(1)}k`;\n return `${Math.round(count / TOKENS_PER_KILO)}k`;\n}\n\n/**\n * One task row for the persistent overlay.\n *\n * A delegated row carries the agent name and its current tool so the operator\n * can see that background work is progressing without opening a transcript.\n */\nexport function formatOverlayTaskLine(\n task: Task,\n theme: Theme,\n showId: boolean,\n progress?: DelegationProgress,\n nowMs = Date.now(),\n): string {\n const subjectColor =\n task.status === 'in_progress'\n ? 'accent'\n : task.status === 'completed' || task.status === 'deleted'\n ? 'muted'\n : 'text';\n let subject = theme.fg(subjectColor, task.subject);\n if (task.status === 'completed' || task.status === 'deleted') {\n subject = theme.strikethrough(subject);\n }\n\n let line = overlayStatusGlyph(task.status, theme);\n if (showId) line += ` ${theme.fg('dim', `#${task.id}`)}`;\n line += ` ${subject}`;\n\n const agent = task.delegation?.agent;\n if (agent && task.delegation?.state === 'running') {\n // No progress means no timing is known, so the chips are omitted rather than\n // reported as `[0s]`. The transcript renderer has no progress feed at all.\n const chips: string[] = [];\n if (progress) {\n chips.push(theme.fg('muted', `[${formatElapsedMs(DelegationManager.elapsedMs(progress, nowMs))}]`));\n if (progress.tokens !== undefined) chips.push(theme.fg('muted', `[${formatTokenCount(progress.tokens)}]`));\n }\n chips.push(theme.fg(agentIdentityColor(task.delegation.runId ?? task.delegation.requestId), `[${agent}]`));\n line += ` ${chips.join('')}`;\n if (progress?.currentTool) line += ` ${theme.fg('muted', `· ${progress.currentTool}`)}`;\n } else if (agent) {\n line += ` ${theme.fg('muted', `[${agent}]`)}`;\n }\n\n if (task.status === 'in_progress' && task.activeForm) {\n line += ` ${theme.fg('muted', `(${task.activeForm})`)}`;\n }\n if (task.blockedBy?.length) {\n line += ` ${theme.fg('muted', `⛓ ${task.blockedBy.map((id) => `#${id}`).join(',')}`)}`;\n }\n return line;\n}\n\n/** One task line for the `/tasks` command output. */\nexport function formatCommandTaskLine(task: Task, glyph: string): string {\n const form = task.status === 'in_progress' && task.activeForm ? ` (${task.activeForm})` : '';\n const agent = task.delegation?.agent ? ` [${task.delegation.agent}]` : '';\n const block = task.blockedBy?.length ? ` ⛓ ${task.blockedBy.map((id) => `#${id}`).join(',')}` : '';\n return ` ${glyph} #${task.id} ${task.subject}${form}${agent}${block}`;\n}\n\nexport function renderTaskCall(\n args: TaskMutationParams & { action: TaskAction },\n theme: Theme,\n tasks: readonly Task[],\n): Text {\n const items = args.action === 'upsert' ? (args.tasks ?? []) : [];\n const glyph = args.action === 'upsert' ? upsertGlyph(items) : (ACTION_GLYPH[args.action] ?? args.action);\n let text = theme.fg('toolTitle', theme.bold('task ')) + theme.fg('muted', glyph);\n\n if (args.action === 'upsert') {\n // One entry reads exactly as create or update did; a batch reads as a count\n // rather than a subject it would have to pick arbitrarily.\n if (items.length === 1) {\n const only = items[0];\n if (only.id === undefined) {\n if (only.subject) text += ` ${theme.fg('dim', only.subject)}`;\n } else {\n const subject = tasks.find((task) => task.id === only.id)?.subject ?? only.subject ?? `#${only.id}`;\n text += ` ${theme.fg('accent', subject)}`;\n }\n } else if (items.length > 1) {\n text += ` ${theme.fg('dim', `${items.length} tasks`)}`;\n }\n } else if (args.action === 'assign' && args.id !== undefined) {\n const subject = tasks.find((task) => task.id === args.id)?.subject ?? `#${args.id}`;\n text += ` ${theme.fg('accent', subject)}`;\n if (args.agent) text += ` ${theme.fg('muted', `→ ${args.agent}`)}`;\n } else if ((args.action === 'get' || args.action === 'delete' || args.action === 'cancel') && args.id !== undefined) {\n const subject = tasks.find((task) => task.id === args.id)?.subject ?? `#${args.id}`;\n text += ` ${theme.fg('accent', subject)}`;\n } else if (args.action === 'list' && args.status) {\n text += ` ${theme.fg('muted', STATUS_LABEL[args.status])}`;\n }\n return new Text(text, 0, 0);\n}\n\n/** Task rows kept in a collapsed result, before `ctrl+o` reveals the rest. */\nconst TRANSCRIPT_TASK_ROWS = 8;\n/** Minimum gap between a row's subject and its right-aligned status. */\nconst STATUS_GUTTER = 2;\n\nexport interface JustifiedRow {\n left: string;\n /** Pinned to the right edge. The subject is truncated before this is dropped. */\n right?: string;\n}\n\n/**\n * Rows whose trailing text is flushed right.\n *\n * `Text` cannot do this: the status has to be placed against the viewport edge,\n * which is only known at render time.\n */\nexport class JustifiedRows implements Component {\n constructor(private readonly rows: readonly JustifiedRow[]) {}\n\n /**\n * Nothing to discard: the rows are themed by the caller and held verbatim, and\n * Pi rebuilds this component from `renderResult` whenever the theme changes.\n */\n invalidate(): void {}\n\n render(width: number): string[] {\n return this.rows.map(({ left, right }) => {\n if (right === undefined || right.length === 0) return truncateToWidth(left, width);\n const rightWidth = visibleWidth(right);\n const room = width - rightWidth - STATUS_GUTTER;\n if (room <= 0) return truncateToWidth(left, width);\n const subject = truncateToWidth(left, room);\n const gap = Math.max(STATUS_GUTTER, width - visibleWidth(subject) - rightWidth);\n return subject + ' '.repeat(gap) + right;\n });\n }\n}\n\nexport interface TaskResultLike {\n content?: Array<{ type: string; text?: string }>;\n details?: unknown;\n isError?: boolean;\n}\n\nexport interface TaskResultOptions {\n expanded: boolean;\n isPartial: boolean;\n}\n\n/** Concatenated result text, which is all a thrown failure leaves behind. */\nfunction contentText(result: TaskResultLike): string {\n return (result.content ?? []).map((block) => block.text ?? '').join('');\n}\n\nfunction nonEmptyLines(text: string): string[] {\n return text.split('\\n').filter((line) => line.trim().length > 0);\n}\n\n/**\n * The rows `list` reported to the model.\n *\n * `details.tasks` is the whole post-mutation document, so the filters applied by\n * `formatContent` have to be applied again here or the transcript would disagree\n * with the text the model was given.\n */\nfunction listedTasks(details: TaskDetails): Task[] {\n const params = details.params as TaskMutationParams;\n let view = details.tasks;\n if (params.includeDeleted !== true) view = view.filter((task) => task.status !== 'deleted');\n if (params.status) view = view.filter((task) => task.status === params.status);\n return view;\n}\n\n/** The single task an id-bearing action acted on, so the transcript names it rather than a bare tick. */\nfunction subjectTask(details: TaskDetails): Task | undefined {\n const params = details.params as TaskMutationParams;\n if (params.id === undefined) return undefined;\n return details.tasks.find((task) => task.id === params.id);\n}\n\n/**\n * Tasks an upsert applied, resolved from the ids the reducer reported.\n *\n * The ids are read rather than guessed from the tail of the list: a batch\n * touches many rows, and a failed entry contributes none.\n */\nfunction upsertTasks(details: TaskDetails): Task[] {\n return (details.upsert?.applied ?? []).flatMap((id) => details.tasks.find((task) => task.id === id) ?? []);\n}\n\nexport function renderTaskResult(result: TaskResultLike, options: TaskResultOptions, theme: Theme): Component {\n const details = result.details as TaskDetails | undefined;\n\n // Running. `assign` and `cancel` stream a placeholder before the run settles.\n if (options.isPartial) {\n const text = nonEmptyLines(contentText(result)).at(-1) ?? 'working';\n return new Text(theme.fg('warning', '◐') + theme.fg('dim', ` ${text}`), 0, 0);\n }\n\n // Failed. Every failure path throws, so Pi hands back error text and no\n // details; without this the block would render a green tick on a failure.\n if (result.isError === true || details?.error !== undefined) {\n const message = details?.error ?? contentText(result);\n const all = nonEmptyLines(message);\n if (all.length <= 1) {\n return new Text(theme.fg('error', '✗') + theme.fg('dim', all[0] ? ` ${all[0]}` : ''), 0, 0);\n }\n const body = options.expanded ? all : all.slice(0, TRANSCRIPT_TASK_ROWS);\n return new Text([...body.map((line) => theme.fg('toolOutput', line)), theme.fg('error', '✗')].join('\\n'), 0, 0);\n }\n\n if (!details) return new Text(theme.fg('success', '✓'), 0, 0);\n\n /** Status rides on the task's own row, flushed right, rather than costing a line. */\n const row = (task: Task): JustifiedRow => ({\n left: formatOverlayTaskLine(task, theme, true),\n right: theme.fg(STATUS_COLOR[task.status], STATUS_LABEL[task.status]),\n });\n\n if (details.action === 'list') {\n const tasks = listedTasks(details);\n const shown = options.expanded ? tasks : tasks.slice(0, TRANSCRIPT_TASK_ROWS);\n const rows: JustifiedRow[] = shown.map(row);\n let summary = tasks.length === 0 ? 'no tasks' : `${tasks.length} task${tasks.length === 1 ? '' : 's'}`;\n if (tasks.length > shown.length) summary += ' · ctrl+o';\n rows.push({ left: theme.fg('success', '✓') + theme.fg('dim', ` ${summary}`) });\n return new JustifiedRows(rows);\n }\n\n if (details.action === 'clear') {\n return new Text(theme.fg('success', '✓') + theme.fg('dim', ' cleared'), 0, 0);\n }\n\n if (details.action === 'upsert') {\n const touched = upsertTasks(details);\n const failed = details.upsert?.failed ?? 0;\n // One applied task and nothing failed is the common case: keep the single\n // row it has always had rather than dressing it as a bulk report.\n if (touched.length === 1 && failed === 0) return new JustifiedRows([row(touched[0])]);\n\n const shown = options.expanded ? touched : touched.slice(0, TRANSCRIPT_TASK_ROWS);\n const rows: JustifiedRow[] = shown.map(row);\n let summary = `${touched.length} applied`;\n if (failed > 0) summary += ` · ${failed} failed`;\n if (touched.length > shown.length) summary += ' · ctrl+o';\n // Failed entries get no row: there is no task to render, and their messages\n // are already in the text the model was given.\n const mark = failed > 0 ? theme.fg('warning', '!') : theme.fg('success', '✓');\n rows.push({ left: mark + theme.fg('dim', ` ${summary}`) });\n return new JustifiedRows(rows);\n }\n\n const task = subjectTask(details);\n if (!task) return new Text(theme.fg('success', '✓'), 0, 0);\n return new JustifiedRows([row(task)]);\n}\n"],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { Task, TaskAction, TaskMutationParams, TaskStatus } from "../store/types.cjs";
2
+ import { DelegationProgress } from "../delegation/manager.cjs";
3
+ import { Theme } from "@earendil-works/pi-coding-agent";
4
+ import { Component, Text } from "@earendil-works/pi-tui";
5
+ //#region src/tui/format.d.ts
6
+ declare const STATUS_GLYPH: Record<TaskStatus, string>;
7
+ type TaskStatusColor = 'dim' | 'warning' | 'success' | 'error' | 'muted';
8
+ declare const STATUS_COLOR: Record<TaskStatus, TaskStatusColor>;
9
+ declare const STATUS_LABEL: Record<TaskStatus, string>;
10
+ declare const ACTION_GLYPH: Record<TaskAction, string>;
11
+ declare function overlayStatusGlyph(status: TaskStatus, theme: Theme): string;
12
+ declare function formatElapsedMs(durationMs: number): string;
13
+ declare function formatTokenCount(tokens: number): string;
14
+ /**
15
+ * One task row for the persistent overlay.
16
+ *
17
+ * A delegated row carries the agent name and its current tool so the operator
18
+ * can see that background work is progressing without opening a transcript.
19
+ */
20
+ declare function formatOverlayTaskLine(task: Task, theme: Theme, showId: boolean, progress?: DelegationProgress, nowMs?: number): string;
21
+ /** One task line for the `/tasks` command output. */
22
+ declare function formatCommandTaskLine(task: Task, glyph: string): string;
23
+ declare function renderTaskCall(args: TaskMutationParams & {
24
+ action: TaskAction;
25
+ }, theme: Theme, tasks: readonly Task[]): Text;
26
+ interface JustifiedRow {
27
+ left: string;
28
+ /** Pinned to the right edge. The subject is truncated before this is dropped. */
29
+ right?: string;
30
+ }
31
+ /**
32
+ * Rows whose trailing text is flushed right.
33
+ *
34
+ * `Text` cannot do this: the status has to be placed against the viewport edge,
35
+ * which is only known at render time.
36
+ */
37
+ declare class JustifiedRows implements Component {
38
+ private readonly rows;
39
+ constructor(rows: readonly JustifiedRow[]);
40
+ /**
41
+ * Nothing to discard: the rows are themed by the caller and held verbatim, and
42
+ * Pi rebuilds this component from `renderResult` whenever the theme changes.
43
+ */
44
+ invalidate(): void;
45
+ render(width: number): string[];
46
+ }
47
+ interface TaskResultLike {
48
+ content?: Array<{
49
+ type: string;
50
+ text?: string;
51
+ }>;
52
+ details?: unknown;
53
+ isError?: boolean;
54
+ }
55
+ interface TaskResultOptions {
56
+ expanded: boolean;
57
+ isPartial: boolean;
58
+ }
59
+ declare function renderTaskResult(result: TaskResultLike, options: TaskResultOptions, theme: Theme): Component;
60
+ //#endregion
61
+ export { ACTION_GLYPH, JustifiedRow, JustifiedRows, STATUS_COLOR, STATUS_GLYPH, STATUS_LABEL, TaskResultLike, TaskResultOptions, formatCommandTaskLine, formatElapsedMs, formatOverlayTaskLine, formatTokenCount, overlayStatusGlyph, renderTaskCall, renderTaskResult };
62
+ //# sourceMappingURL=format.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.cts","names":[],"sources":["../../src/tui/format.ts"],"mappings":";;;;;cAaa,cAAc,OAAO;KAQ7B;cAEQ,cAAc,OAAO,YAAY;cAQjC,cAAc,OAAO;cAwBrB,cAAc,OAAO;iBAyBlB,mBAAmB,QAAQ,YAAY,OAAO;iBAI9C,gBAAgB;iBAYhB,iBAAiB;;;;;;;iBAajB,sBACd,MAAM,MACN,OAAO,OACP,iBACA,WAAW,oBACX;;iBA2Cc,sBAAsB,MAAM,MAAM;iBAOlC,eACd,MAAM;EAAuB,QAAQ;GACrC,OAAO,OACP,gBAAgB,SACf;UAqCc;EACf;;EAEA;;;;;;;;cASW,yBAAyB;mBACP;EAAA,YAAA,eAAe;;;;;EAM5C;EAEA,OAAO;;UAaQ;EACf,UAAU;IAAQ;IAAc;;EAChC;EACA;;UAGe;EACf;EACA;;iBA4Cc,iBAAiB,QAAQ,gBAAgB,SAAS,mBAAmB,OAAO,QAAQ"}
@@ -0,0 +1,62 @@
1
+ import { Task, TaskAction, TaskMutationParams, TaskStatus } from "../store/types.mjs";
2
+ import { DelegationProgress } from "../delegation/manager.mjs";
3
+ import { Component, Text } from "@earendil-works/pi-tui";
4
+ import { Theme } from "@earendil-works/pi-coding-agent";
5
+ //#region src/tui/format.d.ts
6
+ declare const STATUS_GLYPH: Record<TaskStatus, string>;
7
+ type TaskStatusColor = 'dim' | 'warning' | 'success' | 'error' | 'muted';
8
+ declare const STATUS_COLOR: Record<TaskStatus, TaskStatusColor>;
9
+ declare const STATUS_LABEL: Record<TaskStatus, string>;
10
+ declare const ACTION_GLYPH: Record<TaskAction, string>;
11
+ declare function overlayStatusGlyph(status: TaskStatus, theme: Theme): string;
12
+ declare function formatElapsedMs(durationMs: number): string;
13
+ declare function formatTokenCount(tokens: number): string;
14
+ /**
15
+ * One task row for the persistent overlay.
16
+ *
17
+ * A delegated row carries the agent name and its current tool so the operator
18
+ * can see that background work is progressing without opening a transcript.
19
+ */
20
+ declare function formatOverlayTaskLine(task: Task, theme: Theme, showId: boolean, progress?: DelegationProgress, nowMs?: number): string;
21
+ /** One task line for the `/tasks` command output. */
22
+ declare function formatCommandTaskLine(task: Task, glyph: string): string;
23
+ declare function renderTaskCall(args: TaskMutationParams & {
24
+ action: TaskAction;
25
+ }, theme: Theme, tasks: readonly Task[]): Text;
26
+ interface JustifiedRow {
27
+ left: string;
28
+ /** Pinned to the right edge. The subject is truncated before this is dropped. */
29
+ right?: string;
30
+ }
31
+ /**
32
+ * Rows whose trailing text is flushed right.
33
+ *
34
+ * `Text` cannot do this: the status has to be placed against the viewport edge,
35
+ * which is only known at render time.
36
+ */
37
+ declare class JustifiedRows implements Component {
38
+ private readonly rows;
39
+ constructor(rows: readonly JustifiedRow[]);
40
+ /**
41
+ * Nothing to discard: the rows are themed by the caller and held verbatim, and
42
+ * Pi rebuilds this component from `renderResult` whenever the theme changes.
43
+ */
44
+ invalidate(): void;
45
+ render(width: number): string[];
46
+ }
47
+ interface TaskResultLike {
48
+ content?: Array<{
49
+ type: string;
50
+ text?: string;
51
+ }>;
52
+ details?: unknown;
53
+ isError?: boolean;
54
+ }
55
+ interface TaskResultOptions {
56
+ expanded: boolean;
57
+ isPartial: boolean;
58
+ }
59
+ declare function renderTaskResult(result: TaskResultLike, options: TaskResultOptions, theme: Theme): Component;
60
+ //#endregion
61
+ export { ACTION_GLYPH, JustifiedRow, JustifiedRows, STATUS_COLOR, STATUS_GLYPH, STATUS_LABEL, TaskResultLike, TaskResultOptions, formatCommandTaskLine, formatElapsedMs, formatOverlayTaskLine, formatTokenCount, overlayStatusGlyph, renderTaskCall, renderTaskResult };
62
+ //# sourceMappingURL=format.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.mts","names":[],"sources":["../../src/tui/format.ts"],"mappings":";;;;;cAaa,cAAc,OAAO;KAQ7B;cAEQ,cAAc,OAAO,YAAY;cAQjC,cAAc,OAAO;cAwBrB,cAAc,OAAO;iBAyBlB,mBAAmB,QAAQ,YAAY,OAAO;iBAI9C,gBAAgB;iBAYhB,iBAAiB;;;;;;;iBAajB,sBACd,MAAM,MACN,OAAO,OACP,iBACA,WAAW,oBACX;;iBA2Cc,sBAAsB,MAAM,MAAM;iBAOlC,eACd,MAAM;EAAuB,QAAQ;GACrC,OAAO,OACP,gBAAgB,SACf;UAqCc;EACf;;EAEA;;;;;;;;cASW,yBAAyB;mBACP;EAAA,YAAA,eAAe;;;;;EAM5C;EAEA,OAAO;;UAaQ;EACf,UAAU;IAAQ;IAAc;;EAChC;EACA;;UAGe;EACf;EACA;;iBA4Cc,iBAAiB,QAAQ,gBAAgB,SAAS,mBAAmB,OAAO,QAAQ"}