@agimon-ai/po-task 0.0.0-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 (161) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +131 -0
  3. package/dist/apiContracts.cjs +54 -0
  4. package/dist/apiContracts.cjs.map +1 -0
  5. package/dist/apiContracts.d.mts +53 -0
  6. package/dist/apiContracts.d.mts.map +1 -0
  7. package/dist/apiContracts.mjs +49 -0
  8. package/dist/apiContracts.mjs.map +1 -0
  9. package/dist/config-CFSs3iku.mjs +72 -0
  10. package/dist/config-CFSs3iku.mjs.map +1 -0
  11. package/dist/config-CdX-Bv8q.cjs +173 -0
  12. package/dist/config-CdX-Bv8q.cjs.map +1 -0
  13. package/dist/config.cjs +19 -0
  14. package/dist/config.d.mts +2 -0
  15. package/dist/config.mjs +2 -0
  16. package/dist/delegation-BiOy3_7g.mjs +7 -0
  17. package/dist/delegation-BiOy3_7g.mjs.map +1 -0
  18. package/dist/delegation-CdMqOZB4.mjs +626 -0
  19. package/dist/delegation-CdMqOZB4.mjs.map +1 -0
  20. package/dist/delegation-DsnKjMbJ.cjs +661 -0
  21. package/dist/delegation-DsnKjMbJ.cjs.map +1 -0
  22. package/dist/delegation-LDpHP2CC.cjs +12 -0
  23. package/dist/delegation-LDpHP2CC.cjs.map +1 -0
  24. package/dist/delegationManager.cjs +10 -0
  25. package/dist/delegationManager.d.mts +2 -0
  26. package/dist/delegationManager.mjs +3 -0
  27. package/dist/extensions/mcp-ui.mjs +23 -0
  28. package/dist/extensions/mcp-ui.mjs.map +1 -0
  29. package/dist/extensions/mcp.cjs +1144 -0
  30. package/dist/extensions/mcp.cjs.map +1 -0
  31. package/dist/extensions/mcp.d.mts +5 -0
  32. package/dist/extensions/mcp.d.mts.map +1 -0
  33. package/dist/extensions/mcp.mjs +1115 -0
  34. package/dist/extensions/mcp.mjs.map +1 -0
  35. package/dist/extensions/native.mjs +1175 -0
  36. package/dist/extensions/native.mjs.map +1 -0
  37. package/dist/extensions/server.cjs +569 -0
  38. package/dist/extensions/server.cjs.map +1 -0
  39. package/dist/extensions/server.d.mts +5 -0
  40. package/dist/extensions/server.d.mts.map +1 -0
  41. package/dist/extensions/server.mjs +563 -0
  42. package/dist/extensions/server.mjs.map +1 -0
  43. package/dist/extensions/web.mjs +1018 -0
  44. package/dist/extensions/web.mjs.map +1 -0
  45. package/dist/index-B-3sCF2S.d.mts +43 -0
  46. package/dist/index-B-3sCF2S.d.mts.map +1 -0
  47. package/dist/index-B1JPJdpZ.d.mts +51 -0
  48. package/dist/index-B1JPJdpZ.d.mts.map +1 -0
  49. package/dist/index-CUWCvh-E.d.mts +72 -0
  50. package/dist/index-CUWCvh-E.d.mts.map +1 -0
  51. package/dist/index-DlmXKyhQ.d.mts +34 -0
  52. package/dist/index-DlmXKyhQ.d.mts.map +1 -0
  53. package/dist/index-Dvb8X_qB.d.mts +67 -0
  54. package/dist/index-Dvb8X_qB.d.mts.map +1 -0
  55. package/dist/index-XY9VPmfm.d.mts +26 -0
  56. package/dist/index-XY9VPmfm.d.mts.map +1 -0
  57. package/dist/index-teIf67qQ.d.mts +196 -0
  58. package/dist/index-teIf67qQ.d.mts.map +1 -0
  59. package/dist/index.cjs +93 -0
  60. package/dist/index.d.mts +11 -0
  61. package/dist/index.mjs +12 -0
  62. package/dist/invariants-DhjEjBPU.cjs +79 -0
  63. package/dist/invariants-DhjEjBPU.cjs.map +1 -0
  64. package/dist/invariants-q_UamF7D.mjs +62 -0
  65. package/dist/invariants-q_UamF7D.mjs.map +1 -0
  66. package/dist/logSinkTelemetry-B23qGiP-.cjs +52 -0
  67. package/dist/logSinkTelemetry-B23qGiP-.cjs.map +1 -0
  68. package/dist/logSinkTelemetry-BMBsC54p.mjs +41 -0
  69. package/dist/logSinkTelemetry-BMBsC54p.mjs.map +1 -0
  70. package/dist/logSinkTelemetry.cjs +6 -0
  71. package/dist/logSinkTelemetry.d.mts +23 -0
  72. package/dist/logSinkTelemetry.d.mts.map +1 -0
  73. package/dist/logSinkTelemetry.mjs +3 -0
  74. package/dist/paths-CSya2l9_.cjs +308 -0
  75. package/dist/paths-CSya2l9_.cjs.map +1 -0
  76. package/dist/paths-Cah1vFGv.mjs +207 -0
  77. package/dist/paths-Cah1vFGv.mjs.map +1 -0
  78. package/dist/processLiveness-Ccd9wenT.mjs +20 -0
  79. package/dist/processLiveness-Ccd9wenT.mjs.map +1 -0
  80. package/dist/processLiveness-umpNgsPR.cjs +25 -0
  81. package/dist/processLiveness-umpNgsPR.cjs.map +1 -0
  82. package/dist/reconcile-BcD-hTbd.mjs +63 -0
  83. package/dist/reconcile-BcD-hTbd.mjs.map +1 -0
  84. package/dist/reconcile-cRL0NjDr.cjs +80 -0
  85. package/dist/reconcile-cRL0NjDr.cjs.map +1 -0
  86. package/dist/reducer-BEfJFM5L.mjs +345 -0
  87. package/dist/reducer-BEfJFM5L.mjs.map +1 -0
  88. package/dist/reducer-BV0YIZ2o.cjs +380 -0
  89. package/dist/reducer-BV0YIZ2o.cjs.map +1 -0
  90. package/dist/storeInvariants.cjs +5 -0
  91. package/dist/storeInvariants.d.mts +23 -0
  92. package/dist/storeInvariants.d.mts.map +1 -0
  93. package/dist/storeInvariants.mjs +2 -0
  94. package/dist/storePaths.cjs +14 -0
  95. package/dist/storePaths.d.mts +2 -0
  96. package/dist/storePaths.mjs +2 -0
  97. package/dist/storeProcessLiveness.cjs +3 -0
  98. package/dist/storeProcessLiveness.d.mts +11 -0
  99. package/dist/storeProcessLiveness.d.mts.map +1 -0
  100. package/dist/storeProcessLiveness.mjs +2 -0
  101. package/dist/storeReconcile.cjs +5 -0
  102. package/dist/storeReconcile.d.mts +2 -0
  103. package/dist/storeReconcile.mjs +2 -0
  104. package/dist/storeReducer.cjs +8 -0
  105. package/dist/storeReducer.d.mts +2 -0
  106. package/dist/storeReducer.mjs +2 -0
  107. package/dist/storeTaskGraph.cjs +7 -0
  108. package/dist/storeTaskGraph.d.mts +2 -0
  109. package/dist/storeTaskGraph.mjs +2 -0
  110. package/dist/storeTaskStore.cjs +3 -0
  111. package/dist/storeTaskStore.d.mts +2 -0
  112. package/dist/storeTaskStore.mjs +2 -0
  113. package/dist/storeTypes.cjs +6 -0
  114. package/dist/storeTypes.d.mts +2 -0
  115. package/dist/storeTypes.mjs +2 -0
  116. package/dist/task-CXF9VULl.cjs +49 -0
  117. package/dist/task-CXF9VULl.cjs.map +1 -0
  118. package/dist/task-DJpTteeJ.d.mts +187 -0
  119. package/dist/task-DJpTteeJ.d.mts.map +1 -0
  120. package/dist/task-DO0TwZ0z.mjs +132 -0
  121. package/dist/task-DO0TwZ0z.mjs.map +1 -0
  122. package/dist/task-Dhta7JyA.d.mts +126 -0
  123. package/dist/task-Dhta7JyA.d.mts.map +1 -0
  124. package/dist/task-UvW877Ez.cjs +227 -0
  125. package/dist/task-UvW877Ez.cjs.map +1 -0
  126. package/dist/task-giCbpKzV.mjs +26 -0
  127. package/dist/task-giCbpKzV.mjs.map +1 -0
  128. package/dist/taskGraph-BOQvT0-M.mjs +63 -0
  129. package/dist/taskGraph-BOQvT0-M.mjs.map +1 -0
  130. package/dist/taskGraph-BskRslrr.cjs +92 -0
  131. package/dist/taskGraph-BskRslrr.cjs.map +1 -0
  132. package/dist/taskGraph-D0zFHF2p.d.mts +25 -0
  133. package/dist/taskGraph-D0zFHF2p.d.mts.map +1 -0
  134. package/dist/taskResult-D2G7b4w-.cjs +224 -0
  135. package/dist/taskResult-D2G7b4w-.cjs.map +1 -0
  136. package/dist/taskResult-edBAAKSH.mjs +165 -0
  137. package/dist/taskResult-edBAAKSH.mjs.map +1 -0
  138. package/dist/taskStore-DjU60rMm.cjs +215 -0
  139. package/dist/taskStore-DjU60rMm.cjs.map +1 -0
  140. package/dist/taskStore-pAJ971Ml.mjs +208 -0
  141. package/dist/taskStore-pAJ971Ml.mjs.map +1 -0
  142. package/dist/telemetry-Ca0I3Tqo.cjs +30 -0
  143. package/dist/telemetry-Ca0I3Tqo.cjs.map +1 -0
  144. package/dist/telemetry-DyS44zAD.mjs +25 -0
  145. package/dist/telemetry-DyS44zAD.mjs.map +1 -0
  146. package/dist/telemetry-FMGRovb4.d.mts +35 -0
  147. package/dist/telemetry-FMGRovb4.d.mts.map +1 -0
  148. package/dist/toolPromptGuidelines.cjs +27 -0
  149. package/dist/toolPromptGuidelines.cjs.map +1 -0
  150. package/dist/toolPromptGuidelines.d.mts +13 -0
  151. package/dist/toolPromptGuidelines.d.mts.map +1 -0
  152. package/dist/toolPromptGuidelines.mjs +26 -0
  153. package/dist/toolPromptGuidelines.mjs.map +1 -0
  154. package/dist/toolResponseEnvelope.cjs +12 -0
  155. package/dist/toolResponseEnvelope.d.mts +2 -0
  156. package/dist/toolResponseEnvelope.mjs +2 -0
  157. package/dist/toolSchema.cjs +18 -0
  158. package/dist/toolSchema.d.mts +2 -0
  159. package/dist/toolSchema.mjs +2 -0
  160. package/package.json +223 -0
  161. package/src/types/webTasks.ts +24 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.mjs","names":["isRecord","STATUS_TONE","activityGroupTasks","channelTaskGraph","fillTasks","toolTask"],"sources":["../../src/types/webTasks.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/_lib/tasksModel.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/_lib/tasksStore.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/tasks.web.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/task-graph.web.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_lib/TaskDetailDialog.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_lib/taskStatusTone.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_lib/TasksActivitySection.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Tasks.activity.tasks.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/taskToolFormat.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/TaskToolMessage.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/task.web.tsx","../../generated/web.ts"],"sourcesContent":["/** Browser-safe task view published by the cockpit hub channel. */\nexport const TASKS_CHANNEL_TYPE = 'task_graph';\n\nexport type WebTaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'deleted';\n\nexport interface WebTask {\n id: number;\n subject: string;\n description?: string;\n activeForm?: string;\n status: WebTaskStatus;\n blockedBy: number[];\n owner?: string;\n updatedAt?: string;\n delegation?: {\n agent?: string;\n state?: string;\n };\n}\n\nexport interface WebTasksPayload {\n tasks: WebTask[];\n rev: number;\n}\n","/*\n * The task graph's store-free half: payload parsing and the prompts a cockpit\n * edit becomes. It holds no runtime import, so the web store (tasksStore.ts)\n * and the native store (tasksStore.native.ts) share it unchanged.\n */\nimport type { SessionFrameSender } from '@agimon-ai/po-core/web';\n\nimport type { WebTask, WebTasksPayload } from '../../../../../../types/webTasks';\n\nexport interface TasksSession {\n tasks: WebTask[];\n rev: number;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseTask(value: unknown): WebTask | null {\n if (!isRecord(value) || typeof value.id !== 'number' || typeof value.subject !== 'string') return null;\n if (!['pending', 'in_progress', 'completed', 'failed'].includes(String(value.status))) return null;\n const task: WebTask = {\n id: value.id,\n subject: value.subject,\n status: value.status as WebTask['status'],\n blockedBy: Array.isArray(value.blockedBy)\n ? value.blockedBy.filter((id): id is number => typeof id === 'number')\n : [],\n };\n if (typeof value.description === 'string') task.description = value.description;\n if (typeof value.activeForm === 'string') task.activeForm = value.activeForm;\n if (typeof value.owner === 'string') task.owner = value.owner;\n if (typeof value.updatedAt === 'string') task.updatedAt = value.updatedAt;\n if (isRecord(value.delegation)) {\n task.delegation = {};\n if (typeof value.delegation.agent === 'string') task.delegation.agent = value.delegation.agent;\n if (typeof value.delegation.state === 'string') task.delegation.state = value.delegation.state;\n }\n return task;\n}\n\n/** Narrows a hub frame to a task graph payload; null when it is not one. */\nexport function parseTasksPayload(input: unknown): WebTasksPayload | null {\n if (!isRecord(input) || !Array.isArray(input.tasks) || typeof input.rev !== 'number') return null;\n return { tasks: input.tasks.map(parseTask).filter((task): task is WebTask => task !== null), rev: input.rev };\n}\n\n/** The fields the cockpit lets a human change on a task. */\nexport interface TaskEditDraft {\n subject: string;\n description: string;\n status: WebTask['status'];\n}\n\nexport function taskEditDraft(task: WebTask): TaskEditDraft {\n return { subject: task.subject, description: task.description ?? '', status: task.status };\n}\n\nfunction changedFields(task: WebTask, draft: TaskEditDraft): string[] {\n const changes: string[] = [];\n const subject = draft.subject.trim();\n const description = draft.description.trim();\n if (subject && subject !== task.subject) changes.push(`set subject to \"${subject}\"`);\n if (description !== (task.description ?? '').trim()) {\n changes.push(description ? `set description to \"${description}\"` : 'clear the description');\n }\n if (draft.status !== task.status) changes.push(`set status to ${draft.status}`);\n return changes;\n}\n\n/**\n * The agent stays the only writer of task state, so an edit leaves the cockpit\n * as one prompt naming exactly the fields the human changed. Nothing changed\n * means nothing to send.\n */\nexport function taskEditInstruction(task: WebTask, draft: TaskEditDraft): string | null {\n const changes = changedFields(task, draft);\n if (changes.length === 0) return null;\n return `Update task #${task.id}: ${changes.join('; ')}. Change nothing else and keep the dependency graph valid.`;\n}\n\nexport function requestTaskEdit(\n send: SessionFrameSender,\n sessionId: string,\n task: WebTask,\n draft: TaskEditDraft,\n): boolean {\n const message = taskEditInstruction(task, draft);\n if (message === null) return false;\n send(sessionId, { type: 'prompt', message });\n return true;\n}\n\n/** Steering for the subagent that owns a delegated task. */\nexport function taskMessageInstruction(taskId: number, agent: string, message: string): string {\n return `Steer the ${agent} run working on task #${taskId} with this message, then update the task if its plan changed: ${message.trim()}`;\n}\n\nexport function requestTaskMessage(\n send: SessionFrameSender,\n sessionId: string,\n taskId: number,\n agent: string,\n message: string,\n): void {\n send(sessionId, { type: 'prompt', message: taskMessageInstruction(taskId, agent, message) });\n}\n\nexport function requestTaskRemoval(send: SessionFrameSender, sessionId: string, taskId: number): void {\n send(sessionId, {\n type: 'prompt',\n message: `Remove task #${taskId}. Also remove or repair every dependency that references it so the remaining task graph is valid.`,\n });\n}\n","import { defineSessionStore } from '@agimon-ai/po-core/web';\n\nimport { TASKS_CHANNEL_TYPE, type WebTasksPayload } from '../../../../../../types/webTasks';\nimport { parseTasksPayload, type TasksSession } from './tasksModel';\n\nexport {\n requestTaskEdit,\n requestTaskMessage,\n requestTaskRemoval,\n taskEditDraft,\n taskEditInstruction,\n taskMessageInstruction,\n type TaskEditDraft,\n type TasksSession,\n} from './tasksModel';\n\nexport const tasks = defineSessionStore<TasksSession>({ tasks: [], rev: 0 });\n\nexport const tasksChannel = tasks.channel<WebTasksPayload>({\n channel: TASKS_CHANNEL_TYPE,\n parse: parseTasksPayload,\n reduce: (_current, payload) => payload,\n});\n","import { defineActivityGroup } from '@agimon-ai/po-core/web';\nimport { TaskIcon } from '@agimon-ai/po-web-components';\n\nimport { tasks } from '../channel/_lib/tasksStore';\n\n/**\n * The live task board in the session Activity dock.\n *\n * Active means a delegated run is still out, not that the list has entries. A\n * pending task waits for this agent's next turn and reports to nobody, so\n * counting it as running would leave the dock badge, the top bar and the\n * timeline's background-work notice claiming work that nothing will finish.\n */\nexport default defineActivityGroup({\n keys: 't l',\n icon: TaskIcon,\n statusKey: '@agimon-ai/po-task',\n marksBackgroundWork: false,\n activeSource: {\n subscribe(listener: () => void) {\n const subscription = tasks.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive(sessionId: string | null) {\n return tasks\n .select(tasks.store.state, sessionId)\n .tasks.some((task) => task.delegation?.state === 'requested' || task.delegation?.state === 'running');\n },\n },\n order: 65,\n});\n","import { defineChannelFile } from '@agimon-ai/po-core/web';\n\nimport { tasksChannel } from './_lib/tasksStore';\n\nexport default defineChannelFile(tasksChannel);\n","import type { SessionFrameSender } from '@agimon-ai/po-core/web';\nimport {\n Button,\n Dialog,\n DialogBody,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Textarea,\n} from '@agimon-ai/po-web-components';\nimport { type ReactNode, useState } from 'react';\n\nimport type { WebTask, WebTaskStatus } from '../../../../../../types/webTasks';\nimport { requestTaskEdit, requestTaskMessage, taskEditDraft, type TaskEditDraft } from '../../channel/_lib/tasksStore';\n\n/** How the one task dialog is opened: reading it, changing it, or steering its run. */\nexport type TaskDialogMode = 'view' | 'edit' | 'message';\n\nconst STATUS_CHOICES: readonly WebTaskStatus[] = ['pending', 'in_progress', 'completed', 'failed'];\nconst DESCRIPTION_ROWS = 5;\nconst MESSAGE_ROWS = 4;\n\nfunction FieldLabel({ children }: { children: string }) {\n return <span className=\"text-base font-medium text-doom-text\">{children}</span>;\n}\n\nfunction Field({ label, children }: { label: string; children: ReactNode }) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{label}</FieldLabel>\n {children}\n </div>\n );\n}\n\nfunction ReadOnlyValue({ value, testId }: { value: string; testId: string }) {\n return (\n <span data-testid={testId} className=\"whitespace-pre-wrap break-words text-base leading-relaxed text-doom-dim\">\n {value}\n </span>\n );\n}\n\nfunction TaskFacts({ task }: { task: WebTask }) {\n return (\n <div className=\"flex flex-wrap gap-5\">\n <Field label=\"Status\">\n <ReadOnlyValue testId=\"task-detail-status\" value={task.status.replace('_', ' ')} />\n </Field>\n {task.activeForm ? (\n <Field label=\"Active form\">\n <ReadOnlyValue testId=\"task-detail-active-form\" value={task.activeForm} />\n </Field>\n ) : null}\n {task.owner ? (\n <Field label=\"Owner\">\n <ReadOnlyValue testId=\"task-detail-owner\" value={task.owner} />\n </Field>\n ) : null}\n {task.delegation?.agent ? (\n <Field label=\"Delegated to\">\n <ReadOnlyValue\n testId=\"task-detail-agent\"\n value={\n task.delegation.state ? `${task.delegation.agent} · ${task.delegation.state}` : task.delegation.agent\n }\n />\n </Field>\n ) : null}\n {task.blockedBy.length > 0 ? (\n <Field label=\"Blocked by\">\n <ReadOnlyValue testId=\"task-detail-blocked-by\" value={task.blockedBy.map((id) => `#${id}`).join(', ')} />\n </Field>\n ) : null}\n {task.updatedAt ? (\n <Field label=\"Updated\">\n <ReadOnlyValue testId=\"task-detail-updated\" value={task.updatedAt} />\n </Field>\n ) : null}\n </div>\n );\n}\n\n/**\n * One task, read first and changed second. Every change leaves as a prompt the\n * session can see, so the agent remains the only writer of task state.\n */\nexport function TaskDetailDialog({\n task,\n sessionId,\n mode: initialMode,\n send,\n onClose,\n}: {\n task: WebTask;\n sessionId: string;\n mode: TaskDialogMode;\n send: SessionFrameSender;\n onClose: () => void;\n}) {\n const [mode, setMode] = useState<TaskDialogMode>(initialMode);\n const [draft, setDraft] = useState<TaskEditDraft>(() => taskEditDraft(task));\n const [message, setMessage] = useState('');\n const agent = task.delegation?.agent;\n\n const submitEdit = (): void => {\n if (requestTaskEdit(send, sessionId, task, draft)) onClose();\n };\n const submitMessage = (): void => {\n if (!message.trim() || !agent) return;\n requestTaskMessage(send, sessionId, task.id, agent, message);\n onClose();\n };\n\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open) onClose();\n }}\n >\n <DialogContent width=\"lg\" data-testid=\"task-detail-dialog\" data-mode={mode} aria-describedby={undefined}>\n <DialogHeader>\n <div className=\"flex min-w-0 flex-col items-start gap-1 sm:flex-row sm:items-center sm:gap-2.5\">\n <span className=\"text-sm text-doom-dim\">task #{task.id}</span>\n <DialogTitle data-testid=\"task-detail-title\" className=\"max-w-full break-words\">\n {task.subject}\n </DialogTitle>\n </div>\n </DialogHeader>\n <DialogBody>\n {mode === 'view' ? (\n <>\n <Field label=\"Description\">\n <ReadOnlyValue\n testId=\"task-detail-description\"\n value={task.description ?? 'no description on this task'}\n />\n </Field>\n <TaskFacts task={task} />\n <DialogFooter>\n <span className=\"min-w-0 flex-1\" />\n {agent ? (\n <Button\n variant=\"outline\"\n size=\"xs\"\n data-testid=\"task-detail-open-message\"\n onClick={() => setMode('message')}\n >\n message agent\n </Button>\n ) : null}\n <Button variant=\"primary\" size=\"xs\" data-testid=\"task-detail-open-edit\" onClick={() => setMode('edit')}>\n edit\n </Button>\n </DialogFooter>\n </>\n ) : null}\n\n {mode === 'edit' ? (\n <>\n <Field label=\"Subject\">\n <Input\n data-testid=\"task-detail-subject-input\"\n autoFocus\n value={draft.subject}\n onChange={(event) => setDraft({ ...draft, subject: event.target.value })}\n />\n </Field>\n <Field label=\"Description\">\n <Textarea\n data-testid=\"task-detail-description-input\"\n rows={DESCRIPTION_ROWS}\n value={draft.description}\n placeholder=\"what this task covers\"\n onChange={(event) => setDraft({ ...draft, description: event.target.value })}\n />\n </Field>\n <Field label=\"Status\">\n <Select\n value={draft.status}\n onValueChange={(value) => setDraft({ ...draft, status: value as WebTaskStatus })}\n >\n <SelectTrigger data-testid=\"task-detail-status-input\" className=\"h-7 w-full min-w-0 sm:min-w-[200px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATUS_CHOICES.map((status) => (\n <SelectItem key={status} value={status}>\n {status.replace('_', ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n <DialogFooter className=\"flex-wrap sm:flex-nowrap\">\n <span className=\"w-full text-sm text-doom-dim sm:w-auto\">\n saved as one prompt naming only the fields you changed\n </span>\n <span className=\"min-w-0 flex-1\" />\n <Button variant=\"outline\" size=\"xs\" data-testid=\"task-detail-cancel\" onClick={onClose}>\n cancel\n </Button>\n <Button variant=\"primary\" size=\"xs\" data-testid=\"task-detail-save\" onClick={submitEdit}>\n save\n </Button>\n </DialogFooter>\n </>\n ) : null}\n\n {mode === 'message' && agent ? (\n <>\n <Field label={`Message to ${agent}`}>\n <Textarea\n data-testid=\"task-detail-message-input\"\n autoFocus\n rows={MESSAGE_ROWS}\n value={message}\n placeholder=\"guidance for the run working on this task\"\n onChange={(event) => setMessage(event.target.value)}\n />\n </Field>\n <DialogFooter className=\"flex-wrap sm:flex-nowrap\">\n <span className=\"w-full text-sm text-doom-dim sm:w-auto\">\n steers the run, it does not edit the task\n </span>\n <span className=\"min-w-0 flex-1\" />\n <Button variant=\"outline\" size=\"xs\" data-testid=\"task-detail-cancel\" onClick={onClose}>\n cancel\n </Button>\n <Button variant=\"primary\" size=\"xs\" data-testid=\"task-detail-send\" onClick={submitMessage}>\n send\n </Button>\n </DialogFooter>\n </>\n ) : null}\n </DialogBody>\n </DialogContent>\n </Dialog>\n );\n}\n","import type { WebTaskStatus } from '../../../../../../types/webTasks';\n\n/** The tone a task status reads in, named by theme token so web and native agree. */\nexport type TaskStatusTone = 'muted' | 'yellow' | 'green' | 'red';\n\nexport const TASK_STATUS_TONE: Readonly<Record<WebTaskStatus, TaskStatusTone>> = {\n pending: 'muted',\n in_progress: 'yellow',\n completed: 'green',\n failed: 'red',\n deleted: 'muted',\n};\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/web';\nimport {\n Button,\n ChevronDownIcon,\n ChevronRightIcon,\n Dot,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n EditIcon,\n KebabIcon,\n MessageIcon,\n TrashIcon,\n type DotTone,\n} from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useState } from 'react';\n\nimport type { WebTask } from '../../../../../../types/webTasks';\nimport { requestTaskRemoval, tasks } from '../../channel/_lib/tasksStore';\nimport { TaskDetailDialog, type TaskDialogMode } from './TaskDetailDialog';\nimport { TASK_STATUS_TONE } from './taskStatusTone';\n\nconst STATUS_TONE: Readonly<Record<WebTask['status'], DotTone>> = TASK_STATUS_TONE;\n\ninterface DialogState {\n taskId: number;\n mode: TaskDialogMode;\n}\n\nfunction TaskRow({\n task,\n sessionId,\n sendSessionFrame,\n openDialog,\n}: {\n task: WebTask;\n sessionId: string;\n sendSessionFrame: WebPluginSlotProps['sendSessionFrame'];\n openDialog: (mode: TaskDialogMode) => void;\n}) {\n const detail = task.status === 'in_progress' ? task.activeForm : task.description;\n const agent = task.delegation?.agent;\n return (\n <div\n data-testid={`activity-task-${task.id}`}\n data-task-status={task.status}\n className=\"flex flex-col gap-1 rounded-md px-1 py-1\"\n >\n <div className=\"grid min-w-0 grid-cols-[auto_minmax(0,1fr)_auto_auto] items-center gap-x-1.5\">\n <Dot tone={STATUS_TONE[task.status]} pulse={task.status === 'in_progress'} />\n <button\n type=\"button\"\n data-testid={`activity-task-title-${task.id}`}\n title={task.subject}\n onClick={() => openDialog('view')}\n className={`min-h-6 min-w-0 truncate text-left text-base font-semibold hover:underline ${task.status === 'failed' ? 'text-doom-red' : task.status === 'completed' ? 'text-doom-dim' : 'text-doom-hi'}`}\n >\n <span className=\"text-doom-dim\">#{task.id}</span> {task.subject}\n </button>\n <span className=\"shrink-0 text-sm text-doom-dim\">{task.status.replace('_', ' ')}</span>\n {task.status !== 'completed' && task.status !== 'deleted' ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid={`activity-task-menu-${task.id}`}\n aria-label={`task #${task.id} actions`}\n title={`task #${task.id} actions`}\n className=\"self-center shrink-0 text-doom-faint hover:bg-doom-deep hover:text-doom-hi data-[state=open]:bg-doom-deep data-[state=open]:text-doom-hi\"\n >\n <KebabIcon className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent data-testid={`activity-task-menu-list-${task.id}`}>\n <DropdownMenuItem data-testid={`activity-task-edit-${task.id}`} onSelect={() => openDialog('edit')}>\n <EditIcon className=\"h-3 w-3\" />\n Edit\n </DropdownMenuItem>\n {agent ? (\n <DropdownMenuItem\n data-testid={`activity-task-message-${task.id}`}\n onSelect={() => openDialog('message')}\n >\n <MessageIcon className=\"h-3 w-3\" />\n Message agent\n </DropdownMenuItem>\n ) : null}\n <DropdownMenuItem\n variant=\"destructive\"\n data-testid={`activity-task-remove-${task.id}`}\n onSelect={() => requestTaskRemoval(sendSessionFrame, sessionId, task.id)}\n >\n <TrashIcon className=\"h-3 w-3\" />\n Remove\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </div>\n {detail || agent || task.blockedBy.length > 0 ? (\n <span className=\"truncate pl-3 text-sm text-doom-dim\">\n {agent ? `[${agent}] ` : ''}\n {detail ?? ''}\n {task.blockedBy.length > 0 ? ` · blocked by ${task.blockedBy.map((id) => `#${id}`).join(', ')}` : ''}\n </span>\n ) : null}\n </div>\n );\n}\n\n/**\n * Session task graph in the activity dock. Empty graphs have no cockpit presence.\n *\n * This fills the `tasks` activity group, so the dock has already drawn the\n * heading, the key chip and the section frame. Rendering rows only keeps the\n * group titled once.\n */\nexport function TasksActivitySection({ sessionId, sendSessionFrame }: WebPluginSlotProps) {\n const sessionTasks = useStore(tasks.store, (state) => tasks.select(state, sessionId).tasks);\n const [historyOpen, setHistoryOpen] = useState(false);\n const [dialog, setDialog] = useState<DialogState>();\n if (sessionId === null || sessionTasks.length === 0) return null;\n\n const active = sessionTasks.filter((task) => task.status === 'pending' || task.status === 'in_progress');\n const history = sessionTasks.filter((task) => task.status === 'completed' || task.status === 'failed');\n const dialogTask = dialog ? sessionTasks.find((task) => task.id === dialog.taskId) : undefined;\n return (\n <div className=\"flex flex-col gap-2\">\n {active.length > 0 ? (\n <div className=\"flex flex-col gap-0.5\">\n {active.map((task) => (\n <TaskRow\n key={task.id}\n task={task}\n sessionId={sessionId}\n sendSessionFrame={sendSessionFrame}\n openDialog={(mode) => setDialog({ taskId: task.id, mode })}\n />\n ))}\n </div>\n ) : null}\n {history.length > 0 ? (\n <div className=\"flex flex-col gap-0.5\">\n <Button\n variant=\"ghost\"\n size=\"xs\"\n aria-expanded={historyOpen}\n onClick={() => setHistoryOpen((open) => !open)}\n className=\"justify-start gap-1.5 rounded-md px-1 py-0.5 hover:bg-doom-panel\"\n >\n {historyOpen ? (\n <ChevronDownIcon className=\"h-2.5 w-2.5 text-doom-faint\" />\n ) : (\n <ChevronRightIcon className=\"h-2.5 w-2.5 text-doom-faint\" />\n )}\n <span className=\"text-base font-medium text-doom-dim\">session</span>\n <span className=\"text-2xs text-doom-faint\">{history.length}</span>\n </Button>\n {historyOpen ? (\n <div className=\"flex flex-col gap-0.5 pl-2\">\n {history.map((task) => (\n <TaskRow\n key={task.id}\n task={task}\n sessionId={sessionId}\n sendSessionFrame={sendSessionFrame}\n openDialog={(mode) => setDialog({ taskId: task.id, mode })}\n />\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n {dialog && dialogTask ? (\n <TaskDetailDialog\n key={`${dialogTask.id}-${dialog.mode}`}\n task={dialogTask}\n sessionId={sessionId}\n mode={dialog.mode}\n send={sendSessionFrame}\n onClose={() => setDialog(undefined)}\n />\n ) : null}\n </div>\n );\n}\n","import { defineFill } from '@agimon-ai/po-core/web';\n\nimport { TasksActivitySection } from './_lib/TasksActivitySection';\n\nexport default defineFill({ component: TasksActivitySection });\n","/**\n * Pure view logic for the task tool card, the browser counterpart of\n * the session frontend's shared format helpers (renderTaskCall, renderTaskResult). The plugin may reach\n * only its own files and src/types, so the store shapes it reads are\n * restated here as the wire JSON of a tool_execution frame.\n */\n\nexport type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'deleted';\nexport type TaskAction = 'upsert' | 'list' | 'get' | 'delete' | 'clear' | 'assign' | 'cancel';\n\nexport const STATUS_GLYPH: Record<TaskStatus, string> = {\n pending: '○',\n in_progress: '◐',\n completed: '●',\n failed: '✗',\n deleted: '⊘',\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\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/** Task rows kept in a collapsed result, before the card is expanded. */\nconst TRANSCRIPT_TASK_ROWS = 8;\nconst TASK_STATUSES: readonly TaskStatus[] = ['pending', 'in_progress', 'completed', 'failed', 'deleted'];\nconst TASK_ACTIONS: readonly TaskAction[] = ['upsert', 'list', 'get', 'delete', 'clear', 'assign', 'cancel'];\nconst INLINE_WHITESPACE = /\\s+/gu;\n\n/** One task as the result details carry it (src/models/task.ts Task). */\nexport interface TaskView {\n id: number;\n subject: string;\n status: TaskStatus;\n activeForm?: string;\n blockedBy?: number[];\n delegation?: { agent?: string; state?: string };\n}\n\n/** The result details (src/models/task.ts TaskDetails), narrowed to what the card reads. */\nexport interface TaskDetailsView {\n action: TaskAction;\n params: Record<string, unknown>;\n tasks: TaskView[];\n error?: string;\n upsert?: { applied: number[]; failed: number };\n assignment?: { assigned: number[]; failed: number };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isStatus(value: unknown): value is TaskStatus {\n return typeof value === 'string' && (TASK_STATUSES as readonly string[]).includes(value);\n}\n\nfunction isAction(value: unknown): value is TaskAction {\n return typeof value === 'string' && (TASK_ACTIONS as readonly string[]).includes(value);\n}\n\nfunction taskView(value: unknown): TaskView | null {\n if (!isRecord(value) || typeof value.id !== 'number' || typeof value.subject !== 'string') return null;\n if (!isStatus(value.status)) return null;\n const task: TaskView = { id: value.id, subject: value.subject, status: value.status };\n if (typeof value.activeForm === 'string') task.activeForm = value.activeForm;\n if (Array.isArray(value.blockedBy)) {\n task.blockedBy = value.blockedBy.filter((id): id is number => typeof id === 'number');\n }\n if (isRecord(value.delegation)) {\n task.delegation = {};\n if (typeof value.delegation.agent === 'string') task.delegation.agent = value.delegation.agent;\n if (typeof value.delegation.state === 'string') task.delegation.state = value.delegation.state;\n }\n return task;\n}\n\nfunction idList(value: unknown): number[] {\n return Array.isArray(value) ? value.filter((id): id is number => typeof id === 'number') : [];\n}\n\n/** Narrows the wire details; null when they are not a task result at all. */\nexport function taskDetailsView(details: unknown): TaskDetailsView | null {\n if (!isRecord(details) || !isAction(details.action) || !Array.isArray(details.tasks)) return null;\n const view: TaskDetailsView = {\n action: details.action,\n params: isRecord(details.params) ? details.params : {},\n tasks: details.tasks.map(taskView).filter((task): task is TaskView => task !== null),\n };\n if (typeof details.error === 'string') view.error = details.error;\n if (isRecord(details.upsert)) {\n view.upsert = {\n applied: idList(details.upsert.applied),\n failed: typeof details.upsert.failed === 'number' ? details.upsert.failed : 0,\n };\n }\n if (isRecord(details.assignment)) {\n view.assignment = {\n assigned: idList(details.assignment.assigned),\n failed: typeof details.assignment.failed === 'number' ? details.assignment.failed : 0,\n };\n }\n return view;\n}\n\n/** `#id` for the wire's id, which the TUI would resolve to a subject through the store. */\nfunction idLabel(value: unknown): string {\n return typeof value === 'number' || typeof value === 'string' ? `#${value}` : '#?';\n}\n\n/** Keep dynamic content on one line. */\nfunction inlineText(text: string): string {\n return text.replace(INLINE_WHITESPACE, ' ').trim();\n}\n\nexport type TaskCallTone = 'dim' | 'accent';\n\n/** The call header: glyph, action, then the subject or a count, as renderTaskCall lays it out. */\nexport interface TaskCallView {\n glyph: string;\n action: string;\n subject?: string;\n subjectTone: TaskCallTone;\n /** The assignee (`→ agent`) or the list filter. */\n detail?: string;\n}\n\nfunction upsertGlyph(items: readonly Record<string, unknown>[]): 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\n/**\n * The TUI resolves an id to its subject through the task store; the card has\n * no store and shows `#id` until the result names the task.\n */\nexport function taskCallView(args: Record<string, unknown>): TaskCallView {\n const action = typeof args.action === 'string' ? args.action : 'task';\n if (!isAction(action)) return { glyph: '?', action, subjectTone: 'dim' };\n const items = action === 'upsert' && Array.isArray(args.tasks) ? args.tasks.filter(isRecord) : [];\n const view: TaskCallView = {\n glyph: action === 'upsert' ? upsertGlyph(items) : ACTION_GLYPH[action],\n action,\n subjectTone: 'dim',\n };\n\n if (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 (typeof only.subject === 'string') view.subject = inlineText(only.subject);\n } else {\n view.subject = typeof only.subject === 'string' ? inlineText(only.subject) : idLabel(only.id);\n view.subjectTone = 'accent';\n }\n } else if (items.length > 1) {\n view.subject = `${items.length} tasks`;\n }\n } else if (action === 'assign') {\n const assignments = Array.isArray(args.assignments) ? args.assignments.filter(isRecord) : [];\n if (assignments.length === 1) {\n const only = assignments[0] ?? {};\n view.subject = idLabel(only.id);\n view.subjectTone = 'accent';\n if (typeof only.agent === 'string') view.detail = `→ ${only.agent}`;\n } else if (assignments.length > 1) {\n view.subject = `${assignments.length} tasks`;\n }\n } else if ((action === 'get' || action === 'delete' || action === 'cancel') && args.id !== undefined) {\n view.subject = idLabel(args.id);\n view.subjectTone = 'accent';\n } else if (action === 'list' && isStatus(args.status)) {\n view.detail = STATUS_LABEL[args.status];\n }\n return view;\n}\n\n/** One row of the result: the task line on the left, its status flushed right. */\nexport interface TaskRow {\n id: number;\n glyph: string;\n subject: string;\n status: TaskStatus;\n /** Struck through: the task is done with. */\n closed: boolean;\n agent?: string;\n activeForm?: string;\n blockedBy: number[];\n}\n\nexport type TaskResultTone = 'running' | 'ok' | 'error' | 'warning';\n\nexport interface TaskResultView {\n rows: TaskRow[];\n /** Error text lines when the tool threw or the reducer reported an error. */\n errorLines: string[];\n status: { glyph: string; tone: TaskResultTone; text: string } | null;\n}\n\nexport function taskRow(task: TaskView): TaskRow {\n const row: TaskRow = {\n id: task.id,\n glyph: STATUS_GLYPH[task.status],\n subject: inlineText(task.subject),\n status: task.status,\n closed: task.status === 'completed' || task.status === 'deleted',\n blockedBy: task.blockedBy ?? [],\n };\n if (task.delegation?.agent) row.agent = inlineText(task.delegation.agent);\n if (task.status === 'in_progress' && task.activeForm) row.activeForm = inlineText(task.activeForm);\n return row;\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: `details.tasks` is the whole\n * document, so the call's filters apply again here or the card would disagree\n * with the text the model was given.\n */\nfunction listedTasks(details: TaskDetailsView): TaskView[] {\n let view = details.tasks;\n if (details.params.includeDeleted !== true) view = view.filter((task) => task.status !== 'deleted');\n if (isStatus(details.params.status)) view = view.filter((task) => task.status === details.params.status);\n return view;\n}\n\nfunction byIds(details: TaskDetailsView, ids: readonly number[]): TaskView[] {\n return ids.flatMap((id) => details.tasks.find((task) => task.id === id) ?? []);\n}\n\nfunction batch(\n tasks: readonly TaskView[],\n failed: number,\n verb: string,\n expanded: boolean,\n): Pick<TaskResultView, 'rows' | 'status'> {\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 (tasks.length === 1 && failed === 0) return { rows: [taskRow(tasks[0] as TaskView)], status: null };\n const shown = expanded ? tasks : tasks.slice(0, TRANSCRIPT_TASK_ROWS);\n let summary = `${tasks.length} ${verb}`;\n if (failed > 0) summary += ` · ${failed} failed`;\n if (tasks.length > shown.length) summary += ` · ${tasks.length - shown.length} more`;\n return {\n rows: shown.map(taskRow),\n status: { glyph: failed > 0 ? '!' : '✓', tone: failed > 0 ? 'warning' : 'ok', text: summary },\n };\n}\n\nexport function taskResultView(input: {\n details: unknown;\n output: string;\n expanded: boolean;\n isPartial: boolean;\n isError: boolean;\n}): TaskResultView {\n const details = taskDetailsView(input.details);\n\n // Running. `assign` and `cancel` stream a placeholder before the run settles.\n if (input.isPartial) {\n const text = nonEmptyLines(input.output).at(-1) ?? 'working';\n return { rows: [], errorLines: [], status: { glyph: '◐', tone: 'running', text } };\n }\n\n // Failed. Every failure path throws, so Pi hands back error text and no\n // details; without this the card would show a green tick on a failure.\n if (input.isError || details?.error !== undefined) {\n const all = nonEmptyLines(details?.error ?? input.output);\n if (all.length <= 1) return { rows: [], errorLines: [], status: { glyph: '✗', tone: 'error', text: all[0] ?? '' } };\n const errorLines = input.expanded ? all : all.slice(0, TRANSCRIPT_TASK_ROWS);\n return { rows: [], errorLines, status: { glyph: '✗', tone: 'error', text: '' } };\n }\n\n if (details === null) return { rows: [], errorLines: [], status: { glyph: '✓', tone: 'ok', text: '' } };\n\n if (details.action === 'list') {\n const tasks = listedTasks(details);\n const shown = input.expanded ? tasks : tasks.slice(0, TRANSCRIPT_TASK_ROWS);\n let summary = tasks.length === 0 ? 'no tasks' : `${tasks.length} task${tasks.length === 1 ? '' : 's'}`;\n if (tasks.length > shown.length) summary += ` · ${tasks.length - shown.length} more`;\n return { rows: shown.map(taskRow), errorLines: [], status: { glyph: '✓', tone: 'ok', text: summary } };\n }\n\n if (details.action === 'clear') {\n return { rows: [], errorLines: [], status: { glyph: '✓', tone: 'ok', text: 'cleared' } };\n }\n\n if (details.action === 'assign' && details.assignment) {\n const assigned = byIds(details, details.assignment.assigned);\n return { errorLines: [], ...batch(assigned, details.assignment.failed, 'assigned', input.expanded) };\n }\n\n if (details.action === 'upsert') {\n const touched = byIds(details, details.upsert?.applied ?? []);\n return { errorLines: [], ...batch(touched, details.upsert?.failed ?? 0, 'applied', input.expanded) };\n }\n\n // The single task an id-bearing action acted on, so the card names it rather than a bare tick.\n const id = details.params.id;\n const task = typeof id === 'number' ? details.tasks.find((candidate) => candidate.id === id) : undefined;\n if (!task) return { rows: [], errorLines: [], status: { glyph: '✓', tone: 'ok', text: '' } };\n return { rows: [taskRow(task)], errorLines: [], status: null };\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n type StatusTone,\n toolTone,\n} from '@agimon-ai/po-web-components';\n\nimport {\n STATUS_LABEL,\n type TaskResultTone,\n type TaskRow,\n type TaskStatus,\n taskCallView,\n taskResultView,\n} from './taskToolFormat';\n\nconst STATUS_TONE: Record<TaskStatus, string> = {\n pending: 'text-doom-dim',\n in_progress: 'text-doom-yellow',\n completed: 'text-doom-green',\n failed: 'text-doom-red',\n deleted: 'text-doom-dim',\n};\n\nconst RESULT_TONE: Record<TaskResultTone, StatusTone> = {\n running: 'running',\n ok: 'ok',\n error: 'error',\n warning: 'running',\n};\n\n/** One task row: status glyph, id, subject and chips on the left, the status label flushed right. */\nfunction TaskRowLine({ row }: { row: TaskRow }) {\n return (\n <li data-testid=\"tool-result-task-row\" data-task-id={row.id} className=\"flex items-baseline gap-2\">\n <span className={`shrink-0 ${STATUS_TONE[row.status]}`}>{row.glyph}</span>\n <span className=\"shrink-0 text-doom-dim\">#{row.id}</span>\n <span\n className={`min-w-0 flex-1 truncate text-base font-semibold ${row.closed ? 'text-doom-dim line-through' : row.status === 'in_progress' ? 'text-doom-blue' : 'text-doom-hi'}`}\n >\n {row.subject}\n {row.agent ? <span className=\"text-doom-dim\"> [{row.agent}]</span> : null}\n {row.activeForm ? <span className=\"text-doom-dim\"> ({row.activeForm})</span> : null}\n {row.blockedBy.length > 0 ? (\n <span className=\"text-doom-dim\"> ⛓ {row.blockedBy.map((id) => `#${id}`).join(',')}</span>\n ) : null}\n </span>\n <span className={`shrink-0 ${STATUS_TONE[row.status]}`}>{STATUS_LABEL[row.status]}</span>\n </li>\n );\n}\n\n/**\n * The task tool's timeline item: `glyph action subject` with the assignee or\n * list filter in the header, as renderTaskCall shows it; the rows the action\n * touched, then the batch or list summary, in the body, as renderTaskResult\n * lays it out.\n */\nexport function TaskToolMessage({ args, result, output, running, isError }: ToolMessageRenderProps) {\n const call = taskCallView(args);\n const collapsed = taskResultView({ details: result?.details, output, expanded: false, isPartial: running, isError });\n const full = taskResultView({ details: result?.details, output, expanded: true, isPartial: running, isError });\n const hidden = full.rows.length - collapsed.rows.length + (full.errorLines.length - collapsed.errorLines.length);\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable={hidden > 0}>\n {({ expanded }) => {\n const view = expanded ? full : collapsed;\n const empty = view.rows.length === 0 && view.errorLines.length === 0 && view.status === null;\n return (\n <>\n <MessageItemHeader title=\"task\">\n <span data-testid=\"tool-call-task\" className=\"flex min-w-0 flex-1 items-center gap-1.5\">\n <span className=\"shrink-0 text-base font-semibold text-doom-text\">\n {call.glyph} {call.action}\n </span>\n {call.subject ? (\n <span\n className={`min-w-0 truncate text-base font-semibold ${call.subjectTone === 'accent' ? 'text-doom-blue' : 'text-doom-hi'}`}\n >\n {call.subject}\n </span>\n ) : null}\n {call.detail ? <span className=\"shrink-0 text-doom-dim\">{call.detail}</span> : null}\n </span>\n </MessageItemHeader>\n {empty ? null : (\n <MessageItemBody data-testid=\"tool-result-task\" className=\"flex flex-col gap-1\">\n {view.rows.length > 0 ? (\n <ul className=\"flex flex-col gap-0.5\">\n {view.rows.map((row) => (\n <TaskRowLine key={row.id} row={row} />\n ))}\n </ul>\n ) : null}\n {view.errorLines.length > 0 ? (\n <pre className=\"whitespace-pre-wrap break-words font-mono text-doom-dim\">\n {view.errorLines.join('\\n')}\n </pre>\n ) : null}\n {!expanded && hidden > 0 ? <MessageItemStatus expands>{hidden} more</MessageItemStatus> : null}\n {view.status ? (\n <MessageItemStatus\n data-testid=\"tool-result-task-status\"\n tone={RESULT_TONE[view.status.tone]}\n glyph={view.status.glyph}\n >\n {view.status.text}\n </MessageItemStatus>\n ) : null}\n </MessageItemBody>\n )}\n </>\n );\n }}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { TaskToolMessage } from './_lib/TaskToolMessage';\n\nexport default defineToolRenderer({ message: TaskToolMessage });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport activityGroupTasks from '../src/extensions/workspaces/sessions/(frontend)/activity-group/tasks.web';\nimport channelTaskGraph from '../src/extensions/workspaces/sessions/(frontend)/channel/task-graph.web';\nimport fillTasks from '../src/extensions/workspaces/sessions/(frontend)/fill/Tasks.activity.tasks.web';\nimport toolTask from '../src/extensions/workspaces/sessions/(frontend)/tool/task.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'task',\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'tasks' }, activityGroupTasks)]; },\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'task_graph' }, channelTaskGraph)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'activity.tasks', id: 'tasks' }, fillTasks)]; },\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['task'] }, toolTask)]; },\n },\n});\n"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ //#region src/services/config/index.d.ts
2
+ /**
3
+ * Extension configuration, read from the environment.
4
+ *
5
+ * Env rather than a config file: po already carries per-launch state to Pi
6
+ * through env vars, so this keeps doom-task consistent with how the harness
7
+ * configures the rest of the extension set.
8
+ */
9
+ declare const MAX_WIDGET_LINES_ENV = "DOOM_TASK_MAX_WIDGET_LINES";
10
+ declare const MAX_TASKS_ENV = "DOOM_TASK_MAX_TASKS";
11
+ declare const COLLAPSE_KEY_ENV = "DOOM_TASK_COLLAPSE_KEY";
12
+ declare const STORE_TTL_MS_ENV = "DOOM_TASK_STORE_TTL_MS";
13
+ declare const DELEGATION_TIMEOUT_MS_ENV = "DOOM_TASK_DELEGATION_TIMEOUT_MS";
14
+ declare const DEFAULT_MAX_WIDGET_LINES = 12;
15
+ declare const DEFAULT_MAX_TASKS = 15;
16
+ declare const DEFAULT_COLLAPSE_KEY = "ctrl+shift+t";
17
+ declare const DEFAULT_STORE_TTL_MS: number;
18
+ /** Deliberately under the subagents auto-drain ceiling (30 min) so a headless
19
+ * session still gets the failure and a model turn before draining gives up. */
20
+ declare const DEFAULT_DELEGATION_TIMEOUT_MS: number;
21
+ declare const COLLAPSE_KEY_OFF = "off";
22
+ interface PiTaskConfig {
23
+ maxWidgetLines: number;
24
+ maxTasks: number;
25
+ storeTtlMs: number;
26
+ collapseKey: string;
27
+ delegationTimeoutMs: number;
28
+ }
29
+ /** Parse configuration only after the Pi host has applied its project-trust policy. */
30
+ declare function parsePiTaskConfig(value: unknown): PiTaskConfig;
31
+ /** Rows the overlay may use for content, clamped to a sane range. */
32
+ declare function getMaxWidgetLines(env?: NodeJS.ProcessEnv): number;
33
+ /** Maximum number of non-deleted tasks retained on one board. */
34
+ declare function getMaxTasks(env?: NodeJS.ProcessEnv): number;
35
+ /** Retention window for inactive session-tree stores. */
36
+ declare function getStoreTtlMs(env?: NodeJS.ProcessEnv): number;
37
+ /** How long a delegated run may go without reporting a result. */
38
+ declare function getDelegationTimeoutMs(env?: NodeJS.ProcessEnv): number;
39
+ /** Collapse shortcut, or the `off` sentinel when the user disabled it. */
40
+ declare function resolveCollapseKey(env?: NodeJS.ProcessEnv): string;
41
+ //#endregion
42
+ export { parsePiTaskConfig as _, DEFAULT_MAX_TASKS as a, DELEGATION_TIMEOUT_MS_ENV as c, PiTaskConfig as d, STORE_TTL_MS_ENV as f, getStoreTtlMs as g, getMaxWidgetLines as h, DEFAULT_DELEGATION_TIMEOUT_MS as i, MAX_TASKS_ENV as l, getMaxTasks as m, COLLAPSE_KEY_OFF as n, DEFAULT_MAX_WIDGET_LINES as o, getDelegationTimeoutMs as p, DEFAULT_COLLAPSE_KEY as r, DEFAULT_STORE_TTL_MS as s, COLLAPSE_KEY_ENV as t, MAX_WIDGET_LINES_ENV as u, resolveCollapseKey as v };
43
+ //# sourceMappingURL=index-B-3sCF2S.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-B-3sCF2S.d.mts","names":[],"sources":["../src/services/config/index.ts"],"mappings":";;;;;;;;cAQa;cACA;cACA;cACA;cACA;cAEA;cACA;cACA;cACA;;;cAGA;cACA;UAKI;EACf;EACA;EACA;EACA;EACA;;;iBAQc,kBAAkB,iBAAiB;;iBA+BnC,kBAAkB,MAAK,OAAO;;iBAO9B,YAAY,MAAK,OAAO;;iBAMxB,cAAc,MAAK,OAAO;;iBAM1B,uBAAuB,MAAK,OAAO;;iBAMnC,mBAAmB,MAAK,OAAO"}
@@ -0,0 +1,51 @@
1
+ import { c as TaskAction, d as TaskDetails, f as TaskDocument, m as TaskMutationParams, t as AssignmentSummary } from "./task-DJpTteeJ.mjs";
2
+ import { r as Op } from "./index-CUWCvh-E.mjs";
3
+ //#region src/services/taskResult/index.d.ts
4
+ declare const MSG_ALL_COMPLETE_CLEAR = "All tasks are completed. Review the full task list once more, then close it with task {\"action\":\"clear\"}.";
5
+ /**
6
+ * Steering for a mixed batch. Unlike a batch of spawned subagents, a failed
7
+ * entry here had no side effect at all, so retrying the failures is the safe
8
+ * move and the model must be told so or it will do nothing. The hazard is the
9
+ * other half: resending an applied create would make a second task.
10
+ */
11
+ declare const MSG_UPSERT_PARTIAL = "The applied entries are committed. Resend only the failed entries, corrected — a failed entry changed nothing, so a corrected retry is safe. Do not resend an entry that already applied: an entry without an id creates a second task.";
12
+ declare const MSG_UPSERT_NONE_APPLIED = "No task changed, so the whole call can be resent once corrected.";
13
+ declare const MSG_ASSIGN_PARTIAL = "Successful assignments are already running. Retry only the failed entries after correcting their task state or arguments; do not resend successful entries.";
14
+ interface AssignmentItemResult {
15
+ index: number;
16
+ id: number;
17
+ agent: string;
18
+ ok: boolean;
19
+ message: string;
20
+ }
21
+ /** LLM-facing report for a native assignment batch. */
22
+ declare function formatAssignmentResults(items: readonly AssignmentItemResult[]): string;
23
+ /**
24
+ * The thrown message when an upsert applied nothing. Kept separate from
25
+ * `formatContent` because the caller wraps it in the actionable Options block
26
+ * rather than returning it as a successful result.
27
+ */
28
+ declare function formatUpsertFailureText(op: Extract<Op, {
29
+ kind: 'upsert';
30
+ }>): string;
31
+ /**
32
+ * Pure formatter: `(op, document) -> string`. The switch is closed over `Op`,
33
+ * so a new reducer variant fails to compile until it is handled here.
34
+ */
35
+ declare function formatContent(op: Op, document: TaskDocument): string;
36
+ interface ToolResult {
37
+ content: Array<{
38
+ type: 'text';
39
+ text: string;
40
+ }>;
41
+ details: TaskDetails;
42
+ }
43
+ /** Build the LLM-facing envelope. `details` carries the post-mutation snapshot. */
44
+ declare function buildToolResult(action: TaskAction, params: TaskMutationParams, document: TaskDocument, op: Op): ToolResult;
45
+ /** Envelope for a native assignment batch, including ids used by the consolidated TUI result. */
46
+ declare function buildAssignmentResult(params: TaskMutationParams, document: TaskDocument, text: string, assignment: AssignmentSummary): ToolResult;
47
+ /** Envelope for delegation actions, which do not flow through the reducer. */
48
+ declare function buildTextResult(action: TaskAction, params: TaskMutationParams, document: TaskDocument, text: string, error?: string): ToolResult;
49
+ //#endregion
50
+ export { MSG_UPSERT_PARTIAL as a, buildTextResult as c, formatContent as d, formatUpsertFailureText as f, MSG_UPSERT_NONE_APPLIED as i, buildToolResult as l, MSG_ALL_COMPLETE_CLEAR as n, ToolResult as o, MSG_ASSIGN_PARTIAL as r, buildAssignmentResult as s, AssignmentItemResult as t, formatAssignmentResults as u };
51
+ //# sourceMappingURL=index-B1JPJdpZ.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-B1JPJdpZ.d.mts","names":[],"sources":["../src/services/taskResult/index.ts"],"mappings":";;;cAYa;;;;;;;cASA;cAGA;cAEA;UAGI;EACf;EACA;EACA;EACA;EACA;;;iBAIc,wBAAwB,gBAAgB;;;;;;iBAgFxC,wBAAwB,IAAI,QAAQ;EAAM;;;;;;iBAa1C,cAAc,IAAI,IAAI,UAAU;UAmC/B;EACf,SAAS;IAAQ;IAAc;;EAC/B,SAAS;;;iBAIK,gBACd,QAAQ,YACR,QAAQ,oBACR,UAAU,cACV,IAAI,KACH;;iBA0Ba,sBACd,QAAQ,oBACR,UAAU,cACV,cACA,YAAY,oBACX;;iBAea,gBACd,QAAQ,YACR,QAAQ,oBACR,UAAU,cACV,cACA,iBACC"}
@@ -0,0 +1,72 @@
1
+ import { c as TaskAction, f as TaskDocument, g as UpsertItemOutcome, h as TaskStatus, m as TaskMutationParams, s as Task } from "./task-DJpTteeJ.mjs";
2
+ //#region src/services/reducer/index.d.ts
3
+ /** Bounds the work one call can do, and with it the size of one committed write. */
4
+ declare const MAX_UPSERT_ITEMS = 100;
5
+ /**
6
+ * A ref must start with a letter, which makes it structurally unconfusable with
7
+ * a stringified id. That is why resolving a dependency token is just a `typeof`
8
+ * check with no coercion heuristics.
9
+ */
10
+ declare const REF_PATTERN: RegExp;
11
+ /**
12
+ * Reducer outcome. Closed tagged union: adding an action requires extending
13
+ * this union and the response formatter, which the compiler enforces.
14
+ *
15
+ * `upsert` carries one outcome per request item. It is returned even when every
16
+ * item failed — `error` is reserved for whole-call faults — so the tool layer
17
+ * still has the per-item messages to report.
18
+ */
19
+ type Op = {
20
+ kind: 'upsert';
21
+ items: UpsertItemOutcome[];
22
+ applied: number;
23
+ failed: number;
24
+ } | {
25
+ kind: 'delete';
26
+ id: number;
27
+ subject: string;
28
+ } | {
29
+ kind: 'list';
30
+ statusFilter?: TaskStatus;
31
+ includeDeleted: boolean;
32
+ } | {
33
+ kind: 'get';
34
+ task: Task;
35
+ } | {
36
+ kind: 'clear';
37
+ count: number;
38
+ } | {
39
+ kind: 'error';
40
+ message: string;
41
+ };
42
+ interface ApplyResult {
43
+ document: TaskDocument;
44
+ op: Op;
45
+ }
46
+ /** Actions the reducer owns. `assign`/`cancel` are handled by the delegation manager. */
47
+ type ReducerAction = Exclude<TaskAction, 'assign' | 'cancel'>;
48
+ /**
49
+ * Does this op represent state that must reach disk?
50
+ *
51
+ * The exhaustive switch is the point: a future `Op` variant cannot be added
52
+ * without declaring its persistence intent, so nothing silently starts or stops
53
+ * bumping `rev`.
54
+ */
55
+ declare function isCommittingOp(op: Op): boolean;
56
+ /** Joined per-item failures, for the thrown error when an upsert applied nothing. */
57
+ declare function formatUpsertFailure(op: Extract<Op, {
58
+ kind: 'upsert';
59
+ }>): string;
60
+ /** The single item's outcome, for callers that only ever send a batch of one. */
61
+ declare function singleItemOutcome(op: Op): UpsertItemOutcome | undefined;
62
+ /**
63
+ * Pure reducer: (document, action, params) -> (document, op).
64
+ *
65
+ * All validation is in-line: structural guards plus state-aware checks
66
+ * (transition legality, dangling or deleted blockedBy, self-block, cycles,
67
+ * in-flight delegations). The caller owns persistence and formatting.
68
+ */
69
+ declare function applyTaskMutation(document: TaskDocument, action: ReducerAction, params: TaskMutationParams, now?: string, maxTasks?: number): ApplyResult;
70
+ //#endregion
71
+ export { ReducerAction as a, isCommittingOp as c, REF_PATTERN as i, singleItemOutcome as l, MAX_UPSERT_ITEMS as n, applyTaskMutation as o, Op as r, formatUpsertFailure as s, ApplyResult as t };
72
+ //# sourceMappingURL=index-CUWCvh-E.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CUWCvh-E.d.mts","names":[],"sources":["../src/services/reducer/index.ts"],"mappings":";;;cAmBa;;;;;;cAOA,aAAW;;;;;;;;;KAUZ;EACN;EAAgB,OAAO;EAAqB;EAAiB;;EAC7D;EAAgB;EAAY;;EAC5B;EAAc,eAAe;EAAY;;EACzC;EAAa,MAAM;;EACnB;EAAe;;EACf;EAAe;;UAEJ;EACf,UAAU;EACV,IAAI;;;KAIM,gBAAgB,QAAQ;;;;;;;;iBASpB,eAAe,IAAI;;iBAenB,oBAAoB,IAAI,QAAQ;EAAM;;;iBAQtC,kBAAkB,IAAI,KAAK;;;;;;;;iBA8T3B,kBACd,UAAU,cACV,QAAQ,eACR,QAAQ,oBACR,cACA,oBACC"}
@@ -0,0 +1,34 @@
1
+ import { f as TaskDocument, s as Task } from "./task-DJpTteeJ.mjs";
2
+ //#region src/services/reconcile/index.d.ts
3
+ declare const ERR_ORPHANED_BY_RESTART = "Delegation orphaned by harness restart";
4
+ declare const ERR_ORPHANED_BY_SESSION = "Delegation orphaned by session restart";
5
+ interface ReconcileResult {
6
+ document: TaskDocument;
7
+ orphaned: Task[];
8
+ }
9
+ /** The delegations this process can still settle, used to spot its own leftovers. */
10
+ interface ReconcileSelf {
11
+ pid: number;
12
+ liveRequestIds: ReadonlySet<string>;
13
+ }
14
+ /**
15
+ * Recover tasks that no longer have anyone able to finish them.
16
+ *
17
+ * A subagent run dies with the harness that spawned it, but the store file
18
+ * outlives both, so a crash leaves tasks stuck in `in_progress` forever. Two
19
+ * kinds of delegation qualify as dead:
20
+ *
21
+ * - the owning pid is gone, so nothing is left to report a result;
22
+ * - the owning pid is *this* process, yet the request is absent from the live
23
+ * set. Settling requires an in-memory record, so an in-process session
24
+ * restart (which clears that map without writing to the store) leaves rows
25
+ * nothing can ever resolve. Checking pid liveness alone misses these, because
26
+ * the pid is our own and very much alive.
27
+ *
28
+ * Delegations owned by a different, still-running pid belong to a parallel
29
+ * session and are left untouched.
30
+ */
31
+ declare function reconcileOrphanedDelegations(document: TaskDocument, now?: string, isAlive?: (pid: number) => boolean, self?: ReconcileSelf): ReconcileResult;
32
+ //#endregion
33
+ export { reconcileOrphanedDelegations as a, ReconcileSelf as i, ERR_ORPHANED_BY_SESSION as n, ReconcileResult as r, ERR_ORPHANED_BY_RESTART as t };
34
+ //# sourceMappingURL=index-DlmXKyhQ.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DlmXKyhQ.d.mts","names":[],"sources":["../src/services/reconcile/index.ts"],"mappings":";;cAGa;cACA;UAEI;EACf,UAAU;EACV,UAAU;;;UAIK;EACf;EACA,gBAAgB;;;;;;;;;;;;;;;;;;;iBAoBF,6BACd,UAAU,cACV,cACA,WAAU,yBACV,OAAO,gBACN"}
@@ -0,0 +1,67 @@
1
+ import { o as TaskFailureReporter } from "./telemetry-FMGRovb4.mjs";
2
+ import { f as TaskDocument } from "./task-DJpTteeJ.mjs";
3
+ //#region src/services/taskStore/index.d.ts
4
+ interface TaskStoreOptions {
5
+ cwd?: string;
6
+ env?: Readonly<Record<string, string | undefined>>;
7
+ storePath?: string;
8
+ /** How long to wait for the advisory lock before proceeding lock-free. */
9
+ lockTimeoutMs?: number;
10
+ /** Where swallowed failures go, so silent degradation stays visible. */
11
+ report?: TaskFailureReporter;
12
+ }
13
+ /**
14
+ * File-backed task store shared by one root session and its delegated children.
15
+ *
16
+ * Durability model: the JSON file is the source of truth. Mutations are
17
+ * read-modify-write under an advisory lock so concurrent delegated processes
18
+ * cannot clobber each other, and writes land via temp-file rename so a
19
+ * crash mid-write can never leave a partial document behind.
20
+ */
21
+ declare class TaskStore {
22
+ storePath: string;
23
+ private readonly cwd;
24
+ private readonly env;
25
+ private cached;
26
+ private readonly listeners;
27
+ private readonly lockTimeoutMs;
28
+ private readonly report?;
29
+ constructor(options?: TaskStoreOptions);
30
+ /** Bind a default store to the current session tree before reading it. */
31
+ configureSession(sessionKey: string): void;
32
+ /** Last document read from disk, without hitting the filesystem. */
33
+ get snapshot(): TaskDocument;
34
+ read(): TaskDocument;
35
+ readAsync(shouldApply?: () => boolean, onReadError?: (error: unknown) => void): Promise<TaskDocument>;
36
+ private readDocumentAsync;
37
+ /**
38
+ * Apply a mutation under the store lock.
39
+ *
40
+ * `mutate` receives the freshest on-disk document and returns either the next
41
+ * document to commit or `undefined` for a read-only action (list/get), which
42
+ * skips the write entirely so queries never bump `rev`.
43
+ */
44
+ mutate<T>(mutate: (document: TaskDocument) => {
45
+ document?: TaskDocument;
46
+ value: T;
47
+ }): Promise<{
48
+ document: TaskDocument;
49
+ value: T;
50
+ }>;
51
+ private notifyCommitted;
52
+ private write;
53
+ private acquireLock;
54
+ /** Remove a lock left behind by a dead process or one held implausibly long. */
55
+ private breakStaleLock;
56
+ /**
57
+ * Listen for commits made through this store instance.
58
+ *
59
+ * Live cross-process updates use the owning session's direct event bus. This
60
+ * listener publishes local commits to that bus and never watches the filesystem.
61
+ */
62
+ onExternalChange(listener: (document: TaskDocument) => void): () => void;
63
+ dispose(): void;
64
+ }
65
+ //#endregion
66
+ export { TaskStoreOptions as n, TaskStore as t };
67
+ //# sourceMappingURL=index-Dvb8X_qB.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Dvb8X_qB.d.mts","names":[],"sources":["../src/services/taskStore/index.ts"],"mappings":";;;UAkBiB;EACf;EACA,MAAM,SAAS;EACf;;EAEA;;EAEA,SAAS;;;;;;;;;;cAwCE;EACX;mBAEiB;mBACA;UACT;mBACS;mBACA;mBACA;EAEjB,YAAY,UAAS;;EASrB,iBAAiB;;MAOb,YAAY;EAIhB,QAAQ;EAgBF,UACJ,6BACA,eAAe,0BACd,QAAQ;UAQG;;;;;;;;EA2BR,OAAO,GACX,SAAS,UAAU;IAAmB,WAAW;IAAc,OAAO;MACrE;IAAU,UAAU;IAAc,OAAO;;UAwBpC;UAUA;UAUM;;UAoCN;;;;;;;EAwBR,iBAAiB,WAAW,UAAU;EAKtC"}
@@ -0,0 +1,26 @@
1
+ //#region src/services/paths/index.d.ts
2
+ declare const STORE_PATH_ENV = "DOOM_TASK_STORE";
3
+ /** Resolve the tree root without relying on extension startup order. */
4
+ declare function resolveSessionKey(rootSessionId: string, env?: Readonly<Record<string, string | undefined>>): string;
5
+ /** Resolve one root session tree to a task document under the Pi agent directory. */
6
+ declare function resolveStorePath(_cwd?: string, env?: Readonly<Record<string, string | undefined>>, sessionKey?: string): string;
7
+ /** Whether a deliberate unscoped task-store override is active. */
8
+ declare function hasStorePathOverride(env?: Readonly<Record<string, string | undefined>>): boolean;
9
+ /** Exact legacy Git-directory store, if the current working tree has one. */
10
+ declare function resolveLegacyStoreDirectory(cwd?: string): string | undefined;
11
+ declare function resolveLegacyStoreDirectoryAsync(cwd?: string): Promise<string | undefined>;
12
+ interface StoreSweepResult {
13
+ removed: string[];
14
+ errors: string[];
15
+ }
16
+ /** Remove only the validated legacy Git store unless it contains the active override. */
17
+ declare function removeLegacyStoreDirectory(currentStorePath: string, cwd?: string): StoreSweepResult;
18
+ declare function removeLegacyStoreDirectoryAsync(currentStorePath: string, cwd?: string): Promise<StoreSweepResult>;
19
+ /** Delete expired sibling session stores while preserving active or unreadable stores. */
20
+ declare function sweepStoreFiles(currentStorePath: string, ttlMs: number, now?: number): StoreSweepResult;
21
+ declare function sweepStoreFilesAsync(currentStorePath: string, ttlMs: number, now?: number): Promise<StoreSweepResult>;
22
+ declare function lockPathFor(storePath: string): string;
23
+ declare function tempPathFor(storePath: string, pid?: number): string;
24
+ //#endregion
25
+ export { removeLegacyStoreDirectory as a, resolveLegacyStoreDirectoryAsync as c, sweepStoreFiles as d, sweepStoreFilesAsync as f, lockPathFor as i, resolveSessionKey as l, StoreSweepResult as n, removeLegacyStoreDirectoryAsync as o, tempPathFor as p, hasStorePathOverride as r, resolveLegacyStoreDirectory as s, STORE_PATH_ENV as t, resolveStorePath as u };
26
+ //# sourceMappingURL=index-XY9VPmfm.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-XY9VPmfm.d.mts","names":[],"sources":["../src/services/paths/index.ts"],"mappings":";cAOa;;iBAwCG,kBACd,uBACA,MAAK,SAAS;;iBASA,iBACd,eACA,MAAK,SAAS,qCACd;;iBAWc,qBAAqB,MAAK,SAAS;;iBAKnC,4BAA4B;iBAKtB,iCAAiC,eAA8B;UAKpE;EACf;EACA;;;iBAIc,2BAA2B,0BAA0B,eAA8B;iBAe7E,gCACpB,0BACA,eACC,QAAQ;;iBAkBK,gBAAgB,0BAA0B,eAAe,eAA2B;iBA8B9E,qBACpB,0BACA,eACA,eACC,QAAQ;iBAqCK,YAAY;iBAIZ,YAAY,mBAAmB"}