@agimon-ai/doompi-task 0.0.1-alpha.7 → 0.0.1-alpha.71
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.
- package/README.md +114 -15
- package/dist/api-contracts.cjs +1 -0
- package/dist/api-contracts.d.cts +2 -0
- package/dist/api-contracts.d.mts +2 -0
- package/dist/api-contracts.mjs +1 -0
- package/dist/commands.cjs +1 -2
- package/dist/commands.d.cts +2 -14
- package/dist/commands.d.mts +2 -14
- package/dist/commands.mjs +1 -2
- package/dist/config.cjs +1 -2
- package/dist/config.d.cts +2 -38
- package/dist/config.d.mts +2 -38
- package/dist/config.mjs +1 -2
- package/dist/constants/promptGuidelines.cjs +2 -0
- package/dist/constants/promptGuidelines.cjs.map +1 -0
- package/dist/constants/promptGuidelines.d.cts +13 -0
- package/dist/constants/promptGuidelines.d.cts.map +1 -0
- package/dist/constants/promptGuidelines.d.mts +13 -0
- package/dist/constants/promptGuidelines.d.mts.map +1 -0
- package/dist/constants/promptGuidelines.mjs +2 -0
- package/dist/constants/promptGuidelines.mjs.map +1 -0
- package/dist/constants/task.cjs +2 -0
- package/dist/constants/task.cjs.map +1 -0
- package/dist/constants/task.d.cts +4 -0
- package/dist/constants/task.d.cts.map +1 -0
- package/dist/constants/task.d.mts +4 -0
- package/dist/constants/task.d.mts.map +1 -0
- package/dist/constants/task.mjs +2 -0
- package/dist/constants/task.mjs.map +1 -0
- package/dist/controllers/tasksCommand.cjs +2 -0
- package/dist/controllers/tasksCommand.cjs.map +1 -0
- package/dist/controllers/tasksCommand.d.cts +15 -0
- package/dist/controllers/tasksCommand.d.cts.map +1 -0
- package/dist/controllers/tasksCommand.d.mts +15 -0
- package/dist/controllers/tasksCommand.d.mts.map +1 -0
- package/dist/controllers/tasksCommand.mjs +2 -0
- package/dist/controllers/tasksCommand.mjs.map +1 -0
- package/dist/controllers/webTasksChannel.cjs +2 -0
- package/dist/controllers/webTasksChannel.cjs.map +1 -0
- package/dist/controllers/webTasksChannel.mjs +2 -0
- package/dist/controllers/webTasksChannel.mjs.map +1 -0
- package/dist/delegation-manager.cjs +1 -0
- package/dist/delegation-manager.d.cts +3 -0
- package/dist/delegation-manager.d.mts +3 -0
- package/dist/delegation-manager.mjs +1 -0
- package/dist/extensions/pi.cjs +2 -1
- package/dist/extensions/pi.cjs.map +1 -1
- package/dist/extensions/pi.d.cts +6 -2
- package/dist/extensions/pi.d.cts.map +1 -0
- package/dist/extensions/pi.d.mts +6 -2
- package/dist/extensions/pi.d.mts.map +1 -0
- package/dist/extensions/pi.mjs +2 -1
- package/dist/extensions/pi.mjs.map +1 -1
- package/dist/extensions/server.cjs +2 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.cts +5 -0
- package/dist/extensions/server.d.cts.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +2 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +15 -14
- package/dist/index.d.mts +15 -14
- package/dist/index.mjs +1 -1
- package/dist/logSinkTelemetry.cjs +1 -2
- package/dist/logSinkTelemetry.d.cts +3 -51
- package/dist/logSinkTelemetry.d.mts +3 -51
- package/dist/logSinkTelemetry.mjs +1 -2
- package/dist/models/task.cjs +2 -0
- package/dist/models/task.cjs.map +1 -0
- package/dist/{store/types.d.cts → models/task.d.cts} +41 -30
- package/dist/models/task.d.cts.map +1 -0
- package/dist/{store/types.d.mts → models/task.d.mts} +41 -30
- package/dist/models/task.d.mts.map +1 -0
- package/dist/{store/types.mjs → models/task.mjs} +1 -1
- package/dist/models/task.mjs.map +1 -0
- package/dist/models/taskGraph.cjs +2 -0
- package/dist/models/taskGraph.cjs.map +1 -0
- package/dist/{store → models}/taskGraph.d.cts +7 -8
- package/dist/models/taskGraph.d.cts.map +1 -0
- package/dist/{store → models}/taskGraph.d.mts +7 -8
- package/dist/models/taskGraph.d.mts.map +1 -0
- package/dist/models/taskGraph.mjs.map +1 -0
- package/dist/schemas/apiContracts.cjs +2 -0
- package/dist/schemas/apiContracts.cjs.map +1 -0
- package/dist/schemas/apiContracts.d.cts +53 -0
- package/dist/schemas/apiContracts.d.cts.map +1 -0
- package/dist/schemas/apiContracts.d.mts +53 -0
- package/dist/schemas/apiContracts.d.mts.map +1 -0
- package/dist/schemas/apiContracts.mjs +2 -0
- package/dist/schemas/apiContracts.mjs.map +1 -0
- package/dist/schemas/task.cjs +2 -0
- package/dist/schemas/task.cjs.map +1 -0
- package/dist/{tool/schema.d.cts → schemas/task.d.cts} +46 -29
- package/dist/schemas/task.d.cts.map +1 -0
- package/dist/{tool/schema.d.mts → schemas/task.d.mts} +46 -29
- package/dist/schemas/task.d.mts.map +1 -0
- package/dist/schemas/task.mjs +2 -0
- package/dist/schemas/task.mjs.map +1 -0
- package/dist/services/config/index.cjs +2 -0
- package/dist/services/config/index.cjs.map +1 -0
- package/dist/services/config/index.d.cts +42 -0
- package/dist/services/config/index.d.cts.map +1 -0
- package/dist/services/config/index.d.mts +42 -0
- package/dist/services/config/index.d.mts.map +1 -0
- package/dist/services/config/index.mjs +2 -0
- package/dist/services/config/index.mjs.map +1 -0
- package/dist/services/contextContribution/index.cjs +3 -0
- package/dist/services/contextContribution/index.cjs.map +1 -0
- package/dist/services/contextContribution/index.mjs +3 -0
- package/dist/services/contextContribution/index.mjs.map +1 -0
- package/dist/services/delegation/index.cjs +6 -0
- package/dist/services/delegation/index.cjs.map +1 -0
- package/dist/{delegation/manager.d.cts → services/delegation/index.d.cts} +52 -49
- package/dist/services/delegation/index.d.cts.map +1 -0
- package/dist/{delegation/manager.d.mts → services/delegation/index.d.mts} +52 -49
- package/dist/services/delegation/index.d.mts.map +1 -0
- package/dist/services/delegation/index.mjs +6 -0
- package/dist/services/delegation/index.mjs.map +1 -0
- package/dist/services/delegationPlatform/index.cjs +2 -0
- package/dist/services/delegationPlatform/index.cjs.map +1 -0
- package/dist/services/delegationPlatform/index.mjs +2 -0
- package/dist/services/delegationPlatform/index.mjs.map +1 -0
- package/dist/services/invariants/index.cjs +2 -0
- package/dist/services/invariants/index.cjs.map +1 -0
- package/dist/services/invariants/index.d.cts +23 -0
- package/dist/services/invariants/index.d.cts.map +1 -0
- package/dist/services/invariants/index.d.mts +23 -0
- package/dist/services/invariants/index.d.mts.map +1 -0
- package/dist/services/invariants/index.mjs +2 -0
- package/dist/services/invariants/index.mjs.map +1 -0
- package/dist/services/logSinkTelemetry/index.cjs +2 -0
- package/dist/services/logSinkTelemetry/index.cjs.map +1 -0
- package/dist/services/logSinkTelemetry/index.d.cts +23 -0
- package/dist/services/logSinkTelemetry/index.d.cts.map +1 -0
- package/dist/services/logSinkTelemetry/index.d.mts +23 -0
- package/dist/services/logSinkTelemetry/index.d.mts.map +1 -0
- package/dist/services/logSinkTelemetry/index.mjs +2 -0
- package/dist/services/logSinkTelemetry/index.mjs.map +1 -0
- package/dist/services/paths/index.cjs +2 -0
- package/dist/services/paths/index.cjs.map +1 -0
- package/dist/services/paths/index.d.cts +25 -0
- package/dist/services/paths/index.d.cts.map +1 -0
- package/dist/services/paths/index.d.mts +25 -0
- package/dist/services/paths/index.d.mts.map +1 -0
- package/dist/services/paths/index.mjs +2 -0
- package/dist/services/paths/index.mjs.map +1 -0
- package/dist/services/processLiveness/index.cjs +2 -0
- package/dist/services/processLiveness/index.cjs.map +1 -0
- package/dist/{store/processLiveness.d.cts → services/processLiveness/index.d.cts} +3 -4
- package/dist/services/processLiveness/index.d.cts.map +1 -0
- package/dist/{store/processLiveness.d.mts → services/processLiveness/index.d.mts} +3 -4
- package/dist/services/processLiveness/index.d.mts.map +1 -0
- package/dist/{store/processLiveness.mjs → services/processLiveness/index.mjs} +1 -1
- package/dist/services/processLiveness/index.mjs.map +1 -0
- package/dist/services/reconcile/index.cjs +2 -0
- package/dist/services/reconcile/index.cjs.map +1 -0
- package/dist/{store/reconcile.d.cts → services/reconcile/index.d.cts} +8 -9
- package/dist/services/reconcile/index.d.cts.map +1 -0
- package/dist/{store/reconcile.d.mts → services/reconcile/index.d.mts} +8 -9
- package/dist/services/reconcile/index.d.mts.map +1 -0
- package/dist/services/reconcile/index.mjs +2 -0
- package/dist/services/reconcile/index.mjs.map +1 -0
- package/dist/services/reducer/index.cjs +3 -0
- package/dist/services/reducer/index.cjs.map +1 -0
- package/dist/{store/reducer.d.cts → services/reducer/index.d.cts} +12 -13
- package/dist/services/reducer/index.d.cts.map +1 -0
- package/dist/{store/reducer.d.mts → services/reducer/index.d.mts} +12 -13
- package/dist/services/reducer/index.d.mts.map +1 -0
- package/dist/services/reducer/index.mjs +3 -0
- package/dist/services/reducer/index.mjs.map +1 -0
- package/dist/services/taskNarration/index.cjs +2 -0
- package/dist/services/taskNarration/index.cjs.map +1 -0
- package/dist/services/taskNarration/index.mjs +2 -0
- package/dist/services/taskNarration/index.mjs.map +1 -0
- package/dist/services/taskResult/index.cjs +7 -0
- package/dist/services/taskResult/index.cjs.map +1 -0
- package/dist/services/taskResult/index.d.cts +50 -0
- package/dist/services/taskResult/index.d.cts.map +1 -0
- package/dist/services/taskResult/index.d.mts +50 -0
- package/dist/services/taskResult/index.d.mts.map +1 -0
- package/dist/services/taskResult/index.mjs +7 -0
- package/dist/services/taskResult/index.mjs.map +1 -0
- package/dist/services/taskStore/index.cjs +2 -0
- package/dist/services/taskStore/index.cjs.map +1 -0
- package/dist/{store/taskStore.d.cts → services/taskStore/index.d.cts} +17 -25
- package/dist/services/taskStore/index.d.cts.map +1 -0
- package/dist/{store/taskStore.d.mts → services/taskStore/index.d.mts} +17 -25
- package/dist/services/taskStore/index.d.mts.map +1 -0
- package/dist/services/taskStore/index.mjs +2 -0
- package/dist/services/taskStore/index.mjs.map +1 -0
- package/dist/store-invariants.cjs +1 -0
- package/dist/store-invariants.d.cts +2 -0
- package/dist/store-invariants.d.mts +2 -0
- package/dist/store-invariants.mjs +1 -0
- package/dist/store-paths.cjs +1 -0
- package/dist/store-paths.d.cts +2 -0
- package/dist/store-paths.d.mts +2 -0
- package/dist/store-paths.mjs +1 -0
- package/dist/store-process-liveness.cjs +1 -0
- package/dist/store-process-liveness.d.cts +2 -0
- package/dist/store-process-liveness.d.mts +2 -0
- package/dist/store-process-liveness.mjs +1 -0
- package/dist/store-reconcile.cjs +1 -0
- package/dist/store-reconcile.d.cts +2 -0
- package/dist/store-reconcile.d.mts +2 -0
- package/dist/store-reconcile.mjs +1 -0
- package/dist/store-reducer.cjs +1 -0
- package/dist/store-reducer.d.cts +2 -0
- package/dist/store-reducer.d.mts +2 -0
- package/dist/store-reducer.mjs +1 -0
- package/dist/store-task-graph.cjs +1 -0
- package/dist/store-task-graph.d.cts +2 -0
- package/dist/store-task-graph.d.mts +2 -0
- package/dist/store-task-graph.mjs +1 -0
- package/dist/store-task-store.cjs +1 -0
- package/dist/store-task-store.d.cts +2 -0
- package/dist/store-task-store.d.mts +2 -0
- package/dist/store-task-store.mjs +1 -0
- package/dist/store-types.cjs +1 -0
- package/dist/store-types.d.cts +2 -0
- package/dist/store-types.d.mts +2 -0
- package/dist/store-types.mjs +1 -0
- package/dist/tool-prompt-guidelines.cjs +1 -0
- package/dist/tool-prompt-guidelines.d.cts +2 -0
- package/dist/tool-prompt-guidelines.d.mts +2 -0
- package/dist/tool-prompt-guidelines.mjs +1 -0
- package/dist/tool-response-envelope.cjs +1 -0
- package/dist/tool-response-envelope.d.cts +2 -0
- package/dist/tool-response-envelope.d.mts +2 -0
- package/dist/tool-response-envelope.mjs +1 -0
- package/dist/tool-schema.cjs +1 -0
- package/dist/tool-schema.d.cts +3 -0
- package/dist/tool-schema.d.mts +3 -0
- package/dist/tool-schema.mjs +1 -0
- package/dist/tool-task-tool.cjs +1 -0
- package/dist/tool-task-tool.d.cts +3 -0
- package/dist/tool-task-tool.d.mts +3 -0
- package/dist/tool-task-tool.mjs +1 -0
- package/dist/tools/task.cjs +3 -0
- package/dist/tools/task.cjs.map +1 -0
- package/dist/tools/task.d.cts +22 -0
- package/dist/tools/task.d.cts.map +1 -0
- package/dist/tools/task.d.mts +22 -0
- package/dist/tools/task.d.mts.map +1 -0
- package/dist/tools/task.mjs +3 -0
- package/dist/tools/task.mjs.map +1 -0
- package/dist/tui/format.cjs +3 -3
- package/dist/tui/format.cjs.map +1 -1
- package/dist/tui/format.d.cts +19 -20
- package/dist/tui/format.d.cts.map +1 -1
- package/dist/tui/format.d.mts +19 -20
- package/dist/tui/format.d.mts.map +1 -1
- package/dist/tui/format.mjs +3 -3
- package/dist/tui/format.mjs.map +1 -1
- package/dist/tui/selectors.cjs +1 -1
- package/dist/tui/selectors.cjs.map +1 -1
- package/dist/tui/selectors.d.cts +20 -14
- package/dist/tui/selectors.d.cts.map +1 -1
- package/dist/tui/selectors.d.mts +20 -14
- package/dist/tui/selectors.d.mts.map +1 -1
- package/dist/tui/selectors.mjs +1 -1
- package/dist/tui/selectors.mjs.map +1 -1
- package/dist/tui/taskOverlay.cjs +1 -1
- package/dist/tui/taskOverlay.cjs.map +1 -1
- package/dist/tui/taskOverlay.d.cts +4 -5
- package/dist/tui/taskOverlay.d.cts.map +1 -1
- package/dist/tui/taskOverlay.d.mts +4 -5
- package/dist/tui/taskOverlay.d.mts.map +1 -1
- package/dist/tui/taskOverlay.mjs +1 -1
- package/dist/tui/taskOverlay.mjs.map +1 -1
- package/dist/tui/taskSpace.cjs +3 -3
- package/dist/tui/taskSpace.cjs.map +1 -1
- package/dist/tui/taskSpace.d.cts +9 -10
- package/dist/tui/taskSpace.d.cts.map +1 -1
- package/dist/tui/taskSpace.d.mts +9 -10
- package/dist/tui/taskSpace.d.mts.map +1 -1
- package/dist/tui/taskSpace.mjs +3 -3
- package/dist/tui/taskSpace.mjs.map +1 -1
- package/dist/tui-format.cjs +1 -0
- package/dist/tui-format.d.cts +2 -0
- package/dist/tui-format.d.mts +2 -0
- package/dist/tui-format.mjs +1 -0
- package/dist/tui-selectors.cjs +1 -0
- package/dist/tui-selectors.d.cts +2 -0
- package/dist/tui-selectors.d.mts +2 -0
- package/dist/tui-selectors.mjs +1 -0
- package/dist/tui-task-overlay.cjs +1 -0
- package/dist/tui-task-overlay.d.cts +2 -0
- package/dist/tui-task-overlay.d.mts +2 -0
- package/dist/tui-task-overlay.mjs +1 -0
- package/dist/tui-task-space.cjs +1 -0
- package/dist/tui-task-space.d.cts +2 -0
- package/dist/tui-task-space.d.mts +2 -0
- package/dist/tui-task-space.mjs +1 -0
- package/dist/types/delegation.cjs +2 -0
- package/dist/types/delegation.cjs.map +1 -0
- package/dist/types/delegation.d.cts +5 -0
- package/dist/types/delegation.d.cts.map +1 -0
- package/dist/types/delegation.d.mts +5 -0
- package/dist/types/delegation.d.mts.map +1 -0
- package/dist/types/delegation.mjs +2 -0
- package/dist/types/delegation.mjs.map +1 -0
- package/dist/types/telemetry.cjs +2 -0
- package/dist/types/telemetry.cjs.map +1 -0
- package/dist/types/telemetry.d.cts +35 -0
- package/dist/types/telemetry.d.cts.map +1 -0
- package/dist/types/telemetry.d.mts +35 -0
- package/dist/types/telemetry.d.mts.map +1 -0
- package/dist/types/telemetry.mjs +2 -0
- package/dist/types/telemetry.mjs.map +1 -0
- package/dist/types/webTasks.cjs +2 -0
- package/dist/types/webTasks.cjs.map +1 -0
- package/dist/types/webTasks.mjs +2 -0
- package/dist/types/webTasks.mjs.map +1 -0
- package/package.json +158 -109
- package/src/extensions/web.ts +18 -0
- package/src/types/webTasks.ts +24 -0
- package/src/web/components/TaskDetailDialog.tsx +251 -0
- package/src/web/components/TaskToolMessage.tsx +120 -0
- package/src/web/components/TasksActivitySection.tsx +200 -0
- package/src/web/lib/taskToolFormat.ts +330 -0
- package/src/web/stores/tasksStore.ts +114 -0
- package/src/web/tsconfig.json +23 -0
- package/dist/commands.cjs.map +0 -1
- package/dist/commands.d.cts.map +0 -1
- package/dist/commands.d.mts.map +0 -1
- package/dist/commands.mjs.map +0 -1
- package/dist/config.cjs.map +0 -1
- package/dist/config.d.cts.map +0 -1
- package/dist/config.d.mts.map +0 -1
- package/dist/config.mjs.map +0 -1
- package/dist/delegation/manager.cjs +0 -6
- package/dist/delegation/manager.cjs.map +0 -1
- package/dist/delegation/manager.d.cts.map +0 -1
- package/dist/delegation/manager.d.mts.map +0 -1
- package/dist/delegation/manager.mjs +0 -6
- package/dist/delegation/manager.mjs.map +0 -1
- package/dist/extension.cjs +0 -3
- package/dist/extension.cjs.map +0 -1
- package/dist/extension.d.cts +0 -12
- package/dist/extension.d.cts.map +0 -1
- package/dist/extension.d.mts +0 -12
- package/dist/extension.d.mts.map +0 -1
- package/dist/extension.mjs +0 -3
- package/dist/extension.mjs.map +0 -1
- package/dist/extensions/doom.cjs +0 -2
- package/dist/extensions/doom.cjs.map +0 -1
- package/dist/extensions/doom.d.cts +0 -6
- package/dist/extensions/doom.d.cts.map +0 -1
- package/dist/extensions/doom.d.mts +0 -7
- package/dist/extensions/doom.d.mts.map +0 -1
- package/dist/extensions/doom.mjs +0 -2
- package/dist/extensions/doom.mjs.map +0 -1
- package/dist/logSinkTelemetry.cjs.map +0 -1
- package/dist/logSinkTelemetry.d.cts.map +0 -1
- package/dist/logSinkTelemetry.d.mts.map +0 -1
- package/dist/logSinkTelemetry.mjs.map +0 -1
- package/dist/store/invariants.cjs +0 -2
- package/dist/store/invariants.cjs.map +0 -1
- package/dist/store/invariants.d.cts +0 -14
- package/dist/store/invariants.d.cts.map +0 -1
- package/dist/store/invariants.d.mts +0 -14
- package/dist/store/invariants.d.mts.map +0 -1
- package/dist/store/invariants.mjs +0 -2
- package/dist/store/invariants.mjs.map +0 -1
- package/dist/store/paths.cjs +0 -2
- package/dist/store/paths.cjs.map +0 -1
- package/dist/store/paths.d.cts +0 -23
- package/dist/store/paths.d.cts.map +0 -1
- package/dist/store/paths.d.mts +0 -23
- package/dist/store/paths.d.mts.map +0 -1
- package/dist/store/paths.mjs +0 -2
- package/dist/store/paths.mjs.map +0 -1
- package/dist/store/processLiveness.cjs +0 -2
- package/dist/store/processLiveness.cjs.map +0 -1
- package/dist/store/processLiveness.d.cts.map +0 -1
- package/dist/store/processLiveness.d.mts.map +0 -1
- package/dist/store/processLiveness.mjs.map +0 -1
- package/dist/store/reconcile.cjs +0 -2
- package/dist/store/reconcile.cjs.map +0 -1
- package/dist/store/reconcile.d.cts.map +0 -1
- package/dist/store/reconcile.d.mts.map +0 -1
- package/dist/store/reconcile.mjs +0 -2
- package/dist/store/reconcile.mjs.map +0 -1
- package/dist/store/reducer.cjs +0 -3
- package/dist/store/reducer.cjs.map +0 -1
- package/dist/store/reducer.d.cts.map +0 -1
- package/dist/store/reducer.d.mts.map +0 -1
- package/dist/store/reducer.mjs +0 -3
- package/dist/store/reducer.mjs.map +0 -1
- package/dist/store/taskGraph.cjs +0 -2
- package/dist/store/taskGraph.cjs.map +0 -1
- package/dist/store/taskGraph.d.cts.map +0 -1
- package/dist/store/taskGraph.d.mts.map +0 -1
- package/dist/store/taskGraph.mjs.map +0 -1
- package/dist/store/taskStore.cjs +0 -2
- package/dist/store/taskStore.cjs.map +0 -1
- package/dist/store/taskStore.d.cts.map +0 -1
- package/dist/store/taskStore.d.mts.map +0 -1
- package/dist/store/taskStore.mjs +0 -2
- package/dist/store/taskStore.mjs.map +0 -1
- package/dist/store/types.cjs +0 -2
- package/dist/store/types.cjs.map +0 -1
- package/dist/store/types.d.cts.map +0 -1
- package/dist/store/types.d.mts.map +0 -1
- package/dist/store/types.mjs.map +0 -1
- package/dist/tool/promptGuidelines.cjs +0 -2
- package/dist/tool/promptGuidelines.cjs.map +0 -1
- package/dist/tool/promptGuidelines.d.cts +0 -5
- package/dist/tool/promptGuidelines.d.cts.map +0 -1
- package/dist/tool/promptGuidelines.d.mts +0 -5
- package/dist/tool/promptGuidelines.d.mts.map +0 -1
- package/dist/tool/promptGuidelines.mjs +0 -2
- package/dist/tool/promptGuidelines.mjs.map +0 -1
- package/dist/tool/responseEnvelope.cjs +0 -6
- package/dist/tool/responseEnvelope.cjs.map +0 -1
- package/dist/tool/responseEnvelope.d.cts +0 -39
- package/dist/tool/responseEnvelope.d.cts.map +0 -1
- package/dist/tool/responseEnvelope.d.mts +0 -39
- package/dist/tool/responseEnvelope.d.mts.map +0 -1
- package/dist/tool/responseEnvelope.mjs +0 -6
- package/dist/tool/responseEnvelope.mjs.map +0 -1
- package/dist/tool/schema.cjs +0 -2
- package/dist/tool/schema.cjs.map +0 -1
- package/dist/tool/schema.d.cts.map +0 -1
- package/dist/tool/schema.d.mts.map +0 -1
- package/dist/tool/schema.mjs +0 -2
- package/dist/tool/schema.mjs.map +0 -1
- package/dist/tool/taskTool.cjs +0 -3
- package/dist/tool/taskTool.cjs.map +0 -1
- package/dist/tool/taskTool.d.cts +0 -17
- package/dist/tool/taskTool.d.cts.map +0 -1
- package/dist/tool/taskTool.d.mts +0 -17
- package/dist/tool/taskTool.d.mts.map +0 -1
- package/dist/tool/taskTool.mjs +0 -3
- package/dist/tool/taskTool.mjs.map +0 -1
- /package/dist/{store → models}/taskGraph.mjs +0 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure view logic for the task tool card, the browser counterpart of
|
|
3
|
+
* src/tui/format.ts (renderTaskCall, renderTaskResult). The plugin may reach
|
|
4
|
+
* only its own files and src/types, so the store shapes it reads are
|
|
5
|
+
* restated here as the wire JSON of a tool_execution frame.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'deleted';
|
|
9
|
+
export type TaskAction = 'upsert' | 'list' | 'get' | 'delete' | 'clear' | 'assign' | 'cancel';
|
|
10
|
+
|
|
11
|
+
export const STATUS_GLYPH: Record<TaskStatus, string> = {
|
|
12
|
+
pending: '○',
|
|
13
|
+
in_progress: '◐',
|
|
14
|
+
completed: '●',
|
|
15
|
+
failed: '✗',
|
|
16
|
+
deleted: '⊘',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const STATUS_LABEL: Record<TaskStatus, string> = {
|
|
20
|
+
pending: 'pending',
|
|
21
|
+
in_progress: 'in progress',
|
|
22
|
+
completed: 'completed',
|
|
23
|
+
failed: 'failed',
|
|
24
|
+
deleted: 'deleted',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const ACTION_GLYPH: Record<TaskAction, string> = {
|
|
28
|
+
upsert: '✎',
|
|
29
|
+
delete: '×',
|
|
30
|
+
get: '›',
|
|
31
|
+
list: '☰',
|
|
32
|
+
clear: '∅',
|
|
33
|
+
assign: '⇒',
|
|
34
|
+
cancel: '⊗',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* `upsert` is two operations behind one name, so a homogeneous batch narrows to
|
|
39
|
+
* the glyph the operator already reads: `+` means new work appeared, `→` means
|
|
40
|
+
* work moved. A mixed batch keeps the neutral write glyph.
|
|
41
|
+
*/
|
|
42
|
+
const UPSERT_CREATE_GLYPH = '+';
|
|
43
|
+
const UPSERT_UPDATE_GLYPH = '→';
|
|
44
|
+
/** Task rows kept in a collapsed result, before the card is expanded. */
|
|
45
|
+
const TRANSCRIPT_TASK_ROWS = 8;
|
|
46
|
+
const TASK_STATUSES: readonly TaskStatus[] = ['pending', 'in_progress', 'completed', 'failed', 'deleted'];
|
|
47
|
+
const TASK_ACTIONS: readonly TaskAction[] = ['upsert', 'list', 'get', 'delete', 'clear', 'assign', 'cancel'];
|
|
48
|
+
const INLINE_WHITESPACE = /\s+/gu;
|
|
49
|
+
|
|
50
|
+
/** One task as the result details carry it (src/models/task.ts Task). */
|
|
51
|
+
export interface TaskView {
|
|
52
|
+
id: number;
|
|
53
|
+
subject: string;
|
|
54
|
+
status: TaskStatus;
|
|
55
|
+
activeForm?: string;
|
|
56
|
+
blockedBy?: number[];
|
|
57
|
+
delegation?: { agent?: string; state?: string };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The result details (src/models/task.ts TaskDetails), narrowed to what the card reads. */
|
|
61
|
+
export interface TaskDetailsView {
|
|
62
|
+
action: TaskAction;
|
|
63
|
+
params: Record<string, unknown>;
|
|
64
|
+
tasks: TaskView[];
|
|
65
|
+
error?: string;
|
|
66
|
+
upsert?: { applied: number[]; failed: number };
|
|
67
|
+
assignment?: { assigned: number[]; failed: number };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
71
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isStatus(value: unknown): value is TaskStatus {
|
|
75
|
+
return typeof value === 'string' && (TASK_STATUSES as readonly string[]).includes(value);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function isAction(value: unknown): value is TaskAction {
|
|
79
|
+
return typeof value === 'string' && (TASK_ACTIONS as readonly string[]).includes(value);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function taskView(value: unknown): TaskView | null {
|
|
83
|
+
if (!isRecord(value) || typeof value.id !== 'number' || typeof value.subject !== 'string') return null;
|
|
84
|
+
if (!isStatus(value.status)) return null;
|
|
85
|
+
const task: TaskView = { id: value.id, subject: value.subject, status: value.status };
|
|
86
|
+
if (typeof value.activeForm === 'string') task.activeForm = value.activeForm;
|
|
87
|
+
if (Array.isArray(value.blockedBy)) {
|
|
88
|
+
task.blockedBy = value.blockedBy.filter((id): id is number => typeof id === 'number');
|
|
89
|
+
}
|
|
90
|
+
if (isRecord(value.delegation)) {
|
|
91
|
+
task.delegation = {};
|
|
92
|
+
if (typeof value.delegation.agent === 'string') task.delegation.agent = value.delegation.agent;
|
|
93
|
+
if (typeof value.delegation.state === 'string') task.delegation.state = value.delegation.state;
|
|
94
|
+
}
|
|
95
|
+
return task;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function idList(value: unknown): number[] {
|
|
99
|
+
return Array.isArray(value) ? value.filter((id): id is number => typeof id === 'number') : [];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Narrows the wire details; null when they are not a task result at all. */
|
|
103
|
+
export function taskDetailsView(details: unknown): TaskDetailsView | null {
|
|
104
|
+
if (!isRecord(details) || !isAction(details.action) || !Array.isArray(details.tasks)) return null;
|
|
105
|
+
const view: TaskDetailsView = {
|
|
106
|
+
action: details.action,
|
|
107
|
+
params: isRecord(details.params) ? details.params : {},
|
|
108
|
+
tasks: details.tasks.map(taskView).filter((task): task is TaskView => task !== null),
|
|
109
|
+
};
|
|
110
|
+
if (typeof details.error === 'string') view.error = details.error;
|
|
111
|
+
if (isRecord(details.upsert)) {
|
|
112
|
+
view.upsert = {
|
|
113
|
+
applied: idList(details.upsert.applied),
|
|
114
|
+
failed: typeof details.upsert.failed === 'number' ? details.upsert.failed : 0,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (isRecord(details.assignment)) {
|
|
118
|
+
view.assignment = {
|
|
119
|
+
assigned: idList(details.assignment.assigned),
|
|
120
|
+
failed: typeof details.assignment.failed === 'number' ? details.assignment.failed : 0,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return view;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** `#id` for the wire's id, which the TUI would resolve to a subject through the store. */
|
|
127
|
+
function idLabel(value: unknown): string {
|
|
128
|
+
return typeof value === 'number' || typeof value === 'string' ? `#${value}` : '#?';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Keep dynamic content on one line. */
|
|
132
|
+
function inlineText(text: string): string {
|
|
133
|
+
return text.replace(INLINE_WHITESPACE, ' ').trim();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export type TaskCallTone = 'dim' | 'accent';
|
|
137
|
+
|
|
138
|
+
/** The call header: glyph, action, then the subject or a count, as renderTaskCall lays it out. */
|
|
139
|
+
export interface TaskCallView {
|
|
140
|
+
glyph: string;
|
|
141
|
+
action: string;
|
|
142
|
+
subject?: string;
|
|
143
|
+
subjectTone: TaskCallTone;
|
|
144
|
+
/** The assignee (`→ agent`) or the list filter. */
|
|
145
|
+
detail?: string;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function upsertGlyph(items: readonly Record<string, unknown>[]): string {
|
|
149
|
+
if (items.length === 0) return ACTION_GLYPH.upsert;
|
|
150
|
+
if (items.every((item) => item.id === undefined)) return UPSERT_CREATE_GLYPH;
|
|
151
|
+
if (items.every((item) => item.id !== undefined)) return UPSERT_UPDATE_GLYPH;
|
|
152
|
+
return ACTION_GLYPH.upsert;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The TUI resolves an id to its subject through the task store; the card has
|
|
157
|
+
* no store and shows `#id` until the result names the task.
|
|
158
|
+
*/
|
|
159
|
+
export function taskCallView(args: Record<string, unknown>): TaskCallView {
|
|
160
|
+
const action = typeof args.action === 'string' ? args.action : 'task';
|
|
161
|
+
if (!isAction(action)) return { glyph: '?', action, subjectTone: 'dim' };
|
|
162
|
+
const items = action === 'upsert' && Array.isArray(args.tasks) ? args.tasks.filter(isRecord) : [];
|
|
163
|
+
const view: TaskCallView = {
|
|
164
|
+
glyph: action === 'upsert' ? upsertGlyph(items) : ACTION_GLYPH[action],
|
|
165
|
+
action,
|
|
166
|
+
subjectTone: 'dim',
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
if (action === 'upsert') {
|
|
170
|
+
// One entry reads exactly as create or update did; a batch reads as a count
|
|
171
|
+
// rather than a subject it would have to pick arbitrarily.
|
|
172
|
+
if (items.length === 1) {
|
|
173
|
+
const only = items[0] ?? {};
|
|
174
|
+
if (only.id === undefined) {
|
|
175
|
+
if (typeof only.subject === 'string') view.subject = inlineText(only.subject);
|
|
176
|
+
} else {
|
|
177
|
+
view.subject = typeof only.subject === 'string' ? inlineText(only.subject) : idLabel(only.id);
|
|
178
|
+
view.subjectTone = 'accent';
|
|
179
|
+
}
|
|
180
|
+
} else if (items.length > 1) {
|
|
181
|
+
view.subject = `${items.length} tasks`;
|
|
182
|
+
}
|
|
183
|
+
} else if (action === 'assign') {
|
|
184
|
+
const assignments = Array.isArray(args.assignments) ? args.assignments.filter(isRecord) : [];
|
|
185
|
+
if (assignments.length === 1) {
|
|
186
|
+
const only = assignments[0] ?? {};
|
|
187
|
+
view.subject = idLabel(only.id);
|
|
188
|
+
view.subjectTone = 'accent';
|
|
189
|
+
if (typeof only.agent === 'string') view.detail = `→ ${only.agent}`;
|
|
190
|
+
} else if (assignments.length > 1) {
|
|
191
|
+
view.subject = `${assignments.length} tasks`;
|
|
192
|
+
}
|
|
193
|
+
} else if ((action === 'get' || action === 'delete' || action === 'cancel') && args.id !== undefined) {
|
|
194
|
+
view.subject = idLabel(args.id);
|
|
195
|
+
view.subjectTone = 'accent';
|
|
196
|
+
} else if (action === 'list' && isStatus(args.status)) {
|
|
197
|
+
view.detail = STATUS_LABEL[args.status];
|
|
198
|
+
}
|
|
199
|
+
return view;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** One row of the result: the task line on the left, its status flushed right. */
|
|
203
|
+
export interface TaskRow {
|
|
204
|
+
id: number;
|
|
205
|
+
glyph: string;
|
|
206
|
+
subject: string;
|
|
207
|
+
status: TaskStatus;
|
|
208
|
+
/** Struck through: the task is done with. */
|
|
209
|
+
closed: boolean;
|
|
210
|
+
agent?: string;
|
|
211
|
+
activeForm?: string;
|
|
212
|
+
blockedBy: number[];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export type TaskResultTone = 'running' | 'ok' | 'error' | 'warning';
|
|
216
|
+
|
|
217
|
+
export interface TaskResultView {
|
|
218
|
+
rows: TaskRow[];
|
|
219
|
+
/** Error text lines when the tool threw or the reducer reported an error. */
|
|
220
|
+
errorLines: string[];
|
|
221
|
+
status: { glyph: string; tone: TaskResultTone; text: string } | null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export function taskRow(task: TaskView): TaskRow {
|
|
225
|
+
const row: TaskRow = {
|
|
226
|
+
id: task.id,
|
|
227
|
+
glyph: STATUS_GLYPH[task.status],
|
|
228
|
+
subject: inlineText(task.subject),
|
|
229
|
+
status: task.status,
|
|
230
|
+
closed: task.status === 'completed' || task.status === 'deleted',
|
|
231
|
+
blockedBy: task.blockedBy ?? [],
|
|
232
|
+
};
|
|
233
|
+
if (task.delegation?.agent) row.agent = inlineText(task.delegation.agent);
|
|
234
|
+
if (task.status === 'in_progress' && task.activeForm) row.activeForm = inlineText(task.activeForm);
|
|
235
|
+
return row;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function nonEmptyLines(text: string): string[] {
|
|
239
|
+
return text.split('\n').filter((line) => line.trim().length > 0);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* The rows `list` reported to the model: `details.tasks` is the whole
|
|
244
|
+
* document, so the call's filters apply again here or the card would disagree
|
|
245
|
+
* with the text the model was given.
|
|
246
|
+
*/
|
|
247
|
+
function listedTasks(details: TaskDetailsView): TaskView[] {
|
|
248
|
+
let view = details.tasks;
|
|
249
|
+
if (details.params.includeDeleted !== true) view = view.filter((task) => task.status !== 'deleted');
|
|
250
|
+
if (isStatus(details.params.status)) view = view.filter((task) => task.status === details.params.status);
|
|
251
|
+
return view;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function byIds(details: TaskDetailsView, ids: readonly number[]): TaskView[] {
|
|
255
|
+
return ids.flatMap((id) => details.tasks.find((task) => task.id === id) ?? []);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function batch(
|
|
259
|
+
tasks: readonly TaskView[],
|
|
260
|
+
failed: number,
|
|
261
|
+
verb: string,
|
|
262
|
+
expanded: boolean,
|
|
263
|
+
): Pick<TaskResultView, 'rows' | 'status'> {
|
|
264
|
+
// One applied task and nothing failed is the common case: keep the single
|
|
265
|
+
// row it has always had rather than dressing it as a bulk report.
|
|
266
|
+
if (tasks.length === 1 && failed === 0) return { rows: [taskRow(tasks[0] as TaskView)], status: null };
|
|
267
|
+
const shown = expanded ? tasks : tasks.slice(0, TRANSCRIPT_TASK_ROWS);
|
|
268
|
+
let summary = `${tasks.length} ${verb}`;
|
|
269
|
+
if (failed > 0) summary += ` · ${failed} failed`;
|
|
270
|
+
if (tasks.length > shown.length) summary += ` · ${tasks.length - shown.length} more`;
|
|
271
|
+
return {
|
|
272
|
+
rows: shown.map(taskRow),
|
|
273
|
+
status: { glyph: failed > 0 ? '!' : '✓', tone: failed > 0 ? 'warning' : 'ok', text: summary },
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export function taskResultView(input: {
|
|
278
|
+
details: unknown;
|
|
279
|
+
output: string;
|
|
280
|
+
expanded: boolean;
|
|
281
|
+
isPartial: boolean;
|
|
282
|
+
isError: boolean;
|
|
283
|
+
}): TaskResultView {
|
|
284
|
+
const details = taskDetailsView(input.details);
|
|
285
|
+
|
|
286
|
+
// Running. `assign` and `cancel` stream a placeholder before the run settles.
|
|
287
|
+
if (input.isPartial) {
|
|
288
|
+
const text = nonEmptyLines(input.output).at(-1) ?? 'working';
|
|
289
|
+
return { rows: [], errorLines: [], status: { glyph: '◐', tone: 'running', text } };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Failed. Every failure path throws, so Pi hands back error text and no
|
|
293
|
+
// details; without this the card would show a green tick on a failure.
|
|
294
|
+
if (input.isError || details?.error !== undefined) {
|
|
295
|
+
const all = nonEmptyLines(details?.error ?? input.output);
|
|
296
|
+
if (all.length <= 1) return { rows: [], errorLines: [], status: { glyph: '✗', tone: 'error', text: all[0] ?? '' } };
|
|
297
|
+
const errorLines = input.expanded ? all : all.slice(0, TRANSCRIPT_TASK_ROWS);
|
|
298
|
+
return { rows: [], errorLines, status: { glyph: '✗', tone: 'error', text: '' } };
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (details === null) return { rows: [], errorLines: [], status: { glyph: '✓', tone: 'ok', text: '' } };
|
|
302
|
+
|
|
303
|
+
if (details.action === 'list') {
|
|
304
|
+
const tasks = listedTasks(details);
|
|
305
|
+
const shown = input.expanded ? tasks : tasks.slice(0, TRANSCRIPT_TASK_ROWS);
|
|
306
|
+
let summary = tasks.length === 0 ? 'no tasks' : `${tasks.length} task${tasks.length === 1 ? '' : 's'}`;
|
|
307
|
+
if (tasks.length > shown.length) summary += ` · ${tasks.length - shown.length} more`;
|
|
308
|
+
return { rows: shown.map(taskRow), errorLines: [], status: { glyph: '✓', tone: 'ok', text: summary } };
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (details.action === 'clear') {
|
|
312
|
+
return { rows: [], errorLines: [], status: { glyph: '✓', tone: 'ok', text: 'cleared' } };
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (details.action === 'assign' && details.assignment) {
|
|
316
|
+
const assigned = byIds(details, details.assignment.assigned);
|
|
317
|
+
return { errorLines: [], ...batch(assigned, details.assignment.failed, 'assigned', input.expanded) };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (details.action === 'upsert') {
|
|
321
|
+
const touched = byIds(details, details.upsert?.applied ?? []);
|
|
322
|
+
return { errorLines: [], ...batch(touched, details.upsert?.failed ?? 0, 'applied', input.expanded) };
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// The single task an id-bearing action acted on, so the card names it rather than a bare tick.
|
|
326
|
+
const id = details.params.id;
|
|
327
|
+
const task = typeof id === 'number' ? details.tasks.find((candidate) => candidate.id === id) : undefined;
|
|
328
|
+
if (!task) return { rows: [], errorLines: [], status: { glyph: '✓', tone: 'ok', text: '' } };
|
|
329
|
+
return { rows: [taskRow(task)], errorLines: [], status: null };
|
|
330
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { defineSessionStore, type SessionFrameSender } from '@agimon-ai/doompi-core/web';
|
|
2
|
+
|
|
3
|
+
import { TASKS_CHANNEL_TYPE, type WebTask, type WebTasksPayload } from '../../types/webTasks';
|
|
4
|
+
|
|
5
|
+
export interface TasksSession {
|
|
6
|
+
tasks: WebTask[];
|
|
7
|
+
rev: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const tasks = defineSessionStore<TasksSession>({ tasks: [], rev: 0 });
|
|
11
|
+
|
|
12
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
13
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function parseTask(value: unknown): WebTask | null {
|
|
17
|
+
if (!isRecord(value) || typeof value.id !== 'number' || typeof value.subject !== 'string') return null;
|
|
18
|
+
if (!['pending', 'in_progress', 'completed', 'failed'].includes(String(value.status))) return null;
|
|
19
|
+
const task: WebTask = {
|
|
20
|
+
id: value.id,
|
|
21
|
+
subject: value.subject,
|
|
22
|
+
status: value.status as WebTask['status'],
|
|
23
|
+
blockedBy: Array.isArray(value.blockedBy)
|
|
24
|
+
? value.blockedBy.filter((id): id is number => typeof id === 'number')
|
|
25
|
+
: [],
|
|
26
|
+
};
|
|
27
|
+
if (typeof value.description === 'string') task.description = value.description;
|
|
28
|
+
if (typeof value.activeForm === 'string') task.activeForm = value.activeForm;
|
|
29
|
+
if (typeof value.owner === 'string') task.owner = value.owner;
|
|
30
|
+
if (typeof value.updatedAt === 'string') task.updatedAt = value.updatedAt;
|
|
31
|
+
if (isRecord(value.delegation)) {
|
|
32
|
+
task.delegation = {};
|
|
33
|
+
if (typeof value.delegation.agent === 'string') task.delegation.agent = value.delegation.agent;
|
|
34
|
+
if (typeof value.delegation.state === 'string') task.delegation.state = value.delegation.state;
|
|
35
|
+
}
|
|
36
|
+
return task;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const tasksChannel = tasks.channel<WebTasksPayload>({
|
|
40
|
+
channel: TASKS_CHANNEL_TYPE,
|
|
41
|
+
parse(input) {
|
|
42
|
+
if (!isRecord(input) || !Array.isArray(input.tasks) || typeof input.rev !== 'number') return null;
|
|
43
|
+
return { tasks: input.tasks.map(parseTask).filter((task): task is WebTask => task !== null), rev: input.rev };
|
|
44
|
+
},
|
|
45
|
+
reduce: (_current, payload) => payload,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
/** The fields the cockpit lets a human change on a task. */
|
|
49
|
+
export interface TaskEditDraft {
|
|
50
|
+
subject: string;
|
|
51
|
+
description: string;
|
|
52
|
+
status: WebTask['status'];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function taskEditDraft(task: WebTask): TaskEditDraft {
|
|
56
|
+
return { subject: task.subject, description: task.description ?? '', status: task.status };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function changedFields(task: WebTask, draft: TaskEditDraft): string[] {
|
|
60
|
+
const changes: string[] = [];
|
|
61
|
+
const subject = draft.subject.trim();
|
|
62
|
+
const description = draft.description.trim();
|
|
63
|
+
if (subject && subject !== task.subject) changes.push(`set subject to "${subject}"`);
|
|
64
|
+
if (description !== (task.description ?? '').trim()) {
|
|
65
|
+
changes.push(description ? `set description to "${description}"` : 'clear the description');
|
|
66
|
+
}
|
|
67
|
+
if (draft.status !== task.status) changes.push(`set status to ${draft.status}`);
|
|
68
|
+
return changes;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The agent stays the only writer of task state, so an edit leaves the cockpit
|
|
73
|
+
* as one prompt naming exactly the fields the human changed. Nothing changed
|
|
74
|
+
* means nothing to send.
|
|
75
|
+
*/
|
|
76
|
+
export function taskEditInstruction(task: WebTask, draft: TaskEditDraft): string | null {
|
|
77
|
+
const changes = changedFields(task, draft);
|
|
78
|
+
if (changes.length === 0) return null;
|
|
79
|
+
return `Update task #${task.id}: ${changes.join('; ')}. Change nothing else and keep the dependency graph valid.`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function requestTaskEdit(
|
|
83
|
+
send: SessionFrameSender,
|
|
84
|
+
sessionId: string,
|
|
85
|
+
task: WebTask,
|
|
86
|
+
draft: TaskEditDraft,
|
|
87
|
+
): boolean {
|
|
88
|
+
const message = taskEditInstruction(task, draft);
|
|
89
|
+
if (message === null) return false;
|
|
90
|
+
send(sessionId, { type: 'prompt', message });
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Steering for the subagent that owns a delegated task. */
|
|
95
|
+
export function taskMessageInstruction(taskId: number, agent: string, message: string): string {
|
|
96
|
+
return `Steer the ${agent} run working on task #${taskId} with this message, then update the task if its plan changed: ${message.trim()}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function requestTaskMessage(
|
|
100
|
+
send: SessionFrameSender,
|
|
101
|
+
sessionId: string,
|
|
102
|
+
taskId: number,
|
|
103
|
+
agent: string,
|
|
104
|
+
message: string,
|
|
105
|
+
): void {
|
|
106
|
+
send(sessionId, { type: 'prompt', message: taskMessageInstruction(taskId, agent, message) });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function requestTaskRemoval(send: SessionFrameSender, sessionId: string, taskId: number): void {
|
|
110
|
+
send(sessionId, {
|
|
111
|
+
type: 'prompt',
|
|
112
|
+
message: `Remove task #${taskId}. Also remove or repair every dependency that references it so the remaining task graph is valid.`,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2023", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "Bundler",
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noImplicitAny": true,
|
|
10
|
+
"noUnusedLocals": true,
|
|
11
|
+
"noUnusedParameters": true,
|
|
12
|
+
"noImplicitReturns": true,
|
|
13
|
+
"noFallthroughCasesInSwitch": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"esModuleInterop": true,
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"allowImportingTsExtensions": true,
|
|
19
|
+
"forceConsistentCasingInFileNames": true,
|
|
20
|
+
"types": ["node"]
|
|
21
|
+
},
|
|
22
|
+
"include": [".", "../types", "../extensions/web.ts"]
|
|
23
|
+
}
|
package/dist/commands.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.cjs","names":["COMMAND_NAME","ERR_REQUIRES_INTERACTIVE","openTaskSpace"],"sources":["../src/commands.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport type { TaskStore } from './store/taskStore.ts';\nimport { COMMAND_NAME, ERR_REQUIRES_INTERACTIVE } from './tool/schema.ts';\nimport { openTaskSpace } from './tui/taskSpace.ts';\n\n/**\n * `/tasks`, reachable from the leader palette as `SPC t t`.\n *\n * The command opens the Task Space overlay rather than printing a listing: the\n * overlay is the readable surface and it can edit, while a transcript dump could\n * only be read.\n */\nexport function registerTasksCommand(pi: ExtensionAPI, store: TaskStore): void {\n pi.registerCommand(COMMAND_NAME, {\n description: 'Open Task Space for this session tree',\n handler: async (_args, ctx) => {\n if (!ctx.hasUI) {\n ctx.ui.notify(ERR_REQUIRES_INTERACTIVE, 'error');\n return;\n }\n\n store.read();\n await openTaskSpace(ctx, { store });\n },\n });\n}\n"],"mappings":"yIAYA,SAAgB,EAAqB,EAAkB,EAAwB,CAC7E,EAAG,gBAAgBA,EAAAA,aAAc,CAC/B,YAAa,wCACb,QAAS,MAAO,EAAO,IAAQ,CAC7B,GAAI,CAAC,EAAI,MAAO,CACd,EAAI,GAAG,OAAOC,EAAAA,yBAA0B,OAAO,EAC/C,MACF,CAEA,EAAM,KAAK,EACX,MAAMC,EAAAA,cAAc,EAAK,CAAE,OAAM,CAAC,CACpC,CACF,CAAC,CACH"}
|
package/dist/commands.d.cts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.cts","names":[],"sources":["../src/commands.ts"],"mappings":";;;;;;;;;;iBAYgB,qBAAqB,IAAI,cAAc,OAAO"}
|
package/dist/commands.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.mts","names":[],"sources":["../src/commands.ts"],"mappings":";;;;;;;;;;iBAYgB,qBAAqB,IAAI,cAAc,OAAO"}
|
package/dist/commands.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.mjs","names":[],"sources":["../src/commands.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport type { TaskStore } from './store/taskStore.ts';\nimport { COMMAND_NAME, ERR_REQUIRES_INTERACTIVE } from './tool/schema.ts';\nimport { openTaskSpace } from './tui/taskSpace.ts';\n\n/**\n * `/tasks`, reachable from the leader palette as `SPC t t`.\n *\n * The command opens the Task Space overlay rather than printing a listing: the\n * overlay is the readable surface and it can edit, while a transcript dump could\n * only be read.\n */\nexport function registerTasksCommand(pi: ExtensionAPI, store: TaskStore): void {\n pi.registerCommand(COMMAND_NAME, {\n description: 'Open Task Space for this session tree',\n handler: async (_args, ctx) => {\n if (!ctx.hasUI) {\n ctx.ui.notify(ERR_REQUIRES_INTERACTIVE, 'error');\n return;\n }\n\n store.read();\n await openTaskSpace(ctx, { store });\n },\n });\n}\n"],"mappings":"mIAYA,SAAgB,EAAqB,EAAkB,EAAwB,CAC7E,EAAG,gBAAgB,EAAc,CAC/B,YAAa,wCACb,QAAS,MAAO,EAAO,IAAQ,CAC7B,GAAI,CAAC,EAAI,MAAO,CACd,EAAI,GAAG,OAAO,EAA0B,OAAO,EAC/C,MACF,CAEA,EAAM,KAAK,EACX,MAAM,EAAc,EAAK,CAAE,OAAM,CAAC,CACpC,CACF,CAAC,CACH"}
|
package/dist/config.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.cjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["/**\n * Extension configuration, read from the environment.\n *\n * Env rather than a config file: doom-pi already carries per-launch state to Pi\n * through env vars, so this keeps doom-task consistent with how the harness\n * configures the rest of the extension set.\n */\n\nexport const MAX_WIDGET_LINES_ENV = 'DOOM_TASK_MAX_WIDGET_LINES';\nexport const COLLAPSE_KEY_ENV = 'DOOM_TASK_COLLAPSE_KEY';\nexport const STORE_TTL_MS_ENV = 'DOOM_TASK_STORE_TTL_MS';\nexport const DELEGATION_TIMEOUT_MS_ENV = 'DOOM_TASK_DELEGATION_TIMEOUT_MS';\n\nexport const DEFAULT_MAX_WIDGET_LINES = 12;\nexport const DEFAULT_COLLAPSE_KEY = 'ctrl+shift+t';\nexport const DEFAULT_STORE_TTL_MS = 30 * 24 * 60 * 60 * 1000;\n/** Deliberately under the subagents auto-drain ceiling (30 min) so a headless\n * session still gets the failure and a model turn before draining gives up. */\nexport const DEFAULT_DELEGATION_TIMEOUT_MS = 20 * 60 * 1000;\nexport const COLLAPSE_KEY_OFF = 'off';\n\nconst MIN_WIDGET_LINES = 3;\nconst MAX_WIDGET_LINES = 60;\n\nexport interface PiTaskConfig {\n maxWidgetLines: number;\n storeTtlMs: number;\n collapseKey: string;\n delegationTimeoutMs: number;\n}\n\nfunction configRecord(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\n/** Parse configuration only after the Pi host has applied its project-trust policy. */\nexport function parsePiTaskConfig(value: unknown): PiTaskConfig {\n const config = configRecord(value);\n const maxWidgetLines =\n typeof config.maxWidgetLines === 'number' && Number.isFinite(config.maxWidgetLines)\n ? Math.min(Math.max(config.maxWidgetLines, MIN_WIDGET_LINES), MAX_WIDGET_LINES)\n : DEFAULT_MAX_WIDGET_LINES;\n const storeTtlMs =\n typeof config.storeTtlMs === 'number' && Number.isFinite(config.storeTtlMs) && config.storeTtlMs > 0\n ? config.storeTtlMs\n : DEFAULT_STORE_TTL_MS;\n const delegationTimeoutMs =\n typeof config.delegationTimeoutMs === 'number' &&\n Number.isFinite(config.delegationTimeoutMs) &&\n config.delegationTimeoutMs > 0\n ? config.delegationTimeoutMs\n : DEFAULT_DELEGATION_TIMEOUT_MS;\n const collapseKey =\n typeof config.collapseKey === 'string' && config.collapseKey.trim()\n ? config.collapseKey.trim().toLowerCase() === COLLAPSE_KEY_OFF\n ? COLLAPSE_KEY_OFF\n : config.collapseKey.trim()\n : DEFAULT_COLLAPSE_KEY;\n\n return { maxWidgetLines, storeTtlMs, collapseKey, delegationTimeoutMs };\n}\n\n/** Rows the overlay may use for content, clamped to a sane range. */\nexport function getMaxWidgetLines(env: NodeJS.ProcessEnv = process.env): number {\n const raw = Number.parseInt(env[MAX_WIDGET_LINES_ENV] ?? '', 10);\n if (!Number.isFinite(raw)) return DEFAULT_MAX_WIDGET_LINES;\n return Math.min(Math.max(raw, MIN_WIDGET_LINES), MAX_WIDGET_LINES);\n}\n\n/** Retention window for inactive session-tree stores. */\nexport function getStoreTtlMs(env: NodeJS.ProcessEnv = process.env): number {\n const raw = Number(env[STORE_TTL_MS_ENV]);\n return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_STORE_TTL_MS;\n}\n\n/** How long a delegated run may go without reporting a result. */\nexport function getDelegationTimeoutMs(env: NodeJS.ProcessEnv = process.env): number {\n const raw = Number(env[DELEGATION_TIMEOUT_MS_ENV]);\n return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_DELEGATION_TIMEOUT_MS;\n}\n\n/** Collapse shortcut, or the `off` sentinel when the user disabled it. */\nexport function resolveCollapseKey(env: NodeJS.ProcessEnv = process.env): string {\n const configured = env[COLLAPSE_KEY_ENV]?.trim();\n if (!configured) return DEFAULT_COLLAPSE_KEY;\n return configured.toLowerCase() === COLLAPSE_KEY_OFF ? COLLAPSE_KEY_OFF : configured;\n}\n"],"mappings":"mEAQA,MACa,EAAmB,yBACnB,EAAmB,yBACnB,EAA4B,kCAG5B,EAAuB,eACvB,EAAuB,OAGvB,EAAgC,KAa7C,SAAS,EAAa,EAAyC,CAC7D,OAAyB,OAAO,GAAU,UAAnC,GAA+C,CAAC,MAAM,QAAQ,CAAK,EAAK,EAAoC,CAAC,CACtH,CAGA,SAAgB,EAAkB,EAA8B,CAC9D,IAAM,EAAS,EAAa,CAAK,EAC3B,EACJ,OAAO,EAAO,gBAAmB,UAAY,OAAO,SAAS,EAAO,cAAc,EAC9E,KAAK,IAAI,KAAK,IAAI,EAAO,eAAgB,CAAgB,EAAG,EAAgB,EAAA,GAE5E,EACJ,OAAO,EAAO,YAAe,UAAY,OAAO,SAAS,EAAO,UAAU,GAAK,EAAO,WAAa,EAC/F,EAAO,WACP,EACA,EACJ,OAAO,EAAO,qBAAwB,UACtC,OAAO,SAAS,EAAO,mBAAmB,GAC1C,EAAO,oBAAsB,EACzB,EAAO,oBACP,EAQN,MAAO,CAAE,iBAAgB,aAAY,YANnC,OAAO,EAAO,aAAgB,UAAY,EAAO,YAAY,KAAK,EAC9D,EAAO,YAAY,KAAK,CAAC,CAAC,YAAY,IAAA,MAAA,MAEpC,EAAO,YAAY,KAAK,EAC1B,EAE4C,qBAAoB,CACxE,CAGA,SAAgB,EAAkB,EAAyB,QAAQ,IAAa,CAC9E,IAAM,EAAM,OAAO,SAAS,EAAA,4BAA6B,GAAI,EAAE,EAE/D,OADK,OAAO,SAAS,CAAG,EACjB,KAAK,IAAI,KAAK,IAAI,EAAK,CAAgB,EAAG,EAAgB,EADtC,EAE7B,CAGA,SAAgB,EAAc,EAAyB,QAAQ,IAAa,CAC1E,IAAM,EAAM,OAAO,EAAI,EAAiB,EACxC,OAAO,OAAO,SAAS,CAAG,GAAK,EAAM,EAAI,EAAM,CACjD,CAGA,SAAgB,EAAuB,EAAyB,QAAQ,IAAa,CACnF,IAAM,EAAM,OAAO,EAAI,EAA0B,EACjD,OAAO,OAAO,SAAS,CAAG,GAAK,EAAM,EAAI,EAAM,CACjD,CAGA,SAAgB,EAAmB,EAAyB,QAAQ,IAAa,CAC/E,IAAM,EAAa,EAAI,EAAiB,EAAE,KAAK,EAE/C,OADK,EACE,EAAW,YAAY,IAAA,MAAA,MAA4C,EADlD,CAE1B"}
|
package/dist/config.d.cts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"mappings":";;;;;;;;cAQa;cACA;cACA;cACA;cAEA;cACA;cACA;;;cAGA;cACA;UAKI;EACf;EACA;EACA;EACA;;;iBAQc,kBAAkB,iBAAiB;;iBA2BnC,kBAAkB,MAAK,OAAO;;iBAO9B,cAAc,MAAK,OAAO;;iBAM1B,uBAAuB,MAAK,OAAO;;iBAMnC,mBAAmB,MAAK,OAAO"}
|
package/dist/config.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config.ts"],"mappings":";;;;;;;;cAQa;cACA;cACA;cACA;cAEA;cACA;cACA;;;cAGA;cACA;UAKI;EACf;EACA;EACA;EACA;;;iBAQc,kBAAkB,iBAAiB;;iBA2BnC,kBAAkB,MAAK,OAAO;;iBAO9B,cAAc,MAAK,OAAO;;iBAM1B,uBAAuB,MAAK,OAAO;;iBAMnC,mBAAmB,MAAK,OAAO"}
|
package/dist/config.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["/**\n * Extension configuration, read from the environment.\n *\n * Env rather than a config file: doom-pi already carries per-launch state to Pi\n * through env vars, so this keeps doom-task consistent with how the harness\n * configures the rest of the extension set.\n */\n\nexport const MAX_WIDGET_LINES_ENV = 'DOOM_TASK_MAX_WIDGET_LINES';\nexport const COLLAPSE_KEY_ENV = 'DOOM_TASK_COLLAPSE_KEY';\nexport const STORE_TTL_MS_ENV = 'DOOM_TASK_STORE_TTL_MS';\nexport const DELEGATION_TIMEOUT_MS_ENV = 'DOOM_TASK_DELEGATION_TIMEOUT_MS';\n\nexport const DEFAULT_MAX_WIDGET_LINES = 12;\nexport const DEFAULT_COLLAPSE_KEY = 'ctrl+shift+t';\nexport const DEFAULT_STORE_TTL_MS = 30 * 24 * 60 * 60 * 1000;\n/** Deliberately under the subagents auto-drain ceiling (30 min) so a headless\n * session still gets the failure and a model turn before draining gives up. */\nexport const DEFAULT_DELEGATION_TIMEOUT_MS = 20 * 60 * 1000;\nexport const COLLAPSE_KEY_OFF = 'off';\n\nconst MIN_WIDGET_LINES = 3;\nconst MAX_WIDGET_LINES = 60;\n\nexport interface PiTaskConfig {\n maxWidgetLines: number;\n storeTtlMs: number;\n collapseKey: string;\n delegationTimeoutMs: number;\n}\n\nfunction configRecord(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\n/** Parse configuration only after the Pi host has applied its project-trust policy. */\nexport function parsePiTaskConfig(value: unknown): PiTaskConfig {\n const config = configRecord(value);\n const maxWidgetLines =\n typeof config.maxWidgetLines === 'number' && Number.isFinite(config.maxWidgetLines)\n ? Math.min(Math.max(config.maxWidgetLines, MIN_WIDGET_LINES), MAX_WIDGET_LINES)\n : DEFAULT_MAX_WIDGET_LINES;\n const storeTtlMs =\n typeof config.storeTtlMs === 'number' && Number.isFinite(config.storeTtlMs) && config.storeTtlMs > 0\n ? config.storeTtlMs\n : DEFAULT_STORE_TTL_MS;\n const delegationTimeoutMs =\n typeof config.delegationTimeoutMs === 'number' &&\n Number.isFinite(config.delegationTimeoutMs) &&\n config.delegationTimeoutMs > 0\n ? config.delegationTimeoutMs\n : DEFAULT_DELEGATION_TIMEOUT_MS;\n const collapseKey =\n typeof config.collapseKey === 'string' && config.collapseKey.trim()\n ? config.collapseKey.trim().toLowerCase() === COLLAPSE_KEY_OFF\n ? COLLAPSE_KEY_OFF\n : config.collapseKey.trim()\n : DEFAULT_COLLAPSE_KEY;\n\n return { maxWidgetLines, storeTtlMs, collapseKey, delegationTimeoutMs };\n}\n\n/** Rows the overlay may use for content, clamped to a sane range. */\nexport function getMaxWidgetLines(env: NodeJS.ProcessEnv = process.env): number {\n const raw = Number.parseInt(env[MAX_WIDGET_LINES_ENV] ?? '', 10);\n if (!Number.isFinite(raw)) return DEFAULT_MAX_WIDGET_LINES;\n return Math.min(Math.max(raw, MIN_WIDGET_LINES), MAX_WIDGET_LINES);\n}\n\n/** Retention window for inactive session-tree stores. */\nexport function getStoreTtlMs(env: NodeJS.ProcessEnv = process.env): number {\n const raw = Number(env[STORE_TTL_MS_ENV]);\n return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_STORE_TTL_MS;\n}\n\n/** How long a delegated run may go without reporting a result. */\nexport function getDelegationTimeoutMs(env: NodeJS.ProcessEnv = process.env): number {\n const raw = Number(env[DELEGATION_TIMEOUT_MS_ENV]);\n return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_DELEGATION_TIMEOUT_MS;\n}\n\n/** Collapse shortcut, or the `off` sentinel when the user disabled it. */\nexport function resolveCollapseKey(env: NodeJS.ProcessEnv = process.env): string {\n const configured = env[COLLAPSE_KEY_ENV]?.trim();\n if (!configured) return DEFAULT_COLLAPSE_KEY;\n return configured.toLowerCase() === COLLAPSE_KEY_OFF ? COLLAPSE_KEY_OFF : configured;\n}\n"],"mappings":"AAQA,MAAa,EAAuB,6BACvB,EAAmB,yBACnB,EAAmB,yBACnB,EAA4B,kCAE5B,EAA2B,GAC3B,EAAuB,eACvB,EAAuB,OAGvB,EAAgC,KAChC,EAAmB,MAYhC,SAAS,EAAa,EAAyC,CAC7D,OAAyB,OAAO,GAAU,UAAnC,GAA+C,CAAC,MAAM,QAAQ,CAAK,EAAK,EAAoC,CAAC,CACtH,CAGA,SAAgB,EAAkB,EAA8B,CAC9D,IAAM,EAAS,EAAa,CAAK,EAC3B,EACJ,OAAO,EAAO,gBAAmB,UAAY,OAAO,SAAS,EAAO,cAAc,EAC9E,KAAK,IAAI,KAAK,IAAI,EAAO,eAAgB,CAAgB,EAAG,EAAgB,EAAA,GAE5E,EACJ,OAAO,EAAO,YAAe,UAAY,OAAO,SAAS,EAAO,UAAU,GAAK,EAAO,WAAa,EAC/F,EAAO,WACP,EACA,EACJ,OAAO,EAAO,qBAAwB,UACtC,OAAO,SAAS,EAAO,mBAAmB,GAC1C,EAAO,oBAAsB,EACzB,EAAO,oBACP,EAQN,MAAO,CAAE,iBAAgB,aAAY,YANnC,OAAO,EAAO,aAAgB,UAAY,EAAO,YAAY,KAAK,EAC9D,EAAO,YAAY,KAAK,CAAC,CAAC,YAAY,IAAA,MAAA,MAEpC,EAAO,YAAY,KAAK,EAC1B,EAE4C,qBAAoB,CACxE,CAGA,SAAgB,EAAkB,EAAyB,QAAQ,IAAa,CAC9E,IAAM,EAAM,OAAO,SAAS,EAAA,4BAA6B,GAAI,EAAE,EAE/D,OADK,OAAO,SAAS,CAAG,EACjB,KAAK,IAAI,KAAK,IAAI,EAAK,CAAgB,EAAG,EAAgB,EADtC,EAE7B,CAGA,SAAgB,EAAc,EAAyB,QAAQ,IAAa,CAC1E,IAAM,EAAM,OAAO,EAAI,EAAiB,EACxC,OAAO,OAAO,SAAS,CAAG,GAAK,EAAM,EAAI,EAAM,CACjD,CAGA,SAAgB,EAAuB,EAAyB,QAAQ,IAAa,CACnF,IAAM,EAAM,OAAO,EAAI,EAA0B,EACjD,OAAO,OAAO,SAAS,CAAG,GAAK,EAAM,EAAI,EAAM,CACjD,CAGA,SAAgB,EAAmB,EAAyB,QAAQ,IAAa,CAC/E,IAAM,EAAa,EAAI,EAAiB,EAAE,KAAK,EAE/C,OADK,EACE,EAAW,YAAY,IAAA,MAAA,MAA4C,EADlD,CAE1B"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../logSinkTelemetry.cjs"),n=require("../store/types.cjs"),r=require("../store/reconcile.cjs"),i=require("../store/taskGraph.cjs");let a=require("node:crypto"),o=require("node:path");o=e.__toESM(o,1);let s=require("@agimon-ai/doompi-extension-contracts/delegation"),c=require("@agimon-ai/doompi-extension-contracts/protocol");const l=`doom-task-notify`,u=`completed`,d=`failed`,f=`cancelled`,p=`task.id`,m=`delegation.request_id`,h=`delegation.agent_name`,g=`delegation.context_present`,_=`delegation.context_file_count`,v=`delegation.context_notes_length`,y=`No subagent runtime responded. Delegation needs the subagents extension — relaunch doom-pi with agents enabled.`,b=`assign is only available in the main session. Update this task directly instead of re-delegating it.`,x=`Subagent did not acknowledge the cancel request`;function S(e,t=4e3){if(e)return e.length<=t?e:`${e.slice(0,t)}\n… (truncated)`}function C(e){return e instanceof Error?e.message:String(e)}function w(e,t){if(!o.default.isAbsolute(e))return o.default.normalize(e);let n=o.default.relative(t,e);return n&&!n.startsWith(`..`)?n:e}function T(e,t){let n=new Set;for(let r of e.relevantFiles??[]){if(n.size>=12)break;let e=w(r.trim(),t);e&&e!==`.`&&n.add(e)}return{files:[...n],notes:S(e.priorFindings?.trim(),1500)}}function E(e,t,n){let r=[`Task #${e.id}: ${e.subject}`];if(e.description&&r.push(e.description),t&&r.push(t),n.files.length>0||n.notes){let e=[`Parent context — consume before repository discovery:`];n.files.length>0&&e.push(`- Parent-verified files (read these first with direct reads): ${n.files.join(`, `)}`),n.notes&&e.push(`- Established facts (do not re-derive unless direct evidence contradicts them): ${n.notes}`),e.push(`This pack satisfies initial repository/context exploration. Do not begin with repository-wide listing, find, or grep. Expand only after consuming the pack and naming a concrete missing dependency or invalid path; search narrowly for that item and state why.`),r.push(e.join(`
|
|
2
|
-
`))}return r.push(`Coordination: work directly without changing the task record; ask main through intercom only for blockers or decisions; report changed files and verification when done.`),r.join(`
|
|
3
|
-
|
|
4
|
-
`)}var D=class e{options;progress=new Map;pendingTasks=new Map;timers=new Map;subscriptions=[];protocol;constructor(e){this.options=e}now(){return this.options.now?.()??new Date().toISOString()}nowMs(){return this.options.nowMs?.()??Date.now()}get env(){return this.options.env??process.env}get runTimeoutMs(){return this.options.runTimeoutMs??12e5}report(e,t,n){this.options.report?.error(e,t,n)}get isChildSession(){return!!this.env.PI_SUBAGENT_CHILD}progressFor(e){let t=e.delegation?.requestId;return t?this.progress.get(t):void 0}static elapsedMs(e,t=Date.now()){let n=e.durationMs??0,r=e.durationObservedAt??t;return n+Math.max(0,t-r)}start(){if(this.subscriptions.length>0)return;let e=this.options.getSessionId?.();e&&(this.protocol=(0,c.createProtocolRuntime)({bus:this.options.events,source:`@agimon-ai/doompi-task`,sessionId:e}),this.subscriptions.push(this.protocol.onNotification(s.DelegationAccepted,e=>{this.handleAccepted(e)}),this.protocol.onNotification(s.DelegationStarted,e=>{this.handleStarted(e)}),this.protocol.onNotification(s.DelegationUpdated,e=>{this.handleUpdate(e)}),this.protocol.onNotification(s.DelegationFinished,e=>{this.handleResponse(e).catch(n=>{this.report(t.TASK_EVENT.delegationResponseFailed,n,{[m]:e.requestId})})})))}listActiveWork(){let e=this.options.getSessionId?.()??``;return[...this.pendingTasks.entries()].map(([t,n])=>({id:`task-${n}:${t}`,sessionId:e}))}async reconcile(){let{value:e}=await this.options.store.mutate(e=>{let t=r.reconcileOrphanedDelegations(e,this.now(),void 0,{pid:process.pid,liveRequestIds:new Set(this.pendingTasks.keys())});return t.orphaned.length===0?{value:[]}:{document:t.document,value:t.orphaned}});for(let n of e)this.options.report?.warn(t.TASK_EVENT.delegationOrphaned,Error(n.delegation?.result?.error??``),{[p]:n.id,...n.delegation?.agent?{[h]:n.delegation.agent}:{},...n.delegation?.pid===void 0?{}:{"delegation.pid":n.delegation.pid}});return e.length>0&&this.options.onChange?.(),e}async assign(e,r){let o=r.agent?.trim();if(!o)return{ok:!1,message:`agent required for assign`};if(this.isChildSession)return{ok:!1,message:b};if(r.signal?.aborted)return{ok:!1,message:`delegation cancelled before it started`};let c=(0,a.randomUUID)(),l=this.now(),f=T(r,this.options.cwd),{value:x}=await this.options.store.mutate(t=>{let a=t.tasks.findIndex(t=>t.id===e);if(a===-1)return{value:{ok:!1,message:`#${e} not found`}};let s=t.tasks[a];if(s.status===`deleted`)return{value:{ok:!1,message:`#${e} is deleted`}};if(s.status===u)return{value:{ok:!1,message:`#${e} is already completed`}};if(n.isDelegationActive(s))return{value:{ok:!1,message:`#${e} is already delegated to ${s.delegation?.agent}`}};if(i.isBlocked(t.tasks,s))return{value:{ok:!1,message:`#${e} is blocked by ${(s.blockedBy??[]).map(e=>`#${e}`).join(`, `)}`}};let d={requestId:c,agent:o,state:`requested`,pid:process.pid,startedAt:l,...this.options.getSessionId?.()?{sessionId:this.options.getSessionId()}:{},...r.model?{model:r.model}:{}},f=[...t.tasks];return f[a]={...s,owner:o,updatedAt:l,delegation:d},{document:{...t,tasks:f},value:{ok:!0,message:``,task:f[a]}}});if(!x.ok||!x.task)return{ok:!1,message:x.message};let S=f.notes?.length??0;this.pendingTasks.set(c,e),this.progress.set(c,{agent:o,contextFileCount:f.files.length,contextNotesLength:S}),this.armStartedTimeout(c);let w={requestId:c,taskId:e,agent:o,...r.inlineAgent?{inlineAgent:r.inlineAgent}:{},prompt:E(x.task,r.instructions,f),...r.context?{context:r.context}:{},cwd:this.options.cwd,artifacts:!0,timeoutMs:this.runTimeoutMs,runMode:`detached`,teamTask:{id:String(x.task.id),subject:x.task.subject},...r.model?{model:r.model}:{}};try{if(!this.protocol)throw Error(y);this.protocol.notify(s.DelegationRequested,w)}catch(n){this.report(t.TASK_EVENT.delegationRequestFailed,n,{[p]:e,[m]:c,[h]:o});let r=C(n);return await this.settle(c,d,{status:d,error:`Delegation request failed: ${r}`}),{ok:!1,message:`Could not dispatch #${e} to ${o}: ${r}`}}return this.options.report?.event(t.TASK_EVENT.delegationAssigned,{[p]:e,[m]:c,[h]:o,[g]:f.files.length>0||S>0,[_]:f.files.length,[v]:S,"delegation.brief_length":w.prompt.length}),this.options.onChange?.(),{ok:!0,message:`Delegated #${e} to ${o} in the background. It runs independently of this turn and will notify you when it finishes. Continue non-overlapping work, or end your turn.`}}async cancel(e){let t=this.options.store.read().tasks.find(t=>t.id===e);if(!t)return{ok:!1,message:`#${e} not found`};if(!t.delegation||!n.isDelegationActive(t))return{ok:!1,message:`#${e} has no running delegation`};let{requestId:r}=t.delegation;return this.protocol?.notify(s.DelegationCancelled,{requestId:r}),this.armCancelTimeout(r),{ok:!0,message:`Cancelling delegation for #${e} (${t.delegation.agent})`}}settleDetached(e,n,r,i=t.TASK_EVENT.delegationSettleFailed){this.settle(e,n,r).catch(t=>{this.report(i,t,{[m]:e})})}armStartedTimeout(e){this.armTimer(e,this.options.startedTimeoutMs??5e3,()=>{this.settleDetached(e,d,{status:d,error:y})})}armRunTimeout(e){let n=Math.min(6e4,this.runTimeoutMs);this.armTimer(e,this.runTimeoutMs+n,()=>{let n=this.pendingTasks.get(e),r=this.progress.get(e)?.agent,i=Error(`Delegation produced no result within ${this.runTimeoutMs}ms`);this.options.report?.warn(t.TASK_EVENT.delegationTimedOut,i,{...n===void 0?{}:{[p]:n},[m]:e,...r?{[h]:r}:{}}),this.protocol?.notify(s.DelegationCancelled,{requestId:e,reason:i.message}),this.settleDetached(e,d,{status:`timed_out`,error:i.message})})}armCancelTimeout(e){this.pendingTasks.has(e)&&this.armTimer(e,this.options.cancelTimeoutMs??1e4,()=>{this.settleDetached(e,f,{status:f,error:x})})}armTimer(e,t,n){this.clearTimer(e);let r=setTimeout(n,t);r.unref?.(),this.timers.set(e,r)}clearTimer(e){let t=this.timers.get(e);t&&clearTimeout(t),this.timers.delete(e)}handleAccepted(e){this.pendingTasks.has(e.requestId)&&this.armRunTimeout(e.requestId)}handleStarted(e){let{runId:n}=e,r=this.pendingTasks.get(e.requestId);if(r===void 0)return;this.armRunTimeout(e.requestId);let i=this.progress.get(e.requestId);i&&this.progress.set(e.requestId,{...i,durationMs:i.durationMs??0,durationObservedAt:i.durationObservedAt??this.nowMs()}),this.options.store.mutate(t=>this.patchDelegation(t,e.requestId,(e,t)=>({...e,status:e.status===u?e.status:`in_progress`,delegation:{...t,state:`running`,startedAt:t.startedAt??this.now(),...n?{runId:n}:{}}}))).then(()=>this.options.onChange?.()).catch(n=>{this.report(t.TASK_EVENT.delegationStartFailed,n,{[p]:r,[m]:e.requestId})})}handleUpdate(t){let n=this.progress.get(t.requestId);if(!n)return;let r=this.nowMs(),i=e.elapsedMs(n,r),a=t.durationMs!==void 0;this.progress.set(t.requestId,{...n,currentTool:t.currentTool??n.currentTool,toolCount:t.toolCount===void 0?n.toolCount:Math.max(n.toolCount??0,t.toolCount),tokens:t.tokens===void 0?n.tokens:Math.max(n.tokens??0,t.tokens),durationMs:a?Math.max(i,t.durationMs):n.durationMs,durationObservedAt:a?r:n.durationObservedAt}),this.options.onChange?.()}async handleResponse(e){if(!this.pendingTasks.has(e.requestId))return;let t=e.status===u&&!e.error?u:e.status===f?f:d;await this.settle(e.requestId,t,{status:e.status,error:e.error,output:S(e.output),outputPath:e.outputPath,sessionFile:e.sessionFile,durationMs:e.durationMs,toolCount:e.toolCount})}async settle(e,n,r){let a=this.pendingTasks.get(e);if(a===void 0)return;this.pendingTasks.delete(e),this.clearTimer(e);let o=this.progress.get(e);this.progress.delete(e);let s=this.now(),c;try{let{value:t}=await this.options.store.mutate(t=>this.patchDelegation(t,e,(e,t)=>({...e,status:n===u?u:n===f?`pending`:d,updatedAt:s,delegation:{...t,state:n,endedAt:s,...r?{result:r}:{}}})));c=t}catch(n){this.report(t.TASK_EVENT.delegationSettleFailed,n,{[p]:a,[m]:e})}this.options.onChange?.();let l=c?.delegation?.agent??o?.agent??`subagent`,y=c?.subject??`#${a}`;this.options.report?.event(t.TASK_EVENT.delegationCompleted,{[p]:a,[m]:e,[h]:l,"delegation.outcome":n,[g]:(o?.contextFileCount??0)>0||(o?.contextNotesLength??0)>0,[_]:o?.contextFileCount??0,[v]:o?.contextNotesLength??0,...r?.toolCount===void 0?{}:{"delegation.tool_count":r.toolCount},...r?.durationMs===void 0?{}:{"delegation.duration_ms":r.durationMs}});let b=n===u&&c!==void 0&&i.isTaskListComplete(this.options.store.snapshot.tasks);this.notifyModel(n,a,y,l,r,b)}notifyModel(e,t,n,r,i,a){let o=this.options.notify;if(!o)return;let s=[e===u?`Subagent ${r} completed task #${t}: ${n}`:e===f?`Subagent ${r} was cancelled on task #${t}: ${n} (returned to pending)`:`Subagent ${r} failed task #${t}: ${n}`];a&&s.push(``,`All tasks are completed. Review the full task list once more, then close it with task {"action":"clear"}.`),i?.error&&s.push(`Error: ${i.error}`),i?.output&&s.push(``,i.output),i?.outputPath&&s.push(``,`Full output: ${i.outputPath}`);try{o({customType:l,content:s.join(`
|
|
5
|
-
`),display:!0},{triggerTurn:!0,deliverAs:`steer`})}catch(e){this.options.onNotifyError(e,t)}}patchDelegation(e,t,r){let i=e.tasks.findIndex(e=>e.delegation?.requestId===t);if(i===-1)return{value:void 0};let a=e.tasks[i];if(!n.isDelegationActive(a))return{value:a};let o=r(a,a.delegation);if(o===a)return{value:a};let s=[...e.tasks];return s[i]=o,{document:{...e,tasks:s},value:o}}dispose(){for(let e of this.subscriptions)e();this.subscriptions.length=0,this.protocol=void 0;for(let e of this.timers.values())clearTimeout(e);this.timers.clear(),this.pendingTasks.clear(),this.progress.clear()}};exports.BACKGROUND_WORK_PROVIDER=`doom-task`,exports.DelegationManager=D,exports.ERR_CANCEL_UNACKNOWLEDGED=x,exports.ERR_CHILD_SESSION=b,exports.ERR_NO_RUNTIME=y,exports.MAX_BRIEF_FILES=12,exports.NOTIFY_CUSTOM_TYPE=l;
|
|
6
|
-
//# sourceMappingURL=manager.cjs.map
|