@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.cjs","names":[],"sources":["../../src/tui/selectors.ts"],"sourcesContent":["import type { Task } from '../
|
|
1
|
+
{"version":3,"file":"selectors.cjs","names":["canonicalizeTasks"],"sources":["../../src/tui/selectors.ts"],"sourcesContent":["import type { Task } from '../models/task';\nimport { canonicalizeTasks } from '../services/invariants';\n\nexport interface TaskCounts {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n failed: number;\n blocked: number;\n}\n\nexport interface TaskGroups {\n inProgress: Task[];\n blocked: Task[];\n pending: Task[];\n completed: Task[];\n failed: Task[];\n}\n\nexport interface TaskProjection {\n visible: Task[];\n counts: TaskCounts;\n groups: TaskGroups;\n showIds: boolean;\n hasActiveWork: boolean;\n}\n\nexport function visibleTasks(tasks: readonly Task[]): Task[] {\n return canonicalizeTasks(tasks).filter((task) => task.status !== 'deleted');\n}\n\nfunction indexStatuses(tasks: readonly Task[]): Map<number, Task['status']> {\n return new Map(tasks.map((task) => [task.id, task.status]));\n}\n\nfunction hasUnresolvedBlocker(task: Task, statuses: ReadonlyMap<number, Task['status']>): boolean {\n return (\n task.blockedBy?.some((id) => {\n const status = statuses.get(id);\n return status !== undefined && status !== 'completed' && status !== 'deleted';\n }) ?? false\n );\n}\n\n/**\n * Derive all overlay-facing state in O(tasks + dependency edges).\n *\n * The id index replaces one full task-list scan per dependency, while the\n * ordered pass keeps group ordering identical to the source document.\n */\nexport function deriveTaskProjection(tasks: readonly Task[]): TaskProjection {\n const canonical = canonicalizeTasks(tasks);\n const statuses = indexStatuses(canonical);\n const visible: Task[] = [];\n const counts: TaskCounts = { total: 0, completed: 0, inProgress: 0, pending: 0, failed: 0, blocked: 0 };\n const groups: TaskGroups = { inProgress: [], blocked: [], pending: [], completed: [], failed: [] };\n let showIds = false;\n\n for (const task of canonical) {\n if (task.status === 'deleted') continue;\n\n visible.push(task);\n counts.total += 1;\n showIds ||= Boolean(task.blockedBy?.length);\n\n switch (task.status) {\n case 'in_progress':\n counts.inProgress += 1;\n groups.inProgress.push(task);\n break;\n case 'pending': {\n counts.pending += 1;\n if (hasUnresolvedBlocker(task, statuses)) {\n counts.blocked += 1;\n groups.blocked.push(task);\n } else {\n groups.pending.push(task);\n }\n break;\n }\n case 'failed':\n counts.failed += 1;\n groups.failed.push(task);\n break;\n case 'completed':\n counts.completed += 1;\n groups.completed.push(task);\n break;\n }\n }\n\n return { visible, counts, groups, showIds, hasActiveWork: counts.inProgress > 0 };\n}\n\nexport function countTasks(tasks: readonly Task[]): TaskCounts {\n return deriveTaskProjection(tasks).counts;\n}\n\n/**\n * Group tasks for display.\n *\n * Blocked tasks split out of `pending` because a reader scanning the overlay\n * needs to know at a glance what is actually actionable right now.\n */\nexport function groupTasks(tasks: readonly Task[]): TaskGroups {\n return deriveTaskProjection(tasks).groups;\n}\n\n/** Ids are only worth the visual noise once dependencies are in play. */\nexport function shouldShowIds(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status !== 'deleted' && Boolean(task.blockedBy?.length));\n}\n\nexport function hasActiveWork(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status === 'in_progress');\n}\n\nexport interface OverlayLayout {\n visible: Task[];\n hiddenCompleted: number;\n truncatedTail: number;\n}\n\n/**\n * Choose which rows fit the overlay budget.\n *\n * Active work wins limited space: in-progress first, then failed, blocked, and\n * pending. Selected rows are always returned in source order, however, so a\n * status update does not reshuffle an otherwise unchanged overlay.\n */\nexport function selectOverlayLayoutFromProjection(projection: TaskProjection, budget: number): OverlayLayout {\n const { groups, visible: sourceOrder } = projection;\n const active = [...groups.inProgress, ...groups.failed, ...groups.blocked, ...groups.pending];\n if (budget <= 0) {\n return {\n visible: [],\n hiddenCompleted: groups.completed.length,\n truncatedTail: active.length,\n };\n }\n if (sourceOrder.length <= budget) {\n return { visible: sourceOrder, hiddenCompleted: 0, truncatedTail: 0 };\n }\n\n if (active.length <= budget) {\n const remaining = budget - active.length;\n const shownCompleted = groups.completed.slice(0, remaining);\n const selected = new Set([...active, ...shownCompleted]);\n return {\n visible: sourceOrder.filter((task) => selected.has(task)),\n hiddenCompleted: groups.completed.length - shownCompleted.length,\n truncatedTail: 0,\n };\n }\n\n const selected = new Set(active.slice(0, budget));\n return {\n visible: sourceOrder.filter((task) => selected.has(task)),\n hiddenCompleted: groups.completed.length,\n truncatedTail: active.length - budget,\n };\n}\n\nexport function selectOverlayLayout(tasks: readonly Task[], budget: number): OverlayLayout {\n return selectOverlayLayoutFromProjection(deriveTaskProjection(tasks), budget);\n}\n"],"mappings":"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"}
|
package/dist/tui/selectors.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Task } from "../
|
|
1
|
+
import { Task } from "../models/task.cjs";
|
|
2
2
|
//#region src/tui/selectors.d.ts
|
|
3
|
-
interface TaskCounts {
|
|
3
|
+
export interface TaskCounts {
|
|
4
4
|
total: number;
|
|
5
5
|
completed: number;
|
|
6
6
|
inProgress: number;
|
|
@@ -8,46 +8,52 @@ interface TaskCounts {
|
|
|
8
8
|
failed: number;
|
|
9
9
|
blocked: number;
|
|
10
10
|
}
|
|
11
|
-
interface TaskGroups {
|
|
11
|
+
export interface TaskGroups {
|
|
12
12
|
inProgress: Task[];
|
|
13
13
|
blocked: Task[];
|
|
14
14
|
pending: Task[];
|
|
15
15
|
completed: Task[];
|
|
16
16
|
failed: Task[];
|
|
17
17
|
}
|
|
18
|
-
interface TaskProjection {
|
|
18
|
+
export interface TaskProjection {
|
|
19
19
|
visible: Task[];
|
|
20
20
|
counts: TaskCounts;
|
|
21
21
|
groups: TaskGroups;
|
|
22
22
|
showIds: boolean;
|
|
23
23
|
hasActiveWork: boolean;
|
|
24
24
|
}
|
|
25
|
-
declare function visibleTasks(tasks: readonly Task[]): Task[];
|
|
25
|
+
export declare function visibleTasks(tasks: readonly Task[]): Task[];
|
|
26
26
|
/**
|
|
27
27
|
* Derive all overlay-facing state in O(tasks + dependency edges).
|
|
28
28
|
*
|
|
29
29
|
* The id index replaces one full task-list scan per dependency, while the
|
|
30
30
|
* ordered pass keeps group ordering identical to the source document.
|
|
31
31
|
*/
|
|
32
|
-
declare function deriveTaskProjection(tasks: readonly Task[]): TaskProjection;
|
|
33
|
-
declare function countTasks(tasks: readonly Task[]): TaskCounts;
|
|
32
|
+
export declare function deriveTaskProjection(tasks: readonly Task[]): TaskProjection;
|
|
33
|
+
export declare function countTasks(tasks: readonly Task[]): TaskCounts;
|
|
34
34
|
/**
|
|
35
35
|
* Group tasks for display.
|
|
36
36
|
*
|
|
37
37
|
* Blocked tasks split out of `pending` because a reader scanning the overlay
|
|
38
38
|
* needs to know at a glance what is actually actionable right now.
|
|
39
39
|
*/
|
|
40
|
-
declare function groupTasks(tasks: readonly Task[]): TaskGroups;
|
|
40
|
+
export declare function groupTasks(tasks: readonly Task[]): TaskGroups;
|
|
41
41
|
/** Ids are only worth the visual noise once dependencies are in play. */
|
|
42
|
-
declare function shouldShowIds(tasks: readonly Task[]): boolean;
|
|
43
|
-
declare function hasActiveWork(tasks: readonly Task[]): boolean;
|
|
44
|
-
interface OverlayLayout {
|
|
42
|
+
export declare function shouldShowIds(tasks: readonly Task[]): boolean;
|
|
43
|
+
export declare function hasActiveWork(tasks: readonly Task[]): boolean;
|
|
44
|
+
export interface OverlayLayout {
|
|
45
45
|
visible: Task[];
|
|
46
46
|
hiddenCompleted: number;
|
|
47
47
|
truncatedTail: number;
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Choose which rows fit the overlay budget.
|
|
51
|
+
*
|
|
52
|
+
* Active work wins limited space: in-progress first, then failed, blocked, and
|
|
53
|
+
* pending. Selected rows are always returned in source order, however, so a
|
|
54
|
+
* status update does not reshuffle an otherwise unchanged overlay.
|
|
55
|
+
*/
|
|
56
|
+
export declare function selectOverlayLayoutFromProjection(projection: TaskProjection, budget: number): OverlayLayout;
|
|
57
|
+
export declare function selectOverlayLayout(tasks: readonly Task[], budget: number): OverlayLayout;
|
|
51
58
|
//#endregion
|
|
52
|
-
export { OverlayLayout, TaskCounts, TaskGroups, TaskProjection, countTasks, deriveTaskProjection, groupTasks, hasActiveWork, selectOverlayLayout, selectOverlayLayoutFromProjection, shouldShowIds, visibleTasks };
|
|
53
59
|
//# sourceMappingURL=selectors.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.d.cts","names":[],"sources":["../../src/tui/selectors.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"selectors.d.cts","names":[],"sources":["../../src/tui/selectors.ts"],"mappings":";;iBAGiB;EACf;EACA;EACA;EACA;EACA;EACA;;iBAGe;EACf,YAAY;EACZ,SAAS;EACT,SAAS;EACT,WAAW;EACX,QAAQ;;iBAGO;EACf,SAAS;EACT,QAAQ;EACR,QAAQ;EACR;EACA;;wBAGc,aAAa,gBAAgB,SAAS;;;;;;;wBAuBtC,qBAAqB,gBAAgB,SAAS;wBA4C9C,WAAW,gBAAgB,SAAS;;;;;;;wBAUpC,WAAW,gBAAgB,SAAS;;wBAKpC,cAAc,gBAAgB;wBAI9B,cAAc,gBAAgB;iBAI7B;EACf,SAAS;EACT;EACA;;;;;;;;;wBAUc,kCAAkC,YAAY,gBAAgB,iBAAiB;wBAiC/E,oBAAoB,gBAAgB,QAAQ,iBAAiB"}
|
package/dist/tui/selectors.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Task } from "../
|
|
1
|
+
import { Task } from "../models/task.mjs";
|
|
2
2
|
//#region src/tui/selectors.d.ts
|
|
3
|
-
interface TaskCounts {
|
|
3
|
+
export interface TaskCounts {
|
|
4
4
|
total: number;
|
|
5
5
|
completed: number;
|
|
6
6
|
inProgress: number;
|
|
@@ -8,46 +8,52 @@ interface TaskCounts {
|
|
|
8
8
|
failed: number;
|
|
9
9
|
blocked: number;
|
|
10
10
|
}
|
|
11
|
-
interface TaskGroups {
|
|
11
|
+
export interface TaskGroups {
|
|
12
12
|
inProgress: Task[];
|
|
13
13
|
blocked: Task[];
|
|
14
14
|
pending: Task[];
|
|
15
15
|
completed: Task[];
|
|
16
16
|
failed: Task[];
|
|
17
17
|
}
|
|
18
|
-
interface TaskProjection {
|
|
18
|
+
export interface TaskProjection {
|
|
19
19
|
visible: Task[];
|
|
20
20
|
counts: TaskCounts;
|
|
21
21
|
groups: TaskGroups;
|
|
22
22
|
showIds: boolean;
|
|
23
23
|
hasActiveWork: boolean;
|
|
24
24
|
}
|
|
25
|
-
declare function visibleTasks(tasks: readonly Task[]): Task[];
|
|
25
|
+
export declare function visibleTasks(tasks: readonly Task[]): Task[];
|
|
26
26
|
/**
|
|
27
27
|
* Derive all overlay-facing state in O(tasks + dependency edges).
|
|
28
28
|
*
|
|
29
29
|
* The id index replaces one full task-list scan per dependency, while the
|
|
30
30
|
* ordered pass keeps group ordering identical to the source document.
|
|
31
31
|
*/
|
|
32
|
-
declare function deriveTaskProjection(tasks: readonly Task[]): TaskProjection;
|
|
33
|
-
declare function countTasks(tasks: readonly Task[]): TaskCounts;
|
|
32
|
+
export declare function deriveTaskProjection(tasks: readonly Task[]): TaskProjection;
|
|
33
|
+
export declare function countTasks(tasks: readonly Task[]): TaskCounts;
|
|
34
34
|
/**
|
|
35
35
|
* Group tasks for display.
|
|
36
36
|
*
|
|
37
37
|
* Blocked tasks split out of `pending` because a reader scanning the overlay
|
|
38
38
|
* needs to know at a glance what is actually actionable right now.
|
|
39
39
|
*/
|
|
40
|
-
declare function groupTasks(tasks: readonly Task[]): TaskGroups;
|
|
40
|
+
export declare function groupTasks(tasks: readonly Task[]): TaskGroups;
|
|
41
41
|
/** Ids are only worth the visual noise once dependencies are in play. */
|
|
42
|
-
declare function shouldShowIds(tasks: readonly Task[]): boolean;
|
|
43
|
-
declare function hasActiveWork(tasks: readonly Task[]): boolean;
|
|
44
|
-
interface OverlayLayout {
|
|
42
|
+
export declare function shouldShowIds(tasks: readonly Task[]): boolean;
|
|
43
|
+
export declare function hasActiveWork(tasks: readonly Task[]): boolean;
|
|
44
|
+
export interface OverlayLayout {
|
|
45
45
|
visible: Task[];
|
|
46
46
|
hiddenCompleted: number;
|
|
47
47
|
truncatedTail: number;
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Choose which rows fit the overlay budget.
|
|
51
|
+
*
|
|
52
|
+
* Active work wins limited space: in-progress first, then failed, blocked, and
|
|
53
|
+
* pending. Selected rows are always returned in source order, however, so a
|
|
54
|
+
* status update does not reshuffle an otherwise unchanged overlay.
|
|
55
|
+
*/
|
|
56
|
+
export declare function selectOverlayLayoutFromProjection(projection: TaskProjection, budget: number): OverlayLayout;
|
|
57
|
+
export declare function selectOverlayLayout(tasks: readonly Task[], budget: number): OverlayLayout;
|
|
51
58
|
//#endregion
|
|
52
|
-
export { OverlayLayout, TaskCounts, TaskGroups, TaskProjection, countTasks, deriveTaskProjection, groupTasks, hasActiveWork, selectOverlayLayout, selectOverlayLayoutFromProjection, shouldShowIds, visibleTasks };
|
|
53
59
|
//# sourceMappingURL=selectors.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.d.mts","names":[],"sources":["../../src/tui/selectors.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"selectors.d.mts","names":[],"sources":["../../src/tui/selectors.ts"],"mappings":";;iBAGiB;EACf;EACA;EACA;EACA;EACA;EACA;;iBAGe;EACf,YAAY;EACZ,SAAS;EACT,SAAS;EACT,WAAW;EACX,QAAQ;;iBAGO;EACf,SAAS;EACT,QAAQ;EACR,QAAQ;EACR;EACA;;wBAGc,aAAa,gBAAgB,SAAS;;;;;;;wBAuBtC,qBAAqB,gBAAgB,SAAS;wBA4C9C,WAAW,gBAAgB,SAAS;;;;;;;wBAUpC,WAAW,gBAAgB,SAAS;;wBAKpC,cAAc,gBAAgB;wBAI9B,cAAc,gBAAgB;iBAI7B;EACf,SAAS;EACT;EACA;;;;;;;;;wBAUc,kCAAkC,YAAY,gBAAgB,iBAAiB;wBAiC/E,oBAAoB,gBAAgB,QAAQ,iBAAiB"}
|
package/dist/tui/selectors.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function
|
|
1
|
+
import{canonicalizeTasks as e}from"../services/invariants/index.mjs";function t(t){return e(t).filter(e=>e.status!==`deleted`)}function n(e){return new Map(e.map(e=>[e.id,e.status]))}function r(e,t){return e.blockedBy?.some(e=>{let n=t.get(e);return n!==void 0&&n!==`completed`&&n!==`deleted`})??!1}function i(t){let i=e(t),a=n(i),o=[],s={total:0,completed:0,inProgress:0,pending:0,failed:0,blocked:0},c={inProgress:[],blocked:[],pending:[],completed:[],failed:[]},l=!1;for(let e of i)if(e.status!==`deleted`)switch(o.push(e),s.total+=1,l||=!!e.blockedBy?.length,e.status){case`in_progress`:s.inProgress+=1,c.inProgress.push(e);break;case`pending`:s.pending+=1,r(e,a)?(s.blocked+=1,c.blocked.push(e)):c.pending.push(e);break;case`failed`:s.failed+=1,c.failed.push(e);break;case`completed`:s.completed+=1,c.completed.push(e)}return{visible:o,counts:s,groups:c,showIds:l,hasActiveWork:s.inProgress>0}}function a(e){return i(e).counts}function o(e){return i(e).groups}function s(e){return e.some(e=>e.status!==`deleted`&&!!e.blockedBy?.length)}function c(e){return e.some(e=>e.status===`in_progress`)}function l(e,t){let{groups:n,visible:r}=e,i=[...n.inProgress,...n.failed,...n.blocked,...n.pending];if(t<=0)return{visible:[],hiddenCompleted:n.completed.length,truncatedTail:i.length};if(r.length<=t)return{visible:r,hiddenCompleted:0,truncatedTail:0};if(i.length<=t){let e=t-i.length,a=n.completed.slice(0,e),o=new Set([...i,...a]);return{visible:r.filter(e=>o.has(e)),hiddenCompleted:n.completed.length-a.length,truncatedTail:0}}let a=new Set(i.slice(0,t));return{visible:r.filter(e=>a.has(e)),hiddenCompleted:n.completed.length,truncatedTail:i.length-t}}function u(e,t){return l(i(e),t)}export{a as countTasks,i as deriveTaskProjection,o as groupTasks,c as hasActiveWork,u as selectOverlayLayout,l as selectOverlayLayoutFromProjection,s as shouldShowIds,t as visibleTasks};
|
|
2
2
|
//# sourceMappingURL=selectors.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.mjs","names":[],"sources":["../../src/tui/selectors.ts"],"sourcesContent":["import type { Task } from '../
|
|
1
|
+
{"version":3,"file":"selectors.mjs","names":[],"sources":["../../src/tui/selectors.ts"],"sourcesContent":["import type { Task } from '../models/task';\nimport { canonicalizeTasks } from '../services/invariants';\n\nexport interface TaskCounts {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n failed: number;\n blocked: number;\n}\n\nexport interface TaskGroups {\n inProgress: Task[];\n blocked: Task[];\n pending: Task[];\n completed: Task[];\n failed: Task[];\n}\n\nexport interface TaskProjection {\n visible: Task[];\n counts: TaskCounts;\n groups: TaskGroups;\n showIds: boolean;\n hasActiveWork: boolean;\n}\n\nexport function visibleTasks(tasks: readonly Task[]): Task[] {\n return canonicalizeTasks(tasks).filter((task) => task.status !== 'deleted');\n}\n\nfunction indexStatuses(tasks: readonly Task[]): Map<number, Task['status']> {\n return new Map(tasks.map((task) => [task.id, task.status]));\n}\n\nfunction hasUnresolvedBlocker(task: Task, statuses: ReadonlyMap<number, Task['status']>): boolean {\n return (\n task.blockedBy?.some((id) => {\n const status = statuses.get(id);\n return status !== undefined && status !== 'completed' && status !== 'deleted';\n }) ?? false\n );\n}\n\n/**\n * Derive all overlay-facing state in O(tasks + dependency edges).\n *\n * The id index replaces one full task-list scan per dependency, while the\n * ordered pass keeps group ordering identical to the source document.\n */\nexport function deriveTaskProjection(tasks: readonly Task[]): TaskProjection {\n const canonical = canonicalizeTasks(tasks);\n const statuses = indexStatuses(canonical);\n const visible: Task[] = [];\n const counts: TaskCounts = { total: 0, completed: 0, inProgress: 0, pending: 0, failed: 0, blocked: 0 };\n const groups: TaskGroups = { inProgress: [], blocked: [], pending: [], completed: [], failed: [] };\n let showIds = false;\n\n for (const task of canonical) {\n if (task.status === 'deleted') continue;\n\n visible.push(task);\n counts.total += 1;\n showIds ||= Boolean(task.blockedBy?.length);\n\n switch (task.status) {\n case 'in_progress':\n counts.inProgress += 1;\n groups.inProgress.push(task);\n break;\n case 'pending': {\n counts.pending += 1;\n if (hasUnresolvedBlocker(task, statuses)) {\n counts.blocked += 1;\n groups.blocked.push(task);\n } else {\n groups.pending.push(task);\n }\n break;\n }\n case 'failed':\n counts.failed += 1;\n groups.failed.push(task);\n break;\n case 'completed':\n counts.completed += 1;\n groups.completed.push(task);\n break;\n }\n }\n\n return { visible, counts, groups, showIds, hasActiveWork: counts.inProgress > 0 };\n}\n\nexport function countTasks(tasks: readonly Task[]): TaskCounts {\n return deriveTaskProjection(tasks).counts;\n}\n\n/**\n * Group tasks for display.\n *\n * Blocked tasks split out of `pending` because a reader scanning the overlay\n * needs to know at a glance what is actually actionable right now.\n */\nexport function groupTasks(tasks: readonly Task[]): TaskGroups {\n return deriveTaskProjection(tasks).groups;\n}\n\n/** Ids are only worth the visual noise once dependencies are in play. */\nexport function shouldShowIds(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status !== 'deleted' && Boolean(task.blockedBy?.length));\n}\n\nexport function hasActiveWork(tasks: readonly Task[]): boolean {\n return tasks.some((task) => task.status === 'in_progress');\n}\n\nexport interface OverlayLayout {\n visible: Task[];\n hiddenCompleted: number;\n truncatedTail: number;\n}\n\n/**\n * Choose which rows fit the overlay budget.\n *\n * Active work wins limited space: in-progress first, then failed, blocked, and\n * pending. Selected rows are always returned in source order, however, so a\n * status update does not reshuffle an otherwise unchanged overlay.\n */\nexport function selectOverlayLayoutFromProjection(projection: TaskProjection, budget: number): OverlayLayout {\n const { groups, visible: sourceOrder } = projection;\n const active = [...groups.inProgress, ...groups.failed, ...groups.blocked, ...groups.pending];\n if (budget <= 0) {\n return {\n visible: [],\n hiddenCompleted: groups.completed.length,\n truncatedTail: active.length,\n };\n }\n if (sourceOrder.length <= budget) {\n return { visible: sourceOrder, hiddenCompleted: 0, truncatedTail: 0 };\n }\n\n if (active.length <= budget) {\n const remaining = budget - active.length;\n const shownCompleted = groups.completed.slice(0, remaining);\n const selected = new Set([...active, ...shownCompleted]);\n return {\n visible: sourceOrder.filter((task) => selected.has(task)),\n hiddenCompleted: groups.completed.length - shownCompleted.length,\n truncatedTail: 0,\n };\n }\n\n const selected = new Set(active.slice(0, budget));\n return {\n visible: sourceOrder.filter((task) => selected.has(task)),\n hiddenCompleted: groups.completed.length,\n truncatedTail: active.length - budget,\n };\n}\n\nexport function selectOverlayLayout(tasks: readonly Task[], budget: number): OverlayLayout {\n return selectOverlayLayoutFromProjection(deriveTaskProjection(tasks), budget);\n}\n"],"mappings":"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"}
|
package/dist/tui/taskOverlay.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("../services/config/index.cjs"),t=require("./format.cjs"),n=require("./selectors.cjs");let r=require("@agimon-ai/doompi-ui/theme"),i=require("@earendil-works/pi-tui");const a=`doom-tasks`;var o=class{options;uiCtx;widgetRegistered=!1;tui;progressTimer;collapsed=!1;constructor(e){this.options=e}setUICtx(e){e!==this.uiCtx&&(this.uiCtx&&this.widgetRegistered&&this.uiCtx.setWidget(a,void 0),this.stopProgressTimer(),this.uiCtx=e,this.widgetRegistered=!1,this.tui=void 0)}update(){if(!this.uiCtx){this.stopProgressTimer();return}let e=n.visibleTasks(this.options.getTasks());if(e.length===0){this.widgetRegistered&&(this.uiCtx.setWidget(a,void 0),this.widgetRegistered=!1,this.tui=void 0),this.stopProgressTimer();return}if(this.widgetRegistered){this.syncProgressTimer(e),this.tui?.requestRender();return}this.uiCtx.setWidget(a,(e,t)=>(this.tui=e,{render:e=>this.renderWidget(this.uiCtx?.theme??t,e),invalidate:()=>{}}),{placement:`aboveEditor`}),this.widgetRegistered=!0,this.syncProgressTimer(e)}syncProgressTimer(e){let t=e.some(e=>e.status!==`deleted`&&e.delegation?.state===`running`);if(this.collapsed||!this.widgetRegistered||!t){this.stopProgressTimer();return}this.progressTimer||(this.progressTimer=setInterval(()=>this.tui?.requestRender(),1e3),this.progressTimer.unref?.())}stopProgressTimer(){this.progressTimer&&clearInterval(this.progressTimer),this.progressTimer=void 0}toggleCollapse(){this.collapsed=!this.collapsed,this.syncProgressTimer(this.options.getTasks()),this.tui?.requestRender(!0)}isRegistered(){return this.widgetRegistered}renderWidget(a,o){let s=n.deriveTaskProjection(this.options.getTasks());if(s.visible.length===0)return[];let c=e=>(0,i.truncateToWidth)(e,o,`…`),l=s.hasActiveWork?`accent`:`dim`,u=s.hasActiveWork?`●`:`○`,d=`Tasks (${s.counts.completed}/${s.counts.total})`;s.counts.failed>0&&(d+=` · ${s.counts.failed} failed`);let f=c(`${a.fg(l,u)} ${a.fg(l,d)}`);if(this.collapsed){let t=e.resolveCollapseKey(),n=t===`off`?`collapsed`:`${t} to expand`;return this.withTrailingSpacer([f,c(`${a.fg(`dim`,`└─`)} ${a.fg(`dim`,n)}`)])}let p=n.selectOverlayLayoutFromProjection(s,e.getMaxWidgetLines()-1),m=new Set,h=new Map;for(let e of p.visible){if(e.delegation?.state!==`running`)continue;let t=e.delegation.runId??e.delegation.requestId,n=(0,r.allocateAgentIdentityColor)(t,m);m.add(n),h.set(t,n)}let g=Date.now(),_=[f];for(let e of p.visible){let n=this.options.delegation.progressFor(e),r=e.delegation?.runId??e.delegation?.requestId;_.push(c(`${a.fg(`dim`,`├─`)} ${t.formatOverlayTaskLine(e,a,s.showIds,n,g,r?h.get(r):void 0)}`))}let v=p.hiddenCompleted+p.truncatedTail;if(v===0){let e=_.length-1;return _[e]=_[e].replace(`├─`,`└─`),this.withTrailingSpacer(_)}let y=[];p.hiddenCompleted>0&&y.push(`${p.hiddenCompleted} completed`),p.truncatedTail>0&&y.push(`${p.truncatedTail} pending`);let b=y.length>0?`+${v} more (${y.join(`, `)})`:`+${v} more`;return _.push(c(`${a.fg(`dim`,`└─`)} ${a.fg(`dim`,b)}`)),this.withTrailingSpacer(_)}withTrailingSpacer(e){return e.length===0||e.push(``),e}dispose(){this.stopProgressTimer(),this.uiCtx&&this.uiCtx.setWidget(a,void 0),this.widgetRegistered=!1,this.tui=void 0,this.uiCtx=void 0,this.collapsed=!1}};exports.TaskOverlay=o;
|
|
2
2
|
//# sourceMappingURL=taskOverlay.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taskOverlay.cjs","names":["visibleTasks","deriveTaskProjection","truncateToWidth","resolveCollapseKey","selectOverlayLayoutFromProjection","getMaxWidgetLines","formatOverlayTaskLine"],"sources":["../../src/tui/taskOverlay.ts"],"sourcesContent":["import type { ExtensionUIContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { type TUI, truncateToWidth } from '@earendil-works/pi-tui';\nimport { COLLAPSE_KEY_OFF, getMaxWidgetLines, resolveCollapseKey } from '../config.ts';\nimport type { DelegationManager } from '../delegation/manager.ts';\nimport type { Task } from '../store/types.ts';\nimport { formatOverlayTaskLine } from './format.ts';\nimport { deriveTaskProjection, selectOverlayLayoutFromProjection, visibleTasks } from './selectors.ts';\n\nconst WIDGET_KEY = 'doom-tasks';\nconst OVERLAY_HEADING = 'Tasks';\nconst PROGRESS_TICK_MS = 1000;\n\nexport interface TaskOverlayOptions {\n getTasks: () => readonly Task[];\n delegation: DelegationManager;\n}\n\n/**\n * Persistent widget listing tasks above the editor.\n *\n * Registered once per UI context and refreshed with `requestRender()`; it\n * auto-hides when there is nothing to show so an idle session keeps a clean\n * prompt.\n */\nexport class TaskOverlay {\n private readonly options: TaskOverlayOptions;\n private uiCtx: ExtensionUIContext | undefined;\n private widgetRegistered = false;\n private tui: TUI | undefined;\n private progressTimer: NodeJS.Timeout | undefined;\n private collapsed = false;\n\n constructor(options: TaskOverlayOptions) {\n this.options = options;\n }\n\n /** Identity-compare so repeated session_start handlers stay idempotent. */\n setUICtx(ctx: ExtensionUIContext): void {\n if (ctx === this.uiCtx) return;\n if (this.uiCtx && this.widgetRegistered) this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.stopProgressTimer();\n this.uiCtx = ctx;\n this.widgetRegistered = false;\n this.tui = undefined;\n }\n\n update(): void {\n if (!this.uiCtx) {\n this.stopProgressTimer();\n return;\n }\n const tasks = visibleTasks(this.options.getTasks());\n\n if (tasks.length === 0) {\n if (this.widgetRegistered) {\n this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.widgetRegistered = false;\n this.tui = undefined;\n }\n this.stopProgressTimer();\n return;\n }\n\n if (this.widgetRegistered) {\n this.syncProgressTimer(tasks);\n this.tui?.requestRender();\n return;\n }\n\n this.uiCtx.setWidget(\n WIDGET_KEY,\n (tui, factoryTheme) => {\n this.tui = tui;\n return {\n render: (width: number) => this.renderWidget(this.uiCtx?.theme ?? factoryTheme, width),\n invalidate: () => {\n // Nothing is cached: the next render reads the live theme and store.\n },\n };\n },\n { placement: 'aboveEditor' },\n );\n this.widgetRegistered = true;\n this.syncProgressTimer(tasks);\n }\n\n private syncProgressTimer(tasks: readonly Task[]): void {\n const hasRunningDelegation = tasks.some(\n (task) => task.status !== 'deleted' && task.delegation?.state === 'running',\n );\n if (this.collapsed || !this.widgetRegistered || !hasRunningDelegation) {\n this.stopProgressTimer();\n return;\n }\n if (this.progressTimer) return;\n this.progressTimer = setInterval(() => this.tui?.requestRender(), PROGRESS_TICK_MS);\n this.progressTimer.unref?.();\n }\n\n private stopProgressTimer(): void {\n if (this.progressTimer) clearInterval(this.progressTimer);\n this.progressTimer = undefined;\n }\n\n toggleCollapse(): void {\n this.collapsed = !this.collapsed;\n this.syncProgressTimer(this.options.getTasks());\n // Forced redraw: collapsing changes the widget height, not just its content.\n this.tui?.requestRender(true);\n }\n\n isRegistered(): boolean {\n return this.widgetRegistered;\n }\n\n private renderWidget(theme: Theme, width: number): string[] {\n const projection = deriveTaskProjection(this.options.getTasks());\n if (projection.visible.length === 0) return [];\n\n const truncate = (line: string): string => truncateToWidth(line, width, '…');\n const headingColor = projection.hasActiveWork ? 'accent' : 'dim';\n const headingIcon = projection.hasActiveWork ? '●' : '○';\n let headingText = `${OVERLAY_HEADING} (${projection.counts.completed}/${projection.counts.total})`;\n if (projection.counts.failed > 0) headingText += ` · ${projection.counts.failed} failed`;\n const heading = truncate(`${theme.fg(headingColor, headingIcon)} ${theme.fg(headingColor, headingText)}`);\n\n if (this.collapsed) {\n const key = resolveCollapseKey();\n const hint = key === COLLAPSE_KEY_OFF ? 'collapsed' : `${key} to expand`;\n return this.withTrailingSpacer([heading, truncate(`${theme.fg('dim', '└─')} ${theme.fg('dim', hint)}`)]);\n }\n\n const layout = selectOverlayLayoutFromProjection(projection, getMaxWidgetLines() - 1);\n const lines = [heading];\n for (const task of layout.visible) {\n const progress = this.options.delegation.progressFor(task);\n lines.push(\n truncate(`${theme.fg('dim', '├─')} ${formatOverlayTaskLine(task, theme, projection.showIds, progress)}`),\n );\n }\n\n const hidden = layout.hiddenCompleted + layout.truncatedTail;\n if (hidden === 0) {\n const last = lines.length - 1;\n lines[last] = lines[last].replace('├─', '└─');\n return this.withTrailingSpacer(lines);\n }\n\n const parts: string[] = [];\n if (layout.hiddenCompleted > 0) parts.push(`${layout.hiddenCompleted} completed`);\n if (layout.truncatedTail > 0) parts.push(`${layout.truncatedTail} pending`);\n const summary = parts.length > 0 ? `+${hidden} more (${parts.join(', ')})` : `+${hidden} more`;\n lines.push(truncate(`${theme.fg('dim', '└─')} ${theme.fg('dim', summary)}`));\n return this.withTrailingSpacer(lines);\n }\n\n /** Pi adds a spacer above the widget but none below, which glues the last row to the input box. */\n private withTrailingSpacer(lines: string[]): string[] {\n if (lines.length === 0) return lines;\n lines.push('');\n return lines;\n }\n\n dispose(): void {\n this.stopProgressTimer();\n if (this.uiCtx) this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.widgetRegistered = false;\n this.tui = undefined;\n this.uiCtx = undefined;\n this.collapsed = false;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"taskOverlay.cjs","names":["visibleTasks","deriveTaskProjection","truncateToWidth","resolveCollapseKey","selectOverlayLayoutFromProjection","getMaxWidgetLines","allocateAgentIdentityColor","formatOverlayTaskLine"],"sources":["../../src/tui/taskOverlay.ts"],"sourcesContent":["import { allocateAgentIdentityColor } from '@agimon-ai/doompi-ui/theme';\nimport type { ExtensionUIContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { type TUI, truncateToWidth } from '@earendil-works/pi-tui';\n\nimport type { Task } from '../models/task';\nimport { COLLAPSE_KEY_OFF, getMaxWidgetLines, resolveCollapseKey } from '../services/config';\nimport type { DelegationManager } from '../services/delegation';\nimport { formatOverlayTaskLine } from './format';\nimport { deriveTaskProjection, selectOverlayLayoutFromProjection, visibleTasks } from './selectors';\n\nconst WIDGET_KEY = 'doom-tasks';\nconst OVERLAY_HEADING = 'Tasks';\nconst PROGRESS_TICK_MS = 1000;\n\nexport interface TaskOverlayOptions {\n getTasks: () => readonly Task[];\n delegation: DelegationManager;\n}\n\n/**\n * Persistent widget listing tasks above the editor.\n *\n * Registered once per UI context and refreshed with `requestRender()`; it\n * auto-hides when there is nothing to show so an idle session keeps a clean\n * prompt.\n */\nexport class TaskOverlay {\n private readonly options: TaskOverlayOptions;\n private uiCtx: ExtensionUIContext | undefined;\n private widgetRegistered = false;\n private tui: TUI | undefined;\n private progressTimer: NodeJS.Timeout | undefined;\n private collapsed = false;\n\n constructor(options: TaskOverlayOptions) {\n this.options = options;\n }\n\n /** Identity-compare so repeated session_start handlers stay idempotent. */\n setUICtx(ctx: ExtensionUIContext): void {\n if (ctx === this.uiCtx) return;\n if (this.uiCtx && this.widgetRegistered) this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.stopProgressTimer();\n this.uiCtx = ctx;\n this.widgetRegistered = false;\n this.tui = undefined;\n }\n\n update(): void {\n if (!this.uiCtx) {\n this.stopProgressTimer();\n return;\n }\n const tasks = visibleTasks(this.options.getTasks());\n\n if (tasks.length === 0) {\n if (this.widgetRegistered) {\n this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.widgetRegistered = false;\n this.tui = undefined;\n }\n this.stopProgressTimer();\n return;\n }\n\n if (this.widgetRegistered) {\n this.syncProgressTimer(tasks);\n this.tui?.requestRender();\n return;\n }\n\n this.uiCtx.setWidget(\n WIDGET_KEY,\n (tui, factoryTheme) => {\n this.tui = tui;\n return {\n render: (width: number) => this.renderWidget(this.uiCtx?.theme ?? factoryTheme, width),\n invalidate: () => {\n // Nothing is cached: the next render reads the live theme and store.\n },\n };\n },\n { placement: 'aboveEditor' },\n );\n this.widgetRegistered = true;\n this.syncProgressTimer(tasks);\n }\n\n private syncProgressTimer(tasks: readonly Task[]): void {\n const hasRunningDelegation = tasks.some(\n (task) => task.status !== 'deleted' && task.delegation?.state === 'running',\n );\n if (this.collapsed || !this.widgetRegistered || !hasRunningDelegation) {\n this.stopProgressTimer();\n return;\n }\n if (this.progressTimer) return;\n this.progressTimer = setInterval(() => this.tui?.requestRender(), PROGRESS_TICK_MS);\n this.progressTimer.unref?.();\n }\n\n private stopProgressTimer(): void {\n if (this.progressTimer) clearInterval(this.progressTimer);\n this.progressTimer = undefined;\n }\n\n toggleCollapse(): void {\n this.collapsed = !this.collapsed;\n this.syncProgressTimer(this.options.getTasks());\n // Forced redraw: collapsing changes the widget height, not just its content.\n this.tui?.requestRender(true);\n }\n\n isRegistered(): boolean {\n return this.widgetRegistered;\n }\n\n private renderWidget(theme: Theme, width: number): string[] {\n const projection = deriveTaskProjection(this.options.getTasks());\n if (projection.visible.length === 0) return [];\n\n const truncate = (line: string): string => truncateToWidth(line, width, '…');\n const headingColor = projection.hasActiveWork ? 'accent' : 'dim';\n const headingIcon = projection.hasActiveWork ? '●' : '○';\n let headingText = `${OVERLAY_HEADING} (${projection.counts.completed}/${projection.counts.total})`;\n if (projection.counts.failed > 0) headingText += ` · ${projection.counts.failed} failed`;\n const heading = truncate(`${theme.fg(headingColor, headingIcon)} ${theme.fg(headingColor, headingText)}`);\n\n if (this.collapsed) {\n const key = resolveCollapseKey();\n const hint = key === COLLAPSE_KEY_OFF ? 'collapsed' : `${key} to expand`;\n return this.withTrailingSpacer([heading, truncate(`${theme.fg('dim', '└─')} ${theme.fg('dim', hint)}`)]);\n }\n\n const layout = selectOverlayLayoutFromProjection(projection, getMaxWidgetLines() - 1);\n const occupiedColors = new Set<ReturnType<typeof allocateAgentIdentityColor>>();\n const agentColors = new Map<string, ReturnType<typeof allocateAgentIdentityColor>>();\n for (const task of layout.visible) {\n if (task.delegation?.state !== 'running') continue;\n const identity = task.delegation.runId ?? task.delegation.requestId;\n const color = allocateAgentIdentityColor(identity, occupiedColors);\n occupiedColors.add(color);\n agentColors.set(identity, color);\n }\n\n const nowMs = Date.now();\n const lines = [heading];\n for (const task of layout.visible) {\n const progress = this.options.delegation.progressFor(task);\n const identity = task.delegation?.runId ?? task.delegation?.requestId;\n lines.push(\n truncate(\n `${theme.fg('dim', '├─')} ${formatOverlayTaskLine(\n task,\n theme,\n projection.showIds,\n progress,\n nowMs,\n identity ? agentColors.get(identity) : undefined,\n )}`,\n ),\n );\n }\n\n const hidden = layout.hiddenCompleted + layout.truncatedTail;\n if (hidden === 0) {\n const last = lines.length - 1;\n lines[last] = lines[last].replace('├─', '└─');\n return this.withTrailingSpacer(lines);\n }\n\n const parts: string[] = [];\n if (layout.hiddenCompleted > 0) parts.push(`${layout.hiddenCompleted} completed`);\n if (layout.truncatedTail > 0) parts.push(`${layout.truncatedTail} pending`);\n const summary = parts.length > 0 ? `+${hidden} more (${parts.join(', ')})` : `+${hidden} more`;\n lines.push(truncate(`${theme.fg('dim', '└─')} ${theme.fg('dim', summary)}`));\n return this.withTrailingSpacer(lines);\n }\n\n /** Pi adds a spacer above the widget but none below, which glues the last row to the input box. */\n private withTrailingSpacer(lines: string[]): string[] {\n if (lines.length === 0) return lines;\n lines.push('');\n return lines;\n }\n\n dispose(): void {\n this.stopProgressTimer();\n if (this.uiCtx) this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.widgetRegistered = false;\n this.tui = undefined;\n this.uiCtx = undefined;\n this.collapsed = false;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Task } from "../
|
|
2
|
-
import { DelegationManager } from "../delegation/
|
|
1
|
+
import { Task } from "../models/task.cjs";
|
|
2
|
+
import { DelegationManager } from "../services/delegation/index.cjs";
|
|
3
3
|
import { ExtensionUIContext } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
//#region src/tui/taskOverlay.d.ts
|
|
5
|
-
interface TaskOverlayOptions {
|
|
5
|
+
export interface TaskOverlayOptions {
|
|
6
6
|
getTasks: () => readonly Task[];
|
|
7
7
|
delegation: DelegationManager;
|
|
8
8
|
}
|
|
@@ -13,7 +13,7 @@ interface TaskOverlayOptions {
|
|
|
13
13
|
* auto-hides when there is nothing to show so an idle session keeps a clean
|
|
14
14
|
* prompt.
|
|
15
15
|
*/
|
|
16
|
-
declare class TaskOverlay {
|
|
16
|
+
export declare class TaskOverlay {
|
|
17
17
|
private readonly options;
|
|
18
18
|
private uiCtx;
|
|
19
19
|
private widgetRegistered;
|
|
@@ -34,5 +34,4 @@ declare class TaskOverlay {
|
|
|
34
34
|
dispose(): void;
|
|
35
35
|
}
|
|
36
36
|
//#endregion
|
|
37
|
-
export { TaskOverlay, TaskOverlayOptions };
|
|
38
37
|
//# sourceMappingURL=taskOverlay.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taskOverlay.d.cts","names":[],"sources":["../../src/tui/taskOverlay.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"taskOverlay.d.cts","names":[],"sources":["../../src/tui/taskOverlay.ts"],"mappings":";;;;iBAciB;EACf,yBAAyB;EACzB,YAAY;;;;;;;;;qBAUD;mBACM;UACT;UACA;UACA;UACA;UACA;EAER,YAAY,SAAS;;EAKrB,SAAS,KAAK;EASd;UAwCQ;UAaA;EAKR;EAOA;UAIQ;;UA+DA;EAMR"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Task } from "../
|
|
2
|
-
import { DelegationManager } from "../delegation/
|
|
1
|
+
import { Task } from "../models/task.mjs";
|
|
2
|
+
import { DelegationManager } from "../services/delegation/index.mjs";
|
|
3
3
|
import { ExtensionUIContext } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
//#region src/tui/taskOverlay.d.ts
|
|
5
|
-
interface TaskOverlayOptions {
|
|
5
|
+
export interface TaskOverlayOptions {
|
|
6
6
|
getTasks: () => readonly Task[];
|
|
7
7
|
delegation: DelegationManager;
|
|
8
8
|
}
|
|
@@ -13,7 +13,7 @@ interface TaskOverlayOptions {
|
|
|
13
13
|
* auto-hides when there is nothing to show so an idle session keeps a clean
|
|
14
14
|
* prompt.
|
|
15
15
|
*/
|
|
16
|
-
declare class TaskOverlay {
|
|
16
|
+
export declare class TaskOverlay {
|
|
17
17
|
private readonly options;
|
|
18
18
|
private uiCtx;
|
|
19
19
|
private widgetRegistered;
|
|
@@ -34,5 +34,4 @@ declare class TaskOverlay {
|
|
|
34
34
|
dispose(): void;
|
|
35
35
|
}
|
|
36
36
|
//#endregion
|
|
37
|
-
export { TaskOverlay, TaskOverlayOptions };
|
|
38
37
|
//# sourceMappingURL=taskOverlay.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taskOverlay.d.mts","names":[],"sources":["../../src/tui/taskOverlay.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"taskOverlay.d.mts","names":[],"sources":["../../src/tui/taskOverlay.ts"],"mappings":";;;;iBAciB;EACf,yBAAyB;EACzB,YAAY;;;;;;;;;qBAUD;mBACM;UACT;UACA;UACA;UACA;UACA;EAER,YAAY,SAAS;;EAKrB,SAAS,KAAK;EASd;UAwCQ;UAaA;EAKR;EAOA;UAIQ;;UA+DA;EAMR"}
|
package/dist/tui/taskOverlay.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{getMaxWidgetLines as e,resolveCollapseKey as t}from"../config.mjs";import{formatOverlayTaskLine as n}from"./format.mjs";import{deriveTaskProjection as r,selectOverlayLayoutFromProjection as i,visibleTasks as a}from"./selectors.mjs";import{
|
|
1
|
+
import{getMaxWidgetLines as e,resolveCollapseKey as t}from"../services/config/index.mjs";import{formatOverlayTaskLine as n}from"./format.mjs";import{deriveTaskProjection as r,selectOverlayLayoutFromProjection as i,visibleTasks as a}from"./selectors.mjs";import{allocateAgentIdentityColor as o}from"@agimon-ai/doompi-ui/theme";import{truncateToWidth as s}from"@earendil-works/pi-tui";const c=`doom-tasks`;var l=class{options;uiCtx;widgetRegistered=!1;tui;progressTimer;collapsed=!1;constructor(e){this.options=e}setUICtx(e){e!==this.uiCtx&&(this.uiCtx&&this.widgetRegistered&&this.uiCtx.setWidget(c,void 0),this.stopProgressTimer(),this.uiCtx=e,this.widgetRegistered=!1,this.tui=void 0)}update(){if(!this.uiCtx){this.stopProgressTimer();return}let e=a(this.options.getTasks());if(e.length===0){this.widgetRegistered&&(this.uiCtx.setWidget(c,void 0),this.widgetRegistered=!1,this.tui=void 0),this.stopProgressTimer();return}if(this.widgetRegistered){this.syncProgressTimer(e),this.tui?.requestRender();return}this.uiCtx.setWidget(c,(e,t)=>(this.tui=e,{render:e=>this.renderWidget(this.uiCtx?.theme??t,e),invalidate:()=>{}}),{placement:`aboveEditor`}),this.widgetRegistered=!0,this.syncProgressTimer(e)}syncProgressTimer(e){let t=e.some(e=>e.status!==`deleted`&&e.delegation?.state===`running`);if(this.collapsed||!this.widgetRegistered||!t){this.stopProgressTimer();return}this.progressTimer||(this.progressTimer=setInterval(()=>this.tui?.requestRender(),1e3),this.progressTimer.unref?.())}stopProgressTimer(){this.progressTimer&&clearInterval(this.progressTimer),this.progressTimer=void 0}toggleCollapse(){this.collapsed=!this.collapsed,this.syncProgressTimer(this.options.getTasks()),this.tui?.requestRender(!0)}isRegistered(){return this.widgetRegistered}renderWidget(a,c){let l=r(this.options.getTasks());if(l.visible.length===0)return[];let u=e=>s(e,c,`…`),d=l.hasActiveWork?`accent`:`dim`,f=l.hasActiveWork?`●`:`○`,p=`Tasks (${l.counts.completed}/${l.counts.total})`;l.counts.failed>0&&(p+=` · ${l.counts.failed} failed`);let m=u(`${a.fg(d,f)} ${a.fg(d,p)}`);if(this.collapsed){let e=t(),n=e===`off`?`collapsed`:`${e} to expand`;return this.withTrailingSpacer([m,u(`${a.fg(`dim`,`└─`)} ${a.fg(`dim`,n)}`)])}let h=i(l,e()-1),g=new Set,_=new Map;for(let e of h.visible){if(e.delegation?.state!==`running`)continue;let t=e.delegation.runId??e.delegation.requestId,n=o(t,g);g.add(n),_.set(t,n)}let v=Date.now(),y=[m];for(let e of h.visible){let t=this.options.delegation.progressFor(e),r=e.delegation?.runId??e.delegation?.requestId;y.push(u(`${a.fg(`dim`,`├─`)} ${n(e,a,l.showIds,t,v,r?_.get(r):void 0)}`))}let b=h.hiddenCompleted+h.truncatedTail;if(b===0){let e=y.length-1;return y[e]=y[e].replace(`├─`,`└─`),this.withTrailingSpacer(y)}let x=[];h.hiddenCompleted>0&&x.push(`${h.hiddenCompleted} completed`),h.truncatedTail>0&&x.push(`${h.truncatedTail} pending`);let S=x.length>0?`+${b} more (${x.join(`, `)})`:`+${b} more`;return y.push(u(`${a.fg(`dim`,`└─`)} ${a.fg(`dim`,S)}`)),this.withTrailingSpacer(y)}withTrailingSpacer(e){return e.length===0||e.push(``),e}dispose(){this.stopProgressTimer(),this.uiCtx&&this.uiCtx.setWidget(c,void 0),this.widgetRegistered=!1,this.tui=void 0,this.uiCtx=void 0,this.collapsed=!1}};export{l as TaskOverlay};
|
|
2
2
|
//# sourceMappingURL=taskOverlay.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taskOverlay.mjs","names":[],"sources":["../../src/tui/taskOverlay.ts"],"sourcesContent":["import type { ExtensionUIContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { type TUI, truncateToWidth } from '@earendil-works/pi-tui';\nimport { COLLAPSE_KEY_OFF, getMaxWidgetLines, resolveCollapseKey } from '../config.ts';\nimport type { DelegationManager } from '../delegation/manager.ts';\nimport type { Task } from '../store/types.ts';\nimport { formatOverlayTaskLine } from './format.ts';\nimport { deriveTaskProjection, selectOverlayLayoutFromProjection, visibleTasks } from './selectors.ts';\n\nconst WIDGET_KEY = 'doom-tasks';\nconst OVERLAY_HEADING = 'Tasks';\nconst PROGRESS_TICK_MS = 1000;\n\nexport interface TaskOverlayOptions {\n getTasks: () => readonly Task[];\n delegation: DelegationManager;\n}\n\n/**\n * Persistent widget listing tasks above the editor.\n *\n * Registered once per UI context and refreshed with `requestRender()`; it\n * auto-hides when there is nothing to show so an idle session keeps a clean\n * prompt.\n */\nexport class TaskOverlay {\n private readonly options: TaskOverlayOptions;\n private uiCtx: ExtensionUIContext | undefined;\n private widgetRegistered = false;\n private tui: TUI | undefined;\n private progressTimer: NodeJS.Timeout | undefined;\n private collapsed = false;\n\n constructor(options: TaskOverlayOptions) {\n this.options = options;\n }\n\n /** Identity-compare so repeated session_start handlers stay idempotent. */\n setUICtx(ctx: ExtensionUIContext): void {\n if (ctx === this.uiCtx) return;\n if (this.uiCtx && this.widgetRegistered) this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.stopProgressTimer();\n this.uiCtx = ctx;\n this.widgetRegistered = false;\n this.tui = undefined;\n }\n\n update(): void {\n if (!this.uiCtx) {\n this.stopProgressTimer();\n return;\n }\n const tasks = visibleTasks(this.options.getTasks());\n\n if (tasks.length === 0) {\n if (this.widgetRegistered) {\n this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.widgetRegistered = false;\n this.tui = undefined;\n }\n this.stopProgressTimer();\n return;\n }\n\n if (this.widgetRegistered) {\n this.syncProgressTimer(tasks);\n this.tui?.requestRender();\n return;\n }\n\n this.uiCtx.setWidget(\n WIDGET_KEY,\n (tui, factoryTheme) => {\n this.tui = tui;\n return {\n render: (width: number) => this.renderWidget(this.uiCtx?.theme ?? factoryTheme, width),\n invalidate: () => {\n // Nothing is cached: the next render reads the live theme and store.\n },\n };\n },\n { placement: 'aboveEditor' },\n );\n this.widgetRegistered = true;\n this.syncProgressTimer(tasks);\n }\n\n private syncProgressTimer(tasks: readonly Task[]): void {\n const hasRunningDelegation = tasks.some(\n (task) => task.status !== 'deleted' && task.delegation?.state === 'running',\n );\n if (this.collapsed || !this.widgetRegistered || !hasRunningDelegation) {\n this.stopProgressTimer();\n return;\n }\n if (this.progressTimer) return;\n this.progressTimer = setInterval(() => this.tui?.requestRender(), PROGRESS_TICK_MS);\n this.progressTimer.unref?.();\n }\n\n private stopProgressTimer(): void {\n if (this.progressTimer) clearInterval(this.progressTimer);\n this.progressTimer = undefined;\n }\n\n toggleCollapse(): void {\n this.collapsed = !this.collapsed;\n this.syncProgressTimer(this.options.getTasks());\n // Forced redraw: collapsing changes the widget height, not just its content.\n this.tui?.requestRender(true);\n }\n\n isRegistered(): boolean {\n return this.widgetRegistered;\n }\n\n private renderWidget(theme: Theme, width: number): string[] {\n const projection = deriveTaskProjection(this.options.getTasks());\n if (projection.visible.length === 0) return [];\n\n const truncate = (line: string): string => truncateToWidth(line, width, '…');\n const headingColor = projection.hasActiveWork ? 'accent' : 'dim';\n const headingIcon = projection.hasActiveWork ? '●' : '○';\n let headingText = `${OVERLAY_HEADING} (${projection.counts.completed}/${projection.counts.total})`;\n if (projection.counts.failed > 0) headingText += ` · ${projection.counts.failed} failed`;\n const heading = truncate(`${theme.fg(headingColor, headingIcon)} ${theme.fg(headingColor, headingText)}`);\n\n if (this.collapsed) {\n const key = resolveCollapseKey();\n const hint = key === COLLAPSE_KEY_OFF ? 'collapsed' : `${key} to expand`;\n return this.withTrailingSpacer([heading, truncate(`${theme.fg('dim', '└─')} ${theme.fg('dim', hint)}`)]);\n }\n\n const layout = selectOverlayLayoutFromProjection(projection, getMaxWidgetLines() - 1);\n const lines = [heading];\n for (const task of layout.visible) {\n const progress = this.options.delegation.progressFor(task);\n lines.push(\n truncate(`${theme.fg('dim', '├─')} ${formatOverlayTaskLine(task, theme, projection.showIds, progress)}`),\n );\n }\n\n const hidden = layout.hiddenCompleted + layout.truncatedTail;\n if (hidden === 0) {\n const last = lines.length - 1;\n lines[last] = lines[last].replace('├─', '└─');\n return this.withTrailingSpacer(lines);\n }\n\n const parts: string[] = [];\n if (layout.hiddenCompleted > 0) parts.push(`${layout.hiddenCompleted} completed`);\n if (layout.truncatedTail > 0) parts.push(`${layout.truncatedTail} pending`);\n const summary = parts.length > 0 ? `+${hidden} more (${parts.join(', ')})` : `+${hidden} more`;\n lines.push(truncate(`${theme.fg('dim', '└─')} ${theme.fg('dim', summary)}`));\n return this.withTrailingSpacer(lines);\n }\n\n /** Pi adds a spacer above the widget but none below, which glues the last row to the input box. */\n private withTrailingSpacer(lines: string[]): string[] {\n if (lines.length === 0) return lines;\n lines.push('');\n return lines;\n }\n\n dispose(): void {\n this.stopProgressTimer();\n if (this.uiCtx) this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.widgetRegistered = false;\n this.tui = undefined;\n this.uiCtx = undefined;\n this.collapsed = false;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"taskOverlay.mjs","names":[],"sources":["../../src/tui/taskOverlay.ts"],"sourcesContent":["import { allocateAgentIdentityColor } from '@agimon-ai/doompi-ui/theme';\nimport type { ExtensionUIContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { type TUI, truncateToWidth } from '@earendil-works/pi-tui';\n\nimport type { Task } from '../models/task';\nimport { COLLAPSE_KEY_OFF, getMaxWidgetLines, resolveCollapseKey } from '../services/config';\nimport type { DelegationManager } from '../services/delegation';\nimport { formatOverlayTaskLine } from './format';\nimport { deriveTaskProjection, selectOverlayLayoutFromProjection, visibleTasks } from './selectors';\n\nconst WIDGET_KEY = 'doom-tasks';\nconst OVERLAY_HEADING = 'Tasks';\nconst PROGRESS_TICK_MS = 1000;\n\nexport interface TaskOverlayOptions {\n getTasks: () => readonly Task[];\n delegation: DelegationManager;\n}\n\n/**\n * Persistent widget listing tasks above the editor.\n *\n * Registered once per UI context and refreshed with `requestRender()`; it\n * auto-hides when there is nothing to show so an idle session keeps a clean\n * prompt.\n */\nexport class TaskOverlay {\n private readonly options: TaskOverlayOptions;\n private uiCtx: ExtensionUIContext | undefined;\n private widgetRegistered = false;\n private tui: TUI | undefined;\n private progressTimer: NodeJS.Timeout | undefined;\n private collapsed = false;\n\n constructor(options: TaskOverlayOptions) {\n this.options = options;\n }\n\n /** Identity-compare so repeated session_start handlers stay idempotent. */\n setUICtx(ctx: ExtensionUIContext): void {\n if (ctx === this.uiCtx) return;\n if (this.uiCtx && this.widgetRegistered) this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.stopProgressTimer();\n this.uiCtx = ctx;\n this.widgetRegistered = false;\n this.tui = undefined;\n }\n\n update(): void {\n if (!this.uiCtx) {\n this.stopProgressTimer();\n return;\n }\n const tasks = visibleTasks(this.options.getTasks());\n\n if (tasks.length === 0) {\n if (this.widgetRegistered) {\n this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.widgetRegistered = false;\n this.tui = undefined;\n }\n this.stopProgressTimer();\n return;\n }\n\n if (this.widgetRegistered) {\n this.syncProgressTimer(tasks);\n this.tui?.requestRender();\n return;\n }\n\n this.uiCtx.setWidget(\n WIDGET_KEY,\n (tui, factoryTheme) => {\n this.tui = tui;\n return {\n render: (width: number) => this.renderWidget(this.uiCtx?.theme ?? factoryTheme, width),\n invalidate: () => {\n // Nothing is cached: the next render reads the live theme and store.\n },\n };\n },\n { placement: 'aboveEditor' },\n );\n this.widgetRegistered = true;\n this.syncProgressTimer(tasks);\n }\n\n private syncProgressTimer(tasks: readonly Task[]): void {\n const hasRunningDelegation = tasks.some(\n (task) => task.status !== 'deleted' && task.delegation?.state === 'running',\n );\n if (this.collapsed || !this.widgetRegistered || !hasRunningDelegation) {\n this.stopProgressTimer();\n return;\n }\n if (this.progressTimer) return;\n this.progressTimer = setInterval(() => this.tui?.requestRender(), PROGRESS_TICK_MS);\n this.progressTimer.unref?.();\n }\n\n private stopProgressTimer(): void {\n if (this.progressTimer) clearInterval(this.progressTimer);\n this.progressTimer = undefined;\n }\n\n toggleCollapse(): void {\n this.collapsed = !this.collapsed;\n this.syncProgressTimer(this.options.getTasks());\n // Forced redraw: collapsing changes the widget height, not just its content.\n this.tui?.requestRender(true);\n }\n\n isRegistered(): boolean {\n return this.widgetRegistered;\n }\n\n private renderWidget(theme: Theme, width: number): string[] {\n const projection = deriveTaskProjection(this.options.getTasks());\n if (projection.visible.length === 0) return [];\n\n const truncate = (line: string): string => truncateToWidth(line, width, '…');\n const headingColor = projection.hasActiveWork ? 'accent' : 'dim';\n const headingIcon = projection.hasActiveWork ? '●' : '○';\n let headingText = `${OVERLAY_HEADING} (${projection.counts.completed}/${projection.counts.total})`;\n if (projection.counts.failed > 0) headingText += ` · ${projection.counts.failed} failed`;\n const heading = truncate(`${theme.fg(headingColor, headingIcon)} ${theme.fg(headingColor, headingText)}`);\n\n if (this.collapsed) {\n const key = resolveCollapseKey();\n const hint = key === COLLAPSE_KEY_OFF ? 'collapsed' : `${key} to expand`;\n return this.withTrailingSpacer([heading, truncate(`${theme.fg('dim', '└─')} ${theme.fg('dim', hint)}`)]);\n }\n\n const layout = selectOverlayLayoutFromProjection(projection, getMaxWidgetLines() - 1);\n const occupiedColors = new Set<ReturnType<typeof allocateAgentIdentityColor>>();\n const agentColors = new Map<string, ReturnType<typeof allocateAgentIdentityColor>>();\n for (const task of layout.visible) {\n if (task.delegation?.state !== 'running') continue;\n const identity = task.delegation.runId ?? task.delegation.requestId;\n const color = allocateAgentIdentityColor(identity, occupiedColors);\n occupiedColors.add(color);\n agentColors.set(identity, color);\n }\n\n const nowMs = Date.now();\n const lines = [heading];\n for (const task of layout.visible) {\n const progress = this.options.delegation.progressFor(task);\n const identity = task.delegation?.runId ?? task.delegation?.requestId;\n lines.push(\n truncate(\n `${theme.fg('dim', '├─')} ${formatOverlayTaskLine(\n task,\n theme,\n projection.showIds,\n progress,\n nowMs,\n identity ? agentColors.get(identity) : undefined,\n )}`,\n ),\n );\n }\n\n const hidden = layout.hiddenCompleted + layout.truncatedTail;\n if (hidden === 0) {\n const last = lines.length - 1;\n lines[last] = lines[last].replace('├─', '└─');\n return this.withTrailingSpacer(lines);\n }\n\n const parts: string[] = [];\n if (layout.hiddenCompleted > 0) parts.push(`${layout.hiddenCompleted} completed`);\n if (layout.truncatedTail > 0) parts.push(`${layout.truncatedTail} pending`);\n const summary = parts.length > 0 ? `+${hidden} more (${parts.join(', ')})` : `+${hidden} more`;\n lines.push(truncate(`${theme.fg('dim', '└─')} ${theme.fg('dim', summary)}`));\n return this.withTrailingSpacer(lines);\n }\n\n /** Pi adds a spacer above the widget but none below, which glues the last row to the input box. */\n private withTrailingSpacer(lines: string[]): string[] {\n if (lines.length === 0) return lines;\n lines.push('');\n return lines;\n }\n\n dispose(): void {\n this.stopProgressTimer();\n if (this.uiCtx) this.uiCtx.setWidget(WIDGET_KEY, undefined);\n this.widgetRegistered = false;\n this.tui = undefined;\n this.uiCtx = undefined;\n this.collapsed = false;\n }\n}\n"],"mappings":"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"}
|
package/dist/tui/taskSpace.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("../models/taskGraph.cjs"),t=require("../schemas/task.cjs"),n=require("./format.cjs"),r=require("./selectors.cjs"),i=require("../services/reducer/index.cjs");let a=require("@earendil-works/pi-tui"),o=require("node:os"),s=require("@agimon-ai/doompi-ui/doom-overlay"),c=require("@agimon-ai/doompi-ui/rendering");const l=s.DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;function u(e){for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n<32||n===127)return!0}return!1}function d(e,t){let n=(0,o.homedir)(),r=n&&e.startsWith(n)?`~${e.slice(n.length)}`:e;if((0,a.visibleWidth)(r)<=t)return r;let i=r.split(`/`),s=i.pop()??r;for(;i.length>0;){let e=`${i[i.length-1]}/${s}`;if((0,a.visibleWidth)(`…/${e}`)>t)break;s=e,i.pop()}return(0,a.truncateToWidth)(`…/${s}`,t,``)}const f=`none`,p=[[`↑↓`,`select`],[`enter`,`edit subject`],[`s`,`status`],[`esc`,`close`]];function m(e,t){return(0,c.fitStyledLine)(e,t,`…`)}function h(e,t,n){let r=(0,a.visibleWidth)(t),i=Math.max(0,n-r-1);return m(e,i)+` `.repeat(Math.max(1,n-i-r))+m(t,r)}function g(e,t){if(t<=0)return[];let n=[],r=``;for(let i of e.split(/\s+/).filter(Boolean))r.length===0?r=i:r.length+1+i.length<=t?r+=` ${i}`:(n.push(r),r=i);return r.length>0&&n.push(r),n}var _=class extends s.DoomOverlay{options;done;unwatch;mode=`browse`;selected=0;statusIndex=0;draft=``;notice;bodyHeight=1;constructor(e,t,n,r){super(e,t),this.options=n,this.done=r,this.unwatch=n.store.onExternalChange(()=>this.tui.requestRender())}tasks(){return r.visibleTasks(this.options.store.snapshot.tasks)}selectedTask(){let e=this.tasks();if(e.length!==0)return e[Math.min(this.selected,e.length-1)]}move(e){let t=this.tasks();t.length!==0&&(this.selected=Math.max(0,Math.min(t.length-1,this.selected+e)),this.tui.requestRender())}commit(e){this.options.store.mutate(t=>{let n=i.applyTaskMutation(t,`upsert`,{tasks:[e]});return i.isCommittingOp(n.op)?{document:n.document,value:n.op}:{value:n.op}}).then(e=>{let t=i.singleItemOutcome(e.value);this.notice=t?.kind===`failed`?t.message:void 0,this.tui.requestRender()}).catch(e=>{this.notice=e instanceof Error?e.message:String(e),this.tui.requestRender()})}handleStatusInput(e){let n=this.selectedTask();(0,a.matchesKey)(e,`up`)?this.statusIndex=Math.max(0,this.statusIndex-1):(0,a.matchesKey)(e,`down`)?this.statusIndex=Math.min(t.TASK_STATUSES.length-1,this.statusIndex+1):e===`s`?this.statusIndex=(this.statusIndex+1)%t.TASK_STATUSES.length:e===`\r`||e===`
|
|
2
2
|
`?(this.mode=`browse`,n&&this.commit({id:n.id,status:t.TASK_STATUSES[this.statusIndex]})):(0,a.matchesKey)(e,`escape`)&&(this.mode=`browse`),this.tui.requestRender()}handleSubjectInput(e){let t=this.selectedTask();e===`\r`||e===`
|
|
3
|
-
`?(this.mode=`browse`,t&&this.commit({id:t.id,subject:this.draft})):(0,a.matchesKey)(e,`escape`)?this.mode=`browse`:e===``?this.draft=this.draft.slice(0,-1):
|
|
4
|
-
`)&&(this.mode=`subject`,this.draft=n.subject,this.tui.requestRender())}}badge(e,t,n=`text`){return this.theme.bg(t,this.theme.fg(n,` ${e} `))}hintLine(e){return e.map(([e,t])=>`${this.badge(e,`selectedBg`)}${this.theme.fg(`dim`,` ${t}`)}`).join(this.theme.fg(`dim`,` `))}listLines(
|
|
3
|
+
`?(this.mode=`browse`,t&&this.commit({id:t.id,subject:this.draft})):(0,a.matchesKey)(e,`escape`)?this.mode=`browse`:e===``?this.draft=this.draft.slice(0,-1):u(e)||(this.draft+=e),this.tui.requestRender()}handleInput(e){if(this.mode===`status`){this.handleStatusInput(e);return}if(this.mode===`subject`){this.handleSubjectInput(e);return}if((0,a.matchesKey)(e,`escape`)||(0,a.matchesKey)(e,`ctrl+c`)){this.done(void 0);return}if((0,a.matchesKey)(e,`up`)){this.move(-1);return}if((0,a.matchesKey)(e,`down`)){this.move(1);return}let n=this.selectedTask();if(n){if(e===`s`){this.mode=`status`,this.statusIndex=Math.max(0,t.TASK_STATUSES.indexOf(n.status)),this.tui.requestRender();return}(e===`\r`||e===`
|
|
4
|
+
`)&&(this.mode=`subject`,this.draft=n.subject,this.tui.requestRender())}}badge(e,t,n=`text`){return this.theme.bg(t,this.theme.fg(n,` ${e} `))}hintLine(e){return e.map(([e,t])=>`${this.badge(e,`selectedBg`)}${this.theme.fg(`dim`,` ${t}`)}`).join(this.theme.fg(`dim`,` `))}listLines(r){let i=this.tasks(),o=this.theme.bold(`TASKS`),s=Math.max(0,r-(0,a.visibleWidth)(`TASKS`)-2),c=[`${o} ${this.theme.fg(`dim`,d(this.options.store.storePath,s))}`,``];if(i.length===0)return c.push(this.theme.fg(`dim`,t.MSG_NO_TASKS)),c;let l=Math.max(1,Math.floor((this.bodyHeight-c.length)/2)),u=Math.max(0,Math.min(this.selected-l+1,Math.max(0,i.length-l)));for(let[t,a]of i.slice(u,u+l).entries()){let o=u+t===Math.min(this.selected,i.length-1),s=o?this.theme.fg(`accent`,`›`):` `,l=o?this.theme.bold(a.subject):a.subject,d=n.overlayStatusGlyph(a.status,this.theme),p=a.owner??a.delegation?.agent??f,h=a.status===`pending`&&e.isBlocked(this.options.store.snapshot.tasks,a)?this.theme.fg(`warning`,`blocked by ${(a.blockedBy??[]).map(e=>`#${e}`).join(`, `)}`):this.theme.fg(`dim`,n.STATUS_LABEL[a.status]),g=`${s} ${d} ${this.theme.fg(`dim`,`#${a.id}`)} ${l}`,_=`${` `.repeat(6)}${this.badge(p,`userMessageBg`,`muted`)} ${h}`,v=o?`selectedBg`:`userMessageBg`;for(let e of[g,_])c.push(this.theme.bg(v,m(e,r)))}return c}statusLines(e,r){if(this.mode!==`status`){let t=n.overlayStatusGlyph(e.status,this.theme);return[this.theme.fg(`dim`,`STATUS`),`${t} ${n.STATUS_LABEL[e.status]}`]}let i=[this.theme.fg(`dim`,`STATUS s cycles · enter commits`)];for(let[n,a]of t.TASK_STATUSES.entries()){let t=n===this.statusIndex,o=t?this.theme.fg(`accent`,`▸`):` `,s=t?this.theme.bold(this.theme.fg(`accent`,a)):this.theme.fg(`muted`,a),c=a===e.status?this.theme.fg(`dim`,`current`):``,l=h(` ${o} ${s}`,c,r);i.push(this.theme.bg(t?`selectedBg`:`userMessageBg`,l))}return i}subjectField(e,t){let n=this.mode===`subject`,r=n?`${this.draft}█`:e.subject;return[this.theme.fg(`dim`,n?`SUBJECT enter commits · esc cancels`:`SUBJECT`),this.theme.bg(n?`selectedBg`:`userMessageBg`,m(` ${r}`,t))]}detailLines(e){let t=this.selectedTask();if(!t)return[this.theme.fg(`dim`,`No task selected`)];let n=this.mode===`subject`||this.mode===`status`?this.badge(`EDIT`,`toolSuccessBg`,`warning`):``,r=[h(this.theme.bold(this.theme.fg(`accent`,`TASK #${t.id}`)),n,e),``];r.push(...this.subjectField(t,e)),r.push(``,...this.statusLines(t,e),``),t.activeForm&&r.push(this.theme.fg(`dim`,`ACTIVE FORM`),t.activeForm,``);let i=t.owner??t.delegation?.agent??f,a=t.delegation?.runId?this.theme.fg(`success`,`delegated run ${t.delegation.runId}`):``;return r.push(this.theme.fg(`dim`,`OWNER`),a?`${i} ${this.theme.fg(`dim`,`·`)} ${a}`:i,``),r.push(this.theme.fg(`dim`,`BLOCKED BY`),t.blockedBy?.length?t.blockedBy.map(e=>`#${e}`).join(` · `):f),t.description&&r.push(``,this.theme.fg(`dim`,`DESCRIPTION`),...g(t.description,e)),this.notice&&r.push(``,this.theme.fg(`error`,this.notice)),r}headerSummary(){let e=r.countTasks(this.options.store.snapshot.tasks),t=[`${e.completed}/${e.total} completed`];return e.inProgress>0&&t.push(`${e.inProgress} in progress`),e.blocked>0&&t.push(`${e.blocked} blocked`),e.failed>0&&t.push(`${e.failed} failed`),t.join(` · `)}getChrome(){return{title:`TASK SPACE`,accent:s.DOOM_OVERLAY_ACCENT,breadcrumb:`SPC › t › t / tasks`,headerRight:`${this.headerSummary()} · esc close`,footer:this.hintLine(p)}}renderBody(e,t){if(this.bodyHeight=t,e<48)return this.renderStacked(e,t);let n=Math.max(18,Math.floor((e-1)*.3333333333333333)),r=Math.max(1,e-n-1),i=Math.max(1,n-1),o=Math.max(1,r-1),s=this.listLines(i),c=this.detailLines(o),l=this.theme.fg(`borderMuted`,`│`);return Array.from({length:t},(t,n)=>{let r=`${m(s[n]??``,i)} ${l} ${m(c[n]??``,o)}`;return(0,a.truncateToWidth)(r,e,`…`)})}renderStacked(e,t){let n=Math.max(1,Math.floor((t-1)/2)),r=Math.max(0,t-n-1);this.bodyHeight=n;let i=this.listLines(e),a=this.detailLines(e);return[...i.slice(0,n),...Array.from({length:Math.max(0,n-i.length)},()=>``),this.theme.fg(`borderMuted`,`─`.repeat(e)),...a.slice(0,r)]}dispose(){this.unwatch()}};async function v(e,t){await e.ui.custom((e,n,r,i)=>new _(e,n,t,i),s.DOOM_FULLSCREEN_UI_OPTIONS)}exports.TASK_SPACE_OVERLAY_OPTIONS=l,exports.TaskSpaceComponent=_,exports.openTaskSpace=v;
|
|
5
5
|
//# sourceMappingURL=taskSpace.cjs.map
|