@antelopejs/dms-ai 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -11
- package/dist/channels/bridge.d.ts +6 -1
- package/dist/channels/bridge.js +29 -1
- package/dist/channels/bridge.js.map +1 -1
- package/dist/channels/channel-service.d.ts +2 -1
- package/dist/channels/channel-service.js +3 -2
- package/dist/channels/channel-service.js.map +1 -1
- package/dist/channels/sse-stream.d.ts +3 -2
- package/dist/config.d.ts +0 -2
- package/dist/config.js +0 -7
- package/dist/config.js.map +1 -1
- package/dist/constants/http.d.ts +9 -0
- package/dist/constants/http.js +14 -0
- package/dist/constants/http.js.map +1 -0
- package/dist/constants/i18n.d.ts +11 -0
- package/dist/constants/i18n.js +15 -0
- package/dist/constants/i18n.js.map +1 -0
- package/dist/constants/pages.d.ts +50 -0
- package/dist/constants/pages.js +58 -0
- package/dist/constants/pages.js.map +1 -0
- package/dist/constants/sidecar.d.ts +3 -1
- package/dist/constants/sidecar.js +4 -2
- package/dist/constants/sidecar.js.map +1 -1
- package/dist/index.js +0 -8
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/sidecar-owner.d.ts +14 -0
- package/dist/lifecycle/sidecar-owner.js +102 -0
- package/dist/lifecycle/sidecar-owner.js.map +1 -0
- package/dist/lifecycle/spawn-sidecar.d.ts +1 -0
- package/dist/lifecycle/spawn-sidecar.js +59 -145
- package/dist/lifecycle/spawn-sidecar.js.map +1 -1
- package/dist/lifecycle/terminate-process.d.ts +1 -0
- package/dist/lifecycle/terminate-process.js +34 -0
- package/dist/lifecycle/terminate-process.js.map +1 -0
- package/dist/logging/log-buffer.d.ts +0 -6
- package/dist/logging/log-buffer.js +0 -1
- package/dist/logging/log-buffer.js.map +1 -1
- package/dist/pages/activity/columns.d.ts +2 -0
- package/dist/pages/activity/columns.js +103 -0
- package/dist/pages/activity/columns.js.map +1 -0
- package/dist/pages/activity/page.d.ts +1 -2
- package/dist/pages/activity/page.js +79 -44
- package/dist/pages/activity/page.js.map +1 -1
- package/dist/pages/all.d.ts +1 -0
- package/dist/pages/all.js +1 -0
- package/dist/pages/all.js.map +1 -1
- package/dist/pages/changes/page.d.ts +9 -0
- package/dist/pages/changes/page.js +22 -0
- package/dist/pages/changes/page.js.map +1 -0
- package/dist/pages/meta.d.ts +9 -0
- package/dist/pages/meta.js +31 -0
- package/dist/pages/meta.js.map +1 -0
- package/dist/pages/module.js +9 -5
- package/dist/pages/module.js.map +1 -1
- package/dist/pages/overview/insights.d.ts +3 -0
- package/dist/pages/overview/insights.js +77 -0
- package/dist/pages/overview/insights.js.map +1 -0
- package/dist/pages/overview/kpis.d.ts +2 -0
- package/dist/pages/overview/kpis.js +39 -0
- package/dist/pages/overview/kpis.js.map +1 -0
- package/dist/pages/overview/page.d.ts +6 -3
- package/dist/pages/overview/page.js +19 -62
- package/dist/pages/overview/page.js.map +1 -1
- package/dist/pages/overview/recent-changes.d.ts +2 -0
- package/dist/pages/overview/recent-changes.js +144 -0
- package/dist/pages/overview/recent-changes.js.map +1 -0
- package/dist/pages/overview/status.d.ts +3 -0
- package/dist/pages/overview/status.js +36 -0
- package/dist/pages/overview/status.js.map +1 -0
- package/dist/pages/settings/availability.d.ts +2 -0
- package/dist/pages/settings/availability.js +46 -0
- package/dist/pages/settings/availability.js.map +1 -0
- package/dist/pages/settings/options.d.ts +10 -0
- package/dist/pages/settings/options.js +58 -0
- package/dist/pages/settings/options.js.map +1 -0
- package/dist/pages/settings/page.d.ts +2 -1
- package/dist/pages/settings/page.js +39 -13
- package/dist/pages/settings/page.js.map +1 -1
- package/dist/pages/settings/sections.d.ts +2 -0
- package/dist/pages/settings/sections.js +164 -0
- package/dist/pages/settings/sections.js.map +1 -0
- package/dist/pages/skills/page.d.ts +2 -1
- package/dist/pages/skills/page.js +122 -12
- package/dist/pages/skills/page.js.map +1 -1
- package/dist/routes/activity-csv.d.ts +2 -0
- package/dist/routes/activity-csv.js +42 -0
- package/dist/routes/activity-csv.js.map +1 -0
- package/dist/routes/activity.d.ts +8 -0
- package/dist/routes/activity.js +105 -0
- package/dist/routes/activity.js.map +1 -0
- package/dist/routes/actor.d.ts +2 -0
- package/dist/routes/actor.js +8 -0
- package/dist/routes/actor.js.map +1 -0
- package/dist/routes/banner.d.ts +3 -0
- package/dist/routes/banner.js +9 -0
- package/dist/routes/banner.js.map +1 -0
- package/dist/routes/builder.js +1 -5
- package/dist/routes/builder.js.map +1 -1
- package/dist/routes/changes.d.ts +17 -0
- package/dist/routes/changes.js +152 -0
- package/dist/routes/changes.js.map +1 -0
- package/dist/routes/channels.js +2 -1
- package/dist/routes/channels.js.map +1 -1
- package/dist/routes/index.d.ts +3 -0
- package/dist/routes/index.js +3 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/list-query.d.ts +9 -0
- package/dist/routes/list-query.js +34 -0
- package/dist/routes/list-query.js.map +1 -0
- package/dist/routes/metric-shapes.d.ts +8 -0
- package/dist/routes/metric-shapes.js +107 -0
- package/dist/routes/metric-shapes.js.map +1 -0
- package/dist/routes/metrics.d.ts +5 -48
- package/dist/routes/metrics.js +52 -42
- package/dist/routes/metrics.js.map +1 -1
- package/dist/routes/settings.d.ts +3 -16
- package/dist/routes/settings.js +40 -14
- package/dist/routes/settings.js.map +1 -1
- package/dist/routes/sidecar-results.d.ts +6 -0
- package/dist/routes/sidecar-results.js +44 -0
- package/dist/routes/sidecar-results.js.map +1 -0
- package/dist/routes/skills.d.ts +4 -14
- package/dist/routes/skills.js +91 -6
- package/dist/routes/skills.js.map +1 -1
- package/dist/routes/status-shapes.d.ts +5 -0
- package/dist/routes/status-shapes.js +176 -0
- package/dist/routes/status-shapes.js.map +1 -0
- package/dist/routes/status.d.ts +9 -0
- package/dist/routes/status.js +92 -0
- package/dist/routes/status.js.map +1 -0
- package/dist/routes/undo-confirm.d.ts +3 -0
- package/dist/routes/undo-confirm.js +51 -0
- package/dist/routes/undo-confirm.js.map +1 -0
- package/dist/sidecar/http-client.d.ts +11 -0
- package/dist/sidecar/http-client.js +59 -0
- package/dist/sidecar/http-client.js.map +1 -0
- package/dist/sidecar/index.d.ts +2 -0
- package/dist/sidecar/index.js +19 -0
- package/dist/sidecar/index.js.map +1 -0
- package/dist/sidecar/query.d.ts +3 -0
- package/dist/sidecar/query.js +25 -0
- package/dist/sidecar/query.js.map +1 -0
- package/dist/types/activity.d.ts +31 -0
- package/dist/types/activity.js +3 -0
- package/dist/types/activity.js.map +1 -0
- package/dist/types/changes.d.ts +45 -0
- package/dist/types/changes.js +3 -0
- package/dist/types/changes.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/metrics.d.ts +76 -0
- package/dist/types/metrics.js +3 -0
- package/dist/types/metrics.js.map +1 -0
- package/dist/types/skills.d.ts +51 -0
- package/dist/types/skills.js +3 -0
- package/dist/types/skills.js.map +1 -0
- package/dist/types/status.d.ts +16 -0
- package/dist/types/status.js +3 -0
- package/dist/types/status.js.map +1 -0
- package/dist/vocabulary/enumerations.d.ts +9 -0
- package/dist/vocabulary/enumerations.js +52 -0
- package/dist/vocabulary/enumerations.js.map +1 -0
- package/dist/vocabulary/index.d.ts +5 -0
- package/dist/vocabulary/index.js +22 -0
- package/dist/vocabulary/index.js.map +1 -0
- package/dist/vocabulary/keys.d.ts +1 -0
- package/dist/vocabulary/keys.js +8 -0
- package/dist/vocabulary/keys.js.map +1 -0
- package/dist/vocabulary/options.d.ts +7 -0
- package/dist/vocabulary/options.js +33 -0
- package/dist/vocabulary/options.js.map +1 -0
- package/dist/vocabulary/tools.d.ts +7 -0
- package/dist/vocabulary/tools.js +99 -0
- package/dist/vocabulary/tools.js.map +1 -0
- package/dist/vocabulary/types.d.ts +20 -0
- package/dist/vocabulary/types.js +3 -0
- package/dist/vocabulary/types.js.map +1 -0
- package/frontend-vue/app/chat/components/AnswerRecord.vue +95 -0
- package/frontend-vue/app/chat/components/ApprovalDock.vue +371 -0
- package/frontend-vue/app/chat/components/ChangeSetCard.vue +297 -0
- package/frontend-vue/app/chat/components/ChatEmpty.vue +142 -0
- package/frontend-vue/app/chat/components/ChatView.vue +664 -406
- package/frontend-vue/app/chat/components/Composer.vue +589 -0
- package/frontend-vue/app/chat/components/ConnectionBanner.vue +41 -65
- package/frontend-vue/app/chat/components/ConversationDrawer.vue +387 -177
- package/frontend-vue/app/chat/components/DiffView.vue +131 -0
- package/frontend-vue/app/chat/components/FullAutoBanner.vue +76 -0
- package/frontend-vue/app/chat/components/FullAutoDialog.vue +103 -0
- package/frontend-vue/app/chat/components/MarkdownContent.vue +15 -15
- package/frontend-vue/app/chat/components/MessageList.vue +389 -295
- package/frontend-vue/app/chat/components/NoticeCard.vue +193 -0
- package/frontend-vue/app/chat/components/PanelHeader.vue +242 -0
- package/frontend-vue/app/chat/components/PermissionCard.vue +470 -0
- package/frontend-vue/app/chat/components/PlanCard.vue +115 -0
- package/frontend-vue/app/chat/components/QuestionDock.vue +407 -0
- package/frontend-vue/app/chat/components/QueueDock.vue +310 -0
- package/frontend-vue/app/chat/components/RulesList.vue +97 -0
- package/frontend-vue/app/chat/components/StepsDock.vue +181 -0
- package/frontend-vue/app/chat/components/ToolCluster.vue +186 -178
- package/frontend-vue/app/chat/components/ToolRow.vue +251 -0
- package/frontend-vue/app/chat/components/TurnErrorCard.vue +135 -0
- package/frontend-vue/app/chat/composables/conversation-events.ts +404 -0
- package/frontend-vue/app/chat/composables/useChangeSetActions.ts +135 -0
- package/frontend-vue/app/chat/composables/useChatChannel.ts +11 -3
- package/frontend-vue/app/chat/composables/useChatI18n.ts +35 -0
- package/frontend-vue/app/chat/composables/useComposerAttachments.ts +111 -0
- package/frontend-vue/app/chat/composables/useConversation.ts +149 -651
- package/frontend-vue/app/chat/composables/useConversationId.ts +2 -10
- package/frontend-vue/app/chat/composables/useConversationList.ts +77 -21
- package/frontend-vue/app/chat/composables/useConversationMode.ts +73 -0
- package/frontend-vue/app/chat/composables/usePaletteTurn.ts +124 -0
- package/frontend-vue/app/chat/composables/usePermissionQueue.ts +211 -34
- package/frontend-vue/app/chat/composables/useQuestionQueue.ts +103 -21
- package/frontend-vue/app/chat/composables/useQueueActions.ts +55 -0
- package/frontend-vue/app/chat/composables/useSettings.ts +17 -34
- package/frontend-vue/app/chat/constants/attachments.ts +2 -1
- package/frontend-vue/app/chat/constants/conversation.ts +18 -32
- package/frontend-vue/app/chat/constants/protocol.ts +25 -2
- package/frontend-vue/app/chat/constants/run-status.ts +8 -14
- package/frontend-vue/app/chat/constants/settings.ts +5 -47
- package/frontend-vue/app/chat/types/conversation.ts +72 -2
- package/frontend-vue/app/chat/types/permission.ts +31 -0
- package/frontend-vue/app/chat/types/protocol.ts +226 -0
- package/frontend-vue/app/chat/types/question.ts +10 -1
- package/frontend-vue/app/chat/types/settings.ts +9 -5
- package/frontend-vue/app/chat/utils/approval-keyboard.ts +49 -0
- package/frontend-vue/app/chat/utils/arrays.ts +10 -0
- package/frontend-vue/app/chat/utils/conversation-groups.ts +96 -0
- package/frontend-vue/app/chat/utils/conversation-messages.ts +251 -0
- package/frontend-vue/app/chat/utils/diff.ts +78 -0
- package/frontend-vue/app/chat/utils/format.ts +43 -0
- package/frontend-vue/app/chat/utils/markdown.ts +1 -1
- package/frontend-vue/app/chat/utils/permission-view.ts +159 -0
- package/frontend-vue/app/chat/utils/platform.ts +34 -0
- package/frontend-vue/app/chat/utils/queue.ts +18 -0
- package/frontend-vue/app/chat/utils/render-items.ts +164 -0
- package/frontend-vue/app/chat/utils/run-status.ts +19 -23
- package/frontend-vue/app/chat/utils/suggestions.ts +101 -0
- package/frontend-vue/app/chat/utils/todos.ts +2 -2
- package/frontend-vue/app/chat/utils/tool-lexicon.ts +540 -0
- package/frontend-vue/app/chat/utils/tool-state.ts +60 -0
- package/frontend-vue/app/components/ActivityDetail.vue +235 -0
- package/frontend-vue/app/components/ChangesView.vue +249 -0
- package/frontend-vue/app/components/ChatPanel.vue +141 -196
- package/frontend-vue/app/components/PaletteAnswer.vue +185 -0
- package/frontend-vue/app/components/SkillCard.vue +77 -0
- package/frontend-vue/app/components/SkillDetail.vue +188 -0
- package/frontend-vue/app/plugins/ai.client.ts +349 -57
- package/frontend-vue/app/plugins/side-panel.ts +13 -0
- package/frontend-vue/app/runtime/assistant-activity.ts +105 -0
- package/frontend-vue/app/runtime/assistant-commands.ts +210 -0
- package/frontend-vue/app/runtime/assistant-notifications.ts +181 -0
- package/frontend-vue/app/runtime/assistant-session.ts +49 -6
- package/frontend-vue/app/runtime/channel-client.ts +3 -6
- package/frontend-vue/app/runtime/constants.ts +29 -35
- package/frontend-vue/app/runtime/host-commands.ts +4 -4
- package/frontend-vue/app/runtime/listeners.ts +1 -1
- package/frontend-vue/app/runtime/navigation-complete.ts +1 -1
- package/frontend-vue/app/runtime/panel-intents.ts +55 -0
- package/frontend-vue/app/runtime/shortcuts.ts +3 -1
- package/frontend-vue/app/runtime/sidecar-status.ts +9 -1
- package/frontend-vue/app/runtime/stream-holds.ts +24 -0
- package/frontend-vue/app/views/ChangeSetPanel.vue +222 -0
- package/frontend-vue/app/views/DecisionLabel.vue +30 -0
- package/frontend-vue/app/views/DiffView.vue +215 -0
- package/frontend-vue/app/views/ResultPill.vue +32 -0
- package/frontend-vue/app/views/RowStepper.vue +48 -0
- package/frontend-vue/app/views/UnavailableState.vue +66 -0
- package/frontend-vue/app/views/composables/useAiRequest.ts +89 -0
- package/frontend-vue/app/views/composables/useAssistant.ts +33 -0
- package/frontend-vue/app/views/composables/useChangeSetActions.ts +102 -0
- package/frontend-vue/app/views/composables/useViewFormat.ts +55 -0
- package/frontend-vue/app/views/constants.ts +43 -0
- package/frontend-vue/app/views/types.ts +189 -0
- package/frontend-vue/app/views/utils/activity.ts +77 -0
- package/frontend-vue/app/views/utils/change-sets.ts +44 -0
- package/frontend-vue/app/views/utils/diff.ts +98 -0
- package/frontend-vue/app/views/utils/moment.ts +92 -0
- package/frontend-vue/app/views/utils/skills.ts +27 -0
- package/frontend-vue/app/views/utils/tools.ts +73 -0
- package/frontend-vue/dms.frontend.ts +17 -5
- package/frontend-vue/i18n/locales/dms-ai-pages-en-GB.json +607 -0
- package/frontend-vue/i18n/locales/dms-ai-pages-fr-FR.json +607 -0
- package/frontend-vue/i18n/locales/dms-ai-panel-en-GB.json +425 -0
- package/frontend-vue/i18n/locales/dms-ai-panel-fr-FR.json +425 -0
- package/frontend-vue/i18n/locales/dms-ai-views-en-GB.json +142 -0
- package/frontend-vue/i18n/locales/dms-ai-views-fr-FR.json +142 -0
- package/frontend-vue/package.json +1 -1
- package/frontend-vue/tests/chat/conversation-events.test.ts +590 -0
- package/frontend-vue/tests/chat/diff-and-keys.test.ts +178 -0
- package/frontend-vue/tests/chat/tool-lexicon.test.ts +188 -0
- package/frontend-vue/tests/chat/useConversation.test.ts +36 -33
- package/frontend-vue/tests/chat-panel.test.ts +78 -131
- package/frontend-vue/tests/i18n-panel.test.ts +118 -0
- package/frontend-vue/tests/palette-assistant.test.ts +220 -0
- package/frontend-vue/tests/panel-states.test.ts +806 -0
- package/frontend-vue/tests/sidecar-guest.test.ts +35 -3
- package/frontend-vue/tests/support/i18n.ts +49 -0
- package/frontend-vue/tests/support/panel-harness.ts +198 -0
- package/frontend-vue/tests/support/stubs.ts +201 -0
- package/frontend-vue/tests/views/diff-view.test.ts +149 -0
- package/frontend-vue/tests/views/view-format.test.ts +59 -0
- package/package.json +5 -3
- package/sidecar/dist/agent/attachment-files.d.ts +0 -1
- package/sidecar/dist/agent/attachment-files.js +1 -1
- package/sidecar/dist/agent/attachment-files.js.map +1 -1
- package/sidecar/dist/agent/call-ledger.d.ts +6 -0
- package/sidecar/dist/agent/call-ledger.js +41 -0
- package/sidecar/dist/agent/call-ledger.js.map +1 -0
- package/sidecar/dist/agent/command-analysis.d.ts +9 -0
- package/sidecar/dist/agent/command-analysis.js +104 -0
- package/sidecar/dist/agent/command-analysis.js.map +1 -0
- package/sidecar/dist/agent/conversation-modes.d.ts +32 -0
- package/sidecar/dist/agent/conversation-modes.js +122 -0
- package/sidecar/dist/agent/conversation-modes.js.map +1 -0
- package/sidecar/dist/agent/edit-targets.d.ts +5 -0
- package/sidecar/dist/agent/edit-targets.js +41 -0
- package/sidecar/dist/agent/edit-targets.js.map +1 -0
- package/sidecar/dist/agent/effective-mode.d.ts +9 -2
- package/sidecar/dist/agent/effective-mode.js +14 -16
- package/sidecar/dist/agent/effective-mode.js.map +1 -1
- package/sidecar/dist/agent/host-context.js +2 -2
- package/sidecar/dist/agent/host-context.js.map +1 -1
- package/sidecar/dist/agent/line-diff.d.ts +8 -0
- package/sidecar/dist/agent/line-diff.js +204 -0
- package/sidecar/dist/agent/line-diff.js.map +1 -0
- package/sidecar/dist/agent/permission-bus.d.ts +55 -10
- package/sidecar/dist/agent/permission-bus.js +130 -100
- package/sidecar/dist/agent/permission-bus.js.map +1 -1
- package/sidecar/dist/agent/permission-preview.d.ts +20 -0
- package/sidecar/dist/agent/permission-preview.js +203 -0
- package/sidecar/dist/agent/permission-preview.js.map +1 -0
- package/sidecar/dist/agent/permission-rules.d.ts +17 -0
- package/sidecar/dist/agent/permission-rules.js +95 -0
- package/sidecar/dist/agent/permission-rules.js.map +1 -0
- package/sidecar/dist/agent/provider.d.ts +12 -4
- package/sidecar/dist/agent/question-bus.d.ts +14 -2
- package/sidecar/dist/agent/question-bus.js +30 -11
- package/sidecar/dist/agent/question-bus.js.map +1 -1
- package/sidecar/dist/agent/runner-events.d.ts +3 -1
- package/sidecar/dist/agent/runner.d.ts +6 -4
- package/sidecar/dist/agent/runner.js +24 -7
- package/sidecar/dist/agent/runner.js.map +1 -1
- package/sidecar/dist/agent/switching-runner.js +1 -0
- package/sidecar/dist/agent/switching-runner.js.map +1 -1
- package/sidecar/dist/agent/tool-kinds.d.ts +12 -0
- package/sidecar/dist/agent/tool-kinds.js +50 -0
- package/sidecar/dist/agent/tool-kinds.js.map +1 -0
- package/sidecar/dist/agent/typecheck.d.ts +2 -6
- package/sidecar/dist/audit/activity-query.d.ts +37 -0
- package/sidecar/dist/audit/activity-query.js +111 -0
- package/sidecar/dist/audit/activity-query.js.map +1 -0
- package/sidecar/dist/audit/activity-target.d.ts +2 -0
- package/sidecar/dist/audit/activity-target.js +46 -0
- package/sidecar/dist/audit/activity-target.js.map +1 -0
- package/sidecar/dist/audit/activity.d.ts +45 -0
- package/sidecar/dist/audit/activity.js +255 -0
- package/sidecar/dist/audit/activity.js.map +1 -0
- package/sidecar/dist/audit/call-audit.d.ts +11 -0
- package/sidecar/dist/audit/call-audit.js +23 -0
- package/sidecar/dist/audit/call-audit.js.map +1 -0
- package/sidecar/dist/checkpoints/checkpoints.d.ts +69 -0
- package/sidecar/dist/checkpoints/checkpoints.js +244 -0
- package/sidecar/dist/checkpoints/checkpoints.js.map +1 -0
- package/sidecar/dist/checkpoints/shadow-git.d.ts +23 -0
- package/sidecar/dist/checkpoints/shadow-git.js +173 -0
- package/sidecar/dist/checkpoints/shadow-git.js.map +1 -0
- package/sidecar/dist/constants/agent.d.ts +2 -0
- package/sidecar/dist/constants/agent.js +4 -0
- package/sidecar/dist/constants/agent.js.map +1 -1
- package/sidecar/dist/constants/audit.d.ts +22 -0
- package/sidecar/dist/constants/audit.js +49 -0
- package/sidecar/dist/constants/audit.js.map +1 -0
- package/sidecar/dist/constants/builder.d.ts +3 -0
- package/sidecar/dist/constants/builder.js +2 -0
- package/sidecar/dist/constants/builder.js.map +1 -1
- package/sidecar/dist/constants/checkpoints.d.ts +15 -0
- package/sidecar/dist/constants/checkpoints.js +26 -0
- package/sidecar/dist/constants/checkpoints.js.map +1 -0
- package/sidecar/dist/constants/claude.d.ts +1 -0
- package/sidecar/dist/constants/claude.js +1 -0
- package/sidecar/dist/constants/claude.js.map +1 -1
- package/sidecar/dist/constants/codex.d.ts +2 -4
- package/sidecar/dist/constants/codex.js +2 -4
- package/sidecar/dist/constants/codex.js.map +1 -1
- package/sidecar/dist/constants/http.d.ts +1 -0
- package/sidecar/dist/constants/http.js +1 -0
- package/sidecar/dist/constants/http.js.map +1 -1
- package/sidecar/dist/constants/mcp.d.ts +3 -0
- package/sidecar/dist/constants/mcp.js +9 -0
- package/sidecar/dist/constants/mcp.js.map +1 -1
- package/sidecar/dist/constants/permissions.d.ts +9 -3
- package/sidecar/dist/constants/permissions.js +9 -2
- package/sidecar/dist/constants/permissions.js.map +1 -1
- package/sidecar/dist/constants/settings.d.ts +2 -1
- package/sidecar/dist/constants/settings.js +7 -1
- package/sidecar/dist/constants/settings.js.map +1 -1
- package/sidecar/dist/constants/tool-kinds.d.ts +14 -0
- package/sidecar/dist/constants/tool-kinds.js +65 -0
- package/sidecar/dist/constants/tool-kinds.js.map +1 -0
- package/sidecar/dist/index.d.ts +4 -0
- package/sidecar/dist/index.js +35 -5
- package/sidecar/dist/index.js.map +1 -1
- package/sidecar/dist/mcp/define-tool.d.ts +3 -2
- package/sidecar/dist/mcp/tool-definitions.js +4 -1
- package/sidecar/dist/mcp/tool-definitions.js.map +1 -1
- package/sidecar/dist/mcp/tools/ask-user.d.ts +2 -2
- package/sidecar/dist/mcp/tools/ask-user.js +7 -4
- package/sidecar/dist/mcp/tools/ask-user.js.map +1 -1
- package/sidecar/dist/mcp/tools/builder-catalog.d.ts +3 -0
- package/sidecar/dist/mcp/tools/builder-catalog.js +86 -0
- package/sidecar/dist/mcp/tools/builder-catalog.js.map +1 -0
- package/sidecar/dist/mcp/tools/builder-gate.d.ts +8 -0
- package/sidecar/dist/mcp/tools/builder-gate.js +22 -0
- package/sidecar/dist/mcp/tools/builder-gate.js.map +1 -0
- package/sidecar/dist/mcp/tools/builder.d.ts +7 -2
- package/sidecar/dist/mcp/tools/builder.js +48 -7
- package/sidecar/dist/mcp/tools/builder.js.map +1 -1
- package/sidecar/dist/mcp/types.d.ts +2 -0
- package/sidecar/dist/metrics/aggregate.d.ts +13 -10
- package/sidecar/dist/metrics/aggregate.js +140 -143
- package/sidecar/dist/metrics/aggregate.js.map +1 -1
- package/sidecar/dist/metrics/types.d.ts +36 -23
- package/sidecar/dist/metrics/types.js +3 -1
- package/sidecar/dist/metrics/types.js.map +1 -1
- package/sidecar/dist/pages/imports-scanner.d.ts +1 -1
- package/sidecar/dist/pages/imports-scanner.js +2 -5
- package/sidecar/dist/pages/imports-scanner.js.map +1 -1
- package/sidecar/dist/prompts/agent.d.ts +1 -3
- package/sidecar/dist/prompts/agent.js +4 -4
- package/sidecar/dist/prompts/agent.js.map +1 -1
- package/sidecar/dist/prompts/builder.d.ts +2 -2
- package/sidecar/dist/prompts/builder.js +2 -2
- package/sidecar/dist/protocol/events.d.ts +1084 -18
- package/sidecar/dist/protocol/events.js +239 -5
- package/sidecar/dist/protocol/events.js.map +1 -1
- package/sidecar/dist/protocol/messages.d.ts +273 -19
- package/sidecar/dist/protocol/messages.js +107 -7
- package/sidecar/dist/protocol/messages.js.map +1 -1
- package/sidecar/dist/providers/claude/config.d.ts +3 -2
- package/sidecar/dist/providers/claude/config.js +10 -4
- package/sidecar/dist/providers/claude/config.js.map +1 -1
- package/sidecar/dist/providers/claude/provider.d.ts +2 -8
- package/sidecar/dist/providers/claude/provider.js +37 -35
- package/sidecar/dist/providers/claude/provider.js.map +1 -1
- package/sidecar/dist/providers/claude/safe-mode.d.ts +6 -1
- package/sidecar/dist/providers/claude/safe-mode.js +13 -5
- package/sidecar/dist/providers/claude/safe-mode.js.map +1 -1
- package/sidecar/dist/providers/codex/adapter.d.ts +6 -0
- package/sidecar/dist/providers/codex/adapter.js +14 -4
- package/sidecar/dist/providers/codex/adapter.js.map +1 -1
- package/sidecar/dist/providers/codex/client.d.ts +0 -11
- package/sidecar/dist/providers/codex/config.d.ts +1 -3
- package/sidecar/dist/providers/codex/config.js +5 -11
- package/sidecar/dist/providers/codex/config.js.map +1 -1
- package/sidecar/dist/providers/codex/permissions.d.ts +7 -4
- package/sidecar/dist/providers/codex/permissions.js +32 -16
- package/sidecar/dist/providers/codex/permissions.js.map +1 -1
- package/sidecar/dist/providers/codex/process.js +1 -5
- package/sidecar/dist/providers/codex/process.js.map +1 -1
- package/sidecar/dist/providers/codex/provider.js +14 -3
- package/sidecar/dist/providers/codex/provider.js.map +1 -1
- package/sidecar/dist/providers/codex/skills.d.ts +0 -1
- package/sidecar/dist/providers/codex/skills.js +1 -1
- package/sidecar/dist/providers/codex/skills.js.map +1 -1
- package/sidecar/dist/providers/codex/stop.js +1 -10
- package/sidecar/dist/providers/codex/stop.js.map +1 -1
- package/sidecar/dist/server/change-set-actions.d.ts +10 -0
- package/sidecar/dist/server/change-set-actions.js +14 -0
- package/sidecar/dist/server/change-set-actions.js.map +1 -0
- package/sidecar/dist/server/chat-events.d.ts +15 -0
- package/sidecar/dist/server/chat-events.js +115 -0
- package/sidecar/dist/server/chat-events.js.map +1 -0
- package/sidecar/dist/server/chat-socket-registry.d.ts +2 -0
- package/sidecar/dist/server/chat-socket-registry.js +48 -37
- package/sidecar/dist/server/chat-socket-registry.js.map +1 -1
- package/sidecar/dist/server/conversation-runs.d.ts +13 -0
- package/sidecar/dist/server/conversation-runs.js +114 -0
- package/sidecar/dist/server/conversation-runs.js.map +1 -0
- package/sidecar/dist/server/http-io.d.ts +4 -0
- package/sidecar/dist/server/http-io.js +31 -0
- package/sidecar/dist/server/http-io.js.map +1 -0
- package/sidecar/dist/server/http-params.d.ts +9 -0
- package/sidecar/dist/server/http-params.js +79 -0
- package/sidecar/dist/server/http-params.js.map +1 -0
- package/sidecar/dist/server/http-routes.d.ts +27 -0
- package/sidecar/dist/server/http-routes.js +281 -0
- package/sidecar/dist/server/http-routes.js.map +1 -0
- package/sidecar/dist/server/http.d.ts +6 -1
- package/sidecar/dist/server/http.js +76 -164
- package/sidecar/dist/server/http.js.map +1 -1
- package/sidecar/dist/server/pending-queue.d.ts +2 -0
- package/sidecar/dist/server/pending-queue.js +16 -0
- package/sidecar/dist/server/pending-queue.js.map +1 -1
- package/sidecar/dist/server/permission-events.d.ts +15 -0
- package/sidecar/dist/server/permission-events.js +163 -0
- package/sidecar/dist/server/permission-events.js.map +1 -0
- package/sidecar/dist/server/routing.d.ts +4 -52
- package/sidecar/dist/server/routing.js +190 -501
- package/sidecar/dist/server/routing.js.map +1 -1
- package/sidecar/dist/server/safety-net.d.ts +7 -0
- package/sidecar/dist/server/safety-net.js +34 -6
- package/sidecar/dist/server/safety-net.js.map +1 -1
- package/sidecar/dist/server/services.d.ts +55 -0
- package/sidecar/dist/server/services.js +2 -0
- package/sidecar/dist/server/services.js.map +1 -0
- package/sidecar/dist/server/tool-calls.d.ts +6 -0
- package/sidecar/dist/server/tool-calls.js +134 -0
- package/sidecar/dist/server/tool-calls.js.map +1 -0
- package/sidecar/dist/server/turn-registry.d.ts +44 -0
- package/sidecar/dist/server/turn-registry.js +40 -0
- package/sidecar/dist/server/turn-registry.js.map +1 -0
- package/sidecar/dist/server/turns.d.ts +17 -0
- package/sidecar/dist/server/turns.js +335 -0
- package/sidecar/dist/server/turns.js.map +1 -0
- package/sidecar/dist/server/ws.d.ts +4 -1
- package/sidecar/dist/server/ws.js +102 -62
- package/sidecar/dist/server/ws.js.map +1 -1
- package/sidecar/dist/skills/build-catalog.d.ts +1 -0
- package/sidecar/dist/skills/build-catalog.js +14 -1
- package/sidecar/dist/skills/build-catalog.js.map +1 -1
- package/sidecar/dist/skills/skill-usage.d.ts +22 -0
- package/sidecar/dist/skills/skill-usage.js +97 -0
- package/sidecar/dist/skills/skill-usage.js.map +1 -0
- package/sidecar/dist/state/change-sets.d.ts +12 -0
- package/sidecar/dist/state/change-sets.js +77 -0
- package/sidecar/dist/state/change-sets.js.map +1 -0
- package/sidecar/dist/state/conversations.d.ts +19 -7
- package/sidecar/dist/state/conversations.js +61 -20
- package/sidecar/dist/state/conversations.js.map +1 -1
- package/sidecar/dist/state/host-state.d.ts +2 -1
- package/sidecar/dist/state/settings-store.d.ts +1 -0
- package/sidecar/dist/state/settings-store.js +27 -26
- package/sidecar/dist/state/settings-store.js.map +1 -1
- package/sidecar/dist/state/settings-types.d.ts +11 -1
- package/sidecar/dist/state/settings-types.js +3 -1
- package/sidecar/dist/state/settings-types.js.map +1 -1
- package/sidecar/dist/state/types.d.ts +114 -8
- package/sidecar/dist/state/types.js +6 -3
- package/sidecar/dist/state/types.js.map +1 -1
- package/skills/dms-builder-safe/REFERENCE.md +1 -1
- package/skills/dms-builder-safe/SKILL.md +12 -7
- package/dist/routes/proxy.d.ts +0 -4
- package/dist/routes/proxy.js +0 -55
- package/dist/routes/proxy.js.map +0 -1
- package/frontend-vue/app/chat/components/ComposerInput.vue +0 -742
- package/frontend-vue/app/chat/components/PermissionRequests.vue +0 -323
- package/frontend-vue/app/chat/components/QuestionPrompt.vue +0 -275
- package/frontend-vue/app/chat/components/QueuedMessages.vue +0 -109
- package/frontend-vue/app/chat/components/TodoList.vue +0 -291
- package/frontend-vue/app/chat/components/ToolCallEntry.vue +0 -218
- package/frontend-vue/app/chat/constants/connection-banner.ts +0 -7
- package/frontend-vue/app/chat/constants/conversation-drawer.ts +0 -13
- package/frontend-vue/app/chat/constants/permissions.ts +0 -50
- package/frontend-vue/app/chat/utils/tool-summary.ts +0 -53
- package/frontend-vue/app/components/ActivityView.vue +0 -94
- package/frontend-vue/app/components/SettingsView.vue +0 -387
- package/frontend-vue/app/components/SkillsView.vue +0 -230
- package/frontend-vue/app/runtime/header-action.ts +0 -64
- package/frontend-vue/app/runtime/overlay-prefs.ts +0 -89
- package/frontend-vue/app/runtime/panel-state.ts +0 -88
- package/frontend-vue/tests/overlay-prefs.test.ts +0 -91
- package/frontend-vue/tests/panel-state.test.ts +0 -58
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import type { Ref } from "vue";
|
|
2
|
+
import type { Translate } from "../chat/composables/useChatI18n";
|
|
3
|
+
import type { CurrentPage } from "../chat/types/conversation";
|
|
4
|
+
import { shortcutLabel } from "../chat/utils/platform";
|
|
5
|
+
import {
|
|
6
|
+
type PageSuggestion,
|
|
7
|
+
pageName,
|
|
8
|
+
pageSuggestions,
|
|
9
|
+
} from "../chat/utils/suggestions";
|
|
10
|
+
import {
|
|
11
|
+
CHAT_PANEL_COMPONENT_NAME,
|
|
12
|
+
COMMAND_PALETTE_ASSISTANT_ID,
|
|
13
|
+
COMMAND_PALETTE_ORDER,
|
|
14
|
+
COMMAND_PALETTE_SOURCE_ID,
|
|
15
|
+
LAUNCHER_ACTION_ID,
|
|
16
|
+
LAUNCHER_ICON,
|
|
17
|
+
LAUNCHER_LABEL_KEY,
|
|
18
|
+
LAUNCHER_ORDER,
|
|
19
|
+
PALETTE_ANSWER_COMPONENT_NAME,
|
|
20
|
+
PALETTE_ASSISTANT_LABEL,
|
|
21
|
+
PALETTE_ASSISTANT_PLACEHOLDER,
|
|
22
|
+
PANEL_ARIA_LABEL,
|
|
23
|
+
PANEL_DEFAULT_WIDTH_PX,
|
|
24
|
+
PANEL_MAX_WIDTH_PX,
|
|
25
|
+
PANEL_MIN_WIDTH_PX,
|
|
26
|
+
SIDE_PANEL_ID,
|
|
27
|
+
TOGGLE_SHORTCUT_KEY,
|
|
28
|
+
} from "./constants";
|
|
29
|
+
|
|
30
|
+
/** The panel, in the shape `registerSidePanel` takes. */
|
|
31
|
+
export interface AssistantSidePanel {
|
|
32
|
+
id: string;
|
|
33
|
+
component: string;
|
|
34
|
+
ariaLabel: string;
|
|
35
|
+
defaultWidth: number;
|
|
36
|
+
minWidth: number;
|
|
37
|
+
maxWidth: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The header button, in the shape `registerHeaderAction` takes. */
|
|
41
|
+
export interface LauncherAction {
|
|
42
|
+
id: string;
|
|
43
|
+
icon: string;
|
|
44
|
+
label: string;
|
|
45
|
+
order: number;
|
|
46
|
+
sidePanelId: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** One entry of the command palette. */
|
|
50
|
+
interface PaletteItem {
|
|
51
|
+
id: string;
|
|
52
|
+
label: string;
|
|
53
|
+
icon: string;
|
|
54
|
+
suffix?: string;
|
|
55
|
+
onSelect: () => void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface PaletteGroup {
|
|
59
|
+
id: string;
|
|
60
|
+
label: string;
|
|
61
|
+
items: PaletteItem[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** A command palette source, in the shape `registerCommandPaletteSource` takes. */
|
|
65
|
+
export interface PaletteSource {
|
|
66
|
+
id: string;
|
|
67
|
+
order: number;
|
|
68
|
+
groups: () => PaletteGroup[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** A first prompt the palette's assistant mode offers. */
|
|
72
|
+
interface PaletteSuggestion {
|
|
73
|
+
label: string;
|
|
74
|
+
icon: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** The palette's assistant mode, in the shape `registerCommandPaletteAssistant` takes. */
|
|
78
|
+
export interface PaletteAssistant {
|
|
79
|
+
id: string;
|
|
80
|
+
label: string;
|
|
81
|
+
icon: string;
|
|
82
|
+
placeholder: string;
|
|
83
|
+
suggestions: () => PaletteSuggestion[];
|
|
84
|
+
answerComponent: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** What the palette's entries do. */
|
|
88
|
+
export interface AssistantCommandActions {
|
|
89
|
+
ask: () => void;
|
|
90
|
+
startConversation: () => void;
|
|
91
|
+
reviewApprovals: () => void;
|
|
92
|
+
openChanges: () => void;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** The panel docked on the right of the dashboard; the DMS owns its state. */
|
|
96
|
+
export function assistantSidePanel(): AssistantSidePanel {
|
|
97
|
+
return {
|
|
98
|
+
id: SIDE_PANEL_ID,
|
|
99
|
+
component: CHAT_PANEL_COMPONENT_NAME,
|
|
100
|
+
ariaLabel: PANEL_ARIA_LABEL,
|
|
101
|
+
defaultWidth: PANEL_DEFAULT_WIDTH_PX,
|
|
102
|
+
minWidth: PANEL_MIN_WIDTH_PX,
|
|
103
|
+
maxWidth: PANEL_MAX_WIDTH_PX,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* "Assistant (⌘⇧K)": the launcher's label with its shortcut. The DMS toggles
|
|
109
|
+
* the panel from it and draws it engaged while the panel is open.
|
|
110
|
+
*/
|
|
111
|
+
export function launcherAction(t: Translate): LauncherAction {
|
|
112
|
+
return {
|
|
113
|
+
id: LAUNCHER_ACTION_ID,
|
|
114
|
+
icon: LAUNCHER_ICON,
|
|
115
|
+
label: `${t(LAUNCHER_LABEL_KEY)} (${shortcutLabel(TOGGLE_SHORTCUT_KEY, true)})`,
|
|
116
|
+
order: LAUNCHER_ORDER,
|
|
117
|
+
sidePanelId: SIDE_PANEL_ID,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** The palette answers read-only: what it can answer in place comes first. */
|
|
122
|
+
function byReadOnlyFirst(
|
|
123
|
+
suggestions: readonly PageSuggestion[],
|
|
124
|
+
): PageSuggestion[] {
|
|
125
|
+
return [...suggestions].sort(
|
|
126
|
+
(left, right) => Number(right.isReadOnly) - Number(left.isReadOnly),
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The palette's assistant mode (Tab in ⌘K): first prompts that fit the page on
|
|
132
|
+
* screen, as the panel's empty chat offers them, and an answer drawn by
|
|
133
|
+
* `DmsAiPaletteAnswer`.
|
|
134
|
+
*/
|
|
135
|
+
export function paletteAssistant(
|
|
136
|
+
t: Translate,
|
|
137
|
+
currentPage: Readonly<Ref<CurrentPage | null>>,
|
|
138
|
+
): PaletteAssistant {
|
|
139
|
+
return {
|
|
140
|
+
id: COMMAND_PALETTE_ASSISTANT_ID,
|
|
141
|
+
label: PALETTE_ASSISTANT_LABEL,
|
|
142
|
+
icon: LAUNCHER_ICON,
|
|
143
|
+
placeholder: PALETTE_ASSISTANT_PLACEHOLDER,
|
|
144
|
+
suggestions: () => {
|
|
145
|
+
const page = currentPage.value;
|
|
146
|
+
return byReadOnlyFirst(pageSuggestions(page)).map((suggestion) => ({
|
|
147
|
+
label: t(suggestion.textKey, { page: pageName(page) }),
|
|
148
|
+
icon: suggestion.icon,
|
|
149
|
+
}));
|
|
150
|
+
},
|
|
151
|
+
answerComponent: PALETTE_ANSWER_COMPONENT_NAME,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The assistant's commands among the palette's search results: ways into the
|
|
157
|
+
* panel and its pages. Asking a question inline is the palette's assistant
|
|
158
|
+
* mode, registered apart.
|
|
159
|
+
*/
|
|
160
|
+
export function paletteSource(
|
|
161
|
+
t: Translate,
|
|
162
|
+
pendingApprovals: Readonly<Ref<number>>,
|
|
163
|
+
actions: AssistantCommandActions,
|
|
164
|
+
): PaletteSource {
|
|
165
|
+
return {
|
|
166
|
+
id: COMMAND_PALETTE_SOURCE_ID,
|
|
167
|
+
order: COMMAND_PALETTE_ORDER,
|
|
168
|
+
groups: () => [
|
|
169
|
+
{
|
|
170
|
+
id: `${COMMAND_PALETTE_SOURCE_ID}-assistant`,
|
|
171
|
+
label: t("dms_ai.panel.palette.group"),
|
|
172
|
+
items: [
|
|
173
|
+
{
|
|
174
|
+
id: "dms-ai-ask",
|
|
175
|
+
label: t("dms_ai.panel.palette.ask"),
|
|
176
|
+
icon: "i-ph-sparkle",
|
|
177
|
+
suffix: shortcutLabel(TOGGLE_SHORTCUT_KEY, true),
|
|
178
|
+
onSelect: actions.ask,
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: "dms-ai-new",
|
|
182
|
+
label: t("dms_ai.panel.palette.new"),
|
|
183
|
+
icon: "i-ph-note-pencil",
|
|
184
|
+
onSelect: actions.startConversation,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: "dms-ai-approvals",
|
|
188
|
+
label: t("dms_ai.panel.palette.approvals"),
|
|
189
|
+
icon: "i-ph-hand-palm",
|
|
190
|
+
suffix:
|
|
191
|
+
pendingApprovals.value > 0
|
|
192
|
+
? t(
|
|
193
|
+
"dms_ai.panel.palette.waiting",
|
|
194
|
+
{ count: pendingApprovals.value },
|
|
195
|
+
pendingApprovals.value,
|
|
196
|
+
)
|
|
197
|
+
: undefined,
|
|
198
|
+
onSelect: actions.reviewApprovals,
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
id: "dms-ai-changes",
|
|
202
|
+
label: t("dms_ai.panel.palette.changes"),
|
|
203
|
+
icon: "i-ph-git-diff",
|
|
204
|
+
onSelect: actions.openChanges,
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
};
|
|
210
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { type Ref, watch } from "vue";
|
|
2
|
+
import type { Translate } from "../chat/composables/useChatI18n";
|
|
3
|
+
import type { ChangeSetSummary } from "../chat/types/protocol";
|
|
4
|
+
import type { ChatTransport } from "./chat-transport";
|
|
5
|
+
import { TOAST_DURATION_MS } from "./constants";
|
|
6
|
+
import { isTypedMessage } from "./typed-message";
|
|
7
|
+
|
|
8
|
+
/** One button of a toast, as Nuxt UI's `useToast().add` takes it. */
|
|
9
|
+
interface ToastAction {
|
|
10
|
+
label: string;
|
|
11
|
+
color?: "secondary" | "neutral";
|
|
12
|
+
variant?: "solid" | "outline";
|
|
13
|
+
onClick: () => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ToastInput {
|
|
17
|
+
title: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
icon: string;
|
|
20
|
+
color: "secondary";
|
|
21
|
+
duration: number;
|
|
22
|
+
actions: ToastAction[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AssistantNotificationsOptions {
|
|
26
|
+
chat: ChatTransport;
|
|
27
|
+
isPanelOpen: Readonly<Ref<boolean>>;
|
|
28
|
+
pendingApprovals: Readonly<Ref<number>>;
|
|
29
|
+
t: Translate;
|
|
30
|
+
toast: (input: ToastInput) => void;
|
|
31
|
+
reviewApprovals: (conversationId?: string) => void;
|
|
32
|
+
undoChangeSet: (changeSet: ChangeSetSummary) => void;
|
|
33
|
+
reviewChangeSet: (changeSetId: string) => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface PermissionRequestFrame {
|
|
37
|
+
type: "permission_request";
|
|
38
|
+
conversationId?: string;
|
|
39
|
+
summary?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface ChangeSetFrame {
|
|
43
|
+
type: "change_set";
|
|
44
|
+
changeSet?: ChangeSetSummary;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface SettingsFrame {
|
|
48
|
+
type: "settings_update";
|
|
49
|
+
settings?: SettingsFlags;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface SettingsFlags {
|
|
53
|
+
notifyRequests?: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const ICON = "i-ph-sparkle";
|
|
57
|
+
|
|
58
|
+
interface NotifierState {
|
|
59
|
+
options: AssistantNotificationsOptions;
|
|
60
|
+
isEnabled: boolean;
|
|
61
|
+
announcedApprovals: number;
|
|
62
|
+
seenChangeSets: Set<string>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function approvalToast(
|
|
66
|
+
state: NotifierState,
|
|
67
|
+
title: string,
|
|
68
|
+
conversationId?: string,
|
|
69
|
+
): void {
|
|
70
|
+
const { t, toast, reviewApprovals, pendingApprovals } = state.options;
|
|
71
|
+
const count = Math.max(pendingApprovals.value, 1);
|
|
72
|
+
state.announcedApprovals = count;
|
|
73
|
+
toast({
|
|
74
|
+
title,
|
|
75
|
+
description: t("dms_ai.panel.toast.approvals_waiting", { count }, count),
|
|
76
|
+
icon: ICON,
|
|
77
|
+
color: "secondary",
|
|
78
|
+
duration: TOAST_DURATION_MS,
|
|
79
|
+
actions: [
|
|
80
|
+
{
|
|
81
|
+
label: t("dms_ai.panel.toast.review"),
|
|
82
|
+
color: "secondary",
|
|
83
|
+
onClick: () => reviewApprovals(conversationId),
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
label: t("dms_ai.panel.toast.later"),
|
|
87
|
+
color: "neutral",
|
|
88
|
+
variant: "outline",
|
|
89
|
+
onClick: () => undefined,
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function onPermissionRequest(
|
|
96
|
+
state: NotifierState,
|
|
97
|
+
frame: PermissionRequestFrame,
|
|
98
|
+
): void {
|
|
99
|
+
if (state.options.isPanelOpen.value || !state.isEnabled) return;
|
|
100
|
+
const title = frame.summary
|
|
101
|
+
? t(state, "dms_ai.panel.toast.request_title", { summary: frame.summary })
|
|
102
|
+
: t(state, "dms_ai.panel.toast.request_generic");
|
|
103
|
+
approvalToast(state, title, frame.conversationId);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function t(
|
|
107
|
+
state: NotifierState,
|
|
108
|
+
key: string,
|
|
109
|
+
params?: Record<string, string | number>,
|
|
110
|
+
): string {
|
|
111
|
+
return state.options.t(key, params);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function onChangeSet(state: NotifierState, frame: ChangeSetFrame): void {
|
|
115
|
+
const set = frame.changeSet;
|
|
116
|
+
if (set === undefined || state.seenChangeSets.has(set.id)) return;
|
|
117
|
+
state.seenChangeSets.add(set.id);
|
|
118
|
+
if (set.state !== "applied" || state.options.isPanelOpen.value) return;
|
|
119
|
+
const { toast, undoChangeSet, reviewChangeSet } = state.options;
|
|
120
|
+
toast({
|
|
121
|
+
title: t(state, "dms_ai.panel.toast.applied", { number: set.number }),
|
|
122
|
+
description: set.title,
|
|
123
|
+
icon: ICON,
|
|
124
|
+
color: "secondary",
|
|
125
|
+
duration: TOAST_DURATION_MS,
|
|
126
|
+
actions: [
|
|
127
|
+
{
|
|
128
|
+
label: t(state, "dms_ai.panel.change.undo"),
|
|
129
|
+
color: "neutral",
|
|
130
|
+
variant: "outline",
|
|
131
|
+
onClick: () => undoChangeSet(set),
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
label: t(state, "dms_ai.panel.change.review"),
|
|
135
|
+
color: "secondary",
|
|
136
|
+
onClick: () => reviewChangeSet(set.id),
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const FRAME_HANDLERS: Record<
|
|
143
|
+
string,
|
|
144
|
+
(state: NotifierState, frame: never) => void
|
|
145
|
+
> = {
|
|
146
|
+
permission_request: onPermissionRequest,
|
|
147
|
+
change_set: onChangeSet,
|
|
148
|
+
settings_update: (state, frame: SettingsFrame) => {
|
|
149
|
+
state.isEnabled = frame.settings?.notifyRequests !== false;
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* DMS toasts for what happens while the panel is closed: a request waiting
|
|
155
|
+
* for the user (when the settings allow it) and a change set just applied,
|
|
156
|
+
* with Undo. A request the stream did not carry is caught by the polled count.
|
|
157
|
+
*/
|
|
158
|
+
export function installAssistantNotifications(
|
|
159
|
+
options: AssistantNotificationsOptions,
|
|
160
|
+
): () => void {
|
|
161
|
+
const state: NotifierState = {
|
|
162
|
+
options,
|
|
163
|
+
isEnabled: true,
|
|
164
|
+
announcedApprovals: options.pendingApprovals.value,
|
|
165
|
+
seenChangeSets: new Set(),
|
|
166
|
+
};
|
|
167
|
+
const stopListening = options.chat.onMessage((msg) => {
|
|
168
|
+
if (!isTypedMessage(msg)) return;
|
|
169
|
+
FRAME_HANDLERS[msg.type]?.(state, msg as never);
|
|
170
|
+
});
|
|
171
|
+
const stopWatching = watch(options.pendingApprovals, (count) => {
|
|
172
|
+
const isNew = count > state.announcedApprovals;
|
|
173
|
+
if (!isNew) state.announcedApprovals = count;
|
|
174
|
+
if (!isNew || options.isPanelOpen.value || !state.isEnabled) return;
|
|
175
|
+
approvalToast(state, t(state, "dms_ai.panel.toast.request_generic"));
|
|
176
|
+
});
|
|
177
|
+
return () => {
|
|
178
|
+
stopListening();
|
|
179
|
+
stopWatching();
|
|
180
|
+
};
|
|
181
|
+
}
|
|
@@ -1,12 +1,27 @@
|
|
|
1
|
-
import type { InjectionKey, Ref } from "vue";
|
|
1
|
+
import type { InjectionKey, Ref, ShallowRef } from "vue";
|
|
2
|
+
import type { ChatApi } from "../chat/composables/useChangeSetActions";
|
|
3
|
+
import type { CurrentPage } from "../chat/types/conversation";
|
|
2
4
|
import type { ChatTransport } from "./chat-transport";
|
|
3
|
-
import type {
|
|
5
|
+
import type { PanelIntents } from "./panel-intents";
|
|
4
6
|
import type { SidecarStatus } from "./sidecar-status";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
9
|
+
* Whether the assistant panel is open, and the ways to change it. The DMS owns
|
|
10
|
+
* the state (`useSidePanel`): it remembers it in a cookie, renders the panel
|
|
11
|
+
* docked next to the page, and the header launcher toggles it.
|
|
12
|
+
*/
|
|
13
|
+
export interface ChatPanelState {
|
|
14
|
+
isOpen: Readonly<Ref<boolean>>;
|
|
15
|
+
open: () => void;
|
|
16
|
+
close: () => void;
|
|
17
|
+
toggle: () => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The tab's assistant, as the plugin that owns it hands it to the panel, the
|
|
22
|
+
* command palette's answer and the workspace pages: the sidecar's
|
|
23
|
+
* reachability, the chat's side of the tab's stream, the panel's state, and
|
|
24
|
+
* ways to open it on a chat.
|
|
10
25
|
*/
|
|
11
26
|
export interface AssistantSession {
|
|
12
27
|
status: Readonly<Ref<SidecarStatus>>;
|
|
@@ -14,8 +29,36 @@ export interface AssistantSession {
|
|
|
14
29
|
panel: ChatPanelState;
|
|
15
30
|
/** Opens a page of the dashboard, as its own links do. */
|
|
16
31
|
navigate: (path: string) => void;
|
|
32
|
+
/** Opens the panel on that conversation. */
|
|
33
|
+
openConversation: (conversationId: string) => void;
|
|
34
|
+
/** Opens the panel on a new conversation, the composer optionally prefilled. */
|
|
35
|
+
startConversation: (prompt?: string) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Keeps the tab's stream open while the panel is closed, until the returned
|
|
38
|
+
* function releases it: the command palette's answer streams through it.
|
|
39
|
+
*/
|
|
40
|
+
holdStream: () => () => void;
|
|
41
|
+
/** Requests waiting for an answer, across every chat. */
|
|
42
|
+
pendingApprovals: Readonly<Ref<number>>;
|
|
43
|
+
/** What the panel was asked to do and has not done yet. */
|
|
44
|
+
intents: PanelIntents;
|
|
45
|
+
/** The page the dashboard shows. */
|
|
46
|
+
currentPage: Readonly<Ref<CurrentPage | null>>;
|
|
47
|
+
/** The dashboard's authenticated requests, for the panel's own HTTP calls. */
|
|
48
|
+
api: ChatApi;
|
|
49
|
+
/** Why the sidecar last failed to start, when the backend knows. */
|
|
50
|
+
lastError: Readonly<Ref<string | null>>;
|
|
51
|
+
/** Asks the backend to restart the sidecar, then probes it again. */
|
|
52
|
+
restart: () => Promise<void>;
|
|
17
53
|
}
|
|
18
54
|
|
|
19
|
-
|
|
55
|
+
/**
|
|
56
|
+
* The tab's assistant session, provided from the start: `null` until the
|
|
57
|
+
* sidecar answered its first probe, and for good when the assistant does not
|
|
58
|
+
* run in this tab (production, a guest, the sidecar disabled).
|
|
59
|
+
*/
|
|
60
|
+
export type AssistantSessionRef = Readonly<ShallowRef<AssistantSession | null>>;
|
|
61
|
+
|
|
62
|
+
export const ASSISTANT_SESSION_KEY: InjectionKey<AssistantSessionRef> = Symbol(
|
|
20
63
|
"dms-ai:assistant-session",
|
|
21
64
|
);
|
|
@@ -26,13 +26,10 @@ export type ChannelStatus =
|
|
|
26
26
|
| typeof CHANNEL_STATUS_RECONNECTING;
|
|
27
27
|
|
|
28
28
|
/** Posts one message as JSON; `$authFetch` in the dashboard refreshes a stale session. */
|
|
29
|
-
|
|
29
|
+
type PostMessage = (path: string, body: unknown) => Promise<unknown>;
|
|
30
30
|
|
|
31
31
|
/** Opens the tab's event stream. */
|
|
32
|
-
|
|
33
|
-
path: string,
|
|
34
|
-
signal: AbortSignal,
|
|
35
|
-
) => Promise<Response>;
|
|
32
|
+
type OpenStream = (path: string, signal: AbortSignal) => Promise<Response>;
|
|
36
33
|
|
|
37
34
|
export interface ChannelClientOptions {
|
|
38
35
|
post: PostMessage;
|
|
@@ -80,7 +77,7 @@ interface ClientState {
|
|
|
80
77
|
backoff: BackoffState;
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
|
|
80
|
+
function channelMessagesPath(connectionId: string): string {
|
|
84
81
|
return `${CHANNEL_PATH}/${encodeURIComponent(connectionId)}/${CHANNEL_MESSAGES_SEGMENT}`;
|
|
85
82
|
}
|
|
86
83
|
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
export const OVERLAY_DEFAULT_WIDTH_PX = 460;
|
|
2
|
-
/**
|
|
3
|
-
* Above the dashboard's header and the builder's overlay (z-50), below what the
|
|
4
|
-
* dashboard portals out of the app: the DMS paints its popovers, modals and
|
|
5
|
-
* toasts in an isolated layer after the app, whatever this value is.
|
|
6
|
-
*/
|
|
7
|
-
export const OVERLAY_Z_INDEX = 55;
|
|
8
|
-
export const OVERLAY_DOM_ID = "dms-ai-overlay-root";
|
|
9
|
-
export const DMS_OVERLAYS_DOM_ID = "dms-overlays";
|
|
10
1
|
export const SIDECAR_INFO_PATH = "/ai/sidecar-info";
|
|
11
2
|
/** Event stream to receive, POST to send: HTTP the DMS frontend server relays. */
|
|
12
3
|
export const CHANNEL_PATH = "/ai/channel";
|
|
@@ -39,10 +30,6 @@ export const SIDECAR_STATUS_UNAVAILABLE = "unavailable";
|
|
|
39
30
|
// side, so this doubles as the respawn heartbeat; capped so a genuinely stuck
|
|
40
31
|
// sidecar is polled sparingly rather than hammered.
|
|
41
32
|
export const SIDECAR_POLL_DELAYS_MS = [500, 1000, 2000, 4000, 8000] as const;
|
|
42
|
-
export const PLACEHOLDER_CONNECTING_TEXT = "Connecting the assistant…";
|
|
43
|
-
export const PLACEHOLDER_REVIVING_TEXT = "Reconnecting the assistant…";
|
|
44
|
-
export const PLACEHOLDER_UNAVAILABLE_TITLE = "Assistant unavailable";
|
|
45
|
-
export const PLACEHOLDER_UNAVAILABLE_TEXT = "Reload the page to try again.";
|
|
46
33
|
|
|
47
34
|
export const CHANNEL_STATUS_CONNECTING = "connecting";
|
|
48
35
|
export const CHANNEL_STATUS_CONNECTED = "connected";
|
|
@@ -58,34 +45,41 @@ export const HOST_COMMAND_NAVIGATE_TYPE = "host_command_navigate";
|
|
|
58
45
|
export const HOST_COMMAND_TYPES: ReadonlySet<string> = new Set([
|
|
59
46
|
HOST_COMMAND_NAVIGATE_TYPE,
|
|
60
47
|
]);
|
|
61
|
-
export const OVERLAY_MIN_WIDTH_PX = 320;
|
|
62
|
-
export const OVERLAY_PREFS_STORAGE_KEY = "dms-ai:overlay-prefs";
|
|
63
|
-
export const OVERLAY_OUTSIDE_TOGGLE_SUPPRESS_MS = 300;
|
|
64
|
-
export const OVERLAY_PREFS_DEBOUNCE_MS = 300;
|
|
65
48
|
export const TOGGLE_SHORTCUT_KEY = "k";
|
|
66
49
|
export const MODAL_OPEN_SELECTOR = '[role="dialog"][aria-modal="true"]';
|
|
67
50
|
|
|
68
|
-
// Generic header-action registry exposed by the DMS core (dms-back). Any module
|
|
69
|
-
// can push a button by writing to this shared `useDmsState` key; the core renders
|
|
70
|
-
// it with no knowledge of who registered it.
|
|
71
|
-
export const HEADER_ACTIONS_STATE_KEY = "dms:header-actions";
|
|
72
|
-
/**
|
|
73
|
-
* The DMS's persistent overlays: components rendered on every page, inside the
|
|
74
|
-
* app but outside the routed page, so they live through Inertia navigations.
|
|
75
|
-
* The state key and the component name are the whole contract.
|
|
76
|
-
*/
|
|
77
|
-
export const APP_OVERLAYS_STATE_KEY = "dms-app-overlays";
|
|
78
51
|
export const CHAT_PANEL_COMPONENT_NAME = "DmsAiChatPanel";
|
|
52
|
+
/** The panel's id among the dashboard's docked side panels. */
|
|
53
|
+
export const SIDE_PANEL_ID = "dms-ai:assistant";
|
|
54
|
+
export const PANEL_DEFAULT_WIDTH_PX = 460;
|
|
55
|
+
export const PANEL_MIN_WIDTH_PX = 360;
|
|
56
|
+
/** Wide enough for a diff side by side; the DMS caps it at 60% of the window too. */
|
|
57
|
+
export const PANEL_MAX_WIDTH_PX = 820;
|
|
58
|
+
export const COMMAND_PALETTE_ASSISTANT_ID = "dms-ai:assistant";
|
|
59
|
+
export const PALETTE_ANSWER_COMPONENT_NAME = "DmsAiPaletteAnswer";
|
|
60
|
+
export const PALETTE_ASSISTANT_LABEL = "$dms_ai.panel.palette.assistant";
|
|
61
|
+
export const PALETTE_ASSISTANT_PLACEHOLDER =
|
|
62
|
+
"$dms_ai.panel.palette.placeholder";
|
|
79
63
|
export const LAUNCHER_ACTION_ID = "dms-ai-launcher";
|
|
80
64
|
/**
|
|
81
65
|
* The chat panel's header shows the same icon, which is what gets it into the
|
|
82
|
-
* renderer's icon bundle
|
|
66
|
+
* renderer's icon bundle.
|
|
83
67
|
*/
|
|
84
|
-
export const LAUNCHER_ICON = "i-ph-
|
|
85
|
-
export const LAUNCHER_LABEL = "AI assistant";
|
|
86
|
-
export const PANEL_LABEL = LAUNCHER_LABEL;
|
|
68
|
+
export const LAUNCHER_ICON = "i-ph-sparkle";
|
|
87
69
|
export const LAUNCHER_ORDER = 50;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
export const
|
|
91
|
-
export const
|
|
70
|
+
export const LAUNCHER_LABEL_KEY = "dms_ai.panel.launcher";
|
|
71
|
+
/** The panel landmark's name, as an i18n key the DMS resolves. */
|
|
72
|
+
export const PANEL_ARIA_LABEL = `$${LAUNCHER_LABEL_KEY}`;
|
|
73
|
+
export const COMMAND_PALETTE_SOURCE_ID = "dms-ai";
|
|
74
|
+
export const COMMAND_PALETTE_ORDER = 60;
|
|
75
|
+
/** The backend's view of the sidecar: pending approvals, last start error. */
|
|
76
|
+
export const STATUS_PATH = "/ai/status";
|
|
77
|
+
export const RESTART_PATH = "/ai/sidecar/restart";
|
|
78
|
+
export const CHANGES_PATH = "/modules/ai/changes";
|
|
79
|
+
/**
|
|
80
|
+
* How often a closed panel re-reads the pending approvals, so a request that
|
|
81
|
+
* arrives while no stream is open still gets its toast.
|
|
82
|
+
*/
|
|
83
|
+
export const STATUS_POLL_MS = 15_000;
|
|
84
|
+
/** How long the panel's toasts stay up. */
|
|
85
|
+
export const TOAST_DURATION_MS = 8_000;
|
|
@@ -6,7 +6,7 @@ interface RouterLike {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* The slice of the host's `
|
|
9
|
+
* The slice of the host's `useDevReload()` composable this module needs:
|
|
10
10
|
* resolve `true` once the committed site layout serves `path`, `false` on
|
|
11
11
|
* timeout.
|
|
12
12
|
*/
|
|
@@ -19,12 +19,12 @@ export interface HostCommandContext {
|
|
|
19
19
|
devReload: DevReloadWaiter;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
interface HostCommandNavigateMessage {
|
|
23
23
|
type: typeof HOST_COMMAND_NAVIGATE_TYPE;
|
|
24
24
|
path: string;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
type HostCommandMessage = HostCommandNavigateMessage;
|
|
28
28
|
|
|
29
29
|
/** Takes a sidecar message already parsed; anything that is not a host command is ignored. */
|
|
30
30
|
export type HostCommandDispatcher = (msg: unknown) => void;
|
|
@@ -84,7 +84,7 @@ async function runNavigate(state: DispatcherState): Promise<void> {
|
|
|
84
84
|
* Whether the agent may send the dashboard to `path`. What it asks for comes
|
|
85
85
|
* from model output, so it may only ever lead to a page of this origin.
|
|
86
86
|
*/
|
|
87
|
-
|
|
87
|
+
function isInAppPath(path: unknown): path is string {
|
|
88
88
|
if (typeof path !== "string" || !IN_APP_PATH.test(path)) return false;
|
|
89
89
|
try {
|
|
90
90
|
const origin = globalThis.location.origin;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { router } from "@inertiajs/vue3";
|
|
2
2
|
import { HOST_NAVIGATION_COMPLETE_TYPE } from "./constants";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
interface HostNavigationCompleteMessage {
|
|
5
5
|
type: typeof HOST_NAVIGATION_COMPLETE_TYPE;
|
|
6
6
|
path: string;
|
|
7
7
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Ref, ref } from "vue";
|
|
2
|
+
|
|
3
|
+
/** Opens the panel on a stored conversation. */
|
|
4
|
+
interface OpenConversationIntent {
|
|
5
|
+
kind: "open";
|
|
6
|
+
conversationId: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** Opens the panel on a new conversation, the composer optionally prefilled. */
|
|
10
|
+
interface StartConversationIntent {
|
|
11
|
+
kind: "start";
|
|
12
|
+
prompt?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Puts the caret in the composer of the current conversation. */
|
|
16
|
+
interface FocusComposerIntent {
|
|
17
|
+
kind: "focus";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Brings the approvals dock forward. */
|
|
21
|
+
interface ReviewApprovalsIntent {
|
|
22
|
+
kind: "approvals";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type PanelIntent =
|
|
26
|
+
| OpenConversationIntent
|
|
27
|
+
| StartConversationIntent
|
|
28
|
+
| FocusComposerIntent
|
|
29
|
+
| ReviewApprovalsIntent;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* What the dashboard asked the panel to do: open a chat, start one, focus the
|
|
33
|
+
* composer. The chat may not be mounted yet when it is asked, so the latest
|
|
34
|
+
* request waits here until the chat takes it.
|
|
35
|
+
*/
|
|
36
|
+
export interface PanelIntents {
|
|
37
|
+
pending: Readonly<Ref<PanelIntent | null>>;
|
|
38
|
+
push: (intent: PanelIntent) => void;
|
|
39
|
+
take: () => PanelIntent | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function createPanelIntents(): PanelIntents {
|
|
43
|
+
const pending = ref<PanelIntent | null>(null);
|
|
44
|
+
return {
|
|
45
|
+
pending,
|
|
46
|
+
push: (intent) => {
|
|
47
|
+
pending.value = intent;
|
|
48
|
+
},
|
|
49
|
+
take: () => {
|
|
50
|
+
const intent = pending.value;
|
|
51
|
+
pending.value = null;
|
|
52
|
+
return intent;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|