@antelopejs/dms-ai 0.6.0 → 0.7.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 +2 -2
- package/dist/builder/presence.js.map +1 -1
- package/dist/channels/bridge.js +4 -2
- package/dist/channels/bridge.js.map +1 -1
- package/dist/channels/sse-stream.d.ts +1 -1
- package/dist/config.d.ts +6 -1
- package/dist/config.js +9 -21
- package/dist/config.js.map +1 -1
- package/dist/constants/channels.d.ts +5 -1
- package/dist/constants/channels.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/build-id.js +1 -1
- package/dist/lifecycle/build-id.js.map +1 -1
- package/dist/lifecycle/module-roots.js +12 -14
- package/dist/lifecycle/module-roots.js.map +1 -1
- package/dist/lifecycle/sidecar-owner.js.map +1 -1
- package/dist/lifecycle/skill-sources.js +35 -22
- package/dist/lifecycle/skill-sources.js.map +1 -1
- package/dist/lifecycle/spawn-sidecar.js +11 -6
- package/dist/lifecycle/spawn-sidecar.js.map +1 -1
- package/dist/logging/log-buffer.js +6 -2
- package/dist/logging/log-buffer.js.map +1 -1
- package/dist/pages/activity/columns.d.ts +66 -2
- package/dist/pages/activity/columns.js.map +1 -1
- package/dist/pages/activity/page.js.map +1 -1
- package/dist/pages/index.js.map +1 -1
- package/dist/pages/overview/page.js.map +1 -1
- package/dist/pages/overview/recent-changes.js.map +1 -1
- package/dist/pages/settings/availability.d.ts +1 -1
- package/dist/pages/settings/availability.js +19 -5
- package/dist/pages/settings/availability.js.map +1 -1
- package/dist/pages/settings/page.js +1 -1
- package/dist/pages/settings/page.js.map +1 -1
- package/dist/pages/skills/page.js.map +1 -1
- package/dist/pages-registry.js +9 -10
- package/dist/pages-registry.js.map +1 -1
- package/dist/routes/activity.d.ts +5 -4
- package/dist/routes/activity.js.map +1 -1
- package/dist/routes/changes.d.ts +6 -4
- package/dist/routes/changes.js.map +1 -1
- package/dist/routes/codex-account.d.ts +5 -1
- package/dist/routes/codex-account.js +2 -2
- package/dist/routes/codex-account.js.map +1 -1
- package/dist/routes/database.d.ts +21 -4
- package/dist/routes/database.js.map +1 -1
- package/dist/routes/metric-shapes.js +8 -5
- package/dist/routes/metric-shapes.js.map +1 -1
- package/dist/routes/metrics.d.ts +4 -2
- package/dist/routes/metrics.js +2 -2
- package/dist/routes/metrics.js.map +1 -1
- package/dist/routes/pages-registry.js.map +1 -1
- package/dist/routes/settings.d.ts +4 -3
- package/dist/routes/settings.js +4 -15
- package/dist/routes/settings.js.map +1 -1
- package/dist/routes/sidecar-info.js.map +1 -1
- package/dist/routes/sidecar-results.d.ts +2 -2
- package/dist/routes/sidecar-results.js +10 -10
- package/dist/routes/sidecar-results.js.map +1 -1
- package/dist/routes/skills.d.ts +2 -1
- package/dist/routes/skills.js +6 -4
- package/dist/routes/skills.js.map +1 -1
- package/dist/routes/status-shapes.js +12 -12
- package/dist/routes/status-shapes.js.map +1 -1
- package/dist/routes/undo-confirm.js.map +1 -1
- package/dist/sidecar/http-client.js.map +1 -1
- package/dist/sidecar/index.d.ts +1 -0
- package/dist/sidecar/index.js +1 -0
- package/dist/sidecar/index.js.map +1 -1
- package/dist/sidecar/settings-values.d.ts +3 -0
- package/dist/sidecar/settings-values.js +21 -0
- package/dist/sidecar/settings-values.js.map +1 -0
- package/dist/vocabulary/tools.js.map +1 -1
- package/frontend-vue/app/chat/components/ChatView.vue +33 -133
- package/frontend-vue/app/chat/components/ProviderNotice.vue +77 -0
- package/frontend-vue/app/chat/components/UndoConflictModal.vue +98 -0
- package/frontend-vue/app/chat/composables/useChangeSetActions.ts +1 -1
- package/frontend-vue/app/plugins/ai.client.ts +10 -2
- package/frontend-vue/app/runtime/assistant-actions.ts +41 -0
- package/frontend-vue/app/runtime/assistant-session.ts +8 -2
- package/frontend-vue/app/runtime/panel-intents.ts +3 -1
- package/frontend-vue/build/backend-boundary.ts +89 -0
- package/frontend-vue/dms.frontend.build.ts +6 -0
- package/frontend-vue/package.json +2 -1
- package/frontend-vue/pnpm-lock.yaml +3 -0
- package/frontend-vue/tests/assistant-actions.test.ts +72 -0
- package/frontend-vue/tests/backend-boundary.test.ts +130 -0
- package/frontend-vue/tests/panel-approvals.test.ts +190 -0
- package/frontend-vue/tests/panel-questions.test.ts +169 -0
- package/frontend-vue/tests/panel-states.test.ts +1 -556
- package/frontend-vue/tests/panel-tools.test.ts +165 -0
- package/frontend-vue/tests/sidecar-guest.test.ts +39 -71
- package/frontend-vue/tests/support/panel-fixtures.ts +110 -0
- package/frontend-vue/tests/support/panel-harness.ts +2 -2
- package/frontend-vue/vitest.config.ts +2 -1
- package/package.json +21 -10
- package/sidecar/dist/agent/attachment-files.js.map +1 -1
- package/sidecar/dist/agent/call-ledger.d.ts +3 -2
- package/sidecar/dist/agent/call-ledger.js +1 -1
- package/sidecar/dist/agent/call-ledger.js.map +1 -1
- package/sidecar/dist/agent/command-analysis.js +13 -14
- package/sidecar/dist/agent/command-analysis.js.map +1 -1
- package/sidecar/dist/agent/conversation-modes.js.map +1 -1
- package/sidecar/dist/agent/edit-targets.d.ts +5 -1
- package/sidecar/dist/agent/edit-targets.js +8 -6
- package/sidecar/dist/agent/edit-targets.js.map +1 -1
- package/sidecar/dist/agent/edit-tracker.d.ts +2 -1
- package/sidecar/dist/agent/edit-tracker.js +3 -4
- package/sidecar/dist/agent/edit-tracker.js.map +1 -1
- package/sidecar/dist/agent/effective-mode.js.map +1 -1
- package/sidecar/dist/agent/line-diff.js +10 -8
- package/sidecar/dist/agent/line-diff.js.map +1 -1
- package/sidecar/dist/agent/permission-bus.js +2 -1
- package/sidecar/dist/agent/permission-bus.js.map +1 -1
- package/sidecar/dist/agent/permission-preview.d.ts +1 -1
- package/sidecar/dist/agent/permission-preview.js +54 -37
- package/sidecar/dist/agent/permission-preview.js.map +1 -1
- package/sidecar/dist/agent/permission-rules.js +4 -6
- package/sidecar/dist/agent/permission-rules.js.map +1 -1
- package/sidecar/dist/agent/provider.d.ts +2 -1
- package/sidecar/dist/agent/question-bus.js.map +1 -1
- package/sidecar/dist/agent/read-access.d.ts +2 -1
- package/sidecar/dist/agent/read-access.js +4 -7
- package/sidecar/dist/agent/read-access.js.map +1 -1
- package/sidecar/dist/agent/runner.js.map +1 -1
- package/sidecar/dist/agent/session.js +2 -6
- package/sidecar/dist/agent/session.js.map +1 -1
- package/sidecar/dist/agent/switching-runner.js.map +1 -1
- package/sidecar/dist/agent/system-prompt.js.map +1 -1
- package/sidecar/dist/agent/tool-summary.d.ts +2 -1
- package/sidecar/dist/agent/tool-summary.js +26 -13
- package/sidecar/dist/agent/tool-summary.js.map +1 -1
- package/sidecar/dist/agent/typecheck.d.ts +1 -4
- package/sidecar/dist/agent/typecheck.js +3 -2
- package/sidecar/dist/agent/typecheck.js.map +1 -1
- package/sidecar/dist/audit/activity-query.js +4 -8
- package/sidecar/dist/audit/activity-query.js.map +1 -1
- package/sidecar/dist/audit/activity-target.d.ts +4 -2
- package/sidecar/dist/audit/activity-target.js +10 -9
- package/sidecar/dist/audit/activity-target.js.map +1 -1
- package/sidecar/dist/audit/activity.js +4 -3
- package/sidecar/dist/audit/activity.js.map +1 -1
- package/sidecar/dist/audit/call-audit.js.map +1 -1
- package/sidecar/dist/builder/builder-client.d.ts +2 -1
- package/sidecar/dist/builder/builder-client.js +6 -8
- package/sidecar/dist/builder/builder-client.js.map +1 -1
- package/sidecar/dist/builder/capability.js.map +1 -1
- package/sidecar/dist/checkpoints/checkpoints.js.map +1 -1
- package/sidecar/dist/checkpoints/shadow-git.js +6 -2
- package/sidecar/dist/checkpoints/shadow-git.js.map +1 -1
- package/sidecar/dist/constants/agent.js.map +1 -1
- package/sidecar/dist/constants/attachments.js.map +1 -1
- package/sidecar/dist/constants/builder.js.map +1 -1
- package/sidecar/dist/constants/chatgpt.js.map +1 -1
- package/sidecar/dist/constants/checkpoints.d.ts +1 -1
- package/sidecar/dist/constants/checkpoints.js +6 -6
- package/sidecar/dist/constants/checkpoints.js.map +1 -1
- package/sidecar/dist/constants/claude.d.ts +3 -4
- package/sidecar/dist/constants/claude.js +16 -16
- package/sidecar/dist/constants/claude.js.map +1 -1
- package/sidecar/dist/constants/cli.js.map +1 -1
- package/sidecar/dist/constants/codex.d.ts +4 -5
- package/sidecar/dist/constants/codex.js +25 -25
- package/sidecar/dist/constants/codex.js.map +1 -1
- package/sidecar/dist/constants/database.js.map +1 -1
- package/sidecar/dist/constants/mcp.js.map +1 -1
- package/sidecar/dist/constants/paths.js.map +1 -1
- package/sidecar/dist/constants/project.d.ts +1 -1
- package/sidecar/dist/constants/project.js.map +1 -1
- package/sidecar/dist/constants/providers.js.map +1 -1
- package/sidecar/dist/constants/questions.js.map +1 -1
- package/sidecar/dist/constants/read-access.d.ts +1 -1
- package/sidecar/dist/constants/read-access.js +7 -7
- package/sidecar/dist/constants/read-access.js.map +1 -1
- package/sidecar/dist/constants/timing.js.map +1 -1
- package/sidecar/dist/database/database-client.d.ts +3 -2
- package/sidecar/dist/database/database-client.js +13 -9
- package/sidecar/dist/database/database-client.js.map +1 -1
- package/sidecar/dist/host/project-info.js +13 -7
- package/sidecar/dist/host/project-info.js.map +1 -1
- package/sidecar/dist/index.d.ts +1 -1
- package/sidecar/dist/index.js +60 -34
- package/sidecar/dist/index.js.map +1 -1
- package/sidecar/dist/logs/logs-client.js +12 -2
- package/sidecar/dist/logs/logs-client.js.map +1 -1
- package/sidecar/dist/mcp/define-tool.d.ts +9 -8
- package/sidecar/dist/mcp/define-tool.js.map +1 -1
- package/sidecar/dist/mcp/http-binding.js.map +1 -1
- package/sidecar/dist/mcp/tools/ask-user.js.map +1 -1
- package/sidecar/dist/mcp/tools/builder-catalog.d.ts +6 -1
- package/sidecar/dist/mcp/tools/builder-catalog.js +32 -24
- package/sidecar/dist/mcp/tools/builder-catalog.js.map +1 -1
- package/sidecar/dist/mcp/tools/builder-gate.js.map +1 -1
- package/sidecar/dist/mcp/tools/builder-project.d.ts +2 -1
- package/sidecar/dist/mcp/tools/builder-project.js +60 -43
- package/sidecar/dist/mcp/tools/builder-project.js.map +1 -1
- package/sidecar/dist/mcp/tools/builder.js +8 -9
- package/sidecar/dist/mcp/tools/builder.js.map +1 -1
- package/sidecar/dist/mcp/tools/database.js +5 -9
- package/sidecar/dist/mcp/tools/database.js.map +1 -1
- package/sidecar/dist/mcp/tools/find-pages-using.js.map +1 -1
- package/sidecar/dist/mcp/tools/get-current-page.js.map +1 -1
- package/sidecar/dist/mcp/tools/list-pages.js.map +1 -1
- package/sidecar/dist/mcp/tools/navigate-to-page.js +6 -6
- package/sidecar/dist/mcp/tools/navigate-to-page.js.map +1 -1
- package/sidecar/dist/mcp/tools/preview-blocks.js +15 -11
- package/sidecar/dist/mcp/tools/preview-blocks.js.map +1 -1
- package/sidecar/dist/mcp/tools/query-logs.js.map +1 -1
- package/sidecar/dist/mcp/tools/typecheck.js.map +1 -1
- package/sidecar/dist/metrics/aggregate.js.map +1 -1
- package/sidecar/dist/metrics/types.js.map +1 -1
- package/sidecar/dist/pages/registry-client.js +14 -5
- package/sidecar/dist/pages/registry-client.js.map +1 -1
- package/sidecar/dist/pages/route-match.js.map +1 -1
- package/sidecar/dist/protocol/events.d.ts +7 -7
- package/sidecar/dist/protocol/events.js.map +1 -1
- package/sidecar/dist/protocol/json.d.ts +5 -0
- package/sidecar/dist/protocol/json.js +3 -0
- package/sidecar/dist/protocol/json.js.map +1 -0
- package/sidecar/dist/protocol/messages.d.ts +4 -4
- package/sidecar/dist/protocol/messages.js +3 -3
- package/sidecar/dist/protocol/messages.js.map +1 -1
- package/sidecar/dist/providers/claude/activity.d.ts +4 -2
- package/sidecar/dist/providers/claude/activity.js +29 -38
- package/sidecar/dist/providers/claude/activity.js.map +1 -1
- package/sidecar/dist/providers/claude/adapter.js +62 -91
- package/sidecar/dist/providers/claude/adapter.js.map +1 -1
- package/sidecar/dist/providers/claude/attachments.js +4 -4
- package/sidecar/dist/providers/claude/attachments.js.map +1 -1
- package/sidecar/dist/providers/claude/config.js.map +1 -1
- package/sidecar/dist/providers/claude/module.js.map +1 -1
- package/sidecar/dist/providers/claude/provider.d.ts +4 -2
- package/sidecar/dist/providers/claude/provider.js.map +1 -1
- package/sidecar/dist/providers/claude/resolve-binary.js +6 -4
- package/sidecar/dist/providers/claude/resolve-binary.js.map +1 -1
- package/sidecar/dist/providers/claude/safe-mode.js +14 -3
- package/sidecar/dist/providers/claude/safe-mode.js.map +1 -1
- package/sidecar/dist/providers/codex/adapter.js +124 -46
- package/sidecar/dist/providers/codex/adapter.js.map +1 -1
- package/sidecar/dist/providers/codex/attachments.js +1 -1
- package/sidecar/dist/providers/codex/attachments.js.map +1 -1
- package/sidecar/dist/providers/codex/chatgpt/credentials.js.map +1 -1
- package/sidecar/dist/providers/codex/chatgpt/http.js +8 -5
- package/sidecar/dist/providers/codex/chatgpt/http.js.map +1 -1
- package/sidecar/dist/providers/codex/chatgpt/lock.js +3 -3
- package/sidecar/dist/providers/codex/chatgpt/lock.js.map +1 -1
- package/sidecar/dist/providers/codex/chatgpt/login.js.map +1 -1
- package/sidecar/dist/providers/codex/chatgpt/oauth.js +51 -8
- package/sidecar/dist/providers/codex/chatgpt/oauth.js.map +1 -1
- package/sidecar/dist/providers/codex/chatgpt/store.js +23 -23
- package/sidecar/dist/providers/codex/chatgpt/store.js.map +1 -1
- package/sidecar/dist/providers/codex/client.d.ts +4 -3
- package/sidecar/dist/providers/codex/client.js +10 -3
- package/sidecar/dist/providers/codex/client.js.map +1 -1
- package/sidecar/dist/providers/codex/config.js.map +1 -1
- package/sidecar/dist/providers/codex/module.js.map +1 -1
- package/sidecar/dist/providers/codex/permissions.d.ts +2 -2
- package/sidecar/dist/providers/codex/permissions.js +20 -6
- package/sidecar/dist/providers/codex/permissions.js.map +1 -1
- package/sidecar/dist/providers/codex/process.d.ts +3 -1
- package/sidecar/dist/providers/codex/process.js +35 -36
- package/sidecar/dist/providers/codex/process.js.map +1 -1
- package/sidecar/dist/providers/codex/provider.d.ts +2 -0
- package/sidecar/dist/providers/codex/provider.js +23 -7
- package/sidecar/dist/providers/codex/provider.js.map +1 -1
- package/sidecar/dist/providers/codex/resolve-binary.js +2 -2
- package/sidecar/dist/providers/codex/resolve-binary.js.map +1 -1
- package/sidecar/dist/providers/codex/stop.d.ts +6 -1
- package/sidecar/dist/providers/codex/stop.js +29 -22
- package/sidecar/dist/providers/codex/stop.js.map +1 -1
- package/sidecar/dist/providers/registry.js +4 -5
- package/sidecar/dist/providers/registry.js.map +1 -1
- package/sidecar/dist/server/chat-socket-registry.d.ts +6 -6
- package/sidecar/dist/server/chat-socket-registry.js.map +1 -1
- package/sidecar/dist/server/conversation-runs.d.ts +1 -1
- package/sidecar/dist/server/conversation-runs.js +4 -5
- package/sidecar/dist/server/conversation-runs.js.map +1 -1
- package/sidecar/dist/server/host-socket-registry.d.ts +4 -3
- package/sidecar/dist/server/host-socket-registry.js.map +1 -1
- package/sidecar/dist/server/http-io.d.ts +1 -1
- package/sidecar/dist/server/http-io.js +2 -3
- package/sidecar/dist/server/http-io.js.map +1 -1
- package/sidecar/dist/server/http-params.js.map +1 -1
- package/sidecar/dist/server/http-routes.d.ts +9 -2
- package/sidecar/dist/server/http-routes.js +15 -8
- package/sidecar/dist/server/http-routes.js.map +1 -1
- package/sidecar/dist/server/http.js +21 -10
- package/sidecar/dist/server/http.js.map +1 -1
- package/sidecar/dist/server/pending-queue.js +4 -1
- package/sidecar/dist/server/pending-queue.js.map +1 -1
- package/sidecar/dist/server/raw-data.js +2 -1
- package/sidecar/dist/server/raw-data.js.map +1 -1
- package/sidecar/dist/server/routing.js +1 -1
- package/sidecar/dist/server/routing.js.map +1 -1
- package/sidecar/dist/server/safety-net.js +20 -9
- package/sidecar/dist/server/safety-net.js.map +1 -1
- package/sidecar/dist/server/tool-calls.js +7 -5
- package/sidecar/dist/server/tool-calls.js.map +1 -1
- package/sidecar/dist/server/turns.js +2 -1
- package/sidecar/dist/server/turns.js.map +1 -1
- package/sidecar/dist/server/ws.js +2 -6
- package/sidecar/dist/server/ws.js.map +1 -1
- package/sidecar/dist/skills/build-catalog.js.map +1 -1
- package/sidecar/dist/skills/frontmatter.js.map +1 -1
- package/sidecar/dist/skills/plugin-wrapper.js.map +1 -1
- package/sidecar/dist/skills/resolve-sources.js.map +1 -1
- package/sidecar/dist/skills/skill-usage.js +18 -12
- package/sidecar/dist/skills/skill-usage.js.map +1 -1
- package/sidecar/dist/state/conversations.js.map +1 -1
- package/sidecar/dist/state/lock.js +6 -2
- package/sidecar/dist/state/lock.js.map +1 -1
- package/sidecar/dist/state/settings-store.d.ts +31 -1
- package/sidecar/dist/state/settings-store.js +23 -24
- package/sidecar/dist/state/settings-store.js.map +1 -1
- package/sidecar/dist/state/settings-types.js.map +1 -1
- package/sidecar/dist/state/sidecar-version.js +3 -1
- package/sidecar/dist/state/sidecar-version.js.map +1 -1
- package/sidecar/dist/state/store.js +1 -1
- package/sidecar/dist/state/store.js.map +1 -1
- package/sidecar/dist/state/types.js.map +1 -1
- package/sidecar/package.json +1 -7
- package/skills/dms-ai/cases.json +47 -0
- package/skills/dms-ai-code-mode/cases.json +38 -0
- package/skills/dms-builder-safe/cases.json +67 -0
- package/skills/dms-external-database/REFERENCE.md +34 -9
- package/skills/dms-external-database/SKILL.md +24 -11
- package/skills/dms-external-database/cases.json +47 -0
- package/frontend-vue/tests/i18n-panel.test.ts +0 -118
- package/frontend-vue/tests/i18n-views.test.ts +0 -63
- package/frontend-vue/tests/panel-header-height.test.ts +0 -40
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import { nextTick } from "vue";
|
|
4
|
+
import {
|
|
5
|
+
buttonWithText,
|
|
6
|
+
CONVERSATION_ID,
|
|
7
|
+
createHarness,
|
|
8
|
+
deliver,
|
|
9
|
+
openPanel,
|
|
10
|
+
sentOfType,
|
|
11
|
+
unmountPanel,
|
|
12
|
+
} from "./support/panel-harness";
|
|
13
|
+
import {
|
|
14
|
+
COMMAND_REQUEST,
|
|
15
|
+
DELETE_REQUEST,
|
|
16
|
+
DIFF_REQUEST,
|
|
17
|
+
keydown,
|
|
18
|
+
} from "./support/panel-fixtures";
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
localStorage.setItem("dms-ai-conversation-id", CONVERSATION_ID);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
unmountPanel();
|
|
26
|
+
localStorage.clear();
|
|
27
|
+
vi.useRealTimers();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("the approvals dock", () => {
|
|
31
|
+
it("previews a diff with line numbers and allows a scope with ↵", async () => {
|
|
32
|
+
// The countdown reads the clock: frozen at the request's creation, it
|
|
33
|
+
// shows the full grace period however slow the run is.
|
|
34
|
+
vi.useFakeTimers({ toFake: ["Date"] });
|
|
35
|
+
vi.setSystemTime(DIFF_REQUEST.createdAtMs);
|
|
36
|
+
const harness = createHarness();
|
|
37
|
+
const panel = await openPanel(harness);
|
|
38
|
+
deliver(harness, DIFF_REQUEST);
|
|
39
|
+
deliver(harness, COMMAND_REQUEST);
|
|
40
|
+
await nextTick();
|
|
41
|
+
const dock = panel.find(".cb-approve");
|
|
42
|
+
expect(dock.attributes("role")).toBe("alertdialog");
|
|
43
|
+
expect(dock.text()).toContain("Needs your approval · 1 of 2");
|
|
44
|
+
expect(dock.text()).toContain("denies in 4:12");
|
|
45
|
+
expect(panel.find(".perm.is-focused .perm__title").text()).toBe(
|
|
46
|
+
"Edit customer.form.ts",
|
|
47
|
+
);
|
|
48
|
+
expect(panel.findAll(".ln").map((row) => row.text())).toEqual([
|
|
49
|
+
"@@ −42 +42 @@",
|
|
50
|
+
'42−label: "VAT",',
|
|
51
|
+
'42+label: "VAT number",',
|
|
52
|
+
]);
|
|
53
|
+
expect(dock.text()).toContain("Every edit under crm/customers/");
|
|
54
|
+
await panel.findAll(".perm.is-focused .scope-opt input")[2].setValue(true);
|
|
55
|
+
keydown(dock.element, "Enter");
|
|
56
|
+
await nextTick();
|
|
57
|
+
expect(sentOfType(harness, "permission_response")[0]).toEqual({
|
|
58
|
+
type: "permission_response",
|
|
59
|
+
conversationId: CONVERSATION_ID,
|
|
60
|
+
requestId: "r1",
|
|
61
|
+
decision: "allow_rule",
|
|
62
|
+
rule: { kind: "directory", value: "crm/customers/" },
|
|
63
|
+
});
|
|
64
|
+
expect(panel.find(".perm.is-focused .perm__title").text()).toBe(
|
|
65
|
+
"Run pnpm add jsvat",
|
|
66
|
+
);
|
|
67
|
+
expect(panel.find(".perm.is-focused").text()).toContain(
|
|
68
|
+
"adds a dependency · package.json, pnpm-lock.yaml",
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("moves with J and K, denies with N, and denies everything at once", async () => {
|
|
73
|
+
const harness = createHarness();
|
|
74
|
+
const panel = await openPanel(harness);
|
|
75
|
+
deliver(harness, DIFF_REQUEST);
|
|
76
|
+
deliver(harness, COMMAND_REQUEST);
|
|
77
|
+
await nextTick();
|
|
78
|
+
const dock = panel.find(".cb-approve");
|
|
79
|
+
keydown(dock.element, "j");
|
|
80
|
+
await nextTick();
|
|
81
|
+
expect(dock.text()).toContain("2 of 2");
|
|
82
|
+
keydown(dock.element, "k");
|
|
83
|
+
await nextTick();
|
|
84
|
+
expect(dock.text()).toContain("1 of 2");
|
|
85
|
+
keydown(dock.element, "n");
|
|
86
|
+
await nextTick();
|
|
87
|
+
expect(sentOfType(harness, "permission_response")[0]).toMatchObject({
|
|
88
|
+
requestId: "r1",
|
|
89
|
+
decision: "deny",
|
|
90
|
+
});
|
|
91
|
+
deliver(harness, DIFF_REQUEST);
|
|
92
|
+
await nextTick();
|
|
93
|
+
await buttonWithText(
|
|
94
|
+
panel.find(".cb-approve"),
|
|
95
|
+
"Deny both and stop",
|
|
96
|
+
).trigger("click");
|
|
97
|
+
expect(sentOfType(harness, "permission_response").at(-1)).toMatchObject({
|
|
98
|
+
decision: "deny_all",
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("denies with the user's suggestion", async () => {
|
|
103
|
+
const harness = createHarness();
|
|
104
|
+
const panel = await openPanel(harness);
|
|
105
|
+
deliver(harness, DIFF_REQUEST);
|
|
106
|
+
await nextTick();
|
|
107
|
+
await buttonWithText(panel, "Suggest a change").trigger("click");
|
|
108
|
+
await panel
|
|
109
|
+
.find(".u-textarea")
|
|
110
|
+
.setValue("Use the Builder's validation instead");
|
|
111
|
+
await buttonWithText(panel, "Deny and send").trigger("click");
|
|
112
|
+
expect(sentOfType(harness, "permission_response")[0]).toMatchObject({
|
|
113
|
+
decision: "deny",
|
|
114
|
+
feedback: "Use the Builder's validation instead",
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("makes a data loss typed, offers to keep the data, and never a chat-wide rule", async () => {
|
|
119
|
+
const harness = createHarness();
|
|
120
|
+
const panel = await openPanel(harness);
|
|
121
|
+
deliver(harness, DELETE_REQUEST);
|
|
122
|
+
await nextTick();
|
|
123
|
+
const card = panel.find(".perm.is-danger");
|
|
124
|
+
expect(card.text()).toContain("Data loss");
|
|
125
|
+
expect(card.text()).not.toContain("this chat");
|
|
126
|
+
const confirm = buttonWithText(card, "Delete");
|
|
127
|
+
expect(confirm.attributes("disabled")).toBeDefined();
|
|
128
|
+
await card.find(".perm__confirm input").setValue("legacy_coupons");
|
|
129
|
+
expect(
|
|
130
|
+
buttonWithText(card, "Delete").attributes("disabled"),
|
|
131
|
+
).toBeUndefined();
|
|
132
|
+
await card.find('input[type="checkbox"]').setValue(true);
|
|
133
|
+
await buttonWithText(card, "Remove the code only").trigger("click");
|
|
134
|
+
expect(sentOfType(harness, "permission_response")[0]).toMatchObject({
|
|
135
|
+
decision: "allow_once",
|
|
136
|
+
keepData: true,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("turns an expired request into a card that asks again", async () => {
|
|
141
|
+
const harness = createHarness();
|
|
142
|
+
const panel = await openPanel(harness);
|
|
143
|
+
deliver(harness, DIFF_REQUEST);
|
|
144
|
+
deliver(harness, {
|
|
145
|
+
type: "permission_expired",
|
|
146
|
+
requestId: "r1",
|
|
147
|
+
toolName: "Edit",
|
|
148
|
+
summary: "Edit customer.form.ts",
|
|
149
|
+
expiredAtMs: Date.now(),
|
|
150
|
+
});
|
|
151
|
+
await nextTick();
|
|
152
|
+
expect(panel.find(".cb-approve").exists()).toBe(false);
|
|
153
|
+
const card = panel.find(".cb-expired");
|
|
154
|
+
expect(card.text()).toContain("Edit file request expired");
|
|
155
|
+
await buttonWithText(card, "Ask again").trigger("click");
|
|
156
|
+
expect(sentOfType(harness, "user_message")[0].content).toContain(
|
|
157
|
+
"Edit customer.form.ts",
|
|
158
|
+
);
|
|
159
|
+
expect(panel.find(".cb-expired").exists()).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("lists the rules allowed in this chat and revokes one", async () => {
|
|
163
|
+
const harness = createHarness();
|
|
164
|
+
const panel = await openPanel(harness);
|
|
165
|
+
deliver(harness, DIFF_REQUEST);
|
|
166
|
+
deliver(harness, {
|
|
167
|
+
type: "rules_state",
|
|
168
|
+
rules: [
|
|
169
|
+
{
|
|
170
|
+
id: "rule-1",
|
|
171
|
+
kind: "command",
|
|
172
|
+
value: "pnpm test",
|
|
173
|
+
label: "Commands starting pnpm test",
|
|
174
|
+
createdAtMs: 1,
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
});
|
|
178
|
+
await nextTick();
|
|
179
|
+
const rules = panel.find(".cb-approve .cb-rules");
|
|
180
|
+
expect(rules.text()).toContain("Commands starting pnpm test");
|
|
181
|
+
await buttonWithText(rules, "Revoke").trigger("click");
|
|
182
|
+
expect(sentOfType(harness, "revoke_rule")).toEqual([
|
|
183
|
+
{
|
|
184
|
+
type: "revoke_rule",
|
|
185
|
+
conversationId: CONVERSATION_ID,
|
|
186
|
+
ruleId: "rule-1",
|
|
187
|
+
},
|
|
188
|
+
]);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import { nextTick } from "vue";
|
|
4
|
+
import {
|
|
5
|
+
buttonWithText,
|
|
6
|
+
CONVERSATION_ID,
|
|
7
|
+
createHarness,
|
|
8
|
+
deliver,
|
|
9
|
+
openPanel,
|
|
10
|
+
sendMessage,
|
|
11
|
+
sentOfType,
|
|
12
|
+
unmountPanel,
|
|
13
|
+
} from "./support/panel-harness";
|
|
14
|
+
import { keydown } from "./support/panel-fixtures";
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
localStorage.setItem("dms-ai-conversation-id", CONVERSATION_ID);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
unmountPanel();
|
|
22
|
+
localStorage.clear();
|
|
23
|
+
vi.useRealTimers();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("questions, queue and modes", () => {
|
|
27
|
+
const QUESTIONS = {
|
|
28
|
+
type: "ask_question",
|
|
29
|
+
requestId: "q1",
|
|
30
|
+
questions: [
|
|
31
|
+
{
|
|
32
|
+
question: "Where should the page live?",
|
|
33
|
+
header: "Placement",
|
|
34
|
+
options: [
|
|
35
|
+
{
|
|
36
|
+
label: "Finance › Overdue invoices",
|
|
37
|
+
description: "Next to Invoices",
|
|
38
|
+
},
|
|
39
|
+
{ label: "A tab on Invoices", description: "" },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
question: "Default sort?",
|
|
44
|
+
header: "Sort",
|
|
45
|
+
options: [
|
|
46
|
+
{ label: "Days overdue", description: "" },
|
|
47
|
+
{ label: "Amount", description: "" },
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
it("pages through questions with numbers, Other… and Skip, then keeps the answers", async () => {
|
|
54
|
+
const harness = createHarness();
|
|
55
|
+
const panel = await openPanel(harness);
|
|
56
|
+
deliver(harness, QUESTIONS);
|
|
57
|
+
await nextTick();
|
|
58
|
+
const dock = panel.find(".cb-ask");
|
|
59
|
+
expect(dock.text()).toContain("Question 1 of 2 · Placement");
|
|
60
|
+
expect(dock.find(".opt-card.is-selected").text()).toContain("Suggested");
|
|
61
|
+
keydown(dock.element, "3");
|
|
62
|
+
await nextTick();
|
|
63
|
+
await dock.find(".cb-ask__custom").setValue("Under Finance, as a tab");
|
|
64
|
+
await buttonWithText(dock.find(".cb-ask__foot"), "Next").trigger("click");
|
|
65
|
+
expect(dock.text()).toContain("Question 2 of 2 · Sort");
|
|
66
|
+
await buttonWithText(dock, "Skip, you decide").trigger("click");
|
|
67
|
+
expect(sentOfType(harness, "question_response")[0]).toEqual({
|
|
68
|
+
type: "question_response",
|
|
69
|
+
conversationId: CONVERSATION_ID,
|
|
70
|
+
requestId: "q1",
|
|
71
|
+
answers: ["Under Finance, as a tab", ""],
|
|
72
|
+
skipped: [false, true],
|
|
73
|
+
});
|
|
74
|
+
await nextTick();
|
|
75
|
+
const record = panel.find(".cb-answers");
|
|
76
|
+
expect(record.text()).toContain("“Under Finance, as a tab”");
|
|
77
|
+
expect(record.text()).toContain("Skipped: the assistant decides");
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("edits, reorders and clears the queue", async () => {
|
|
81
|
+
const harness = createHarness();
|
|
82
|
+
const panel = await openPanel(harness);
|
|
83
|
+
deliver(harness, {
|
|
84
|
+
type: "queue_state",
|
|
85
|
+
items: [
|
|
86
|
+
{ id: "a", content: "Sort by order count" },
|
|
87
|
+
{ id: "b", content: "Limit to 3 orders" },
|
|
88
|
+
],
|
|
89
|
+
});
|
|
90
|
+
await nextTick();
|
|
91
|
+
await panel
|
|
92
|
+
.find('button[aria-label="Edit queued message"]')
|
|
93
|
+
.trigger("click");
|
|
94
|
+
await panel.find(".cb-queued__editor").setValue("Sort by revenue");
|
|
95
|
+
await buttonWithText(panel.find(".cb-queue"), "Save").trigger("click");
|
|
96
|
+
keydown(panel.findAll(".cb-queued__handle")[1].element, "ArrowUp");
|
|
97
|
+
await nextTick();
|
|
98
|
+
expect(panel.findAll(".cb-queued__txt").map((item) => item.text())).toEqual(
|
|
99
|
+
["Limit to 3 orders", "Sort by revenue"],
|
|
100
|
+
);
|
|
101
|
+
await buttonWithText(panel.find(".cb-queue"), "Clear").trigger("click");
|
|
102
|
+
expect(
|
|
103
|
+
harness.sent
|
|
104
|
+
.map((msg) => msg.type)
|
|
105
|
+
.filter((type) => String(type).startsWith("queue_")),
|
|
106
|
+
).toEqual(["queue_update", "queue_move", "queue_clear"]);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("switches the chat's mode and scope, and confirms Full auto with a duration", async () => {
|
|
110
|
+
const harness = createHarness();
|
|
111
|
+
const panel = await openPanel(harness);
|
|
112
|
+
await buttonWithText(panel, "Plan only").trigger("click");
|
|
113
|
+
await buttonWithText(panel, "Full auto…").trigger("click");
|
|
114
|
+
await nextTick();
|
|
115
|
+
const modal = panel.find(".u-modal");
|
|
116
|
+
expect(modal.text()).toContain("Turn on Full auto?");
|
|
117
|
+
await buttonWithText(modal, "30 minutes").trigger("click");
|
|
118
|
+
await buttonWithText(modal, "Turn on Full auto").trigger("click");
|
|
119
|
+
expect(sentOfType(harness, "set_conversation_mode")).toEqual([
|
|
120
|
+
{
|
|
121
|
+
type: "set_conversation_mode",
|
|
122
|
+
conversationId: CONVERSATION_ID,
|
|
123
|
+
mode: "plan",
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: "set_conversation_mode",
|
|
127
|
+
conversationId: CONVERSATION_ID,
|
|
128
|
+
fullAuto: { duration: "30m" },
|
|
129
|
+
},
|
|
130
|
+
]);
|
|
131
|
+
await nextTick();
|
|
132
|
+
const banner = panel.find(".cb-banner-auto");
|
|
133
|
+
expect(banner.text()).toContain("Full auto · for 30 minutes");
|
|
134
|
+
await buttonWithText(banner, "Turn off").trigger("click");
|
|
135
|
+
expect(sentOfType(harness, "set_conversation_mode").at(-1)).toMatchObject({
|
|
136
|
+
fullAuto: null,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("runs a proposed plan in Ask first", async () => {
|
|
141
|
+
const harness = createHarness();
|
|
142
|
+
const panel = await openPanel(harness);
|
|
143
|
+
await sendMessage(panel, "plan a customer health page");
|
|
144
|
+
deliver(harness, {
|
|
145
|
+
type: "tool_call_start",
|
|
146
|
+
callId: "p1",
|
|
147
|
+
toolName: "ExitPlanMode",
|
|
148
|
+
args: { plan: "1. Create the page\n2. Add a query" },
|
|
149
|
+
});
|
|
150
|
+
deliver(harness, {
|
|
151
|
+
type: "tool_call_end",
|
|
152
|
+
callId: "p1",
|
|
153
|
+
status: "success",
|
|
154
|
+
result: "",
|
|
155
|
+
outcome: "done",
|
|
156
|
+
});
|
|
157
|
+
deliver(harness, { type: "run_done" });
|
|
158
|
+
await nextTick();
|
|
159
|
+
const plan = panel.find(".cb-plan");
|
|
160
|
+
expect(plan.text()).toContain("Proposed plan · 2 steps");
|
|
161
|
+
await buttonWithText(plan, "Run with Ask first").trigger("click");
|
|
162
|
+
expect(sentOfType(harness, "set_conversation_mode")[0]).toMatchObject({
|
|
163
|
+
mode: "normal",
|
|
164
|
+
});
|
|
165
|
+
expect(sentOfType(harness, "user_message").at(-1)).toMatchObject({
|
|
166
|
+
content: "Go ahead with the plan.",
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|