praxis-agent 0.7.0 → 0.9.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 +8 -0
- package/dist/application/background-agent-manager.d.ts +5 -0
- package/dist/application/background-agent-manager.js +21 -0
- package/dist/application/background-bash-manager.d.ts +14 -0
- package/dist/application/background-bash-manager.js +42 -4
- package/dist/application/background-task-runtime.d.ts +34 -0
- package/dist/application/background-task-runtime.js +59 -0
- package/dist/application/session-service.d.ts +21 -1
- package/dist/application/session-service.js +188 -17
- package/dist/application/session-worktree.d.ts +1 -0
- package/dist/application/session-worktree.js +13 -2
- package/dist/application/subagent-service.d.ts +3 -0
- package/dist/application/subagent-service.js +6 -0
- package/dist/application/workflow-manager.d.ts +70 -2
- package/dist/application/workflow-manager.js +21 -4
- package/dist/cli/agents-dashboard.d.ts +9 -0
- package/dist/cli/agents-dashboard.js +16 -5
- package/dist/cli/interactive.d.ts +41 -3
- package/dist/cli/interactive.js +1281 -183
- package/dist/cli/tui/claude-style.d.ts +31 -3
- package/dist/cli/tui/claude-style.js +171 -54
- package/dist/cli/tui/config-dashboard.d.ts +63 -0
- package/dist/cli/tui/config-dashboard.js +150 -0
- package/dist/cli/tui/config-settings.d.ts +32 -0
- package/dist/cli/tui/config-settings.js +276 -0
- package/dist/cli/tui/custom-themes.d.ts +21 -0
- package/dist/cli/tui/custom-themes.js +284 -0
- package/dist/cli/tui/file-picker.d.ts +3 -1
- package/dist/cli/tui/file-picker.js +8 -2
- package/dist/cli/tui/keybindings.js +0 -1
- package/dist/cli/tui/mcp-panel-controller.d.ts +32 -0
- package/dist/cli/tui/mcp-panel-controller.js +80 -0
- package/dist/cli/tui/mcp-panel-projector.d.ts +79 -0
- package/dist/cli/tui/mcp-panel-projector.js +181 -0
- package/dist/cli/tui/mcp-panel.d.ts +8 -0
- package/dist/cli/tui/mcp-panel.js +99 -0
- package/dist/cli/tui/recently-denied.d.ts +15 -0
- package/dist/cli/tui/recently-denied.js +19 -0
- package/dist/cli/tui/runtime-interactions.d.ts +17 -0
- package/dist/cli/tui/runtime-interactions.js +100 -0
- package/dist/cli/tui/runtime-settings.d.ts +40 -0
- package/dist/cli/tui/runtime-settings.js +84 -0
- package/dist/cli/tui/slash-commands.js +10 -0
- package/dist/cli/tui/task-panel.d.ts +53 -0
- package/dist/cli/tui/task-panel.js +204 -0
- package/dist/cli/tui/terminal-notifications.d.ts +10 -0
- package/dist/cli/tui/terminal-notifications.js +48 -0
- package/dist/cli/tui/terminal-setup.d.ts +24 -0
- package/dist/cli/tui/terminal-setup.js +618 -0
- package/dist/cli/tui/theme-settings.d.ts +8 -0
- package/dist/cli/tui/theme-settings.js +132 -0
- package/dist/cli/tui/theme.d.ts +53 -0
- package/dist/cli/tui/theme.js +265 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +97 -17
- package/dist/compatibility/claude/schema.js +2 -0
- package/dist/core/runtime.d.ts +12 -0
- package/dist/core/runtime.js +24 -0
- package/dist/maintenance/self-update.js +1 -1
- package/dist/mcp/claude-mcp-management.d.ts +6 -1
- package/dist/mcp/claude-mcp-management.js +191 -44
- package/dist/mcp/claude-mcp-oauth.js +2 -0
- package/dist/mcp/claude-mcp-tools.d.ts +31 -3
- package/dist/mcp/claude-mcp-tools.js +116 -34
- package/dist/permissions/claude-permission-resolver.d.ts +3 -0
- package/dist/permissions/claude-permission-resolver.js +42 -20
- package/dist/platform/claude-version.js +2 -1
- package/dist/plugins/claude-plugin-runtime.js +11 -3
- package/dist/tools/claude-interactive-tools.d.ts +7 -0
- package/dist/tools/claude-interactive-tools.js +21 -8
- package/dist/tools/claude-task-tools.d.ts +4 -0
- package/dist/tools/claude-task-tools.js +7 -0
- package/package.json +2 -1
- package/dist/application/background-agent-manager.d.ts.map +0 -1
- package/dist/application/background-agent-manager.js.map +0 -1
- package/dist/application/background-bash-manager.d.ts.map +0 -1
- package/dist/application/background-bash-manager.js.map +0 -1
- package/dist/application/background-task-id.d.ts.map +0 -1
- package/dist/application/background-task-id.js.map +0 -1
- package/dist/application/claude-project-purge.d.ts.map +0 -1
- package/dist/application/claude-project-purge.js.map +0 -1
- package/dist/application/managed-worktree.d.ts.map +0 -1
- package/dist/application/managed-worktree.js.map +0 -1
- package/dist/application/model-compactor.d.ts.map +0 -1
- package/dist/application/model-compactor.js.map +0 -1
- package/dist/application/scheduled-prompt-manager.d.ts.map +0 -1
- package/dist/application/scheduled-prompt-manager.js.map +0 -1
- package/dist/application/session-service.d.ts.map +0 -1
- package/dist/application/session-service.js.map +0 -1
- package/dist/application/session-worktree.d.ts.map +0 -1
- package/dist/application/session-worktree.js.map +0 -1
- package/dist/application/subagent-service.d.ts.map +0 -1
- package/dist/application/subagent-service.js.map +0 -1
- package/dist/application/tool-use-summary.d.ts.map +0 -1
- package/dist/application/tool-use-summary.js.map +0 -1
- package/dist/application/top-level-agent-manager.d.ts.map +0 -1
- package/dist/application/top-level-agent-manager.js.map +0 -1
- package/dist/application/workflow-manager.d.ts.map +0 -1
- package/dist/application/workflow-manager.js.map +0 -1
- package/dist/application/workflow-meta.d.ts.map +0 -1
- package/dist/application/workflow-meta.js.map +0 -1
- package/dist/application/workflow-runtime.d.ts.map +0 -1
- package/dist/application/workflow-runtime.js.map +0 -1
- package/dist/application/workflow-worktree.d.ts.map +0 -1
- package/dist/application/workflow-worktree.js.map +0 -1
- package/dist/cli/agents-dashboard.d.ts.map +0 -1
- package/dist/cli/agents-dashboard.js.map +0 -1
- package/dist/cli/controls.d.ts.map +0 -1
- package/dist/cli/controls.js.map +0 -1
- package/dist/cli/debug.d.ts.map +0 -1
- package/dist/cli/debug.js.map +0 -1
- package/dist/cli/interactive.d.ts.map +0 -1
- package/dist/cli/interactive.js.map +0 -1
- package/dist/cli/protocol.d.ts.map +0 -1
- package/dist/cli/protocol.js.map +0 -1
- package/dist/cli/tui/claude-style.d.ts.map +0 -1
- package/dist/cli/tui/claude-style.js.map +0 -1
- package/dist/cli/tui/clipboard.d.ts.map +0 -1
- package/dist/cli/tui/clipboard.js.map +0 -1
- package/dist/cli/tui/composer-editor.d.ts.map +0 -1
- package/dist/cli/tui/composer-editor.js.map +0 -1
- package/dist/cli/tui/composer-images.d.ts.map +0 -1
- package/dist/cli/tui/composer-images.js.map +0 -1
- package/dist/cli/tui/conversation-export.d.ts.map +0 -1
- package/dist/cli/tui/conversation-export.js.map +0 -1
- package/dist/cli/tui/external-editor.d.ts.map +0 -1
- package/dist/cli/tui/external-editor.js.map +0 -1
- package/dist/cli/tui/file-picker.d.ts.map +0 -1
- package/dist/cli/tui/file-picker.js.map +0 -1
- package/dist/cli/tui/git-diff.d.ts.map +0 -1
- package/dist/cli/tui/git-diff.js.map +0 -1
- package/dist/cli/tui/hook-settings.d.ts.map +0 -1
- package/dist/cli/tui/hook-settings.js.map +0 -1
- package/dist/cli/tui/keybindings.d.ts.map +0 -1
- package/dist/cli/tui/keybindings.js.map +0 -1
- package/dist/cli/tui/memory-files.d.ts.map +0 -1
- package/dist/cli/tui/memory-files.js.map +0 -1
- package/dist/cli/tui/permission-settings.d.ts.map +0 -1
- package/dist/cli/tui/permission-settings.js.map +0 -1
- package/dist/cli/tui/slash-commands.d.ts.map +0 -1
- package/dist/cli/tui/slash-commands.js.map +0 -1
- package/dist/cli/tui/terminal-suspend.d.ts.map +0 -1
- package/dist/cli/tui/terminal-suspend.js.map +0 -1
- package/dist/cli/tui/workspace-directories.d.ts.map +0 -1
- package/dist/cli/tui/workspace-directories.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/compatibility/claude/compaction.d.ts.map +0 -1
- package/dist/compatibility/claude/compaction.js.map +0 -1
- package/dist/compatibility/claude/context.d.ts.map +0 -1
- package/dist/compatibility/claude/context.js.map +0 -1
- package/dist/compatibility/claude/dynamic-context.d.ts.map +0 -1
- package/dist/compatibility/claude/dynamic-context.js.map +0 -1
- package/dist/compatibility/claude/file-history.d.ts.map +0 -1
- package/dist/compatibility/claude/file-history.js.map +0 -1
- package/dist/compatibility/claude/file-resources.d.ts.map +0 -1
- package/dist/compatibility/claude/file-resources.js.map +0 -1
- package/dist/compatibility/claude/fork.d.ts.map +0 -1
- package/dist/compatibility/claude/fork.js.map +0 -1
- package/dist/compatibility/claude/history.d.ts.map +0 -1
- package/dist/compatibility/claude/history.js.map +0 -1
- package/dist/compatibility/claude/ownership.d.ts.map +0 -1
- package/dist/compatibility/claude/ownership.js.map +0 -1
- package/dist/compatibility/claude/paths.d.ts.map +0 -1
- package/dist/compatibility/claude/paths.js.map +0 -1
- package/dist/compatibility/claude/pr-links.d.ts.map +0 -1
- package/dist/compatibility/claude/pr-links.js.map +0 -1
- package/dist/compatibility/claude/projection.d.ts.map +0 -1
- package/dist/compatibility/claude/projection.js.map +0 -1
- package/dist/compatibility/claude/schema.d.ts.map +0 -1
- package/dist/compatibility/claude/schema.js.map +0 -1
- package/dist/compatibility/claude/shared-resources.d.ts.map +0 -1
- package/dist/compatibility/claude/shared-resources.js.map +0 -1
- package/dist/compatibility/claude/sidechain.d.ts.map +0 -1
- package/dist/compatibility/claude/sidechain.js.map +0 -1
- package/dist/compatibility/claude/tool-links.d.ts.map +0 -1
- package/dist/compatibility/claude/tool-links.js.map +0 -1
- package/dist/compatibility/claude/translation.d.ts.map +0 -1
- package/dist/compatibility/claude/translation.js.map +0 -1
- package/dist/compatibility/claude/workflow-replay.d.ts.map +0 -1
- package/dist/compatibility/claude/workflow-replay.js.map +0 -1
- package/dist/compatibility/claude/workflow.d.ts.map +0 -1
- package/dist/compatibility/claude/workflow.js.map +0 -1
- package/dist/core/compaction.d.ts.map +0 -1
- package/dist/core/compaction.js.map +0 -1
- package/dist/core/context-budget.d.ts.map +0 -1
- package/dist/core/context-budget.js.map +0 -1
- package/dist/core/context.d.ts.map +0 -1
- package/dist/core/context.js.map +0 -1
- package/dist/core/runtime.d.ts.map +0 -1
- package/dist/core/runtime.js.map +0 -1
- package/dist/core/usage.d.ts.map +0 -1
- package/dist/core/usage.js.map +0 -1
- package/dist/extensions/claude-extension-tools.d.ts.map +0 -1
- package/dist/extensions/claude-extension-tools.js.map +0 -1
- package/dist/extensions/claude-extensions.d.ts.map +0 -1
- package/dist/extensions/claude-extensions.js.map +0 -1
- package/dist/hooks/claude-hook-tools.d.ts.map +0 -1
- package/dist/hooks/claude-hook-tools.js.map +0 -1
- package/dist/hooks/claude-hooks.d.ts.map +0 -1
- package/dist/hooks/claude-hooks.js.map +0 -1
- package/dist/maintenance/doctor.d.ts.map +0 -1
- package/dist/maintenance/doctor.js.map +0 -1
- package/dist/maintenance/self-update.d.ts.map +0 -1
- package/dist/maintenance/self-update.js.map +0 -1
- package/dist/mcp/claude-mcp-management.d.ts.map +0 -1
- package/dist/mcp/claude-mcp-management.js.map +0 -1
- package/dist/mcp/claude-mcp-oauth.d.ts.map +0 -1
- package/dist/mcp/claude-mcp-oauth.js.map +0 -1
- package/dist/mcp/claude-mcp-tools.d.ts.map +0 -1
- package/dist/mcp/claude-mcp-tools.js.map +0 -1
- package/dist/mcp/praxis-mcp-server.d.ts.map +0 -1
- package/dist/mcp/praxis-mcp-server.js.map +0 -1
- package/dist/permissions/claude-auto-classifier.d.ts.map +0 -1
- package/dist/permissions/claude-auto-classifier.js.map +0 -1
- package/dist/permissions/claude-permission-resolver.d.ts.map +0 -1
- package/dist/permissions/claude-permission-resolver.js.map +0 -1
- package/dist/persistence/claude-job-store.d.ts.map +0 -1
- package/dist/persistence/claude-job-store.js.map +0 -1
- package/dist/persistence/claude-scheduled-task-store.d.ts.map +0 -1
- package/dist/persistence/claude-scheduled-task-store.js.map +0 -1
- package/dist/persistence/claude-sidechain-store.d.ts.map +0 -1
- package/dist/persistence/claude-sidechain-store.js.map +0 -1
- package/dist/persistence/claude-task-store.d.ts.map +0 -1
- package/dist/persistence/claude-task-store.js.map +0 -1
- package/dist/persistence/claude-transcript-store.d.ts.map +0 -1
- package/dist/persistence/claude-transcript-store.js.map +0 -1
- package/dist/persistence/claude-workflow-store.d.ts.map +0 -1
- package/dist/persistence/claude-workflow-store.js.map +0 -1
- package/dist/persistence/in-memory-sidechain-store.d.ts.map +0 -1
- package/dist/persistence/in-memory-sidechain-store.js.map +0 -1
- package/dist/persistence/in-memory-transcript-store.d.ts.map +0 -1
- package/dist/persistence/in-memory-transcript-store.js.map +0 -1
- package/dist/platform/atomic-write.d.ts.map +0 -1
- package/dist/platform/atomic-write.js.map +0 -1
- package/dist/platform/bounded-process-runner.d.ts.map +0 -1
- package/dist/platform/bounded-process-runner.js.map +0 -1
- package/dist/platform/claude-version.d.ts.map +0 -1
- package/dist/platform/claude-version.js.map +0 -1
- package/dist/platform/command-shell.d.ts.map +0 -1
- package/dist/platform/command-shell.js.map +0 -1
- package/dist/platform/exclusive-file-lease.d.ts.map +0 -1
- package/dist/platform/exclusive-file-lease.js.map +0 -1
- package/dist/platform/sensitive-data.d.ts.map +0 -1
- package/dist/platform/sensitive-data.js.map +0 -1
- package/dist/platform/tmux-worktree.d.ts.map +0 -1
- package/dist/platform/tmux-worktree.js.map +0 -1
- package/dist/plugins/claude-plugin-eval-discovery.d.ts.map +0 -1
- package/dist/plugins/claude-plugin-eval-discovery.js.map +0 -1
- package/dist/plugins/claude-plugin-eval-graders.d.ts.map +0 -1
- package/dist/plugins/claude-plugin-eval-graders.js.map +0 -1
- package/dist/plugins/claude-plugin-eval-runner.d.ts.map +0 -1
- package/dist/plugins/claude-plugin-eval-runner.js.map +0 -1
- package/dist/plugins/claude-plugin-eval-schema.d.ts.map +0 -1
- package/dist/plugins/claude-plugin-eval-schema.js.map +0 -1
- package/dist/plugins/claude-plugin-eval.d.ts.map +0 -1
- package/dist/plugins/claude-plugin-eval.js.map +0 -1
- package/dist/plugins/claude-plugin-maintenance.d.ts.map +0 -1
- package/dist/plugins/claude-plugin-maintenance.js.map +0 -1
- package/dist/plugins/claude-plugin-marketplace.d.ts.map +0 -1
- package/dist/plugins/claude-plugin-marketplace.js.map +0 -1
- package/dist/plugins/claude-plugin-mcpb.d.ts.map +0 -1
- package/dist/plugins/claude-plugin-mcpb.js.map +0 -1
- package/dist/plugins/claude-plugin-runtime.d.ts.map +0 -1
- package/dist/plugins/claude-plugin-runtime.js.map +0 -1
- package/dist/providers/anthropic-compatible.d.ts.map +0 -1
- package/dist/providers/anthropic-compatible.js.map +0 -1
- package/dist/providers/environment.d.ts.map +0 -1
- package/dist/providers/environment.js.map +0 -1
- package/dist/providers/fallback-provider.d.ts.map +0 -1
- package/dist/providers/fallback-provider.js.map +0 -1
- package/dist/providers/openai-compatible.d.ts.map +0 -1
- package/dist/providers/openai-compatible.js.map +0 -1
- package/dist/tools/claude-interactive-tools.d.ts.map +0 -1
- package/dist/tools/claude-interactive-tools.js.map +0 -1
- package/dist/tools/claude-lsp-formatters.d.ts.map +0 -1
- package/dist/tools/claude-lsp-formatters.js.map +0 -1
- package/dist/tools/claude-lsp-tool.d.ts.map +0 -1
- package/dist/tools/claude-lsp-tool.js.map +0 -1
- package/dist/tools/claude-scheduled-tools.d.ts.map +0 -1
- package/dist/tools/claude-scheduled-tools.js.map +0 -1
- package/dist/tools/claude-task-tools.d.ts.map +0 -1
- package/dist/tools/claude-task-tools.js.map +0 -1
- package/dist/tools/claude-user-message.d.ts.map +0 -1
- package/dist/tools/claude-user-message.js.map +0 -1
- package/dist/tools/claude-workflow-tools.d.ts.map +0 -1
- package/dist/tools/claude-workflow-tools.js.map +0 -1
- package/dist/tools/claude-worktree-tools.d.ts.map +0 -1
- package/dist/tools/claude-worktree-tools.js.map +0 -1
- package/dist/tools/filtered-tool-registry.d.ts.map +0 -1
- package/dist/tools/filtered-tool-registry.js.map +0 -1
- package/dist/tools/glob.d.ts.map +0 -1
- package/dist/tools/glob.js.map +0 -1
- package/dist/tools/local-tools.d.ts.map +0 -1
- package/dist/tools/local-tools.js.map +0 -1
- package/dist/tools/notebook.d.ts.map +0 -1
- package/dist/tools/notebook.js.map +0 -1
- package/dist/tools/pdf.d.ts.map +0 -1
- package/dist/tools/pdf.js.map +0 -1
- package/dist/tools/web.d.ts.map +0 -1
- package/dist/tools/web.js.map +0 -1
|
@@ -4,7 +4,10 @@ import { type TuiDiffSnapshot } from './git-diff.js';
|
|
|
4
4
|
import { type TuiHookConfiguration } from './hook-settings.js';
|
|
5
5
|
import type { TuiMemoryFileEntry } from './memory-files.js';
|
|
6
6
|
import type { TuiPermissionRule } from './permission-settings.js';
|
|
7
|
+
import type { RecentlyDeniedAction } from './recently-denied.js';
|
|
8
|
+
import type { CustomThemeToken, TuiCustomTheme } from './custom-themes.js';
|
|
7
9
|
import type { TuiSlashCommand } from './slash-commands.js';
|
|
10
|
+
import { type TuiTheme } from './theme.js';
|
|
8
11
|
export interface TuiDisplayMetadata {
|
|
9
12
|
version: string;
|
|
10
13
|
cwd: string;
|
|
@@ -88,12 +91,13 @@ export declare function DiffDashboard({ snapshots, sourceIndex, selectedIndex, v
|
|
|
88
91
|
width: number;
|
|
89
92
|
screenReader: boolean;
|
|
90
93
|
}): import("react").JSX.Element;
|
|
91
|
-
export declare function PermissionDashboard({ tabIndex, selectedIndex, query, rules, recentDenied, workspaceDirectories, width, screenReader, }: {
|
|
94
|
+
export declare function PermissionDashboard({ tabIndex, selectedIndex, query, rules, recentDenied, retryingDeniedId, workspaceDirectories, width, screenReader, }: {
|
|
92
95
|
tabIndex: number;
|
|
93
96
|
selectedIndex: number;
|
|
94
97
|
query: string;
|
|
95
98
|
rules: readonly TuiPermissionRule[];
|
|
96
|
-
recentDenied: readonly
|
|
99
|
+
recentDenied: readonly RecentlyDeniedAction[];
|
|
100
|
+
retryingDeniedId?: string | null;
|
|
97
101
|
workspaceDirectories: readonly {
|
|
98
102
|
path: string;
|
|
99
103
|
original: boolean;
|
|
@@ -101,6 +105,25 @@ export declare function PermissionDashboard({ tabIndex, selectedIndex, query, ru
|
|
|
101
105
|
width: number;
|
|
102
106
|
screenReader: boolean;
|
|
103
107
|
}): import("react").JSX.Element;
|
|
108
|
+
export declare function ThemePicker({ currentTheme, selectedIndex, syntaxHighlightingDisabled, customThemes, allowCustomThemes, width, screenReader, }: {
|
|
109
|
+
currentTheme: TuiTheme | `custom:${string}`;
|
|
110
|
+
selectedIndex: number;
|
|
111
|
+
syntaxHighlightingDisabled: boolean;
|
|
112
|
+
customThemes?: readonly TuiCustomTheme[];
|
|
113
|
+
allowCustomThemes?: boolean;
|
|
114
|
+
width: number;
|
|
115
|
+
screenReader: boolean;
|
|
116
|
+
}): import("react").JSX.Element;
|
|
117
|
+
export declare function CustomThemeEditor({ theme, token, value, tokens, selectedIndex, query, width, screenReader, }: {
|
|
118
|
+
theme: TuiCustomTheme;
|
|
119
|
+
token?: CustomThemeToken;
|
|
120
|
+
value: string;
|
|
121
|
+
tokens?: readonly CustomThemeToken[];
|
|
122
|
+
selectedIndex?: number;
|
|
123
|
+
query?: string;
|
|
124
|
+
width: number;
|
|
125
|
+
screenReader: boolean;
|
|
126
|
+
}): import("react").JSX.Element;
|
|
104
127
|
export declare function StatusDashboard({ tabIndex, version, sessionId, display, usage, costUsd, turnCount, toolCount, commandCount, detailedTranscript, width, screenReader, }: {
|
|
105
128
|
tabIndex: number;
|
|
106
129
|
version: string;
|
|
@@ -209,7 +232,7 @@ export declare function SelectionMenu({ title, description, options, selectedInd
|
|
|
209
232
|
export declare function ExternalEditorWait({ screenReader, }: {
|
|
210
233
|
screenReader: boolean;
|
|
211
234
|
}): import("react").JSX.Element;
|
|
212
|
-
export declare function Composer({ input, cursor, busy, clipboardBusy, status, display, usage, costUsd, width, screenReader, hasThinking, thinkingExpanded, shortcutsVisible, shellMode, footerMessage, }: {
|
|
235
|
+
export declare function Composer({ input, cursor, busy, clipboardBusy, status, display, usage, costUsd, width, screenReader, hasThinking, thinkingExpanded, shortcutsVisible, shellMode, footerMessage, reduceMotion, progressBar, turnDuration, editorMode, prStatus, }: {
|
|
213
236
|
input: string;
|
|
214
237
|
cursor?: number;
|
|
215
238
|
busy: boolean;
|
|
@@ -228,6 +251,11 @@ export declare function Composer({ input, cursor, busy, clipboardBusy, status, d
|
|
|
228
251
|
text: string;
|
|
229
252
|
isError: boolean;
|
|
230
253
|
};
|
|
254
|
+
reduceMotion?: boolean;
|
|
255
|
+
progressBar?: boolean;
|
|
256
|
+
turnDuration?: string;
|
|
257
|
+
editorMode?: 'normal' | 'vim';
|
|
258
|
+
prStatus?: string;
|
|
231
259
|
}): import("react").JSX.Element;
|
|
232
260
|
export declare function DialogFrame({ title, children, screenReader, }: {
|
|
233
261
|
title: string;
|
|
@@ -4,8 +4,7 @@ import { Box, Text, useStdout } from 'ink';
|
|
|
4
4
|
import { composerEditorSegments } from './composer-editor.js';
|
|
5
5
|
import { visiblePatchLines } from './git-diff.js';
|
|
6
6
|
import { TUI_HOOK_MENU } from './hook-settings.js';
|
|
7
|
-
|
|
8
|
-
const ACCENT = '#B8A1FF';
|
|
7
|
+
import { tuiPalette, tuiSyntaxStyle, useTuiPalette, } from './theme.js';
|
|
9
8
|
const SPINNER = ['✳', '✢', '✣', '✤', '✥'];
|
|
10
9
|
export function useTerminalWidth(override) {
|
|
11
10
|
const { stdout } = useStdout();
|
|
@@ -45,31 +44,45 @@ function permissionLabel(mode) {
|
|
|
45
44
|
return 'permissions default';
|
|
46
45
|
}
|
|
47
46
|
}
|
|
47
|
+
function selectionPrefix(selected, screenReader) {
|
|
48
|
+
if (selected)
|
|
49
|
+
return screenReader ? 'Selected: ' : '❯ ';
|
|
50
|
+
return screenReader ? '' : ' ';
|
|
51
|
+
}
|
|
48
52
|
export function WelcomePanel({ display, width, }) {
|
|
53
|
+
const palette = useTuiPalette();
|
|
49
54
|
const panelWidth = Math.min(100, Math.max(32, width));
|
|
50
55
|
const wide = panelWidth >= 68;
|
|
51
|
-
|
|
56
|
+
const brand = 'Praxis';
|
|
57
|
+
// Claude 2.1.208 embeds the title in the top border row:
|
|
58
|
+
// ╭───Claude Code v2.1.208 ───...───╮
|
|
59
|
+
// Title block = "╭" + "───" + "Praxis Code vX.Y.Z" + " " = 4 + title.length + 1 chars.
|
|
60
|
+
const title = `${brand} Code v${display.version}`;
|
|
61
|
+
const fill = Math.max(1, panelWidth - title.length - 6);
|
|
62
|
+
return (_jsxs(Box, { flexDirection: "column", width: panelWidth, children: [_jsxs(Text, { color: palette.muted, children: ['╭───', _jsx(Text, { color: palette.brand, bold: true, children: brand }), ` Code v${display.version} `, _jsx(Text, { dimColor: true, children: '─'.repeat(fill) }), '╮'] }), _jsx(Box, { borderStyle: "round", borderColor: palette.muted, borderTop: false, flexDirection: "column", width: panelWidth, paddingX: 1, children: _jsxs(Box, { flexDirection: wide ? 'row' : 'column', children: [_jsxs(Box, { alignItems: wide ? 'center' : undefined, flexDirection: "column", width: wide ? '50%' : '100%', children: [_jsx(Text, { children: " " }), _jsx(Text, { bold: true, children: "Welcome back!" }), _jsx(Text, { children: " " }), _jsx(Text, { color: palette.brand, bold: true, children: "\u2590\u259B\u2588\u2588\u2588\u259C\u258C" }), _jsx(Text, { color: palette.brand, children: "\u259D\u259C\u2588\u2588\u2588\u2588\u2588\u259B\u2598" }), _jsx(Text, { color: palette.brand, children: " \u2598\u2598 \u259D\u259D" }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [display.model ?? 'provider default', display.effort ? (_jsxs(Text, { dimColor: true, children: [" \u00B7 ", display.effort, " effort"] })) : null] }), _jsx(Text, { dimColor: true, children: compactPath(display.cwd) })] }), _jsxs(Box, { flexDirection: "column", width: wide ? '50%' : '100%', marginTop: wide ? 0 : 1, children: [_jsx(Text, { bold: true, children: "Tips for getting started" }), _jsx(Text, { children: "Run /help for commands" }), _jsx(Text, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }), _jsx(Text, { bold: true, children: "Shared with Claude Code" }), _jsx(Text, { children: "Sessions, memory, skills" })] })] }) })] }));
|
|
52
63
|
}
|
|
53
64
|
function InlineText({ text }) {
|
|
65
|
+
const palette = useTuiPalette();
|
|
54
66
|
const tokens = text.split(/(`[^`]+`|\*\*[^*]+\*\*|\[[^\]]+\]\([^)]+\))/u);
|
|
55
67
|
return (_jsx(Text, { children: tokens.map((token, index) => {
|
|
56
68
|
if (token.startsWith('`') && token.endsWith('`'))
|
|
57
|
-
return (_jsx(Text, { color:
|
|
69
|
+
return (_jsx(Text, { color: palette.info, children: token.slice(1, -1) }, index));
|
|
58
70
|
if (token.startsWith('**') && token.endsWith('**'))
|
|
59
71
|
return (_jsx(Text, { bold: true, children: token.slice(2, -2) }, index));
|
|
60
72
|
const link = /^\[([^\]]+)\]\(([^)]+)\)$/u.exec(token);
|
|
61
73
|
if (link)
|
|
62
|
-
return (_jsx(Text, { color:
|
|
74
|
+
return (_jsx(Text, { color: palette.link, underline: true, children: link[1] }, index));
|
|
63
75
|
return token;
|
|
64
76
|
}) }));
|
|
65
77
|
}
|
|
66
78
|
function MarkdownLine({ line }) {
|
|
79
|
+
const palette = useTuiPalette();
|
|
67
80
|
if (line.startsWith('### '))
|
|
68
81
|
return (_jsx(Text, { bold: true, children: _jsx(InlineText, { text: line.slice(4) }) }));
|
|
69
82
|
if (line.startsWith('## '))
|
|
70
|
-
return (_jsx(Text, { bold: true, color:
|
|
83
|
+
return (_jsx(Text, { bold: true, color: palette.accent, children: _jsx(InlineText, { text: line.slice(3) }) }));
|
|
71
84
|
if (line.startsWith('# '))
|
|
72
|
-
return (_jsx(Text, { bold: true, color:
|
|
85
|
+
return (_jsx(Text, { bold: true, color: palette.brand, children: _jsx(InlineText, { text: line.slice(2) }) }));
|
|
73
86
|
if (/^[-*] /u.test(line))
|
|
74
87
|
return (_jsxs(Text, { children: [' • ', _jsx(InlineText, { text: line.slice(2) })] }));
|
|
75
88
|
if (/^\d+\. /u.test(line))
|
|
@@ -78,14 +91,51 @@ function MarkdownLine({ line }) {
|
|
|
78
91
|
return (_jsxs(Text, { dimColor: true, children: ['│ ', _jsx(InlineText, { text: line.slice(2) })] }));
|
|
79
92
|
return line ? _jsx(InlineText, { text: line }) : _jsx(Text, { children: " " });
|
|
80
93
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
const CODE_KEYWORDS = new Set([
|
|
95
|
+
'async',
|
|
96
|
+
'await',
|
|
97
|
+
'class',
|
|
98
|
+
'const',
|
|
99
|
+
'else',
|
|
100
|
+
'export',
|
|
101
|
+
'false',
|
|
102
|
+
'from',
|
|
103
|
+
'function',
|
|
104
|
+
'if',
|
|
105
|
+
'import',
|
|
106
|
+
'let',
|
|
107
|
+
'new',
|
|
108
|
+
'null',
|
|
109
|
+
'return',
|
|
110
|
+
'true',
|
|
111
|
+
'undefined',
|
|
112
|
+
'var',
|
|
113
|
+
]);
|
|
114
|
+
const CODE_TOKEN_PATTERN = /("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\b(?:async|await|class|const|else|export|false|from|function|if|import|let|new|null|return|true|undefined|var)\b|\b[A-Za-z_$][\w$]*(?=\s*\())/gu;
|
|
115
|
+
function SyntaxCodeLine({ text, prefix = '', change, }) {
|
|
116
|
+
const palette = useTuiPalette();
|
|
117
|
+
if (palette.syntaxHighlightingDisabled) {
|
|
118
|
+
return (_jsxs(Text, { children: [prefix, text || ' '] }));
|
|
119
|
+
}
|
|
120
|
+
const lineStyle = tuiSyntaxStyle(palette, 'text', change);
|
|
121
|
+
return (_jsxs(Text, { children: [prefix, _jsx(Text, { ...lineStyle, children: text.split(CODE_TOKEN_PATTERN).map((token, index) => {
|
|
122
|
+
const kind = token.startsWith('"') || token.startsWith("'")
|
|
123
|
+
? 'string'
|
|
124
|
+
: CODE_KEYWORDS.has(token)
|
|
125
|
+
? 'keyword'
|
|
126
|
+
: /^[A-Za-z_$][\w$]*$/u.test(token)
|
|
127
|
+
? 'identifier'
|
|
128
|
+
: 'text';
|
|
129
|
+
if (kind === 'text')
|
|
130
|
+
return token;
|
|
131
|
+
return (_jsx(Text, { ...tuiSyntaxStyle(palette, kind), children: token }, index));
|
|
132
|
+
}) })] }));
|
|
133
|
+
}
|
|
134
|
+
function ToolResultText({ text, prefix = '', }) {
|
|
135
|
+
const palette = useTuiPalette();
|
|
136
|
+
return (_jsx(Box, { flexDirection: "column", children: text.split('\n').map((line, index) => line.startsWith('+') && !line.startsWith('+++') ? (_jsx(SyntaxCodeLine, { prefix: index === 0 ? prefix : prefix ? ' ' : '', text: line, change: "added" }, index)) : line.startsWith('-') && !line.startsWith('---') ? (_jsx(SyntaxCodeLine, { prefix: index === 0 ? prefix : prefix ? ' ' : '', text: line, change: "removed" }, index)) : (_jsxs(Text, { ...(line.startsWith('@@')
|
|
137
|
+
? { color: palette.info }
|
|
138
|
+
: { dimColor: true }), children: [index === 0 ? prefix : prefix ? ' ' : '', line || ' '] }, index))) }));
|
|
89
139
|
}
|
|
90
140
|
function inputString(call, key) {
|
|
91
141
|
const value = call.input[key];
|
|
@@ -107,6 +157,7 @@ function toolHeading(call) {
|
|
|
107
157
|
return call.name;
|
|
108
158
|
}
|
|
109
159
|
function ToolTranscriptEntry({ call, detail, result, detailed, }) {
|
|
160
|
+
const palette = useTuiPalette();
|
|
110
161
|
const displayResult = call.name === 'Read' &&
|
|
111
162
|
result?.text.startsWith('Wasted call — file unchanged since your last Read')
|
|
112
163
|
? 'Unchanged since last read'
|
|
@@ -117,17 +168,20 @@ function ToolTranscriptEntry({ call, detail, result, detailed, }) {
|
|
|
117
168
|
}
|
|
118
169
|
const visible = detailed ? resultLines : resultLines.slice(0, 3);
|
|
119
170
|
const hidden = resultLines.length - visible.length;
|
|
171
|
+
const resultIsDiff = resultLines.some((line) => line.startsWith('+') && !line.startsWith('+++')) &&
|
|
172
|
+
resultLines.some((line) => line.startsWith('-') && !line.startsWith('---'));
|
|
120
173
|
const errorText = displayResult.length > 500
|
|
121
174
|
? `${displayResult.slice(0, 497)}...`
|
|
122
175
|
: displayResult;
|
|
123
176
|
const oldLines = contentLines(inputString(call, 'old_string'));
|
|
124
177
|
const newLines = contentLines(inputString(call, 'new_string'));
|
|
125
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color:
|
|
178
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: palette.accent, children: "\u23FA" }), ' ', _jsx(Text, { bold: true, children: toolHeading(call) })] }), !['Bash', 'Read', 'Edit'].includes(call.name) && detail ? (_jsxs(Text, { dimColor: true, children: [" ", detail] })) : null, result ? (_jsx(Box, { marginLeft: 2, flexDirection: "column", children: result.isError ? (_jsxs(Text, { color: palette.error, children: ["\u23BF Error: ", errorText] })) : call.name === 'Edit' ? (_jsxs(_Fragment, { children: [_jsxs(Text, { dimColor: true, children: ["\u23BF Added ", newLines.length, " line", newLines.length === 1 ? '' : 's', ", removed ", oldLines.length, " line", oldLines.length === 1 ? '' : 's'] }), oldLines.map((line, index) => (_jsx(SyntaxCodeLine, { prefix: ` ${index + 1} -`, text: line, change: "removed" }, `old-${index}`))), newLines.map((line, index) => (_jsx(SyntaxCodeLine, { prefix: ` ${index + 1} +`, text: line, change: "added" }, `new-${index}`)))] })) : resultIsDiff ? (_jsx(ToolResultText, { text: visible.join('\n'), prefix: "\u23BF " })) : (_jsxs(_Fragment, { children: [visible.map((line, index) => (_jsxs(Text, { dimColor: true, children: [index === 0 ? '⎿ ' : ' ', line || ' '] }, index))), hidden > 0 ? (_jsxs(Text, { dimColor: true, children: [' ', "\u2026 +", hidden, " lines (ctrl+o to expand)"] })) : null] })) })) : null] }));
|
|
126
179
|
}
|
|
127
180
|
function ThinkingBlock({ text, active, expanded, screenReader, }) {
|
|
181
|
+
const palette = useTuiPalette();
|
|
128
182
|
const summary = text.replace(/\s+/gu, ' ').trim();
|
|
129
183
|
const showFull = screenReader || active || expanded;
|
|
130
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { ...(!screenReader ? { color:
|
|
184
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { ...(!screenReader ? { color: palette.accent } : {}), dimColor: !screenReader, italic: !screenReader, children: [screenReader ? 'Thinking:' : '✻ ', active ? 'Thinking…' : 'Thought for a moment', !showFull && summary ? ` · ${summary.slice(0, 160)}` : ''] }), showFull && text ? (_jsx(Box, { marginLeft: screenReader ? 0 : 2, flexDirection: "column", children: _jsx(MarkdownText, { text: text }) })) : !screenReader && summary.length > 160 ? (_jsx(Text, { dimColor: true, children: " ctrl+o to expand thinking" })) : null] }));
|
|
131
185
|
}
|
|
132
186
|
function ContextUsageBlock({ usedTokens, contextWindowTokens, skills, screenReader, }) {
|
|
133
187
|
const totalTokens = Math.max(1, contextWindowTokens);
|
|
@@ -151,10 +205,11 @@ export function MarkdownText({ text }) {
|
|
|
151
205
|
code = !code;
|
|
152
206
|
return (_jsx(Text, { dimColor: true, children: code ? `╭─ ${line.slice(3) || 'code'}` : '╰─' }, index));
|
|
153
207
|
}
|
|
154
|
-
return code ? (
|
|
208
|
+
return code ? (_jsx(SyntaxCodeLine, { prefix: "\u2502 ", text: line }, index)) : (_jsx(MarkdownLine, { line: line }, index));
|
|
155
209
|
}) }));
|
|
156
210
|
}
|
|
157
211
|
export function Transcript({ items, activeText, activeThinking = '', thinkingExpanded = false, detailedTranscript = false, screenReader, }) {
|
|
212
|
+
const palette = useTuiPalette();
|
|
158
213
|
const detailed = thinkingExpanded || detailedTranscript;
|
|
159
214
|
const results = new Map(items
|
|
160
215
|
.filter((item) => item.kind === 'tool-result')
|
|
@@ -213,16 +268,16 @@ export function Transcript({ items, activeText, activeThinking = '', thinkingExp
|
|
|
213
268
|
if (groupedReadTools.has(index))
|
|
214
269
|
return null;
|
|
215
270
|
if (item.kind === 'user') {
|
|
216
|
-
return (_jsxs(Box, { marginTop: index === 0 ? 0 : 1, children: [_jsx(Text, { color:
|
|
271
|
+
return (_jsxs(Box, { marginTop: index === 0 ? 0 : 1, children: [_jsx(Text, { color: palette.brand, bold: true, children: screenReader ? 'You: ' : '❯ ' }), _jsx(Text, { bold: true, children: item.text })] }, index));
|
|
217
272
|
}
|
|
218
273
|
if (item.kind === 'assistant') {
|
|
219
|
-
return (_jsxs(Box, { marginTop: 1, children: [screenReader ? _jsx(Text, { children: "Praxis:" }) : null, !screenReader ? _jsx(Text, { color:
|
|
274
|
+
return (_jsxs(Box, { marginTop: 1, children: [screenReader ? _jsx(Text, { children: "Praxis:" }) : null, !screenReader ? _jsx(Text, { color: palette.accent, children: "\u23FA " }) : null, _jsx(MarkdownText, { text: item.text })] }, index));
|
|
220
275
|
}
|
|
221
276
|
if (item.kind === 'thinking') {
|
|
222
277
|
return (_jsx(ThinkingBlock, { text: item.text, active: false, expanded: detailed, screenReader: screenReader }, index));
|
|
223
278
|
}
|
|
224
279
|
if (item.kind === 'compact') {
|
|
225
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color:
|
|
280
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: palette.accent, italic: true, children: screenReader
|
|
226
281
|
? 'Conversation compacted'
|
|
227
282
|
: '✻ Conversation compacted (ctrl+o for history)' }), detailed ? (_jsx(Box, { marginLeft: screenReader ? 0 : 2, children: _jsx(MarkdownText, { text: item.summary }) })) : null] }, index));
|
|
228
283
|
}
|
|
@@ -237,7 +292,7 @@ export function Transcript({ items, activeText, activeThinking = '', thinkingExp
|
|
|
237
292
|
if (pairedResults.has(item.callId))
|
|
238
293
|
return null;
|
|
239
294
|
const text = item.text.length > 500 ? `${item.text.slice(0, 497)}...` : item.text;
|
|
240
|
-
return (_jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [_jsx(Text, { color: item.isError ?
|
|
295
|
+
return (_jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [_jsx(Text, { color: item.isError ? palette.error : palette.muted, children: item.isError ? '└ Error' : '└ Result' }), item.isError ? (_jsx(Text, { color: palette.error, children: text })) : (_jsx(ToolResultText, { text: text }))] }, index));
|
|
241
296
|
}
|
|
242
297
|
if (item.kind === 'shell') {
|
|
243
298
|
const result = shellResults.get(item.callId);
|
|
@@ -253,21 +308,22 @@ export function Transcript({ items, activeText, activeThinking = '', thinkingExp
|
|
|
253
308
|
const lines = contentLines(output);
|
|
254
309
|
const visible = detailed || screenReader ? lines : lines.slice(0, 3);
|
|
255
310
|
const hidden = lines.length - visible.length;
|
|
256
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { children: _jsxs(Text, { bold: true, children: [screenReader ? 'Shell command: ' : '! ', item.command] }) }), result ? (_jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [lines.length === 0 ? (_jsx(Text, { dimColor: true, children: "\u23BF " })) : (visible.map((line, lineIndex) => (_jsxs(Text, { ...(result.isError ? { color:
|
|
311
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { children: _jsxs(Text, { bold: true, children: [screenReader ? 'Shell command: ' : '! ', item.command] }) }), result ? (_jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [lines.length === 0 ? (_jsx(Text, { dimColor: true, children: "\u23BF " })) : (visible.map((line, lineIndex) => (_jsxs(Text, { ...(result.isError ? { color: palette.error } : {}), dimColor: !result.isError, children: [lineIndex === 0 ? '⎿ ' : ' ', line || ' '] }, lineIndex)))), hidden > 0 ? (_jsxs(Text, { dimColor: true, children: [' ', "\u2026 +", hidden, " lines (ctrl+o to expand)"] })) : null] })) : null] }, index));
|
|
257
312
|
}
|
|
258
313
|
if (item.kind === 'shell-result') {
|
|
259
314
|
if (pairedShellResults.has(item.callId))
|
|
260
315
|
return null;
|
|
261
316
|
const output = [item.stdout, item.stderr].filter(Boolean).join('\n');
|
|
262
|
-
return (_jsxs(Text, { ...(item.isError ? { color:
|
|
317
|
+
return (_jsxs(Text, { ...(item.isError ? { color: palette.error } : {}), children: ["\u23BF ", output] }, index));
|
|
263
318
|
}
|
|
264
319
|
if (item.kind === 'local-result') {
|
|
265
320
|
return (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { dimColor: true, children: ["\u23BF ", item.text] }) }, index));
|
|
266
321
|
}
|
|
267
|
-
return (_jsxs(Text, { ...(item.kind === 'warning' ? { color:
|
|
268
|
-
}), activeThinking ? (_jsx(ThinkingBlock, { text: activeThinking, active: true, expanded: detailed, screenReader: screenReader })) : activeText ? (_jsxs(Box, { marginTop: 1, children: [screenReader ? (_jsx(Text, { children: "Praxis: " })) : (_jsx(Text, { color:
|
|
322
|
+
return (_jsxs(Text, { ...(item.kind === 'warning' ? { color: palette.error } : {}), dimColor: item.kind === 'notice', children: [item.kind === 'warning' ? '⚠ ' : '· ', item.text] }, index));
|
|
323
|
+
}), activeThinking ? (_jsx(ThinkingBlock, { text: activeThinking, active: true, expanded: detailed, screenReader: screenReader })) : activeText ? (_jsxs(Box, { marginTop: 1, children: [screenReader ? (_jsx(Text, { children: "Praxis: " })) : (_jsx(Text, { color: palette.accent, children: "\u2733 " })), _jsx(MarkdownText, { text: activeText })] })) : null] }));
|
|
269
324
|
}
|
|
270
325
|
export function DiffDashboard({ snapshots, sourceIndex, selectedIndex, viewingFile, scrollOffset, width, screenReader, }) {
|
|
326
|
+
const palette = useTuiPalette();
|
|
271
327
|
const source = snapshots[sourceIndex];
|
|
272
328
|
const snapshot = source?.snapshot ?? { files: [], additions: 0, deletions: 0 };
|
|
273
329
|
const selected = snapshot.files[selectedIndex];
|
|
@@ -275,15 +331,11 @@ export function DiffDashboard({ snapshots, sourceIndex, selectedIndex, viewingFi
|
|
|
275
331
|
const line = '─'.repeat(panelWidth);
|
|
276
332
|
if (viewingFile && selected) {
|
|
277
333
|
const lines = visiblePatchLines(selected.patch).slice(scrollOffset, scrollOffset + 18);
|
|
278
|
-
return (_jsxs(Box, { flexDirection: "column", children: [!screenReader ? _jsx(Text, { dimColor: true, children: line }) : null, _jsx(Text, { bold: true, children: " Uncommitted changes (git diff HEAD)" }), _jsxs(Text, { children: [' ', snapshots.map((item, index) => (_jsxs(Text, { inverse: index === sourceIndex, children: [' ', item.label, ' '] }, item.label)))] }), _jsx(Text, { children: " " }), _jsxs(Text, { bold: true, children: [" ", selected.path] }), _jsxs(Text, { dimColor: true, children: [" ", '─'.repeat(Math.max(1, panelWidth - 4))] }), lines.map((patchLine, index) => (
|
|
279
|
-
? { color: 'green' }
|
|
280
|
-
: patchLine.startsWith('-')
|
|
281
|
-
? { color: 'red' }
|
|
282
|
-
: { dimColor: true }), children: [' ', patchLine] }, `${scrollOffset}-${index}`))), _jsx(Text, { dimColor: true, children: " \u2191/\u2193 to scroll \u00B7 Esc to back" })] }));
|
|
334
|
+
return (_jsxs(Box, { flexDirection: "column", children: [!screenReader ? _jsx(Text, { dimColor: true, children: line }) : null, _jsx(Text, { bold: true, children: " Uncommitted changes (git diff HEAD)" }), _jsxs(Text, { children: [' ', snapshots.map((item, index) => (_jsxs(Text, { inverse: !screenReader && index === sourceIndex, children: [screenReader && index === sourceIndex ? 'Current source: ' : ' ', item.label, ' '] }, item.label)))] }), _jsx(Text, { children: " " }), _jsxs(Text, { bold: true, children: [" ", selected.path] }), !screenReader ? (_jsxs(Text, { dimColor: true, children: [" ", '─'.repeat(Math.max(1, panelWidth - 4))] })) : null, lines.map((patchLine, index) => patchLine.startsWith('+') && !patchLine.startsWith('+++') ? (_jsx(SyntaxCodeLine, { prefix: " ", text: patchLine, change: "added" }, `${scrollOffset}-${index}`)) : patchLine.startsWith('-') && !patchLine.startsWith('---') ? (_jsx(SyntaxCodeLine, { prefix: " ", text: patchLine, change: "removed" }, `${scrollOffset}-${index}`)) : (_jsxs(Text, { dimColor: true, children: [' ', patchLine] }, `${scrollOffset}-${index}`))), _jsx(Text, { dimColor: true, children: " \u2191/\u2193 to scroll \u00B7 Esc to back" })] }));
|
|
283
335
|
}
|
|
284
|
-
return (_jsxs(Box, { flexDirection: "column", children: [!screenReader ? _jsx(Text, { dimColor: true, children: line }) : null, _jsx(Text, { bold: true, children: " Uncommitted changes (git diff HEAD)" }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [' ', snapshots.map((item, index) => (_jsxs(Text, { inverse: index === sourceIndex, children: [' ', item.label, ' '] }, item.label)))] }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [' ', snapshot.files.length, " file", snapshot.files.length === 1 ? '' : 's', ' ', "changed ", _jsxs(Text, { color:
|
|
336
|
+
return (_jsxs(Box, { flexDirection: "column", children: [!screenReader ? _jsx(Text, { dimColor: true, children: line }) : null, _jsx(Text, { bold: true, children: " Uncommitted changes (git diff HEAD)" }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [' ', snapshots.map((item, index) => (_jsxs(Text, { inverse: !screenReader && index === sourceIndex, children: [screenReader && index === sourceIndex ? 'Current source: ' : ' ', item.label, ' '] }, item.label)))] }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [' ', snapshot.files.length, " file", snapshot.files.length === 1 ? '' : 's', ' ', "changed ", _jsxs(Text, { color: palette.success, children: ["+", snapshot.additions] }), ' ', _jsxs(Text, { color: palette.error, children: ["-", snapshot.deletions] })] }), _jsx(Text, { children: " " }), snapshot.files.length === 0 ? (_jsx(Text, { dimColor: true, children: " No uncommitted changes." })) : (snapshot.files.map((file, index) => (_jsxs(Text, { inverse: !screenReader && index === selectedIndex, children: [selectionPrefix(index === selectedIndex, screenReader), file.path, ' ', _jsxs(Text, { ...(!screenReader ? { color: palette.success } : {}), children: ["+", file.additions] }), ' ', _jsxs(Text, { ...(!screenReader ? { color: palette.error } : {}), children: ["-", file.deletions] })] }, file.path)))), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "\u2190/\u2192 to switch source \u00B7 \u2191/\u2193 to select \u00B7 Enter to view \u00B7 Esc to close" })] }));
|
|
285
337
|
}
|
|
286
|
-
export function PermissionDashboard({ tabIndex, selectedIndex, query, rules, recentDenied, workspaceDirectories, width, screenReader, }) {
|
|
338
|
+
export function PermissionDashboard({ tabIndex, selectedIndex, query, rules, recentDenied, retryingDeniedId, workspaceDirectories, width, screenReader, }) {
|
|
287
339
|
const tabs = ['Recently denied', 'Allow', 'Ask', 'Deny', 'Workspace'];
|
|
288
340
|
const behavior = ['allow', 'ask', 'deny'][tabIndex - 1];
|
|
289
341
|
const normalizedQuery = query.trim().toLowerCase();
|
|
@@ -293,13 +345,13 @@ export function PermissionDashboard({ tabIndex, selectedIndex, query, rules, rec
|
|
|
293
345
|
rule.rule.toLowerCase().includes(normalizedQuery) ||
|
|
294
346
|
rule.scope.includes(normalizedQuery)))
|
|
295
347
|
: [];
|
|
296
|
-
const rows =
|
|
348
|
+
const rows = matchingRules.map((rule) => rule.rule);
|
|
297
349
|
const originalWorkspace = workspaceDirectories.find((directory) => directory.original);
|
|
298
350
|
const additionalWorkspaces = workspaceDirectories.filter((directory) => !directory.original);
|
|
299
351
|
const description = tabIndex === 0
|
|
300
352
|
? recentDenied.length === 0
|
|
301
353
|
? 'No recent denials. Commands denied by the auto mode classifier will appear here.'
|
|
302
|
-
: 'Commands denied by the auto mode classifier
|
|
354
|
+
: 'Commands recently denied by the auto mode classifier.'
|
|
303
355
|
: tabIndex === 1
|
|
304
356
|
? "Praxis Code won't ask before using allowed tools."
|
|
305
357
|
: tabIndex === 2
|
|
@@ -307,9 +359,60 @@ export function PermissionDashboard({ tabIndex, selectedIndex, query, rules, rec
|
|
|
307
359
|
: tabIndex === 3
|
|
308
360
|
? 'Praxis Code will reject requests to use denied tools.'
|
|
309
361
|
: 'Praxis Code can read files in the workspace, and make edits when auto-accept edits is on.';
|
|
310
|
-
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [!screenReader ? (_jsx(Text, { dimColor: true, children: '─'.repeat(Math.min(100, width)) })) : null, _jsx(Text, { bold: true, children: " Permissions" }), _jsxs(Text, { children: [' ', tabs.map((tab, index) => (_jsxs(Text, { inverse: index === tabIndex, children: [' ', tab, ' '] }, tab)))] }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [" ", description] }), tabIndex >= 1 && tabIndex <= 3 ? (_jsx(Box, { borderStyle: screenReader ? undefined : 'round', paddingX: 1, marginY: 1, children: _jsxs(Text, { ...(query ? {} : { dimColor: true }), children: [
|
|
311
|
-
? '
|
|
312
|
-
:
|
|
362
|
+
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [!screenReader ? (_jsx(Text, { dimColor: true, children: '─'.repeat(Math.min(100, width)) })) : null, _jsx(Text, { bold: true, children: " Permissions" }), _jsxs(Text, { children: [' ', tabs.map((tab, index) => (_jsxs(Text, { inverse: !screenReader && index === tabIndex, children: [screenReader && index === tabIndex ? 'Current tab: ' : ' ', tab, ' '] }, tab)))] }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [" ", description] }), tabIndex >= 1 && tabIndex <= 3 ? (_jsx(Box, { borderStyle: screenReader ? undefined : 'round', paddingX: 1, marginY: 1, children: _jsxs(Text, { ...(query ? {} : { dimColor: true }), children: [screenReader ? 'Search: ' : '⌕ ', query || 'Search…'] }) })) : (_jsx(Text, { children: " " })), tabIndex >= 1 && tabIndex <= 3 ? (['Add a new rule…', ...rows].map((row, index) => (_jsxs(Text, { inverse: !screenReader && index === selectedIndex, children: [selectionPrefix(index === selectedIndex, screenReader), index + 1, ". ", row] }, `${index}-${row}`)))) : tabIndex === 0 ? (recentDenied.map((action, index) => (_jsxs(Text, { inverse: !screenReader && index === selectedIndex, children: [selectionPrefix(index === selectedIndex, screenReader), index + 1, ". ", action.id === retryingDeniedId ? '✔' : '✘', ' ', action.display, action.id === retryingDeniedId ? ' (retry)' : '', action.reason ? ` ${action.reason}` : ''] }, action.id)))) : tabIndex === 4 ? (_jsxs(_Fragment, { children: [originalWorkspace ? (_jsxs(Text, { children: [' - ', originalWorkspace.path, " (Original working directory)"] })) : null, additionalWorkspaces.map((directory, index) => (_jsxs(Text, { inverse: !screenReader && selectedIndex === index, children: [selectionPrefix(selectedIndex === index, screenReader), index + 1, ". ", directory.path] }, directory.path))), _jsxs(Text, { inverse: !screenReader && selectedIndex === additionalWorkspaces.length, children: [selectionPrefix(selectedIndex === additionalWorkspaces.length, screenReader), additionalWorkspaces.length + 1, ". Add directory\u2026"] })] })) : rows.length > 0 ? (rows.map((row, index) => (_jsxs(Text, { inverse: !screenReader && index === selectedIndex, children: [selectionPrefix(index === selectedIndex, screenReader), index + 1, ". ", row] }, `${index}-${row}`)))) : null, _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: tabIndex === 0 && recentDenied.length > 0
|
|
363
|
+
? 'Enter to approve · r to retry · ↑/↓ to navigate · Esc to cancel'
|
|
364
|
+
: selectedIndex >= 0
|
|
365
|
+
? '↑/↓ navigate · Enter to select · ←/→ to switch · Esc to cancel'
|
|
366
|
+
: '←/→ to switch · ↓ to select · Esc to cancel' })] }));
|
|
367
|
+
}
|
|
368
|
+
const THEME_OPTIONS = [
|
|
369
|
+
{ theme: 'auto', label: 'Auto (match terminal)' },
|
|
370
|
+
{ theme: 'dark', label: 'Dark mode' },
|
|
371
|
+
{ theme: 'light', label: 'Light mode' },
|
|
372
|
+
{ theme: 'dark-daltonized', label: 'Dark mode (colorblind-friendly)' },
|
|
373
|
+
{ theme: 'light-daltonized', label: 'Light mode (colorblind-friendly)' },
|
|
374
|
+
{ theme: 'dark-ansi', label: 'Dark mode (ANSI colors only)' },
|
|
375
|
+
{ theme: 'light-ansi', label: 'Light mode (ANSI colors only)' },
|
|
376
|
+
];
|
|
377
|
+
export function ThemePicker({ currentTheme, selectedIndex, syntaxHighlightingDisabled, customThemes = [], allowCustomThemes = true, width, screenReader, }) {
|
|
378
|
+
const options = [
|
|
379
|
+
...THEME_OPTIONS.map((option) => ({ ...option, customTheme: undefined })),
|
|
380
|
+
...customThemes.map((theme) => ({
|
|
381
|
+
theme: `custom:${theme.slug}`,
|
|
382
|
+
label: `${theme.name} (custom)`,
|
|
383
|
+
customTheme: theme,
|
|
384
|
+
})),
|
|
385
|
+
...(allowCustomThemes
|
|
386
|
+
? [{ theme: '__new__', label: 'New custom theme…' }]
|
|
387
|
+
: []),
|
|
388
|
+
];
|
|
389
|
+
const selected = options[selectedIndex];
|
|
390
|
+
const selectedCustomTheme = selected && 'customTheme' in selected ? selected.customTheme : undefined;
|
|
391
|
+
const previewTheme = selected?.theme.startsWith('custom:') && selectedCustomTheme
|
|
392
|
+
? selectedCustomTheme.base
|
|
393
|
+
: selected?.theme === '__new__'
|
|
394
|
+
? 'dark'
|
|
395
|
+
: (selected?.theme ??
|
|
396
|
+
(currentTheme.startsWith('custom:') ? 'dark' : currentTheme));
|
|
397
|
+
const preview = tuiPalette(previewTheme, syntaxHighlightingDisabled, process.env, selectedCustomTheme);
|
|
398
|
+
const syntax = preview.syntax;
|
|
399
|
+
const syntaxColor = (color) => syntaxHighlightingDisabled ? {} : { color };
|
|
400
|
+
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [!screenReader ? _jsx(Text, { children: '▔'.repeat(Math.min(100, width)) }) : null, _jsx(Text, { bold: true, children: " Theme" }), _jsx(Text, { children: " " }), _jsx(Text, { children: " Choose the text style that looks best with your terminal" }), _jsx(Text, { children: " " }), options.map((option, index) => screenReader ? (_jsxs(Text, { children: [index + 1, ". ", option.label, option.theme === currentTheme ? ' (current)' : '', index === selectedIndex ? ' (focused)' : ''] }, option.theme)) : (_jsxs(Text, { inverse: index === selectedIndex, children: [index === selectedIndex ? ' ❯ ' : ' ', index + 1, ". ", option.label, option.theme === currentTheme ? ' ✔' : ''] }, option.theme))), _jsx(Text, { children: " " }), screenReader ? (_jsxs(Text, { children: ["Selected: ", options[selectedIndex]?.label] })) : null, !screenReader ? (_jsxs(_Fragment, { children: [_jsxs(Text, { dimColor: true, children: [' ', '╌'.repeat(Math.max(1, Math.min(96, width - 3)))] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: " 1 " }), _jsx(Text, { ...syntaxColor(syntax.keyword), children: "function" }), _jsx(Text, { ...syntaxColor(syntax.text), children: " " }), _jsx(Text, { ...syntaxColor(syntax.identifier), children: "greet" }), _jsxs(Text, { ...syntaxColor(syntax.text), children: ["() ", '{'] })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: " 2 - " }), _jsx(Text, { ...syntaxColor(syntax.text), ...(syntaxHighlightingDisabled || !syntax.removedBackground
|
|
401
|
+
? {}
|
|
402
|
+
: { backgroundColor: syntax.removedBackground }), children: ' console.log("Hello, World!"); ' })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: " 2 + " }), _jsxs(Text, { ...syntaxColor(syntax.text), ...(syntaxHighlightingDisabled || !syntax.addedBackground
|
|
403
|
+
? {}
|
|
404
|
+
: { backgroundColor: syntax.addedBackground }), children: [' console.', _jsx(Text, { ...syntaxColor(syntax.identifier), children: "log" }), '(', _jsx(Text, { ...syntaxColor(syntax.string), children: "\"Hello, " }), _jsx(Text, { ...(syntaxHighlightingDisabled || !syntax.addedHighlight
|
|
405
|
+
? {}
|
|
406
|
+
: { backgroundColor: syntax.addedHighlight }), children: "Praxis" }), _jsx(Text, { ...syntaxColor(syntax.string), children: "!\"" }), '); '] })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: " 3 " }), _jsx(Text, { ...syntaxColor(syntax.text), children: '}' })] }), _jsxs(Text, { dimColor: true, children: [' ', '╌'.repeat(Math.max(1, Math.min(96, width - 3)))] })] })) : null, _jsxs(Text, { dimColor: true, children: [' ', selected?.theme === '__new__'
|
|
407
|
+
? 'Enter to create a custom theme'
|
|
408
|
+
: syntaxHighlightingDisabled
|
|
409
|
+
? 'Syntax highlighting disabled (ctrl+t to enable)'
|
|
410
|
+
: `Syntax theme: ${preview.syntaxTheme} (ctrl+t to disable)`] }), _jsx(Text, { dimColor: true, children: " Enter to select \u00B7 Esc to cancel" })] }));
|
|
411
|
+
}
|
|
412
|
+
export function CustomThemeEditor({ theme, token, value, tokens = [], selectedIndex = 0, query = '', width, screenReader, }) {
|
|
413
|
+
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [_jsx(Text, { bold: true, children: theme.name }), token ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsxs(Text, { children: ["\u2588\u2588 ", token] }), _jsxs(Text, { dimColor: true, children: ["preset: ", value || '(not customized)'] }), _jsx(Text, { children: " " }), _jsxs(Text, { children: ["Value: ", value] }), _jsx(Text, { dimColor: true, children: "Accepts rgb(r,g,b), #rrggbb, ansi256(n), or ansi:name" }), _jsx(Text, { dimColor: true, children: "Enter to save \u00B7 Esc to cancel" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { dimColor: true, children: ["\u2315 ", query || 'Filter color tokens…'] }), tokens
|
|
414
|
+
.slice(selectedIndex, selectedIndex + 8)
|
|
415
|
+
.map((entry, index) => (_jsxs(Text, { inverse: index === 0, children: [index === 0 ? '❯ ' : ' ', "\u2588\u2588 ", entry, theme.overrides[entry] === undefined ? '' : ' (custom)'] }, entry))), _jsx(Text, { dimColor: true, children: "\u2191/\u2193 to nav \u00B7 Enter to edit \u00B7 Tab to reset \u00B7 Esc to done" })] })), screenReader ? _jsx(Text, { children: "Editing custom theme token" }) : null] }));
|
|
313
416
|
}
|
|
314
417
|
export function StatusDashboard({ tabIndex, version, sessionId, display, usage, costUsd, turnCount, toolCount, commandCount, detailedTranscript, width, screenReader, }) {
|
|
315
418
|
const tabs = ['Settings', 'Status', 'Config', 'Usage', 'Stats'];
|
|
@@ -364,8 +467,9 @@ export function ListDashboard({ title, rows, emptyText, selectedIndex, width, sc
|
|
|
364
467
|
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [!screenReader ? (_jsx(Text, { dimColor: true, children: '─'.repeat(Math.min(100, width)) })) : null, _jsxs(Text, { bold: true, children: [" ", title] }), _jsx(Text, { children: " " }), rows.length === 0 ? (_jsxs(Text, { dimColor: true, children: [" ", emptyText] })) : (rows.map((row, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { inverse: index === selectedIndex, children: [index === selectedIndex ? '❯ ' : ' ', row.label] }), row.description ? _jsxs(Text, { dimColor: true, children: [" ", row.description] }) : null] }, `${index}-${row.label}`)))), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "\u2191/\u2193 to select \u00B7 Esc to close" })] }));
|
|
365
468
|
}
|
|
366
469
|
export function MemoryDashboard({ autoMemoryEnabled, entries, selectedIndex, openedIndex, loading = false, width, screenReader, }) {
|
|
470
|
+
const palette = useTuiPalette();
|
|
367
471
|
const panelWidth = Math.min(100, width);
|
|
368
|
-
return (_jsxs(Box, { flexDirection: "column", width: panelWidth, children: [!screenReader ? (_jsx(Text, { color:
|
|
472
|
+
return (_jsxs(Box, { flexDirection: "column", width: panelWidth, children: [!screenReader ? (_jsx(Text, { color: palette.accent, children: '─'.repeat(panelWidth) })) : null, _jsx(Text, { bold: true, children: " Memory" }), _jsx(Text, { children: " " }), loading ? (_jsx(Text, { dimColor: true, children: " \u2736 Loading memory files\u2026" })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [" Auto-memory: ", autoMemoryEnabled ? 'on' : 'off'] }), _jsx(Text, { children: " " }), entries.map((entry, index) => (_jsxs(Box, { children: [_jsx(Box, { width: Math.max(24, Math.min(52, panelWidth - 28)), children: _jsxs(Text, { inverse: index === selectedIndex, children: [index === selectedIndex ? '❯ ' : ' ', index + 1, ". ", entry.label, openedIndex === index ? ' ✔' : ''] }) }), entry.annotation ? (_jsx(Text, { dimColor: true, children: entry.annotation })) : null] }, `${entry.kind}-${entry.path}`)))] })), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: " Learn more: https://code.claude.com/docs/en/memory" }), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, italic: true, children: "Enter to confirm \u00B7 Esc to cancel" })] }));
|
|
369
473
|
}
|
|
370
474
|
function selectedWindow(length, selectedIndex, size) {
|
|
371
475
|
return Math.max(0, Math.min(selectedIndex - Math.floor(size / 2), Math.max(0, length - size)));
|
|
@@ -429,6 +533,7 @@ export function HookDashboard({ configuration, depth, eventIndex, matcherIndex,
|
|
|
429
533
|
: 'Enter to confirm · Esc to cancel' })] }));
|
|
430
534
|
}
|
|
431
535
|
export function BtwPanel({ entries, selectedIndex, scrollOffset, copied, width, screenReader, }) {
|
|
536
|
+
const palette = useTuiPalette();
|
|
432
537
|
const selected = entries[selectedIndex];
|
|
433
538
|
const lines = selected?.answer.split('\n') ?? [];
|
|
434
539
|
const visibleLines = lines.slice(scrollOffset, scrollOffset + 16);
|
|
@@ -452,20 +557,22 @@ export function BtwPanel({ entries, selectedIndex, scrollOffset, copied, width,
|
|
|
452
557
|
].join(' · ');
|
|
453
558
|
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [!screenReader ? (_jsx(Text, { dimColor: true, children: '─'.repeat(Math.min(100, width)) })) : null, entries.map((entry, index) => (_jsxs(Text, { dimColor: index !== selectedIndex, children: [' ', "/btw ", entry.question] }, entry.id))), _jsx(Text, { children: " " }), selected?.status === 'answering' ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [" ", ' ', "\u00B7 Answering\u2026"] }), selected.answer
|
|
454
559
|
? visibleLines.map((line, index) => (_jsxs(Text, { children: [' ', ' ', line || ' '] }, `${scrollOffset + index}-${line}`)))
|
|
455
|
-
: null] })) : selected?.status === 'forking' ? (_jsxs(Text, { children: [" ", ' ', "\u00B7 Forking\u2026"] })) : selected?.status === 'error' ? (_jsxs(Text, { color:
|
|
560
|
+
: null] })) : selected?.status === 'forking' ? (_jsxs(Text, { children: [" ", ' ', "\u00B7 Forking\u2026"] })) : selected?.status === 'error' ? (_jsxs(Text, { color: palette.error, children: [' ', ' ', selected.error ?? 'Side question failed'] })) : (visibleLines.map((line, index) => (_jsxs(Text, { children: [' ', ' ', line || ' '] }, `${scrollOffset + index}-${line}`)))), _jsx(Text, { children: " " }), _jsxs(Text, { dimColor: true, children: [" ", footer] })] }));
|
|
456
561
|
}
|
|
457
562
|
export function SessionPicker({ sessions, selectedIndex, screenReader, query = '', }) {
|
|
563
|
+
const palette = useTuiPalette();
|
|
458
564
|
const maxVisible = 8;
|
|
459
565
|
const start = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), sessions.length - maxVisible));
|
|
460
566
|
const visible = sessions.slice(start, start + maxVisible);
|
|
461
|
-
return (_jsxs(Box, { flexDirection: "column", children: [!screenReader ? _jsx(Text, { dimColor: true, children: '─'.repeat(80) }) : null, _jsx(Text, { bold: true, children: " Resume session" }), _jsx(Box, { borderStyle: screenReader ? undefined : 'round', borderColor:
|
|
567
|
+
return (_jsxs(Box, { flexDirection: "column", children: [!screenReader ? _jsx(Text, { dimColor: true, children: '─'.repeat(80) }) : null, _jsx(Text, { bold: true, children: " Resume session" }), _jsx(Box, { borderStyle: screenReader ? undefined : 'round', borderColor: palette.muted, paddingX: screenReader ? 0 : 1, marginY: 1, children: _jsxs(Text, { ...(query ? {} : { dimColor: true }), children: ["\u2315 ", query || 'Search…'] }) }), start > 0 ? _jsxs(Text, { dimColor: true, children: [" \u2191 ", start, " earlier"] }) : null, visible.length === 0 ? _jsx(Text, { dimColor: true, children: "No sessions found." }) : null, visible.map((session, visibleIndex) => {
|
|
462
568
|
const index = start + visibleIndex;
|
|
463
|
-
return (_jsxs(Box, { children: [_jsxs(Text, { ...(index === selectedIndex ? { color:
|
|
569
|
+
return (_jsxs(Box, { children: [_jsxs(Text, { ...(index === selectedIndex ? { color: palette.brand } : {}), bold: index === selectedIndex, children: [index === selectedIndex ? '❯ ' : ' ', session
|
|
464
570
|
? (session.name ?? session.lastPrompt ?? 'Untitled')
|
|
465
571
|
: 'Start a new session'] }), session ? (_jsxs(Text, { dimColor: true, children: [' ', "\u00B7 ", session.sessionId, " \u00B7 ", session.status] })) : null] }, session?.sessionId ?? 'new'));
|
|
466
572
|
}), start + visible.length < sessions.length ? (_jsxs(Text, { dimColor: true, children: [" \u2193 ", sessions.length - start - visible.length, " more"] })) : null, !screenReader ? (_jsx(Text, { dimColor: true, children: "\u2191/\u2193 to navigate \u00B7 Enter to select \u00B7 Type to search \u00B7 Esc to cancel" })) : null] }));
|
|
467
573
|
}
|
|
468
574
|
export function CommandPalette({ commands, selectedIndex, width, screenReader, }) {
|
|
575
|
+
const palette = useTuiPalette();
|
|
469
576
|
const maxVisible = 12;
|
|
470
577
|
const start = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), Math.max(0, commands.length - maxVisible)));
|
|
471
578
|
const visible = commands.slice(start, start + maxVisible);
|
|
@@ -475,7 +582,7 @@ export function CommandPalette({ commands, selectedIndex, width, screenReader, }
|
|
|
475
582
|
return (_jsx(Box, { flexDirection: "column", width: Math.min(100, width), children: visible.length === 0 ? (_jsx(Text, { dimColor: true, children: "No matching commands." })) : (visible.map((command, visibleIndex) => {
|
|
476
583
|
const index = start + visibleIndex;
|
|
477
584
|
const selected = index === selectedIndex;
|
|
478
|
-
return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 30, children: _jsxs(Text, { ...(selected ? { color:
|
|
585
|
+
return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 30, children: _jsxs(Text, { ...(selected ? { color: palette.brand, bold: true } : {}), children: ["/", command.name] }) }), _jsx(Box, { flexGrow: 1, children: _jsx(Text, { dimColor: true, children: command.description }) })] }, command.name));
|
|
479
586
|
})) }));
|
|
480
587
|
}
|
|
481
588
|
export function FilePicker({ entries, selectedIndex, width, screenReader, }) {
|
|
@@ -526,54 +633,63 @@ export function ShortcutHelp({ width }) {
|
|
|
526
633
|
return (_jsx(Box, { flexDirection: "column", width: Math.min(100, width), children: SHORTCUT_ROWS.map((row, rowIndex) => wide ? (_jsx(Box, { flexDirection: "row", children: row.map((cell, cellIndex) => (_jsx(Box, { width: cellIndex === 2 ? undefined : '33%', children: _jsx(Text, { dimColor: true, children: cell }) }, cellIndex))) }, rowIndex)) : (row.filter(Boolean).map((cell, cellIndex) => (_jsx(Text, { dimColor: true, children: cell }, `${rowIndex}-${cellIndex}`))))) }));
|
|
527
634
|
}
|
|
528
635
|
export function HelpMenu({ tabIndex, selectedIndex, builtinCommands, customCommands, width, screenReader, }) {
|
|
636
|
+
const palette = useTuiPalette();
|
|
529
637
|
const tabs = ['General', 'Commands', 'Custom commands'];
|
|
530
638
|
const commands = tabIndex === 1 ? builtinCommands : customCommands;
|
|
531
639
|
const maxVisible = 10;
|
|
532
640
|
const start = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), Math.max(0, commands.length - maxVisible)));
|
|
533
641
|
const visible = commands.slice(start, start + maxVisible);
|
|
534
642
|
const line = '─'.repeat(Math.max(12, Math.min(100, width)));
|
|
535
|
-
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [!screenReader ? _jsx(Text, { dimColor: true, children: line }) : null, _jsxs(Box, { children: [_jsx(Text, { bold: true, children: " Help " }), tabs.map((tab, index) => (_jsxs(Text, { ...(index === tabIndex
|
|
643
|
+
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [!screenReader ? _jsx(Text, { dimColor: true, children: line }) : null, _jsxs(Box, { children: [_jsx(Text, { bold: true, children: " Help " }), tabs.map((tab, index) => (_jsxs(Text, { ...(index === tabIndex
|
|
644
|
+
? { color: palette.brand, bold: true }
|
|
645
|
+
: {}), children: [' ', tab, ' '] }, tab)))] }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: tabIndex === 0 ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: "Praxis understands your codebase, makes edits with your permission, and executes commands from your terminal." }), _jsx(Text, { bold: true, children: "Shortcuts" }), _jsx(ShortcutHelp, { width: width })] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: tabIndex === 1
|
|
536
646
|
? 'Browse default commands'
|
|
537
647
|
: 'Browse shared commands and skills' }), visible.length === 0 ? (_jsx(Text, { dimColor: true, children: "No commands found." })) : (visible.map((command, visibleIndex) => {
|
|
538
648
|
const index = start + visibleIndex;
|
|
539
649
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { ...(index === selectedIndex
|
|
540
|
-
? { color:
|
|
650
|
+
? { color: palette.brand, bold: true }
|
|
541
651
|
: {}), children: [index === selectedIndex ? '↓ ' : ' ', "/", command.name] }), _jsxs(Text, { dimColor: true, children: [" ", command.description] })] }, command.name));
|
|
542
652
|
}))] })) }), _jsx(Text, { dimColor: true, children: "\u2190/\u2192 to switch \u00B7 \u2191/\u2193 to navigate \u00B7 Esc to cancel" })] }));
|
|
543
653
|
}
|
|
544
654
|
export function SelectionMenu({ title, description, options, selectedIndex, footer, width, screenReader, }) {
|
|
655
|
+
const palette = useTuiPalette();
|
|
545
656
|
const maxVisible = 7;
|
|
546
657
|
const start = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), Math.max(0, options.length - maxVisible)));
|
|
547
658
|
const visible = options.slice(start, start + maxVisible);
|
|
548
|
-
|
|
659
|
+
const current = options.find((option) => option.selected);
|
|
660
|
+
return (_jsxs(Box, { borderStyle: screenReader ? undefined : 'round', borderColor: palette.muted, flexDirection: "column", marginTop: 1, paddingX: screenReader ? 0 : 1, width: screenReader ? undefined : Math.min(80, width), children: [_jsx(Text, { bold: true, children: title }), description ? _jsx(Text, { dimColor: true, children: description }) : null, screenReader && current ? _jsxs(Text, { children: ["Current: ", current.label] }) : null, visible.map((option, visibleIndex) => {
|
|
549
661
|
const index = start + visibleIndex;
|
|
550
662
|
const selected = index === selectedIndex;
|
|
551
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { ...(
|
|
663
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { ...(!screenReader && selected
|
|
664
|
+
? { color: palette.brand, bold: true }
|
|
665
|
+
: {}), children: [selectionPrefix(selected, screenReader), index + 1, ". ", option.label, !screenReader && option.selected ? ' ✔' : ''] }), option.description ? (_jsxs(Text, { dimColor: true, children: [" ", option.description] })) : null] }, `${index}-${option.label}`));
|
|
552
666
|
}), start > 0 || start + visible.length < options.length ? (_jsxs(Text, { dimColor: true, children: [start > 0 ? `↑ ${start} earlier` : '', start > 0 && start + visible.length < options.length ? ' · ' : '', start + visible.length < options.length
|
|
553
667
|
? `↓ ${options.length - start - visible.length} more`
|
|
554
668
|
: ''] })) : null, _jsx(Text, { dimColor: true, children: footer })] }));
|
|
555
669
|
}
|
|
556
670
|
function ComposerInput({ input, cursor }) {
|
|
671
|
+
const palette = useTuiPalette();
|
|
557
672
|
const { before, current, after } = composerEditorSegments({
|
|
558
673
|
text: input,
|
|
559
674
|
cursor,
|
|
560
675
|
});
|
|
561
676
|
const cursorText = current === '\n' ? '↵' : (current ?? ' ');
|
|
562
|
-
return (_jsxs(Text, { children: [before, _jsx(Text, { color:
|
|
677
|
+
return (_jsxs(Text, { children: [before, _jsx(Text, { color: palette.selectionText, backgroundColor: palette.accent, children: cursorText }), after] }));
|
|
563
678
|
}
|
|
564
679
|
export function ExternalEditorWait({ screenReader, }) {
|
|
565
680
|
if (screenReader)
|
|
566
681
|
return _jsx(Text, { children: "External editor open. Save and close it to continue." });
|
|
567
682
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }), _jsx(Text, { children: "Save and close editor to continue..." }), _jsx(Text, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" })] }));
|
|
568
683
|
}
|
|
569
|
-
export function Composer({ input, cursor, busy, clipboardBusy = false, status, display, usage, costUsd, width, screenReader, hasThinking = false, thinkingExpanded = false, shortcutsVisible = false, shellMode = false, footerMessage, }) {
|
|
684
|
+
export function Composer({ input, cursor, busy, clipboardBusy = false, status, display, usage, costUsd, width, screenReader, hasThinking = false, thinkingExpanded = false, shortcutsVisible = false, shellMode = false, footerMessage, reduceMotion = false, progressBar = true, turnDuration, editorMode = 'normal', prStatus, }) {
|
|
685
|
+
const palette = useTuiPalette();
|
|
570
686
|
const [spinnerIndex, setSpinnerIndex] = useState(0);
|
|
571
687
|
useEffect(() => {
|
|
572
|
-
if (!busy || screenReader)
|
|
688
|
+
if (!busy || screenReader || reduceMotion)
|
|
573
689
|
return;
|
|
574
690
|
const timer = setInterval(() => setSpinnerIndex((current) => (current + 1) % SPINNER.length), 90);
|
|
575
691
|
return () => clearInterval(timer);
|
|
576
|
-
}, [busy, screenReader]);
|
|
692
|
+
}, [busy, reduceMotion, screenReader]);
|
|
577
693
|
if (screenReader)
|
|
578
694
|
return (_jsx(Text, { children: clipboardBusy
|
|
579
695
|
? 'Pasting…'
|
|
@@ -589,13 +705,14 @@ export function Composer({ input, cursor, busy, clipboardBusy = false, status, d
|
|
|
589
705
|
100))}%)`
|
|
590
706
|
: '', usage.cacheReadInputTokens
|
|
591
707
|
? ` · ${usage.cacheReadInputTokens} cached`
|
|
592
|
-
: '', costUsd === undefined ? '' : ` · $${costUsd.toFixed(6)}`] })) : null, _jsx(Text, { dimColor: true, children: line }), clipboardBusy ? (_jsx(Text, { children: "Pasting\u2026" })) : busy ? (_jsxs(Text, { children: [_jsx(Text, { color:
|
|
708
|
+
: '', costUsd === undefined ? '' : ` · $${costUsd.toFixed(6)}`] })) : null, _jsx(Text, { dimColor: true, children: line }), clipboardBusy ? (_jsx(Text, { children: "Pasting\u2026" })) : busy ? (_jsxs(Text, { children: [progressBar ? (_jsx(Text, { color: palette.accent, children: reduceMotion ? '•' : SPINNER[spinnerIndex] })) : null, ' ', status, "\u2026 ", _jsx(Text, { dimColor: true, children: "\u00B7 esc to interrupt" })] })) : (_jsxs(Text, { children: [_jsx(Text, { ...(shellMode ? {} : { color: palette.brand }), bold: true, children: shellMode ? '! ' : '❯ ' }), input ? (_jsx(ComposerInput, { cursor: cursor ?? Array.from(input).length, input: input })) : (_jsx(Text, { dimColor: true, children: shellMode
|
|
593
709
|
? 'Enter a shell command'
|
|
594
710
|
: 'Try "review this project"' }))] })), _jsx(Text, { dimColor: true, children: line }), shortcutsVisible ? (_jsx(ShortcutHelp, { width: width })) : (_jsxs(Box, { width: Math.min(100, width), children: [_jsx(Text, { dimColor: true, children: shellMode ? ('! for shell mode') : (_jsxs(_Fragment, { children: ["\u23F5\u23F5 ", permissionLabel(display.permissionMode), " \u00B7", ' ', busy ? 'esc to interrupt' : '? for shortcuts', " \u00B7 \u2190 for agents", hasThinking
|
|
595
711
|
? ` · ctrl+o ${thinkingExpanded ? 'collapse' : 'expand'}`
|
|
596
|
-
: ''] })) }), _jsx(Box, { flexGrow: 1 }), footerMessage ? (footerMessage.isError ? (_jsx(Text, { color:
|
|
712
|
+
: ''] })) }), _jsx(Box, { flexGrow: 1 }), footerMessage ? (footerMessage.isError ? (_jsx(Text, { color: palette.error, children: footerMessage.text })) : (_jsx(Text, { dimColor: true, children: footerMessage.text }))) : prStatus ? (_jsx(Text, { dimColor: true, children: prStatus })) : turnDuration ? (_jsxs(Text, { dimColor: true, children: ["Cooked for ", turnDuration] })) : display.effort ? (_jsxs(Text, { children: [_jsxs(Text, { color: palette.accent, children: ["\u25CF ", display.effort] }), _jsxs(Text, { dimColor: true, children: [' ', "\u00B7 ", editorMode === 'vim' ? 'vim' : '/effort'] })] })) : null] }))] }));
|
|
597
713
|
}
|
|
598
714
|
export function DialogFrame({ title, children, screenReader, }) {
|
|
599
|
-
|
|
715
|
+
const palette = useTuiPalette();
|
|
716
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: screenReader ? undefined : 'round', borderColor: palette.warning, paddingX: screenReader ? 0 : 1, marginTop: 1, children: [_jsx(Text, { color: palette.warning, bold: true, children: title }), children] }));
|
|
600
717
|
}
|
|
601
718
|
//# sourceMappingURL=claude-style.js.map
|