@mohanscodex/spectra-code 0.4.6 → 0.4.8
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/dist/package.json +1 -1
- package/dist/src/agents/definitions.d.ts +2 -2
- package/dist/src/agents/definitions.d.ts.map +1 -1
- package/dist/src/agents/definitions.js +18 -18
- package/dist/src/agents/definitions.js.map +1 -1
- package/dist/src/agents/registry.d.ts +1 -1
- package/dist/src/agents/registry.d.ts.map +1 -1
- package/dist/src/agents/registry.js.map +1 -1
- package/dist/src/cli.js +117 -115
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/agent.d.ts +1 -1
- package/dist/src/commands/agent.d.ts.map +1 -1
- package/dist/src/commands/agent.js +14 -14
- package/dist/src/commands/agent.js.map +1 -1
- package/dist/src/commands/db.d.ts +1 -1
- package/dist/src/commands/db.d.ts.map +1 -1
- package/dist/src/commands/db.js +11 -11
- package/dist/src/commands/db.js.map +1 -1
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.js +33 -30
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/mcp.d.ts +1 -1
- package/dist/src/commands/mcp.d.ts.map +1 -1
- package/dist/src/commands/mcp.js +39 -39
- package/dist/src/commands/mcp.js.map +1 -1
- package/dist/src/commands/plugin.d.ts +1 -1
- package/dist/src/commands/plugin.d.ts.map +1 -1
- package/dist/src/commands/plugin.js +13 -13
- package/dist/src/commands/plugin.js.map +1 -1
- package/dist/src/commands/session.d.ts +1 -1
- package/dist/src/commands/session.d.ts.map +1 -1
- package/dist/src/commands/session.js +12 -12
- package/dist/src/commands/session.js.map +1 -1
- package/dist/src/index.d.ts +18 -18
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +16 -16
- package/dist/src/index.js.map +1 -1
- package/dist/src/integrations/acp/index.d.ts +1 -1
- package/dist/src/integrations/acp/index.js +1 -1
- package/dist/src/integrations/acp/server.d.ts.map +1 -1
- package/dist/src/integrations/acp/server.js +89 -79
- package/dist/src/integrations/acp/server.js.map +1 -1
- package/dist/src/integrations/custom-tools/index.d.ts +2 -2
- package/dist/src/integrations/custom-tools/index.js +1 -1
- package/dist/src/integrations/custom-tools/loader.d.ts +2 -2
- package/dist/src/integrations/custom-tools/loader.d.ts.map +1 -1
- package/dist/src/integrations/custom-tools/loader.js +19 -18
- package/dist/src/integrations/custom-tools/loader.js.map +1 -1
- package/dist/src/integrations/mcp/client.d.ts +5 -5
- package/dist/src/integrations/mcp/client.d.ts.map +1 -1
- package/dist/src/integrations/mcp/client.js +7 -7
- package/dist/src/integrations/mcp/client.js.map +1 -1
- package/dist/src/integrations/mcp/index.d.ts +2 -2
- package/dist/src/integrations/mcp/index.d.ts.map +1 -1
- package/dist/src/integrations/mcp/index.js +1 -1
- package/dist/src/integrations/mcp/index.js.map +1 -1
- package/dist/src/security/doom-loop.d.ts +1 -1
- package/dist/src/security/doom-loop.d.ts.map +1 -1
- package/dist/src/security/doom-loop.js +4 -4
- package/dist/src/security/doom-loop.js.map +1 -1
- package/dist/src/security/index.d.ts +10 -10
- package/dist/src/security/index.d.ts.map +1 -1
- package/dist/src/security/index.js +116 -69
- package/dist/src/security/index.js.map +1 -1
- package/dist/src/security/path-safety.d.ts +1 -1
- package/dist/src/security/path-safety.d.ts.map +1 -1
- package/dist/src/security/path-safety.js +19 -19
- package/dist/src/security/path-safety.js.map +1 -1
- package/dist/src/security/permissions.d.ts +1 -1
- package/dist/src/security/permissions.d.ts.map +1 -1
- package/dist/src/security/permissions.js +12 -10
- package/dist/src/security/permissions.js.map +1 -1
- package/dist/src/security/read-tracker.d.ts +2 -2
- package/dist/src/security/read-tracker.d.ts.map +1 -1
- package/dist/src/security/read-tracker.js +15 -13
- package/dist/src/security/read-tracker.js.map +1 -1
- package/dist/src/security/ssrf-guard.d.ts +1 -1
- package/dist/src/security/ssrf-guard.d.ts.map +1 -1
- package/dist/src/security/ssrf-guard.js +11 -11
- package/dist/src/security/ssrf-guard.js.map +1 -1
- package/dist/src/security/types.d.ts +4 -4
- package/dist/src/security/types.d.ts.map +1 -1
- package/dist/src/security/wildcard.d.ts.map +1 -1
- package/dist/src/security/wildcard.js +14 -16
- package/dist/src/security/wildcard.js.map +1 -1
- package/dist/src/services/auth-store.d.ts +3 -3
- package/dist/src/services/auth-store.d.ts.map +1 -1
- package/dist/src/services/auth-store.js +7 -7
- package/dist/src/services/auth-store.js.map +1 -1
- package/dist/src/services/config.d.ts +3 -3
- package/dist/src/services/config.d.ts.map +1 -1
- package/dist/src/services/config.js +17 -21
- package/dist/src/services/config.js.map +1 -1
- package/dist/src/services/context.d.ts.map +1 -1
- package/dist/src/services/context.js +5 -8
- package/dist/src/services/context.js.map +1 -1
- package/dist/src/services/custom-providers.d.ts +2 -2
- package/dist/src/services/custom-providers.d.ts.map +1 -1
- package/dist/src/services/custom-providers.js +108 -49
- package/dist/src/services/custom-providers.js.map +1 -1
- package/dist/src/services/session-store.d.ts +1 -1
- package/dist/src/services/session-store.d.ts.map +1 -1
- package/dist/src/services/session-store.js +32 -24
- package/dist/src/services/session-store.js.map +1 -1
- package/dist/src/services/snapshot-manager.d.ts.map +1 -1
- package/dist/src/services/snapshot-manager.js +14 -15
- package/dist/src/services/snapshot-manager.js.map +1 -1
- package/dist/src/tools/edit.d.ts +1 -1
- package/dist/src/tools/edit.js +18 -16
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/glob.d.ts +1 -1
- package/dist/src/tools/glob.d.ts.map +1 -1
- package/dist/src/tools/glob.js +20 -16
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/grep.d.ts +1 -1
- package/dist/src/tools/grep.d.ts.map +1 -1
- package/dist/src/tools/grep.js +18 -18
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/index.d.ts +4 -4
- package/dist/src/tools/index.d.ts.map +1 -1
- package/dist/src/tools/index.js +40 -32
- package/dist/src/tools/index.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +2 -2
- package/dist/src/tools/mcp-tool.d.ts.map +1 -1
- package/dist/src/tools/mcp-tool.js +28 -25
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/read.d.ts +1 -1
- package/dist/src/tools/read.d.ts.map +1 -1
- package/dist/src/tools/read.js +15 -13
- package/dist/src/tools/read.js.map +1 -1
- package/dist/src/tools/shell.d.ts +1 -1
- package/dist/src/tools/shell.d.ts.map +1 -1
- package/dist/src/tools/shell.js +75 -66
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/task.d.ts +1 -1
- package/dist/src/tools/task.js +22 -22
- package/dist/src/tools/task.js.map +1 -1
- package/dist/src/tools/types.d.ts +3 -3
- package/dist/src/tools/types.d.ts.map +1 -1
- package/dist/src/tools/utils.d.ts +1 -1
- package/dist/src/tools/utils.js +2 -2
- package/dist/src/tools/utils.js.map +1 -1
- package/dist/src/tools/web-fetch.d.ts +1 -1
- package/dist/src/tools/web-fetch.js +31 -31
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/write.d.ts +1 -1
- package/dist/src/tools/write.js +9 -9
- package/dist/src/tools/write.js.map +1 -1
- package/dist/src/tui/app-constants.d.ts.map +1 -1
- package/dist/src/tui/app-constants.js +11 -2
- package/dist/src/tui/app-constants.js.map +1 -1
- package/dist/src/tui/app.d.ts +1 -1
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +314 -121
- package/dist/src/tui/app.js.map +1 -1
- package/dist/src/tui/commands.d.ts +14 -14
- package/dist/src/tui/commands.d.ts.map +1 -1
- package/dist/src/tui/commands.js +242 -49
- package/dist/src/tui/commands.js.map +1 -1
- package/dist/src/tui/components/chat-area.d.ts +2 -2
- package/dist/src/tui/components/chat-area.d.ts.map +1 -1
- package/dist/src/tui/components/chat-area.js +5 -5
- package/dist/src/tui/components/chat-area.js.map +1 -1
- package/dist/src/tui/components/command-palette.d.ts.map +1 -1
- package/dist/src/tui/components/command-palette.js +7 -5
- package/dist/src/tui/components/command-palette.js.map +1 -1
- package/dist/src/tui/components/message.d.ts +2 -2
- package/dist/src/tui/components/message.d.ts.map +1 -1
- package/dist/src/tui/components/message.js +63 -52
- package/dist/src/tui/components/message.js.map +1 -1
- package/dist/src/tui/components/slash-autocomplete.d.ts +2 -2
- package/dist/src/tui/components/slash-autocomplete.d.ts.map +1 -1
- package/dist/src/tui/components/slash-autocomplete.js +6 -8
- package/dist/src/tui/components/slash-autocomplete.js.map +1 -1
- package/dist/src/tui/components/toast.d.ts +2 -2
- package/dist/src/tui/components/toast.d.ts.map +1 -1
- package/dist/src/tui/components/toast.js +11 -6
- package/dist/src/tui/components/toast.js.map +1 -1
- package/dist/src/tui/hooks/use-agent.d.ts +3 -3
- package/dist/src/tui/hooks/use-agent.d.ts.map +1 -1
- package/dist/src/tui/hooks/use-agent.js +22 -29
- package/dist/src/tui/hooks/use-agent.js.map +1 -1
- package/dist/src/tui/hooks/use-app-keyboard.d.ts +3 -3
- package/dist/src/tui/hooks/use-app-keyboard.d.ts.map +1 -1
- package/dist/src/tui/hooks/use-app-keyboard.js +28 -29
- package/dist/src/tui/hooks/use-app-keyboard.js.map +1 -1
- package/dist/src/tui/hooks/use-chat-submit.d.ts +6 -6
- package/dist/src/tui/hooks/use-chat-submit.d.ts.map +1 -1
- package/dist/src/tui/hooks/use-chat-submit.js +115 -54
- package/dist/src/tui/hooks/use-chat-submit.js.map +1 -1
- package/dist/src/tui/hooks/use-permission-queue.d.ts +2 -2
- package/dist/src/tui/hooks/use-permission-queue.d.ts.map +1 -1
- package/dist/src/tui/hooks/use-permission-queue.js +1 -1
- package/dist/src/tui/hooks/use-permission-queue.js.map +1 -1
- package/dist/src/tui/hooks/use-revert.d.ts +4 -4
- package/dist/src/tui/hooks/use-revert.d.ts.map +1 -1
- package/dist/src/tui/hooks/use-revert.js +22 -13
- package/dist/src/tui/hooks/use-revert.js.map +1 -1
- package/dist/src/tui/index.d.ts.map +1 -1
- package/dist/src/tui/index.js +11 -11
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/prompt-bar.d.ts +1 -1
- package/dist/src/tui/prompt-bar.d.ts.map +1 -1
- package/dist/src/tui/prompt-bar.js +45 -16
- package/dist/src/tui/prompt-bar.js.map +1 -1
- package/dist/src/tui/slash-commands.d.ts +2 -2
- package/dist/src/tui/slash-commands.d.ts.map +1 -1
- package/dist/src/tui/slash-commands.js +9 -9
- package/dist/src/tui/slash-commands.js.map +1 -1
- package/dist/src/tui/theme.d.ts +1 -1
- package/dist/src/tui/theme.d.ts.map +1 -1
- package/dist/src/tui/theme.js +46 -38
- package/dist/src/tui/theme.js.map +1 -1
- package/dist/src/tui/tips.d.ts.map +1 -1
- package/dist/src/tui/tips.js +14 -14
- package/dist/src/tui/tips.js.map +1 -1
- package/dist/src/tui/types.d.ts +5 -5
- package/dist/src/tui/types.d.ts.map +1 -1
- package/dist/src/tui/ui/about-dialog.d.ts.map +1 -1
- package/dist/src/tui/ui/about-dialog.js +5 -5
- package/dist/src/tui/ui/about-dialog.js.map +1 -1
- package/dist/src/tui/ui/agent-switcher.d.ts.map +1 -1
- package/dist/src/tui/ui/agent-switcher.js +16 -14
- package/dist/src/tui/ui/agent-switcher.js.map +1 -1
- package/dist/src/tui/ui/debug-dialog.d.ts +1 -1
- package/dist/src/tui/ui/debug-dialog.d.ts.map +1 -1
- package/dist/src/tui/ui/debug-dialog.js +26 -26
- package/dist/src/tui/ui/debug-dialog.js.map +1 -1
- package/dist/src/tui/ui/doctor-dialog.d.ts +2 -2
- package/dist/src/tui/ui/doctor-dialog.d.ts.map +1 -1
- package/dist/src/tui/ui/doctor-dialog.js +10 -8
- package/dist/src/tui/ui/doctor-dialog.js.map +1 -1
- package/dist/src/tui/ui/manage-providers-dialog.d.ts +1 -1
- package/dist/src/tui/ui/manage-providers-dialog.d.ts.map +1 -1
- package/dist/src/tui/ui/manage-providers-dialog.js +102 -86
- package/dist/src/tui/ui/manage-providers-dialog.js.map +1 -1
- package/dist/src/tui/ui/mcp-toggle-dialog.d.ts.map +1 -1
- package/dist/src/tui/ui/mcp-toggle-dialog.js +17 -14
- package/dist/src/tui/ui/mcp-toggle-dialog.js.map +1 -1
- package/dist/src/tui/ui/message-controls.d.ts +1 -1
- package/dist/src/tui/ui/message-controls.d.ts.map +1 -1
- package/dist/src/tui/ui/message-controls.js +40 -28
- package/dist/src/tui/ui/message-controls.js.map +1 -1
- package/dist/src/tui/ui/model-switcher.d.ts.map +1 -1
- package/dist/src/tui/ui/model-switcher.js +40 -25
- package/dist/src/tui/ui/model-switcher.js.map +1 -1
- package/dist/src/tui/ui/permission-dialog.d.ts +1 -1
- package/dist/src/tui/ui/permission-dialog.d.ts.map +1 -1
- package/dist/src/tui/ui/permission-dialog.js +11 -11
- package/dist/src/tui/ui/permission-dialog.js.map +1 -1
- package/dist/src/tui/ui/provider-dialog.d.ts.map +1 -1
- package/dist/src/tui/ui/provider-dialog.js +75 -64
- package/dist/src/tui/ui/provider-dialog.js.map +1 -1
- package/dist/src/tui/ui/session-list.d.ts +3 -3
- package/dist/src/tui/ui/session-list.d.ts.map +1 -1
- package/dist/src/tui/ui/session-list.js +44 -32
- package/dist/src/tui/ui/session-list.js.map +1 -1
- package/dist/src/tui/ui/thinking-effort-dialog.d.ts.map +1 -1
- package/dist/src/tui/ui/thinking-effort-dialog.js +19 -19
- package/dist/src/tui/ui/thinking-effort-dialog.js.map +1 -1
- package/dist/src/tui/ui/update-dialog.d.ts +11 -0
- package/dist/src/tui/ui/update-dialog.d.ts.map +1 -0
- package/dist/src/tui/ui/update-dialog.js +23 -0
- package/dist/src/tui/ui/update-dialog.js.map +1 -0
- package/dist/src/tui/utils/model-config.d.ts.map +1 -1
- package/dist/src/tui/utils/model-config.js +13 -13
- package/dist/src/tui/utils/model-config.js.map +1 -1
- package/dist/src/tui/utils/session-messages.d.ts +2 -2
- package/dist/src/tui/utils/session-messages.d.ts.map +1 -1
- package/dist/src/tui/utils/session-messages.js +35 -22
- package/dist/src/tui/utils/session-messages.js.map +1 -1
- package/dist/src/tui/utils/update-check.d.ts +2 -0
- package/dist/src/tui/utils/update-check.d.ts.map +1 -0
- package/dist/src/tui/utils/update-check.js +65 -0
- package/dist/src/tui/utils/update-check.js.map +1 -0
- package/dist/src/tui/utils/version.d.ts.map +1 -1
- package/dist/src/tui/utils/version.js +7 -7
- package/dist/src/tui/utils/version.js.map +1 -1
- package/dist/src/tui/utils.d.ts +2 -2
- package/dist/src/tui/utils.d.ts.map +1 -1
- package/dist/src/tui/utils.js +7 -7
- package/dist/src/tui/utils.js.map +1 -1
- package/dist/src/tui/variant-cycle.d.ts.map +1 -1
- package/dist/src/tui/variant-cycle.js +23 -23
- package/dist/src/tui/variant-cycle.js.map +1 -1
- package/dist/src/utils/paths.d.ts.map +1 -1
- package/dist/src/utils/paths.js +25 -25
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/platform.d.ts.map +1 -1
- package/dist/src/utils/platform.js +15 -17
- package/dist/src/utils/platform.js.map +1 -1
- package/package.json +3 -3
package/dist/src/tui/app.js
CHANGED
|
@@ -1,43 +1,46 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
-
import { useRef, useCallback, useEffect, useMemo, useState } from
|
|
3
|
-
import { useTerminalDimensions } from
|
|
4
|
-
import {
|
|
5
|
-
import { c, SPINNER } from
|
|
6
|
-
import { ChatArea } from
|
|
7
|
-
import { CommandPalette } from
|
|
8
|
-
import { PromptBar } from
|
|
9
|
-
import { Tips } from
|
|
10
|
-
import { titlecase } from
|
|
11
|
-
import { SessionStore } from
|
|
12
|
-
import { SnapshotManager } from
|
|
13
|
-
import { ProviderDialog } from
|
|
14
|
-
import { SessionList } from
|
|
15
|
-
import { ModelSwitcher } from
|
|
16
|
-
import { ManageProvidersDialog } from
|
|
17
|
-
import { DoctorDialog } from
|
|
18
|
-
import { AboutDialog } from
|
|
19
|
-
import { AgentSwitcher } from
|
|
20
|
-
import { ThinkingEffortDialog } from
|
|
21
|
-
import { McpToggleDialog } from
|
|
22
|
-
import { DebugDialog } from
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import
|
|
26
|
-
import
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
2
|
+
import { useRef, useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { useTerminalDimensions } from '@opentui/react';
|
|
4
|
+
import { execFileSync } from 'child_process';
|
|
5
|
+
import { c, SPINNER } from './theme.js';
|
|
6
|
+
import { ChatArea } from './components/chat-area.js';
|
|
7
|
+
import { CommandPalette } from './components/command-palette.js';
|
|
8
|
+
import { PromptBar } from './prompt-bar.js';
|
|
9
|
+
import { Tips } from './tips.js';
|
|
10
|
+
import { titlecase } from './utils.js';
|
|
11
|
+
import { SessionStore } from '../services/session-store.js';
|
|
12
|
+
import { SnapshotManager } from '../services/snapshot-manager.js';
|
|
13
|
+
import { ProviderDialog } from './ui/provider-dialog.js';
|
|
14
|
+
import { SessionList } from './ui/session-list.js';
|
|
15
|
+
import { ModelSwitcher } from './ui/model-switcher.js';
|
|
16
|
+
import { ManageProvidersDialog } from './ui/manage-providers-dialog.js';
|
|
17
|
+
import { DoctorDialog } from './ui/doctor-dialog.js';
|
|
18
|
+
import { AboutDialog } from './ui/about-dialog.js';
|
|
19
|
+
import { AgentSwitcher } from './ui/agent-switcher.js';
|
|
20
|
+
import { ThinkingEffortDialog } from './ui/thinking-effort-dialog.js';
|
|
21
|
+
import { McpToggleDialog } from './ui/mcp-toggle-dialog.js';
|
|
22
|
+
import { DebugDialog } from './ui/debug-dialog.js';
|
|
23
|
+
import { UpdateDialog } from './ui/update-dialog.js';
|
|
24
|
+
import { MessageControls } from './ui/message-controls.js';
|
|
25
|
+
import { ToastContainer, showToast } from './components/toast.js';
|
|
26
|
+
import clipboard from 'clipboardy';
|
|
27
|
+
import { buildCmdItems, collectSlashNames } from './commands.js';
|
|
28
|
+
import { slashHead } from './slash-commands.js';
|
|
29
|
+
import { SlashAutocomplete } from './components/slash-autocomplete.js';
|
|
30
|
+
import { checkForUpdate } from './utils/update-check.js';
|
|
31
|
+
import { VERSION } from './utils/version.js';
|
|
32
|
+
import { loadConfig } from '../services/config.js';
|
|
33
|
+
import { registerAllCustomProviders } from '../services/custom-providers.js';
|
|
34
|
+
import { PermissionDialog } from './ui/permission-dialog.js';
|
|
35
|
+
import { PLACEHOLDERS } from './app-constants.js';
|
|
36
|
+
import { loadSavedConfig, saveModelConfig, fmtCtx, lookupContextWindow } from './utils/model-config.js';
|
|
37
|
+
import { sdkMessagesToChatMessages } from './utils/session-messages.js';
|
|
38
|
+
import { usePermissionQueue } from './hooks/use-permission-queue.js';
|
|
39
|
+
import { useRevert } from './hooks/use-revert.js';
|
|
40
|
+
import { useAgent } from './hooks/use-agent.js';
|
|
41
|
+
import { useChatSubmit } from './hooks/use-chat-submit.js';
|
|
42
|
+
import { useAppKeyboard } from './hooks/use-app-keyboard.js';
|
|
43
|
+
import { cycleEffort } from './variant-cycle.js';
|
|
41
44
|
export function App({ renderer }) {
|
|
42
45
|
const { width: termWidth, height: termHeight } = useTerminalDimensions();
|
|
43
46
|
// --- State ---
|
|
@@ -51,13 +54,13 @@ export function App({ renderer }) {
|
|
|
51
54
|
const [selectedModel, setSelectedModel] = useState(savedConfig.model);
|
|
52
55
|
const [selectedProvider, setSelectedProvider] = useState(savedConfig.provider);
|
|
53
56
|
const [thinkingEffort, setThinkingEffort] = useState(undefined);
|
|
54
|
-
const [route, setRoute] = useState(
|
|
57
|
+
const [route, setRoute] = useState('home');
|
|
55
58
|
const [messages, setMessages] = useState([]);
|
|
56
59
|
const [isLoading, setIsLoading] = useState(false);
|
|
57
|
-
const [status, setStatus] = useState(
|
|
60
|
+
const [status, setStatus] = useState('Ready');
|
|
58
61
|
const [spinnerFrame, setSpinnerFrame] = useState(0);
|
|
59
62
|
const [showCmd, setShowCmd] = useState(false);
|
|
60
|
-
const [cmdFilter, setCmdFilter] = useState(
|
|
63
|
+
const [cmdFilter, setCmdFilter] = useState('');
|
|
61
64
|
const [cmdSelected, setCmdSelected] = useState(0);
|
|
62
65
|
const [elapsedMs, setElapsedMs] = useState(null);
|
|
63
66
|
const [tokPerSec, setTokPerSec] = useState(null);
|
|
@@ -65,9 +68,10 @@ export function App({ renderer }) {
|
|
|
65
68
|
const [showThinking, setShowThinking] = useState(true);
|
|
66
69
|
const [showToolCalls, setShowToolCalls] = useState(true);
|
|
67
70
|
const [copiedMsg, setCopiedMsg] = useState(false);
|
|
68
|
-
const [selectedAgent, setSelectedAgent] = useState(
|
|
71
|
+
const [selectedAgent, setSelectedAgent] = useState('build');
|
|
69
72
|
const [submitKey, setSubmitKey] = useState(0);
|
|
70
73
|
const [dialogStep, setDialogStep] = useState(null);
|
|
74
|
+
const [updateVersion, setUpdateVersion] = useState(null);
|
|
71
75
|
const [placeholderIdx, setPlaceholderIdx] = useState(0);
|
|
72
76
|
const [promptHistory, setPromptHistory] = useState([]);
|
|
73
77
|
const [historyIdx, setHistoryIdx] = useState(-1);
|
|
@@ -76,7 +80,7 @@ export function App({ renderer }) {
|
|
|
76
80
|
const [interruptKey, setInterruptKey] = useState(0);
|
|
77
81
|
const [msgControls, setMsgControls] = useState(null);
|
|
78
82
|
const [revertPoint, setRevertPoint] = useState(null);
|
|
79
|
-
const [draftText, setDraftText] = useState(
|
|
83
|
+
const [draftText, setDraftText] = useState('');
|
|
80
84
|
const [slashSelected, setSlashSelected] = useState(0);
|
|
81
85
|
const [promptPosition, setPromptPosition] = useState({ top: 0, left: 0, width: 0 });
|
|
82
86
|
// --- Refs ---
|
|
@@ -98,10 +102,14 @@ export function App({ renderer }) {
|
|
|
98
102
|
const mcpCount = 0;
|
|
99
103
|
const customProviderCount = Object.keys(customProviders).length;
|
|
100
104
|
const cwdLabel = useMemo(() => {
|
|
101
|
-
const home = process.env.HOME || process.env.USERPROFILE ||
|
|
102
|
-
const dir = process.cwd().replace(home,
|
|
105
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
106
|
+
const dir = process.cwd().replace(home, '~');
|
|
103
107
|
try {
|
|
104
|
-
const branch =
|
|
108
|
+
const branch = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
109
|
+
encoding: 'utf-8',
|
|
110
|
+
timeout: 2000,
|
|
111
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
112
|
+
}).trim();
|
|
105
113
|
if (branch)
|
|
106
114
|
return `${dir}:${branch}`;
|
|
107
115
|
}
|
|
@@ -113,12 +121,21 @@ export function App({ renderer }) {
|
|
|
113
121
|
const id = setInterval(() => setPlaceholderIdx((p) => (p + 1) % PLACEHOLDERS.length), 4000);
|
|
114
122
|
return () => clearInterval(id);
|
|
115
123
|
}, []);
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
checkForUpdate().then((version) => {
|
|
126
|
+
if (version)
|
|
127
|
+
setUpdateVersion(version);
|
|
128
|
+
});
|
|
129
|
+
}, []);
|
|
116
130
|
useEffect(() => {
|
|
117
131
|
if (!isLoading)
|
|
118
132
|
return;
|
|
119
133
|
const id = setInterval(() => setSpinnerFrame((f) => (f + 1) % SPINNER.length), 80);
|
|
120
134
|
renderer.requestLive();
|
|
121
|
-
return () => {
|
|
135
|
+
return () => {
|
|
136
|
+
clearInterval(id);
|
|
137
|
+
renderer.dropLive();
|
|
138
|
+
};
|
|
122
139
|
}, [isLoading, renderer]);
|
|
123
140
|
useEffect(() => {
|
|
124
141
|
const handler = (selection) => {
|
|
@@ -134,8 +151,10 @@ export function App({ renderer }) {
|
|
|
134
151
|
catch { }
|
|
135
152
|
}, 2000);
|
|
136
153
|
};
|
|
137
|
-
renderer.on(
|
|
138
|
-
return () => {
|
|
154
|
+
renderer.on('selection', handler);
|
|
155
|
+
return () => {
|
|
156
|
+
renderer.off?.('selection', handler);
|
|
157
|
+
};
|
|
139
158
|
}, [renderer]);
|
|
140
159
|
// --- Stable callbacks ---
|
|
141
160
|
const addMessage = useCallback((msg) => setMessages((p) => [...p, msg]), []);
|
|
@@ -143,30 +162,59 @@ export function App({ renderer }) {
|
|
|
143
162
|
// --- Hooks (order matters for ref lifecycle) ---
|
|
144
163
|
const securityRef = useRef(null);
|
|
145
164
|
const { permissionRequest, enqueuePermission, resolvePermission } = usePermissionQueue(securityRef);
|
|
146
|
-
const { agentRef, loadedSessionMessages, getOrCreateAgent, resetAgentForModelSwitch
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
165
|
+
const { agentRef, loadedSessionMessages, getOrCreateAgent, resetAgentForModelSwitch } = useAgent({
|
|
166
|
+
securityRef,
|
|
167
|
+
securityConfig,
|
|
168
|
+
enqueuePermission,
|
|
169
|
+
});
|
|
170
|
+
const { revertedMessagesRef, revertDraftRef, runRevert, runRedo, runRollbackFiles, discardRevert } = useRevert({
|
|
171
|
+
sessionStore,
|
|
172
|
+
sessionId,
|
|
173
|
+
agentRef,
|
|
174
|
+
loadedSessionMessages,
|
|
175
|
+
setMessages,
|
|
176
|
+
setRevertPoint,
|
|
177
|
+
setHistoryIdx,
|
|
178
|
+
setNavKey,
|
|
179
|
+
snapshotManager,
|
|
150
180
|
});
|
|
151
181
|
const handleCycleVariant = useCallback(() => {
|
|
152
182
|
if (!provider) {
|
|
153
|
-
showToast(
|
|
183
|
+
showToast('No provider configured', 'warn');
|
|
154
184
|
return;
|
|
155
185
|
}
|
|
156
186
|
const nextEffort = cycleEffort(provider, thinkingEffort);
|
|
157
187
|
if (!nextEffort) {
|
|
158
|
-
showToast(
|
|
188
|
+
showToast('No variants available', 'info');
|
|
159
189
|
return;
|
|
160
190
|
}
|
|
161
191
|
setThinkingEffort(nextEffort);
|
|
162
192
|
agentRef.current = null;
|
|
163
|
-
showToast(nextEffort ===
|
|
193
|
+
showToast(nextEffort === 'none' ? 'Thinking: off' : `Thinking: ${nextEffort}`, 'info');
|
|
164
194
|
}, [provider, thinkingEffort, agentRef]);
|
|
165
195
|
const cmdItems = useMemo(() => buildCmdItems({
|
|
166
|
-
renderer,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
196
|
+
renderer,
|
|
197
|
+
sessionStore: sessionStore.current,
|
|
198
|
+
sessionIdRef: sessionId,
|
|
199
|
+
hasModel,
|
|
200
|
+
selectedModel,
|
|
201
|
+
provider,
|
|
202
|
+
mcpCount,
|
|
203
|
+
customProviderCount,
|
|
204
|
+
messagesLength: messages.length,
|
|
205
|
+
showThinking,
|
|
206
|
+
showToolCalls,
|
|
207
|
+
setRoute,
|
|
208
|
+
setMessages,
|
|
209
|
+
setStatus,
|
|
210
|
+
setElapsedMs,
|
|
211
|
+
setTokPerSec,
|
|
212
|
+
setTokenUsage,
|
|
213
|
+
setShowThinking,
|
|
214
|
+
setShowToolCalls,
|
|
215
|
+
setHomeKey,
|
|
216
|
+
setNavKey,
|
|
217
|
+
setDialogStep,
|
|
170
218
|
onCycleVariant: handleCycleVariant,
|
|
171
219
|
currentEffort: thinkingEffort,
|
|
172
220
|
selectedAgent,
|
|
@@ -174,23 +222,81 @@ export function App({ renderer }) {
|
|
|
174
222
|
securityRef.current?.getReadTracker().reset();
|
|
175
223
|
securityRef.current?.getDoomLoop().reset();
|
|
176
224
|
},
|
|
177
|
-
}), [
|
|
225
|
+
}), [
|
|
226
|
+
renderer,
|
|
227
|
+
hasModel,
|
|
228
|
+
selectedModel,
|
|
229
|
+
provider,
|
|
230
|
+
mcpCount,
|
|
231
|
+
customProviderCount,
|
|
232
|
+
messages.length,
|
|
233
|
+
showThinking,
|
|
234
|
+
showToolCalls,
|
|
235
|
+
handleCycleVariant,
|
|
236
|
+
thinkingEffort,
|
|
237
|
+
selectedAgent,
|
|
238
|
+
sessionStore,
|
|
239
|
+
sessionId,
|
|
240
|
+
setRoute,
|
|
241
|
+
setMessages,
|
|
242
|
+
setStatus,
|
|
243
|
+
setElapsedMs,
|
|
244
|
+
setTokPerSec,
|
|
245
|
+
setTokenUsage,
|
|
246
|
+
setShowThinking,
|
|
247
|
+
setShowToolCalls,
|
|
248
|
+
setHomeKey,
|
|
249
|
+
setNavKey,
|
|
250
|
+
setDialogStep,
|
|
251
|
+
securityRef,
|
|
252
|
+
]);
|
|
178
253
|
const slashNames = useMemo(() => collectSlashNames(cmdItems), [cmdItems]);
|
|
179
|
-
const { handleSubmit, updateLastAssistantMeta
|
|
180
|
-
sessionStore,
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
254
|
+
const { handleSubmit, updateLastAssistantMeta } = useChatSubmit({
|
|
255
|
+
sessionStore,
|
|
256
|
+
sessionId,
|
|
257
|
+
agentRef,
|
|
258
|
+
securityRef,
|
|
259
|
+
loadedSessionMessages,
|
|
260
|
+
snapshotManager,
|
|
261
|
+
lastAgentRef: useRef(null),
|
|
262
|
+
isStreamingRef,
|
|
263
|
+
currentTurnStartRef,
|
|
264
|
+
currentTurnMsgIdRef,
|
|
265
|
+
revertPoint,
|
|
266
|
+
getOrCreateAgent,
|
|
267
|
+
selectedModel,
|
|
268
|
+
provider,
|
|
269
|
+
selectedAgent,
|
|
270
|
+
customProviders,
|
|
271
|
+
thinkingEffort,
|
|
272
|
+
cmdItems,
|
|
273
|
+
slashNames,
|
|
274
|
+
addMessage,
|
|
275
|
+
updateMessage,
|
|
276
|
+
setMessages,
|
|
277
|
+
setIsLoading,
|
|
278
|
+
setStatus,
|
|
279
|
+
setRoute,
|
|
280
|
+
setElapsedMs,
|
|
281
|
+
setTokPerSec,
|
|
282
|
+
setTokenUsage,
|
|
283
|
+
setDraftText,
|
|
284
|
+
setSlashSelected,
|
|
285
|
+
setSubmitKey,
|
|
286
|
+
setPromptHistory,
|
|
287
|
+
setHistoryIdx,
|
|
288
|
+
setInterruptKey,
|
|
289
|
+
setRevertPoint,
|
|
188
290
|
discardRevert,
|
|
189
291
|
});
|
|
190
292
|
// --- cmdFiltered + slash ---
|
|
191
293
|
const cmdFiltered = useMemo(() => {
|
|
192
294
|
const q = cmdFilter.toLowerCase();
|
|
193
|
-
return !q
|
|
295
|
+
return !q
|
|
296
|
+
? cmdItems
|
|
297
|
+
: cmdItems.filter((i) => i.label.toLowerCase().includes(q) ||
|
|
298
|
+
i.desc.toLowerCase().includes(q) ||
|
|
299
|
+
(i.cat && i.cat.toLowerCase().includes(q)));
|
|
194
300
|
}, [cmdItems, cmdFilter]);
|
|
195
301
|
const slashFiltered = useMemo(() => {
|
|
196
302
|
const head = slashHead(draftText);
|
|
@@ -208,54 +314,98 @@ export function App({ renderer }) {
|
|
|
208
314
|
});
|
|
209
315
|
}, [cmdItems, draftText]);
|
|
210
316
|
const slashActive = useMemo(() => slashHead(draftText) !== undefined, [draftText]);
|
|
211
|
-
useEffect(() => {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
317
|
+
useEffect(() => {
|
|
318
|
+
setSlashSelected(0);
|
|
319
|
+
}, [draftText]);
|
|
320
|
+
useEffect(() => {
|
|
321
|
+
if (cmdSelected >= cmdFiltered.length && cmdFiltered.length > 0)
|
|
322
|
+
setCmdSelected(cmdFiltered.length - 1);
|
|
323
|
+
}, [cmdSelected, cmdFiltered.length]);
|
|
324
|
+
const execCmd = useCallback((item) => {
|
|
325
|
+
item.action();
|
|
326
|
+
setShowCmd(false);
|
|
327
|
+
}, [setShowCmd]);
|
|
215
328
|
// --- Keyboard ---
|
|
216
329
|
useAppKeyboard({
|
|
217
|
-
renderer,
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
330
|
+
renderer,
|
|
331
|
+
isStreamingRef,
|
|
332
|
+
currentTurnStartRef,
|
|
333
|
+
currentTurnMsgIdRef,
|
|
334
|
+
revertPoint,
|
|
335
|
+
revertedMessagesRef,
|
|
336
|
+
runRedo,
|
|
337
|
+
runRollbackFiles,
|
|
338
|
+
dialogStep,
|
|
339
|
+
msgControls,
|
|
340
|
+
permissionRequest,
|
|
341
|
+
dialogKeyHandler,
|
|
342
|
+
showCmd,
|
|
343
|
+
cmdFilter,
|
|
344
|
+
cmdSelected,
|
|
345
|
+
cmdFiltered,
|
|
346
|
+
draftText,
|
|
347
|
+
slashActive,
|
|
348
|
+
slashFiltered,
|
|
349
|
+
slashSelected,
|
|
350
|
+
promptHistory,
|
|
351
|
+
historyIdx,
|
|
352
|
+
interruptKey,
|
|
353
|
+
selectedAgent,
|
|
354
|
+
thinkingEffort,
|
|
355
|
+
provider,
|
|
356
|
+
agentRef,
|
|
357
|
+
securityRef,
|
|
358
|
+
promptTextareaRef,
|
|
359
|
+
setShowCmd,
|
|
360
|
+
setCmdFilter,
|
|
361
|
+
setCmdSelected,
|
|
362
|
+
setDraftText,
|
|
363
|
+
setSlashSelected,
|
|
364
|
+
setHistoryIdx,
|
|
365
|
+
setNavKey,
|
|
366
|
+
setInterruptKey,
|
|
367
|
+
setSelectedAgent,
|
|
368
|
+
setMessages,
|
|
369
|
+
setStatus,
|
|
370
|
+
setThinkingEffort,
|
|
371
|
+
updateMessage,
|
|
372
|
+
updateLastAssistantMeta,
|
|
373
|
+
execCmd,
|
|
374
|
+
handleCycleVariant,
|
|
230
375
|
});
|
|
231
376
|
// --- JSX ---
|
|
232
|
-
return (_jsxs("box", { flexDirection: "column", height: termHeight, backgroundColor: c.bg, children: [route ===
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
{ icon:
|
|
236
|
-
{ icon:
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
377
|
+
return (_jsxs("box", { flexDirection: "column", height: termHeight, backgroundColor: c.bg, children: [route === 'home' ? (_jsxs("box", { flexDirection: "column", flexGrow: 1, children: [_jsx("box", { flexGrow: 1 }), _jsxs("box", { flexDirection: "column", alignItems: "center", flexShrink: 0, children: [_jsx("ascii-font", { text: "SPECTRA", font: "block", color: c.accent }), _jsx("box", { height: 1 }), _jsx(PromptBar, { isLoading: isLoading, spinnerFrame: spinnerFrame, inputKey: `h-${submitKey}-${navKey}`, placeholder: `Ask anything... "${PLACEHOLDERS[placeholderIdx]}"`, onSubmit: handleSubmit, hasModel: hasModel, agent: selectedAgent, model: selectedModel || '', provider: provider || '', thinkingEffort: thinkingEffort, initialValue: revertDraftRef.current || (historyIdx >= 0 ? promptHistory[historyIdx] : ''), width: Math.min(68, termWidth - 8), focused: !dialogStep && !showCmd && !msgControls && !permissionRequest, onTextChange: (t) => setDraftText(t), onGetTextarea: (r) => {
|
|
378
|
+
promptTextareaRef.current = r;
|
|
379
|
+
}, onPositionChange: setPromptPosition }), _jsx("box", { height: 1 }), _jsx("box", { flexDirection: "row", justifyContent: "flex-end", width: Math.min(68, termWidth - 8), children: _jsxs("box", { flexDirection: "row", gap: 2, children: [_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: c.text, children: "tab" }), _jsx("text", { fg: c.dim, children: " agent" })] }), _jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: c.text, children: "ctrl+t" }), _jsx("text", { fg: c.dim, children: " effort" })] }), _jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: c.text, children: "ctrl+p" }), _jsx("text", { fg: c.dim, children: " commands" })] })] }) }), _jsx("box", { height: 1 }), _jsx("box", { flexDirection: "row", gap: 4, alignItems: "center", children: [
|
|
380
|
+
{ icon: '◈', label: `${sessionStore.current.list().length} sessions` },
|
|
381
|
+
{ icon: '◉', label: '3 agents' },
|
|
382
|
+
{ icon: '◆', label: '7 tools' },
|
|
383
|
+
{ icon: '⬢', label: `${mcpCount} MCP` },
|
|
384
|
+
].map((s) => (_jsxs("box", { flexDirection: "row", gap: 1, alignItems: "center", children: [_jsx("text", { fg: c.accent, children: s.icon }), _jsx("text", { fg: c.dim, children: s.label })] }, s.label))) }), _jsx(Tips, {})] }), _jsx("box", { flexGrow: 1 }), _jsxs("box", { flexDirection: "row", justifyContent: "space-between", paddingLeft: 2, paddingRight: 2, height: 1, marginBottom: 1, children: [_jsx("box", { flexDirection: "row", gap: 4, children: _jsx("text", { fg: c.dim, overflow: "hidden", wrapMode: "none", children: cwdLabel }) }), _jsx("text", { fg: c.dim, flexShrink: 0, children: "Spectra Code" })] })] }, `home-${homeKey}`)) : (_jsxs("box", { flexDirection: "column", height: termHeight, paddingLeft: 2, paddingRight: 2, children: [revertPoint && (_jsxs("box", { flexDirection: "column", alignItems: "center", paddingY: 1, children: [_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: c.warn, children: "Messages reverted. " }), _jsx("text", { fg: c.accent, children: "Ctrl+Y" }), _jsx("text", { fg: c.dim, children: " to restore" })] }), _jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: c.dim, children: "Files unchanged. " }), _jsx("text", { fg: c.accent, children: "Ctrl+Shift+Y" }), _jsx("text", { fg: c.dim, children: " to rollback files" })] })] })), _jsx("box", { flexDirection: "column", flexGrow: 1, paddingBottom: 1, children: _jsx(ChatArea, { messages: messages, showThinking: showThinking, showToolCalls: showToolCalls, revertPoint: revertPoint, onMessageClick: (msg) => setMsgControls(msg) }) }), _jsxs("box", { flexShrink: 0, children: [_jsx(PromptBar, { isLoading: isLoading, spinnerFrame: spinnerFrame, inputKey: `c-${submitKey}-${navKey}`, placeholder: "Reply...", onSubmit: handleSubmit, hasModel: hasModel, agent: selectedAgent, model: selectedModel || '', provider: provider || '', thinkingEffort: thinkingEffort, initialValue: revertDraftRef.current || (historyIdx >= 0 ? promptHistory[historyIdx] : ''), elapsedMs: elapsedMs, tokenUsage: tokenUsage, width: termWidth - 4, focused: !dialogStep && !showCmd && !msgControls && !permissionRequest, onTextChange: (t) => setDraftText(t), onGetTextarea: (r) => {
|
|
385
|
+
promptTextareaRef.current = r;
|
|
386
|
+
}, onPositionChange: setPromptPosition }), _jsx("box", { height: 1 }), _jsxs("box", { flexDirection: "row", justifyContent: "space-between", alignItems: "center", height: 1, paddingLeft: 3, paddingRight: 1, children: [_jsxs("box", { flexDirection: "row", gap: 2, alignItems: "center", overflow: "hidden", children: [isLoading ? (_jsxs("box", { flexDirection: "row", gap: 2, alignItems: "center", children: [_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsx("text", { fg: c.warn, children: SPINNER[spinnerFrame] }), _jsx("text", { fg: c.dim, children: "Streaming..." })] }), _jsxs("box", { flexDirection: "row", gap: 1, children: [_jsx("text", { fg: c.accent, children: "esc" }), _jsx("text", { fg: c.dim, children: "interrupt" })] })] })) : (_jsx("text", { fg: c.dim, children: "Ready" })), tokenUsage.input + tokenUsage.output > 0 &&
|
|
387
|
+
(() => {
|
|
388
|
+
const used = tokenUsage.input + tokenUsage.output;
|
|
389
|
+
const cw = lookupContextWindow(selectedModel || '', provider);
|
|
390
|
+
const pct = cw ? Math.round((used / cw) * 100) : null;
|
|
391
|
+
return (_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsx("text", { fg: c.subtext, children: fmtCtx(used) }), pct !== null && _jsxs("text", { fg: pct > 80 ? c.warn : c.dim, children: ["(", pct, "%)"] })] }));
|
|
392
|
+
})()] }), _jsxs("box", { flexDirection: "row", gap: 2, alignItems: "center", children: [_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: c.text, children: "tab" }), _jsx("text", { fg: c.dim, children: " agent" })] }), _jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: c.text, children: "ctrl+t" }), _jsx("text", { fg: c.dim, children: " effort" })] }), _jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: c.text, children: "ctrl+p" }), _jsx("text", { fg: c.dim, children: " commands" })] })] })] })] })] })), showCmd && (_jsx(CommandPalette, { filter: cmdFilter, selected: cmdSelected, items: cmdFiltered, termWidth: termWidth, termHeight: termHeight })), slashActive && slashFiltered.length > 0 && (_jsx(SlashAutocomplete, { query: slashHead(draftText)?.name || '', selected: slashSelected, items: slashFiltered, termWidth: termWidth, termHeight: termHeight, route: route, promptTop: promptPosition.top, promptLeft: promptPosition.left, promptWidth: promptPosition.width })), dialogStep?.type === 'provider' && (_jsx(ProviderDialog, { termWidth: termWidth, termHeight: termHeight, keyHandlerRef: dialogKeyHandler, onModelSelected: (modelId, providerId) => {
|
|
243
393
|
resetAgentForModelSwitch();
|
|
244
394
|
setSelectedModel(modelId);
|
|
245
395
|
setSelectedProvider(providerId);
|
|
246
396
|
setDialogStep(null);
|
|
247
397
|
saveModelConfig(modelId, providerId);
|
|
248
|
-
showToast(`Model set`,
|
|
249
|
-
}, onClose: () => setDialogStep(null) })), dialogStep?.type ===
|
|
398
|
+
showToast(`Model set`, 'success');
|
|
399
|
+
}, onClose: () => setDialogStep(null) })), dialogStep?.type === 'session-list' && (_jsx(SessionList, { store: sessionStore.current, termWidth: termWidth, termHeight: termHeight, mode: dialogStep.mode || 'load', onLoad: (data) => {
|
|
250
400
|
const { messages: loadedMsgs, tokenUsage: tu } = sdkMessagesToChatMessages(data);
|
|
251
401
|
setTokenUsage(tu);
|
|
252
402
|
setMessages(() => loadedMsgs);
|
|
253
403
|
sessionId.current = data.id;
|
|
254
404
|
setSelectedModel(data.model);
|
|
255
|
-
setSelectedProvider(data.provider || data.model.split(
|
|
405
|
+
setSelectedProvider(data.provider || data.model.split('/')[0]);
|
|
256
406
|
setSelectedAgent(data.agent);
|
|
257
407
|
setThinkingEffort(data.thinkingEffort || undefined);
|
|
258
|
-
setRoute(
|
|
408
|
+
setRoute('chat');
|
|
259
409
|
setDialogStep(null);
|
|
260
410
|
loadedSessionMessages.current = data.messages;
|
|
261
411
|
if (agentRef.current) {
|
|
@@ -264,47 +414,80 @@ export function App({ renderer }) {
|
|
|
264
414
|
}
|
|
265
415
|
securityRef.current?.getReadTracker().reset();
|
|
266
416
|
securityRef.current?.getDoomLoop().reset();
|
|
267
|
-
showToast(`Loaded: ${data.title.slice(0, 40)}`,
|
|
417
|
+
showToast(`Loaded: ${data.title.slice(0, 40)}`, 'info');
|
|
268
418
|
}, onDelete: (id) => {
|
|
269
419
|
sessionStore.current.delete(id);
|
|
270
420
|
if (sessionId.current === id) {
|
|
271
421
|
sessionId.current = null;
|
|
272
422
|
setMessages([]);
|
|
273
|
-
setRoute(
|
|
423
|
+
setRoute('home');
|
|
274
424
|
setHomeKey((k) => k + 1);
|
|
275
425
|
}
|
|
276
|
-
showToast(
|
|
426
|
+
showToast('Session deleted', 'success');
|
|
277
427
|
}, onRename: (id, title) => {
|
|
278
428
|
sessionStore.current.rename(id, title);
|
|
279
|
-
showToast(
|
|
280
|
-
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
429
|
+
showToast('Session renamed', 'success');
|
|
430
|
+
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
431
|
+
dialogKeyHandler.current = fn;
|
|
432
|
+
} })), dialogStep?.type === 'switch-model' && (_jsx(ModelSwitcher, { providerId: provider || '', termWidth: termWidth, termHeight: termHeight, onModelSelected: (modelId, providerId) => {
|
|
281
433
|
resetAgentForModelSwitch();
|
|
282
434
|
setSelectedModel(modelId);
|
|
283
435
|
setSelectedProvider(providerId);
|
|
284
436
|
setDialogStep(null);
|
|
285
437
|
saveModelConfig(modelId, providerId);
|
|
286
|
-
showToast(`Switched model`,
|
|
287
|
-
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
438
|
+
showToast(`Switched model`, 'info');
|
|
439
|
+
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
440
|
+
dialogKeyHandler.current = fn;
|
|
441
|
+
} })), dialogStep?.type === 'manage-providers' && (_jsx(ManageProvidersDialog, { termWidth: termWidth, termHeight: termHeight, providers: customProviders, onProvidersChange: (updated) => {
|
|
288
442
|
setCustomProviders(updated);
|
|
289
443
|
resetAgentForModelSwitch();
|
|
290
|
-
showToast(
|
|
291
|
-
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
444
|
+
showToast('Providers updated', 'success');
|
|
445
|
+
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
446
|
+
dialogKeyHandler.current = fn;
|
|
447
|
+
} })), dialogStep?.type === 'doctor' && dialogStep.result && (_jsx(DoctorDialog, { result: dialogStep.result, termWidth: termWidth, termHeight: termHeight, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
448
|
+
dialogKeyHandler.current = fn;
|
|
449
|
+
} })), dialogStep?.type === 'about' && (_jsx(AboutDialog, { termWidth: termWidth, termHeight: termHeight, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
450
|
+
dialogKeyHandler.current = fn;
|
|
451
|
+
} })), updateVersion && (_jsx(UpdateDialog, { newVersion: updateVersion, currentVersion: VERSION, termWidth: termWidth, termHeight: termHeight, onClose: () => setUpdateVersion(null), onInstall: () => {
|
|
452
|
+
try {
|
|
453
|
+
clipboard.writeSync('bun update -g @mohanscodex/spectra-code');
|
|
454
|
+
showToast('Command copied to clipboard', 'success');
|
|
455
|
+
}
|
|
456
|
+
catch { }
|
|
457
|
+
setUpdateVersion(null);
|
|
458
|
+
}, registerHandler: (fn) => {
|
|
459
|
+
dialogKeyHandler.current = fn;
|
|
460
|
+
} })), dialogStep?.type === 'switch-agent' && (_jsx(AgentSwitcher, { currentAgent: selectedAgent, termWidth: termWidth, termHeight: termHeight, onAgentSelected: (agent) => {
|
|
292
461
|
setSelectedAgent(agent);
|
|
293
462
|
resetAgentForModelSwitch();
|
|
294
463
|
setDialogStep(null);
|
|
295
|
-
showToast(`Switched to ${titlecase(agent)} agent`,
|
|
296
|
-
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
464
|
+
showToast(`Switched to ${titlecase(agent)} agent`, 'info');
|
|
465
|
+
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
466
|
+
dialogKeyHandler.current = fn;
|
|
467
|
+
} })), dialogStep?.type === 'thinking-effort' && (_jsx(ThinkingEffortDialog, { provider: provider, currentEffort: thinkingEffort, termWidth: termWidth, termHeight: termHeight, onEffortSelected: (effort) => {
|
|
297
468
|
setThinkingEffort(effort);
|
|
298
469
|
resetAgentForModelSwitch();
|
|
299
470
|
setDialogStep(null);
|
|
300
|
-
showToast(effort ===
|
|
301
|
-
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
471
|
+
showToast(effort === 'none' ? 'Thinking: off' : `Thinking: ${effort}`, 'info');
|
|
472
|
+
}, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
473
|
+
dialogKeyHandler.current = fn;
|
|
474
|
+
} })), dialogStep?.type === 'toggle-mcp' && (_jsx(McpToggleDialog, { termWidth: termWidth, termHeight: termHeight, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
475
|
+
dialogKeyHandler.current = fn;
|
|
476
|
+
} })), dialogStep?.type === 'debug' && (_jsx(DebugDialog, { termWidth: termWidth, termHeight: termHeight, selectedModel: selectedModel, provider: provider, selectedAgent: selectedAgent, thinkingEffort: thinkingEffort, sessionStore: sessionStore.current, mcpCount: mcpCount, onClose: () => setDialogStep(null), registerHandler: (fn) => {
|
|
477
|
+
dialogKeyHandler.current = fn;
|
|
478
|
+
} })), msgControls && sessionId.current && (_jsx(MessageControls, { message: msgControls, sessionId: sessionId.current, messages: messages, termWidth: termWidth, termHeight: termHeight, revertPoint: revertPoint, onRevert: (msgId) => {
|
|
479
|
+
runRevert(messages, msgId);
|
|
480
|
+
setMsgControls(null);
|
|
481
|
+
}, onRedo: () => {
|
|
482
|
+
runRedo();
|
|
483
|
+
setMsgControls(null);
|
|
484
|
+
}, onFork: (msgId) => {
|
|
302
485
|
const forked = sessionStore.current.fork(sessionId.current);
|
|
303
486
|
if (forked) {
|
|
304
|
-
const msgIdx = messages.findIndex(m => m.id === msgId);
|
|
487
|
+
const msgIdx = messages.findIndex((m) => m.id === msgId);
|
|
305
488
|
if (msgIdx >= 0) {
|
|
306
489
|
forked.messages = forked.messages.slice(0, msgIdx + 1);
|
|
307
|
-
forked.title = `${forked.title.split(
|
|
490
|
+
forked.title = `${forked.title.split(' (fork)')[0]} (fork)`;
|
|
308
491
|
sessionStore.current.save(forked);
|
|
309
492
|
}
|
|
310
493
|
const data = sessionStore.current.get(forked.id);
|
|
@@ -313,10 +496,20 @@ export function App({ renderer }) {
|
|
|
313
496
|
setMessages(loadedMsgs);
|
|
314
497
|
sessionId.current = forked.id;
|
|
315
498
|
loadedSessionMessages.current = data.messages;
|
|
316
|
-
showToast(
|
|
499
|
+
showToast('Session forked', 'success');
|
|
317
500
|
}
|
|
318
501
|
}
|
|
319
502
|
setMsgControls(null);
|
|
320
|
-
}, onClose: () => setMsgControls(null), registerHandler: (fn) => {
|
|
503
|
+
}, onClose: () => setMsgControls(null), registerHandler: (fn) => {
|
|
504
|
+
dialogKeyHandler.current = fn;
|
|
505
|
+
} })), permissionRequest && (_jsx(PermissionDialog, { request: permissionRequest, termWidth: termWidth, termHeight: termHeight, onAllow: (id) => {
|
|
506
|
+
resolvePermission(id, { action: 'once' });
|
|
507
|
+
}, onAllowAlways: (id) => {
|
|
508
|
+
resolvePermission(id, { action: 'always' });
|
|
509
|
+
}, onDeny: (id) => {
|
|
510
|
+
resolvePermission(id, { action: 'deny' });
|
|
511
|
+
}, onClose: () => {
|
|
512
|
+
resolvePermission(permissionRequest.id, { action: 'deny' });
|
|
513
|
+
} })), _jsx(ToastContainer, {})] }));
|
|
321
514
|
}
|
|
322
515
|
//# sourceMappingURL=app.js.map
|