@antelopejs/dms-ai 0.1.4 → 0.1.5
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 +48 -29
- package/dist/channels/bridge.d.ts +2 -8
- package/dist/channels/bridge.js +26 -42
- package/dist/channels/bridge.js.map +1 -1
- package/dist/channels/channel-service.d.ts +2 -2
- package/dist/channels/channel-service.js +12 -31
- package/dist/channels/channel-service.js.map +1 -1
- package/dist/channels/registry.d.ts +2 -2
- package/dist/channels/registry.js +7 -7
- package/dist/channels/registry.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +8 -1
- package/dist/config.js.map +1 -1
- package/dist/constants/channels.d.ts +5 -10
- package/dist/constants/channels.js +6 -10
- package/dist/constants/channels.js.map +1 -1
- package/dist/constants/sidecar.d.ts +2 -1
- package/dist/constants/sidecar.js +3 -2
- package/dist/constants/sidecar.js.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/build-id.d.ts +1 -0
- package/dist/lifecycle/build-id.js +32 -0
- package/dist/lifecycle/build-id.js.map +1 -0
- package/dist/lifecycle/sidecar-socket.d.ts +1 -1
- package/dist/lifecycle/sidecar-socket.js +2 -2
- package/dist/lifecycle/sidecar-socket.js.map +1 -1
- package/dist/lifecycle/spawn-sidecar.d.ts +0 -1
- package/dist/lifecycle/spawn-sidecar.js +5 -27
- package/dist/lifecycle/spawn-sidecar.js.map +1 -1
- package/dist/routes/channels.d.ts +3 -3
- package/dist/routes/channels.js +11 -12
- package/dist/routes/channels.js.map +1 -1
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/index.js +0 -1
- package/dist/routes/index.js.map +1 -1
- package/frontend-vue/.prettierignore +3 -0
- package/frontend-vue/.prettierrc +10 -0
- package/frontend-vue/app/chat/components/ChatView.vue +582 -0
- package/frontend-vue/app/chat/components/ComposerInput.vue +742 -0
- package/frontend-vue/app/chat/components/ConnectionBanner.vue +105 -0
- package/frontend-vue/app/chat/components/ConversationDrawer.vue +266 -0
- package/frontend-vue/app/chat/components/MarkdownContent.vue +196 -0
- package/frontend-vue/app/chat/components/MessageList.vue +474 -0
- package/frontend-vue/app/chat/components/PermissionRequests.vue +323 -0
- package/frontend-vue/app/chat/components/QuestionPrompt.vue +275 -0
- package/frontend-vue/app/chat/components/QueuedMessages.vue +109 -0
- package/frontend-vue/app/chat/components/TodoList.vue +291 -0
- package/frontend-vue/app/chat/components/ToolCallEntry.vue +218 -0
- package/frontend-vue/app/chat/components/ToolCluster.vue +282 -0
- package/frontend-vue/app/chat/composables/useChatChannel.ts +116 -0
- package/frontend-vue/app/chat/composables/useConversation.ts +838 -0
- package/frontend-vue/app/chat/composables/useConversationId.ts +34 -0
- package/frontend-vue/app/chat/composables/useConversationList.ts +56 -0
- package/frontend-vue/app/chat/composables/usePermissionQueue.ts +59 -0
- package/frontend-vue/app/chat/composables/useQuestionQueue.ts +50 -0
- package/frontend-vue/app/chat/composables/useRunClock.ts +28 -0
- package/frontend-vue/app/chat/composables/useSettings.ts +67 -0
- package/frontend-vue/app/chat/constants/attachments.ts +16 -0
- package/frontend-vue/app/chat/constants/connection-banner.ts +7 -0
- package/frontend-vue/app/chat/constants/conversation-drawer.ts +13 -0
- package/frontend-vue/app/chat/constants/conversation.ts +75 -0
- package/frontend-vue/app/chat/constants/permissions.ts +50 -0
- package/frontend-vue/app/chat/constants/protocol.ts +48 -0
- package/frontend-vue/app/chat/constants/run-status.ts +50 -0
- package/frontend-vue/app/chat/constants/settings.ts +60 -0
- package/frontend-vue/app/chat/types/conversation.ts +87 -0
- package/frontend-vue/app/chat/types/permission.ts +7 -0
- package/frontend-vue/app/chat/types/question.ts +17 -0
- package/frontend-vue/app/chat/types/settings.ts +27 -0
- package/frontend-vue/app/chat/utils/attachments.ts +62 -0
- package/frontend-vue/app/chat/utils/format.ts +14 -0
- package/frontend-vue/app/chat/utils/ids.ts +34 -0
- package/frontend-vue/app/chat/utils/markdown.ts +188 -0
- package/frontend-vue/app/chat/utils/run-status.ts +90 -0
- package/frontend-vue/app/chat/utils/todos.ts +64 -0
- package/frontend-vue/app/chat/utils/tool-summary.ts +53 -0
- package/frontend-vue/app/components/ActivityView.vue +34 -34
- package/frontend-vue/app/components/ChatPanel.vue +276 -0
- package/frontend-vue/app/components/SettingsView.vue +120 -112
- package/frontend-vue/app/components/SkillsView.vue +55 -53
- package/frontend-vue/app/plugins/ai.client.ts +145 -129
- package/frontend-vue/app/runtime/assistant-session.ts +21 -0
- package/frontend-vue/app/runtime/backoff.ts +11 -14
- package/frontend-vue/app/runtime/channel-client.ts +130 -141
- package/frontend-vue/app/runtime/chat-transport.ts +25 -55
- package/frontend-vue/app/runtime/constants.ts +69 -59
- package/frontend-vue/app/runtime/current-page.ts +49 -15
- package/frontend-vue/app/runtime/event-stream.ts +35 -35
- package/frontend-vue/app/runtime/frame-router.ts +30 -0
- package/frontend-vue/app/runtime/header-action.ts +18 -18
- package/frontend-vue/app/runtime/host-commands.ts +57 -56
- package/frontend-vue/app/runtime/listeners.ts +31 -0
- package/frontend-vue/app/runtime/navigation-complete.ts +7 -7
- package/frontend-vue/app/runtime/overlay-prefs.ts +36 -36
- package/frontend-vue/app/runtime/panel-state.ts +88 -0
- package/frontend-vue/app/runtime/session-gate.ts +8 -8
- package/frontend-vue/app/runtime/shortcuts.ts +12 -12
- package/frontend-vue/app/runtime/sidecar-status.ts +61 -61
- package/frontend-vue/app/runtime/typed-message.ts +11 -0
- package/frontend-vue/dms.frontend.ts +12 -12
- package/frontend-vue/eslint.config.mjs +13 -13
- package/frontend-vue/package.json +11 -4
- package/frontend-vue/pnpm-lock.yaml +298 -96
- package/frontend-vue/tests/backoff.test.ts +26 -30
- package/frontend-vue/tests/channel-client.test.ts +187 -188
- package/frontend-vue/tests/chat/markdown.test.ts +271 -0
- package/frontend-vue/tests/chat/useChatChannel.test.ts +124 -0
- package/frontend-vue/tests/chat/useConversation.test.ts +283 -0
- package/frontend-vue/tests/chat-panel.test.ts +354 -0
- package/frontend-vue/tests/chat-transport.test.ts +84 -57
- package/frontend-vue/tests/host-commands.test.ts +126 -87
- package/frontend-vue/tests/navigation.test.ts +65 -34
- package/frontend-vue/tests/overlay-prefs.test.ts +49 -49
- package/frontend-vue/tests/panel-state.test.ts +58 -0
- package/frontend-vue/tests/session-gate.test.ts +33 -33
- package/frontend-vue/tests/sidecar-guest.test.ts +46 -46
- package/frontend-vue/tests/sidecar-status.test.ts +29 -29
- package/frontend-vue/tsconfig.chat.json +16 -0
- package/frontend-vue/vitest.config.ts +6 -4
- package/package.json +5 -5
- package/sidecar/dist/agent/effective-mode.d.ts +2 -2
- package/sidecar/dist/agent/effective-mode.js +1 -1
- package/sidecar/dist/agent/effective-mode.js.map +1 -1
- package/sidecar/dist/agent/host-context.js +7 -9
- package/sidecar/dist/agent/host-context.js.map +1 -1
- package/sidecar/dist/agent/permission-bus.d.ts +1 -1
- package/sidecar/dist/agent/permission-bus.js +2 -2
- package/sidecar/dist/agent/permission-bus.js.map +1 -1
- package/sidecar/dist/agent/provider.d.ts +2 -2
- package/sidecar/dist/agent/question-bus.d.ts +1 -1
- package/sidecar/dist/agent/question-bus.js +2 -2
- package/sidecar/dist/agent/question-bus.js.map +1 -1
- package/sidecar/dist/agent/runner.d.ts +2 -2
- package/sidecar/dist/agent/runner.js +24 -8
- package/sidecar/dist/agent/runner.js.map +1 -1
- package/sidecar/dist/agent/session.d.ts +2 -2
- package/sidecar/dist/agent/session.js +49 -9
- package/sidecar/dist/agent/session.js.map +1 -1
- package/sidecar/dist/agent/switching-runner.js +10 -5
- package/sidecar/dist/agent/switching-runner.js.map +1 -1
- package/sidecar/dist/agent/turn-end-reasons.d.ts +2 -0
- package/sidecar/dist/agent/turn-end-reasons.js +6 -1
- package/sidecar/dist/agent/turn-end-reasons.js.map +1 -1
- package/sidecar/dist/constants/agent.d.ts +4 -1
- package/sidecar/dist/constants/agent.js +4 -1
- package/sidecar/dist/constants/agent.js.map +1 -1
- package/sidecar/dist/constants/cli.d.ts +0 -1
- package/sidecar/dist/constants/cli.js +0 -1
- package/sidecar/dist/constants/cli.js.map +1 -1
- package/sidecar/dist/constants/codex.d.ts +5 -2
- package/sidecar/dist/constants/codex.js +5 -2
- package/sidecar/dist/constants/codex.js.map +1 -1
- package/sidecar/dist/constants/http.d.ts +0 -9
- package/sidecar/dist/constants/http.js +0 -19
- package/sidecar/dist/constants/http.js.map +1 -1
- package/sidecar/dist/constants/mcp.d.ts +1 -1
- package/sidecar/dist/constants/mcp.js +1 -1
- package/sidecar/dist/constants/mcp.js.map +1 -1
- package/sidecar/dist/constants/paths.d.ts +0 -1
- package/sidecar/dist/constants/paths.js +0 -1
- package/sidecar/dist/constants/paths.js.map +1 -1
- package/sidecar/dist/constants/ws.d.ts +3 -4
- package/sidecar/dist/constants/ws.js +3 -4
- package/sidecar/dist/constants/ws.js.map +1 -1
- package/sidecar/dist/index.d.ts +0 -1
- package/sidecar/dist/index.js +6 -10
- package/sidecar/dist/index.js.map +1 -1
- package/sidecar/dist/mcp/tools/find-pages-using.js +5 -10
- package/sidecar/dist/mcp/tools/find-pages-using.js.map +1 -1
- package/sidecar/dist/mcp/types.d.ts +1 -1
- package/sidecar/dist/pages/page-filepath.d.ts +4 -0
- package/sidecar/dist/pages/page-filepath.js +28 -0
- package/sidecar/dist/pages/page-filepath.js.map +1 -0
- package/sidecar/dist/prompts/agent.d.ts +1 -1
- package/sidecar/dist/prompts/agent.js +1 -1
- package/sidecar/dist/prompts/agent.js.map +1 -1
- package/sidecar/dist/protocol/events.js +2 -2
- package/sidecar/dist/protocol/events.js.map +1 -1
- package/sidecar/dist/protocol/messages.d.ts +4 -15
- package/sidecar/dist/protocol/messages.js +4 -11
- package/sidecar/dist/protocol/messages.js.map +1 -1
- package/sidecar/dist/providers/claude/config.d.ts +2 -2
- package/sidecar/dist/providers/claude/config.js +2 -2
- package/sidecar/dist/providers/claude/config.js.map +1 -1
- package/sidecar/dist/providers/claude/provider.js +1 -1
- package/sidecar/dist/providers/claude/provider.js.map +1 -1
- package/sidecar/dist/providers/codex/config.d.ts +3 -2
- package/sidecar/dist/providers/codex/config.js +3 -3
- package/sidecar/dist/providers/codex/config.js.map +1 -1
- package/sidecar/dist/providers/codex/process.js +107 -74
- package/sidecar/dist/providers/codex/process.js.map +1 -1
- package/sidecar/dist/providers/codex/provider.js +68 -31
- package/sidecar/dist/providers/codex/provider.js.map +1 -1
- package/sidecar/dist/providers/codex/skills.d.ts +1 -0
- package/sidecar/dist/providers/codex/skills.js +4 -1
- package/sidecar/dist/providers/codex/skills.js.map +1 -1
- package/sidecar/dist/providers/codex/stop.d.ts +4 -0
- package/sidecar/dist/providers/codex/stop.js +71 -0
- package/sidecar/dist/providers/codex/stop.js.map +1 -0
- package/sidecar/dist/server/{iframe-socket-registry.d.ts → chat-socket-registry.d.ts} +3 -2
- package/sidecar/dist/server/{iframe-socket-registry.js → chat-socket-registry.js} +4 -3
- package/sidecar/dist/server/chat-socket-registry.js.map +1 -0
- package/sidecar/dist/server/client-auth.js +2 -14
- package/sidecar/dist/server/client-auth.js.map +1 -1
- package/sidecar/dist/server/host-command-router.d.ts +5 -0
- package/sidecar/dist/server/host-command-router.js +4 -0
- package/sidecar/dist/server/host-command-router.js.map +1 -0
- package/sidecar/dist/server/host-socket-registry.d.ts +1 -1
- package/sidecar/dist/server/host-socket-registry.js +16 -13
- package/sidecar/dist/server/host-socket-registry.js.map +1 -1
- package/sidecar/dist/server/http.d.ts +0 -1
- package/sidecar/dist/server/http.js +1 -44
- package/sidecar/dist/server/http.js.map +1 -1
- package/sidecar/dist/server/routing.d.ts +5 -6
- package/sidecar/dist/server/routing.js +18 -28
- package/sidecar/dist/server/routing.js.map +1 -1
- package/sidecar/dist/server/ws.d.ts +2 -2
- package/sidecar/dist/server/ws.js +41 -39
- package/sidecar/dist/server/ws.js.map +1 -1
- package/sidecar/dist/state/host-state.d.ts +10 -2
- package/sidecar/dist/state/host-state.js +13 -3
- package/sidecar/dist/state/host-state.js.map +1 -1
- package/sidecar/dist/state/settings-store.js +2 -2
- package/sidecar/dist/state/settings-store.js.map +1 -1
- package/sidecar/dist/state/settings-types.d.ts +3 -3
- package/sidecar/dist/state/settings-types.js +1 -1
- package/sidecar/dist/state/settings-types.js.map +1 -1
- package/sidecar/package.json +3 -5
- package/dist/chatbox/passthrough.d.ts +0 -3
- package/dist/chatbox/passthrough.js +0 -53
- package/dist/chatbox/passthrough.js.map +0 -1
- package/dist/constants/chatbox.d.ts +0 -10
- package/dist/constants/chatbox.js +0 -35
- package/dist/constants/chatbox.js.map +0 -1
- package/dist/routes/chatbox.d.ts +0 -7
- package/dist/routes/chatbox.js +0 -47
- package/dist/routes/chatbox.js.map +0 -1
- package/frontend-vue/app/runtime/overlay.ts +0 -400
- package/frontend-vue/app/runtime/theme-bridge.ts +0 -189
- package/sidecar/chatbox/dist/assets/index-C8u7mkHn.css +0 -1
- package/sidecar/chatbox/dist/assets/index-tdZvY7ee.js +0 -52
- package/sidecar/chatbox/dist/index.html +0 -13
- package/sidecar/dist/server/iframe-socket-registry.js.map +0 -1
|
@@ -1,188 +1,191 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, onMounted, ref } from
|
|
2
|
+
import { computed, onMounted, ref } from "vue";
|
|
3
3
|
|
|
4
|
-
type Mode =
|
|
5
|
-
type Thinking =
|
|
6
|
-
type GenerationMode =
|
|
7
|
-
type ProviderName =
|
|
4
|
+
type Mode = "normal" | "acceptEdits" | "plan" | "auto";
|
|
5
|
+
type Thinking = "off" | "low" | "medium" | "high";
|
|
6
|
+
type GenerationMode = "safe" | "vibe";
|
|
7
|
+
type ProviderName = "claude" | "codex";
|
|
8
8
|
|
|
9
9
|
interface ProviderAvailability {
|
|
10
|
-
available: boolean
|
|
11
|
-
reason?: string
|
|
10
|
+
available: boolean;
|
|
11
|
+
reason?: string;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
interface AiSettings {
|
|
15
|
-
provider: ProviderName
|
|
16
|
-
mode: Mode
|
|
17
|
-
thinking: Thinking
|
|
18
|
-
generationMode: GenerationMode
|
|
19
|
-
allowLocalSkills: boolean
|
|
20
|
-
builderAvailable: boolean
|
|
21
|
-
providers: Record<ProviderName, ProviderAvailability
|
|
15
|
+
provider: ProviderName;
|
|
16
|
+
mode: Mode;
|
|
17
|
+
thinking: Thinking;
|
|
18
|
+
generationMode: GenerationMode;
|
|
19
|
+
allowLocalSkills: boolean;
|
|
20
|
+
builderAvailable: boolean;
|
|
21
|
+
providers: Record<ProviderName, ProviderAvailability>;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const { $authFetch } = useAuthFetch()
|
|
24
|
+
const { $authFetch } = useAuthFetch();
|
|
25
25
|
|
|
26
26
|
const settings = ref<AiSettings>({
|
|
27
|
-
provider:
|
|
28
|
-
mode:
|
|
29
|
-
thinking:
|
|
30
|
-
generationMode:
|
|
27
|
+
provider: "claude",
|
|
28
|
+
mode: "normal",
|
|
29
|
+
thinking: "medium",
|
|
30
|
+
generationMode: "safe",
|
|
31
31
|
allowLocalSkills: false,
|
|
32
32
|
builderAvailable: false,
|
|
33
33
|
providers: { claude: { available: true }, codex: { available: false } },
|
|
34
|
-
})
|
|
35
|
-
const loading = ref(false)
|
|
36
|
-
const saving = ref(false)
|
|
37
|
-
const error = ref<string | null>(null)
|
|
34
|
+
});
|
|
35
|
+
const loading = ref(false);
|
|
36
|
+
const saving = ref(false);
|
|
37
|
+
const error = ref<string | null>(null);
|
|
38
38
|
|
|
39
39
|
const MODE_OPTIONS: Array<{ value: Mode; label: string; hint: string }> = [
|
|
40
|
-
{ value:
|
|
40
|
+
{ value: "normal", label: "Normal", hint: "Ask before each tool action" },
|
|
41
41
|
{
|
|
42
|
-
value:
|
|
43
|
-
label:
|
|
44
|
-
hint:
|
|
42
|
+
value: "acceptEdits",
|
|
43
|
+
label: "Accept edits",
|
|
44
|
+
hint: "Auto-accept file edits, ask for the rest",
|
|
45
45
|
},
|
|
46
|
-
{ value:
|
|
47
|
-
{ value:
|
|
48
|
-
]
|
|
46
|
+
{ value: "plan", label: "Plan", hint: "Plan only — propose without changes" },
|
|
47
|
+
{ value: "auto", label: "Auto", hint: "Auto-approve every tool action" },
|
|
48
|
+
];
|
|
49
49
|
|
|
50
50
|
// Safe mode refuses raw edits whatever the mode, and Auto stops short of
|
|
51
51
|
// approving everything there, so the mode hint says so while it is active.
|
|
52
52
|
const SAFE_MODE_MODE_NOTE =
|
|
53
|
-
|
|
53
|
+
"Safe mode: raw edits and shell commands stay blocked, and Auto still asks before other actions.";
|
|
54
54
|
|
|
55
55
|
interface ProviderOption {
|
|
56
|
-
value: ProviderName
|
|
57
|
-
label: string
|
|
56
|
+
value: ProviderName;
|
|
57
|
+
label: string;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
const PROVIDER_OPTIONS: ProviderOption[] = [
|
|
61
|
-
{ value:
|
|
62
|
-
{ value:
|
|
63
|
-
]
|
|
61
|
+
{ value: "claude", label: "Anthropic (Claude)" },
|
|
62
|
+
{ value: "codex", label: "OpenAI (Codex)" },
|
|
63
|
+
];
|
|
64
64
|
|
|
65
65
|
// One control, two meanings: a token budget on Claude, a reasoning effort level
|
|
66
66
|
// on Codex, which has no "off" and maps it to its lowest level.
|
|
67
67
|
const THINKING_HINTS: Record<ProviderName, string> = {
|
|
68
|
-
claude:
|
|
68
|
+
claude: "Thinking budget handed to the model.",
|
|
69
69
|
codex:
|
|
70
70
|
'Reasoning effort handed to the model. Codex has no "off": it maps to the lowest level.',
|
|
71
|
-
}
|
|
71
|
+
};
|
|
72
72
|
|
|
73
73
|
const THINKING_OPTIONS: Array<{ value: Thinking; label: string }> = [
|
|
74
|
-
{ value:
|
|
75
|
-
{ value:
|
|
76
|
-
{ value:
|
|
77
|
-
{ value:
|
|
78
|
-
]
|
|
74
|
+
{ value: "off", label: "Off" },
|
|
75
|
+
{ value: "low", label: "Low" },
|
|
76
|
+
{ value: "medium", label: "Medium" },
|
|
77
|
+
{ value: "high", label: "High" },
|
|
78
|
+
];
|
|
79
79
|
|
|
80
80
|
async function load(): Promise<void> {
|
|
81
|
-
loading.value = true
|
|
82
|
-
error.value = null
|
|
81
|
+
loading.value = true;
|
|
82
|
+
error.value = null;
|
|
83
83
|
try {
|
|
84
|
-
settings.value = await $authFetch<AiSettings>(
|
|
84
|
+
settings.value = await $authFetch<AiSettings>("/ai/settings");
|
|
85
85
|
} catch (e) {
|
|
86
|
-
error.value = e instanceof Error ? e.message : String(e)
|
|
86
|
+
error.value = e instanceof Error ? e.message : String(e);
|
|
87
87
|
} finally {
|
|
88
|
-
loading.value = false
|
|
88
|
+
loading.value = false;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
async function persist(): Promise<void> {
|
|
93
|
-
saving.value = true
|
|
94
|
-
error.value = null
|
|
93
|
+
saving.value = true;
|
|
94
|
+
error.value = null;
|
|
95
95
|
try {
|
|
96
|
-
settings.value = await $authFetch<AiSettings>(
|
|
97
|
-
method:
|
|
96
|
+
settings.value = await $authFetch<AiSettings>("/ai/settings", {
|
|
97
|
+
method: "PUT",
|
|
98
98
|
body: settings.value,
|
|
99
|
-
})
|
|
99
|
+
});
|
|
100
100
|
} catch (e) {
|
|
101
|
-
error.value = e instanceof Error ? e.message : String(e)
|
|
101
|
+
error.value = e instanceof Error ? e.message : String(e);
|
|
102
102
|
} finally {
|
|
103
|
-
saving.value = false
|
|
103
|
+
saving.value = false;
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function availabilityOf(name: ProviderName): ProviderAvailability {
|
|
108
|
-
return settings.value.providers?.[name] ?? { available: false }
|
|
108
|
+
return settings.value.providers?.[name] ?? { available: false };
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
function providerLabel(option: ProviderOption): string {
|
|
112
112
|
return availabilityOf(option.value).available
|
|
113
113
|
? option.label
|
|
114
|
-
: `${option.label} — unavailable
|
|
114
|
+
: `${option.label} — unavailable`;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
const activeProvider = computed(() => settings.value.provider)
|
|
117
|
+
const activeProvider = computed(() => settings.value.provider);
|
|
118
118
|
|
|
119
119
|
const providerReason = computed(
|
|
120
120
|
() => availabilityOf(settings.value.provider).reason ?? null,
|
|
121
|
-
)
|
|
121
|
+
);
|
|
122
122
|
|
|
123
123
|
function onProvider(event: Event): void {
|
|
124
|
-
const next = (event.target as HTMLSelectElement).value as ProviderName
|
|
124
|
+
const next = (event.target as HTMLSelectElement).value as ProviderName;
|
|
125
125
|
if (!availabilityOf(next).available) {
|
|
126
126
|
// The option is disabled, so this only fires on a stale DOM; snap back.
|
|
127
|
-
|
|
128
|
-
return
|
|
127
|
+
(event.target as HTMLSelectElement).value = settings.value.provider;
|
|
128
|
+
return;
|
|
129
129
|
}
|
|
130
|
-
settings.value.provider = next
|
|
131
|
-
void persist()
|
|
130
|
+
settings.value.provider = next;
|
|
131
|
+
void persist();
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
function onMode(event: Event): void {
|
|
135
|
-
settings.value.mode = (event.target as HTMLSelectElement).value as Mode
|
|
136
|
-
void persist()
|
|
135
|
+
settings.value.mode = (event.target as HTMLSelectElement).value as Mode;
|
|
136
|
+
void persist();
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
function onThinking(event: Event): void {
|
|
140
|
-
settings.value.thinking = (event.target as HTMLSelectElement)
|
|
141
|
-
|
|
140
|
+
settings.value.thinking = (event.target as HTMLSelectElement)
|
|
141
|
+
.value as Thinking;
|
|
142
|
+
void persist();
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
function onAllowLocalSkills(event: Event): void {
|
|
145
|
-
settings.value.allowLocalSkills = (event.target as HTMLInputElement).checked
|
|
146
|
-
void persist()
|
|
146
|
+
settings.value.allowLocalSkills = (event.target as HTMLInputElement).checked;
|
|
147
|
+
void persist();
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
const activeMode = computed<GenerationMode>(() =>
|
|
150
|
-
settings.value.generationMode ===
|
|
151
|
-
?
|
|
152
|
-
:
|
|
153
|
-
)
|
|
151
|
+
settings.value.generationMode === "safe" && settings.value.builderAvailable
|
|
152
|
+
? "safe"
|
|
153
|
+
: "vibe",
|
|
154
|
+
);
|
|
154
155
|
|
|
155
156
|
function onGenerationMode(mode: GenerationMode): void {
|
|
156
|
-
if (mode ===
|
|
157
|
-
if (mode === settings.value.generationMode) return
|
|
158
|
-
settings.value.generationMode = mode
|
|
159
|
-
void persist()
|
|
157
|
+
if (mode === "safe" && !settings.value.builderAvailable) return;
|
|
158
|
+
if (mode === settings.value.generationMode) return;
|
|
159
|
+
settings.value.generationMode = mode;
|
|
160
|
+
void persist();
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
onMounted(load)
|
|
163
|
+
onMounted(load);
|
|
163
164
|
|
|
164
165
|
const SELECT_CLASS =
|
|
165
|
-
|
|
166
|
+
"w-full rounded-md border border-default bg-elevated px-3 py-2 text-sm";
|
|
166
167
|
</script>
|
|
167
168
|
|
|
168
169
|
<template>
|
|
169
170
|
<div class="flex w-full flex-col gap-5 pb-10">
|
|
170
171
|
<div
|
|
171
172
|
v-if="error"
|
|
172
|
-
class="
|
|
173
|
+
class="border-error bg-error/10 text-error rounded-lg border p-4 text-sm"
|
|
173
174
|
>
|
|
174
175
|
{{ error }}
|
|
175
176
|
</div>
|
|
176
177
|
|
|
177
178
|
<!-- Row 1: Provider (left) · Default behavior (right) -->
|
|
178
179
|
<div class="grid gap-5 lg:grid-cols-2">
|
|
179
|
-
<section class="
|
|
180
|
-
<header class="border-
|
|
181
|
-
<h2 class="text-sm font-semibold
|
|
180
|
+
<section class="border-default bg-elevated/30 rounded-xl border">
|
|
181
|
+
<header class="border-default border-b px-5 py-4">
|
|
182
|
+
<h2 class="text-highlighted text-sm font-semibold">Provider</h2>
|
|
182
183
|
</header>
|
|
183
184
|
<div class="flex flex-col gap-4 p-5">
|
|
184
185
|
<div>
|
|
185
|
-
<label class="mb-1.5 block text-xs font-medium
|
|
186
|
+
<label class="text-toned mb-1.5 block text-xs font-medium">
|
|
187
|
+
Provider
|
|
188
|
+
</label>
|
|
186
189
|
<select
|
|
187
190
|
:class="SELECT_CLASS"
|
|
188
191
|
:value="activeProvider"
|
|
@@ -198,24 +201,27 @@ const SELECT_CLASS =
|
|
|
198
201
|
{{ providerLabel(option) }}
|
|
199
202
|
</option>
|
|
200
203
|
</select>
|
|
201
|
-
<p v-if="providerReason" class="mt-1.5 text-xs
|
|
204
|
+
<p v-if="providerReason" class="text-error mt-1.5 text-xs">
|
|
202
205
|
{{ providerReason }}
|
|
203
206
|
</p>
|
|
204
|
-
<p class="mt-1.5 text-xs
|
|
207
|
+
<p class="text-dimmed mt-1.5 text-xs">
|
|
205
208
|
The provider runs its own default model. Switching provider ends
|
|
206
|
-
the live context of open conversations; their transcripts are
|
|
209
|
+
the live context of open conversations; their transcripts are
|
|
210
|
+
kept.
|
|
207
211
|
</p>
|
|
208
212
|
</div>
|
|
209
213
|
</div>
|
|
210
214
|
</section>
|
|
211
215
|
|
|
212
|
-
<section class="
|
|
213
|
-
<header class="border-
|
|
214
|
-
<h2 class="text-sm font-semibold
|
|
216
|
+
<section class="border-default bg-elevated/30 rounded-xl border">
|
|
217
|
+
<header class="border-default border-b px-5 py-4">
|
|
218
|
+
<h2 class="text-highlighted text-sm font-semibold">
|
|
219
|
+
Default behavior
|
|
220
|
+
</h2>
|
|
215
221
|
</header>
|
|
216
222
|
<div class="flex flex-col gap-4 p-5">
|
|
217
223
|
<div>
|
|
218
|
-
<label class="mb-1.5 block text-xs font-medium
|
|
224
|
+
<label class="text-toned mb-1.5 block text-xs font-medium">
|
|
219
225
|
Operating mode
|
|
220
226
|
</label>
|
|
221
227
|
<select
|
|
@@ -232,15 +238,15 @@ const SELECT_CLASS =
|
|
|
232
238
|
{{ option.label }}
|
|
233
239
|
</option>
|
|
234
240
|
</select>
|
|
235
|
-
<p class="mt-1.5 text-xs
|
|
241
|
+
<p class="text-dimmed mt-1.5 text-xs">
|
|
236
242
|
{{ MODE_OPTIONS.find((o) => o.value === settings.mode)?.hint }}
|
|
237
243
|
</p>
|
|
238
|
-
<p v-if="activeMode === 'safe'" class="mt-1 text-xs
|
|
244
|
+
<p v-if="activeMode === 'safe'" class="text-dimmed mt-1 text-xs">
|
|
239
245
|
{{ SAFE_MODE_MODE_NOTE }}
|
|
240
246
|
</p>
|
|
241
247
|
</div>
|
|
242
248
|
<div>
|
|
243
|
-
<label class="mb-1.5 block text-xs font-medium
|
|
249
|
+
<label class="text-toned mb-1.5 block text-xs font-medium">
|
|
244
250
|
Thinking
|
|
245
251
|
</label>
|
|
246
252
|
<select
|
|
@@ -257,7 +263,7 @@ const SELECT_CLASS =
|
|
|
257
263
|
{{ option.label }}
|
|
258
264
|
</option>
|
|
259
265
|
</select>
|
|
260
|
-
<p class="mt-1.5 text-xs
|
|
266
|
+
<p class="text-dimmed mt-1.5 text-xs">
|
|
261
267
|
{{ THINKING_HINTS[settings.provider] }}
|
|
262
268
|
</p>
|
|
263
269
|
</div>
|
|
@@ -265,20 +271,20 @@ const SELECT_CLASS =
|
|
|
265
271
|
<label class="flex items-start gap-3">
|
|
266
272
|
<input
|
|
267
273
|
type="checkbox"
|
|
268
|
-
class="mt-0.5 size-4 rounded
|
|
274
|
+
class="border-default mt-0.5 size-4 rounded"
|
|
269
275
|
:checked="settings.allowLocalSkills"
|
|
270
276
|
:disabled="loading || saving"
|
|
271
277
|
@change="onAllowLocalSkills"
|
|
272
|
-
|
|
278
|
+
/>
|
|
273
279
|
<span>
|
|
274
|
-
<span class="block text-xs font-medium
|
|
280
|
+
<span class="text-toned block text-xs font-medium">
|
|
275
281
|
Use machine-local skills (~/.claude/skills)
|
|
276
282
|
</span>
|
|
277
|
-
<span class="mt-0.5 block text-xs
|
|
278
|
-
Adds the skills from your machine
|
|
279
|
-
|
|
280
|
-
modules. Machine-local, so not
|
|
281
|
-
Off by default.
|
|
283
|
+
<span class="text-dimmed mt-0.5 block text-xs">
|
|
284
|
+
Adds the skills from your machine (
|
|
285
|
+
<code>~/.claude/skills</code>
|
|
286
|
+
) on top of the ones bundled by modules. Machine-local, so not
|
|
287
|
+
shared with other environments. Off by default.
|
|
282
288
|
</span>
|
|
283
289
|
</span>
|
|
284
290
|
</label>
|
|
@@ -288,10 +294,12 @@ const SELECT_CLASS =
|
|
|
288
294
|
</div>
|
|
289
295
|
|
|
290
296
|
<!-- Row 2: Generation mode (full width) -->
|
|
291
|
-
<section class="
|
|
292
|
-
<header class="border-
|
|
293
|
-
<h2 class="text-sm font-semibold
|
|
294
|
-
<p class="mt-0.5 text-xs
|
|
297
|
+
<section class="border-default bg-elevated/30 rounded-xl border">
|
|
298
|
+
<header class="border-default border-b px-5 py-4">
|
|
299
|
+
<h2 class="text-highlighted text-sm font-semibold">Generation mode</h2>
|
|
300
|
+
<p class="text-dimmed mt-0.5 text-xs">
|
|
301
|
+
Default mode applied to new prompts
|
|
302
|
+
</p>
|
|
295
303
|
</header>
|
|
296
304
|
<div class="grid gap-4 p-5 sm:grid-cols-2">
|
|
297
305
|
<button
|
|
@@ -303,7 +311,7 @@ const SELECT_CLASS =
|
|
|
303
311
|
? 'border-primary bg-primary/10'
|
|
304
312
|
: 'border-default',
|
|
305
313
|
settings.builderAvailable
|
|
306
|
-
? '
|
|
314
|
+
? 'hover:border-primary/60 cursor-pointer'
|
|
307
315
|
: 'cursor-not-allowed opacity-60',
|
|
308
316
|
]"
|
|
309
317
|
@click="onGenerationMode('safe')"
|
|
@@ -333,7 +341,7 @@ const SELECT_CLASS =
|
|
|
333
341
|
Unavailable
|
|
334
342
|
</UBadge>
|
|
335
343
|
</div>
|
|
336
|
-
<p class="text-xs leading-relaxed
|
|
344
|
+
<p class="text-dimmed text-xs leading-relaxed">
|
|
337
345
|
Acts only through the Builder (MCP) — emits accepted configurations,
|
|
338
346
|
never raw code.
|
|
339
347
|
<template v-if="!settings.builderAvailable">
|
|
@@ -348,7 +356,7 @@ const SELECT_CLASS =
|
|
|
348
356
|
:class="
|
|
349
357
|
activeMode === 'vibe'
|
|
350
358
|
? 'border-primary bg-primary/10'
|
|
351
|
-
: '
|
|
359
|
+
: 'border-default hover:border-primary/60 cursor-pointer'
|
|
352
360
|
"
|
|
353
361
|
@click="onGenerationMode('vibe')"
|
|
354
362
|
>
|
|
@@ -368,7 +376,7 @@ const SELECT_CLASS =
|
|
|
368
376
|
Active
|
|
369
377
|
</UBadge>
|
|
370
378
|
</div>
|
|
371
|
-
<p class="text-xs leading-relaxed
|
|
379
|
+
<p class="text-dimmed text-xs leading-relaxed">
|
|
372
380
|
Free to write custom code and bespoke pages beyond the Builder
|
|
373
381
|
blocks — full creative range.
|
|
374
382
|
</p>
|
|
@@ -1,91 +1,91 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, onMounted, ref } from
|
|
2
|
+
import { computed, onMounted, ref } from "vue";
|
|
3
3
|
|
|
4
4
|
interface SkillItem {
|
|
5
|
-
id: string
|
|
6
|
-
name: string
|
|
7
|
-
description: string
|
|
8
|
-
icon?: string
|
|
9
|
-
category?: string
|
|
10
|
-
tags: string[]
|
|
11
|
-
provenance: string
|
|
12
|
-
body: string
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
icon?: string;
|
|
9
|
+
category?: string;
|
|
10
|
+
tags: string[];
|
|
11
|
+
provenance: string;
|
|
12
|
+
body: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const LOCAL_PROVENANCE =
|
|
15
|
+
const LOCAL_PROVENANCE = "local";
|
|
16
16
|
|
|
17
|
-
const { $authFetch } = useAuthFetch()
|
|
17
|
+
const { $authFetch } = useAuthFetch();
|
|
18
18
|
|
|
19
|
-
const items = ref<SkillItem[]>([])
|
|
20
|
-
const loading = ref(false)
|
|
21
|
-
const error = ref<string | null>(null)
|
|
22
|
-
const search = ref(
|
|
23
|
-
const selected = ref<SkillItem | null>(null)
|
|
19
|
+
const items = ref<SkillItem[]>([]);
|
|
20
|
+
const loading = ref(false);
|
|
21
|
+
const error = ref<string | null>(null);
|
|
22
|
+
const search = ref("");
|
|
23
|
+
const selected = ref<SkillItem | null>(null);
|
|
24
24
|
|
|
25
25
|
async function load(): Promise<void> {
|
|
26
|
-
loading.value = true
|
|
27
|
-
error.value = null
|
|
26
|
+
loading.value = true;
|
|
27
|
+
error.value = null;
|
|
28
28
|
try {
|
|
29
|
-
const res = await $authFetch<{ items: SkillItem[] }>(
|
|
30
|
-
items.value = res.items
|
|
29
|
+
const res = await $authFetch<{ items: SkillItem[] }>("/ai/skills");
|
|
30
|
+
items.value = res.items;
|
|
31
31
|
} catch (e) {
|
|
32
|
-
error.value = e instanceof Error ? e.message : String(e)
|
|
32
|
+
error.value = e instanceof Error ? e.message : String(e);
|
|
33
33
|
} finally {
|
|
34
|
-
loading.value = false
|
|
34
|
+
loading.value = false;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
onMounted(load)
|
|
38
|
+
onMounted(load);
|
|
39
39
|
|
|
40
40
|
// Flat list, sorted by provenance then name so skills from the same package
|
|
41
41
|
// stay adjacent without a grouping layer.
|
|
42
42
|
const filtered = computed(() => {
|
|
43
|
-
const q = search.value.trim().toLowerCase()
|
|
43
|
+
const q = search.value.trim().toLowerCase();
|
|
44
44
|
return items.value
|
|
45
45
|
.filter((s) => {
|
|
46
|
-
if (q.length === 0) return true
|
|
47
|
-
const haystack = [s.name, s.description, s.category ??
|
|
48
|
-
.join(
|
|
49
|
-
.toLowerCase()
|
|
50
|
-
return haystack.includes(q)
|
|
46
|
+
if (q.length === 0) return true;
|
|
47
|
+
const haystack = [s.name, s.description, s.category ?? "", ...s.tags]
|
|
48
|
+
.join(" ")
|
|
49
|
+
.toLowerCase();
|
|
50
|
+
return haystack.includes(q);
|
|
51
51
|
})
|
|
52
52
|
.sort(
|
|
53
53
|
(a, b) =>
|
|
54
54
|
a.provenance.localeCompare(b.provenance) ||
|
|
55
55
|
a.name.localeCompare(b.name),
|
|
56
|
-
)
|
|
57
|
-
})
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
58
|
|
|
59
59
|
function isLocal(provenance: string): boolean {
|
|
60
|
-
return provenance === LOCAL_PROVENANCE
|
|
60
|
+
return provenance === LOCAL_PROVENANCE;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
function open(skill: SkillItem): void {
|
|
64
|
-
selected.value = skill
|
|
64
|
+
selected.value = skill;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function close(): void {
|
|
68
|
-
selected.value = null
|
|
68
|
+
selected.value = null;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
const CARD_CLASS =
|
|
72
|
-
|
|
72
|
+
"flex flex-col gap-2 rounded-xl border border-default bg-elevated/30 p-4 text-left transition-colors hover:border-primary";
|
|
73
73
|
</script>
|
|
74
74
|
|
|
75
75
|
<template>
|
|
76
76
|
<div class="flex w-full flex-col gap-5 pb-10">
|
|
77
77
|
<div
|
|
78
78
|
v-if="error"
|
|
79
|
-
class="
|
|
79
|
+
class="border-error bg-error/10 text-error rounded-lg border p-4 text-sm"
|
|
80
80
|
>
|
|
81
81
|
{{ error }}
|
|
82
82
|
</div>
|
|
83
83
|
|
|
84
84
|
<!-- Stat row -->
|
|
85
85
|
<div class="grid gap-4 sm:grid-cols-2">
|
|
86
|
-
<div class="
|
|
87
|
-
<p class="text-xs font-medium
|
|
88
|
-
<p class="mt-1 text-2xl font-semibold
|
|
86
|
+
<div class="border-default bg-elevated/30 rounded-xl border p-4">
|
|
87
|
+
<p class="text-toned text-xs font-medium">Total skills</p>
|
|
88
|
+
<p class="text-highlighted mt-1 text-2xl font-semibold">
|
|
89
89
|
{{ items.length }}
|
|
90
90
|
</p>
|
|
91
91
|
</div>
|
|
@@ -97,13 +97,13 @@ const CARD_CLASS =
|
|
|
97
97
|
v-model="search"
|
|
98
98
|
type="search"
|
|
99
99
|
placeholder="Search skills…"
|
|
100
|
-
class="w-full max-w-xs rounded-md border
|
|
101
|
-
|
|
100
|
+
class="border-default bg-elevated w-full max-w-xs rounded-md border px-3 py-2 text-sm"
|
|
101
|
+
/>
|
|
102
102
|
</div>
|
|
103
103
|
|
|
104
104
|
<p
|
|
105
105
|
v-if="!loading && items.length === 0"
|
|
106
|
-
class="
|
|
106
|
+
class="border-default bg-elevated/30 text-dimmed rounded-lg border p-6 text-center text-sm"
|
|
107
107
|
>
|
|
108
108
|
No skills are loaded. Module-contributed skills appear here, plus
|
|
109
109
|
machine-local skills when enabled in Settings.
|
|
@@ -121,13 +121,13 @@ const CARD_CLASS =
|
|
|
121
121
|
<div class="flex items-start gap-2">
|
|
122
122
|
<UIcon
|
|
123
123
|
:name="skill.icon || 'i-ph-sparkle'"
|
|
124
|
-
class="mt-0.5 shrink-0
|
|
124
|
+
class="text-primary mt-0.5 shrink-0"
|
|
125
125
|
/>
|
|
126
126
|
<div class="min-w-0">
|
|
127
|
-
<p class="truncate text-sm font-semibold
|
|
127
|
+
<p class="text-highlighted truncate text-sm font-semibold">
|
|
128
128
|
{{ skill.name }}
|
|
129
129
|
</p>
|
|
130
|
-
<p class="truncate text-xs
|
|
130
|
+
<p class="text-dimmed truncate text-xs">
|
|
131
131
|
{{ skill.provenance }}
|
|
132
132
|
</p>
|
|
133
133
|
</div>
|
|
@@ -141,7 +141,7 @@ const CARD_CLASS =
|
|
|
141
141
|
Local
|
|
142
142
|
</UBadge>
|
|
143
143
|
</div>
|
|
144
|
-
<p class="line-clamp-3 text-xs leading-relaxed
|
|
144
|
+
<p class="text-toned line-clamp-3 text-xs leading-relaxed">
|
|
145
145
|
{{ skill.description }}
|
|
146
146
|
</p>
|
|
147
147
|
<div v-if="skill.tags.length" class="mt-auto flex flex-wrap gap-1">
|
|
@@ -165,18 +165,18 @@ const CARD_CLASS =
|
|
|
165
165
|
@click.self="close"
|
|
166
166
|
>
|
|
167
167
|
<div
|
|
168
|
-
class="flex h-full w-full max-w-lg flex-col overflow-y-auto border-l
|
|
168
|
+
class="border-default bg-default flex h-full w-full max-w-lg flex-col overflow-y-auto border-l p-6 shadow-xl"
|
|
169
169
|
>
|
|
170
170
|
<div class="mb-4 flex items-start gap-3">
|
|
171
171
|
<UIcon
|
|
172
172
|
:name="selected.icon || 'i-ph-sparkle'"
|
|
173
|
-
class="mt-1 shrink-0 text-xl
|
|
173
|
+
class="text-primary mt-1 shrink-0 text-xl"
|
|
174
174
|
/>
|
|
175
175
|
<div class="min-w-0 flex-1">
|
|
176
|
-
<h2 class="text-lg font-semibold
|
|
176
|
+
<h2 class="text-highlighted text-lg font-semibold">
|
|
177
177
|
{{ selected.name }}
|
|
178
178
|
</h2>
|
|
179
|
-
<p class="text-
|
|
179
|
+
<p class="text-dimmed text-xs">{{ selected.id }}</p>
|
|
180
180
|
</div>
|
|
181
181
|
<UButton
|
|
182
182
|
icon="i-ph-x"
|
|
@@ -211,15 +211,17 @@ const CARD_CLASS =
|
|
|
211
211
|
</UBadge>
|
|
212
212
|
</div>
|
|
213
213
|
|
|
214
|
-
<p class="mb-4 text-sm leading-relaxed
|
|
214
|
+
<p class="text-toned mb-4 text-sm leading-relaxed">
|
|
215
215
|
{{ selected.description }}
|
|
216
216
|
</p>
|
|
217
217
|
|
|
218
|
-
<h3
|
|
218
|
+
<h3
|
|
219
|
+
class="text-dimmed mb-2 text-xs font-semibold uppercase tracking-wide"
|
|
220
|
+
>
|
|
219
221
|
Instructions (SKILL.md)
|
|
220
222
|
</h3>
|
|
221
223
|
<pre
|
|
222
|
-
class="whitespace-pre-wrap rounded-lg border
|
|
224
|
+
class="border-default bg-elevated/40 text-toned whitespace-pre-wrap rounded-lg border p-4 text-xs leading-relaxed"
|
|
223
225
|
>{{ selected.body }}</pre
|
|
224
226
|
>
|
|
225
227
|
</div>
|