praxis-agent 0.6.0 → 0.8.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 +10 -1
- 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 +44 -3
- package/dist/cli/interactive.js +1431 -189
- package/dist/cli/tui/claude-style.d.ts +41 -3
- package/dist/cli/tui/claude-style.js +227 -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/hook-settings.d.ts +33 -0
- package/dist/cli/tui/hook-settings.js +200 -0
- 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 +15 -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 +12 -0
- package/dist/cli.js +140 -21
- package/dist/compatibility/claude/schema.js +2 -0
- package/dist/compatibility/claude/shared-resources.d.ts +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.d.ts +1 -0
- package/dist/plugins/claude-plugin-runtime.js +60 -24
- 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/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
|
@@ -3,8 +3,8 @@ import { useEffect, useState } from 'react';
|
|
|
3
3
|
import { Box, Text, useStdout } from 'ink';
|
|
4
4
|
import { composerEditorSegments } from './composer-editor.js';
|
|
5
5
|
import { visiblePatchLines } from './git-diff.js';
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { TUI_HOOK_MENU } from './hook-settings.js';
|
|
7
|
+
import { tuiPalette, tuiSyntaxStyle, useTuiPalette, } from './theme.js';
|
|
8
8
|
const SPINNER = ['✳', '✢', '✣', '✤', '✥'];
|
|
9
9
|
export function useTerminalWidth(override) {
|
|
10
10
|
const { stdout } = useStdout();
|
|
@@ -44,31 +44,39 @@ function permissionLabel(mode) {
|
|
|
44
44
|
return 'permissions default';
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
function selectionPrefix(selected, screenReader) {
|
|
48
|
+
if (selected)
|
|
49
|
+
return screenReader ? 'Selected: ' : '❯ ';
|
|
50
|
+
return screenReader ? '' : ' ';
|
|
51
|
+
}
|
|
47
52
|
export function WelcomePanel({ display, width, }) {
|
|
53
|
+
const palette = useTuiPalette();
|
|
48
54
|
const panelWidth = Math.min(100, Math.max(32, width));
|
|
49
55
|
const wide = panelWidth >= 68;
|
|
50
|
-
return (_jsxs(Box, { borderStyle: "round", borderColor:
|
|
56
|
+
return (_jsxs(Box, { borderStyle: "round", borderColor: palette.muted, flexDirection: "column", width: panelWidth, paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: palette.brand, bold: true, children: "Praxis" }), _jsxs(Text, { children: [" Code v", display.version, " "] }), _jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(1, panelWidth - 24)) })] }), _jsxs(Box, { flexDirection: wide ? 'row' : 'column', marginTop: 1, children: [_jsxs(Box, { alignItems: wide ? 'center' : undefined, flexDirection: "column", width: wide ? '50%' : '100%', children: [_jsx(Text, { bold: true, children: "Welcome back!" }), _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" }), _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" })] })] })] }));
|
|
51
57
|
}
|
|
52
58
|
function InlineText({ text }) {
|
|
59
|
+
const palette = useTuiPalette();
|
|
53
60
|
const tokens = text.split(/(`[^`]+`|\*\*[^*]+\*\*|\[[^\]]+\]\([^)]+\))/u);
|
|
54
61
|
return (_jsx(Text, { children: tokens.map((token, index) => {
|
|
55
62
|
if (token.startsWith('`') && token.endsWith('`'))
|
|
56
|
-
return (_jsx(Text, { color:
|
|
63
|
+
return (_jsx(Text, { color: palette.info, children: token.slice(1, -1) }, index));
|
|
57
64
|
if (token.startsWith('**') && token.endsWith('**'))
|
|
58
65
|
return (_jsx(Text, { bold: true, children: token.slice(2, -2) }, index));
|
|
59
66
|
const link = /^\[([^\]]+)\]\(([^)]+)\)$/u.exec(token);
|
|
60
67
|
if (link)
|
|
61
|
-
return (_jsx(Text, { color:
|
|
68
|
+
return (_jsx(Text, { color: palette.link, underline: true, children: link[1] }, index));
|
|
62
69
|
return token;
|
|
63
70
|
}) }));
|
|
64
71
|
}
|
|
65
72
|
function MarkdownLine({ line }) {
|
|
73
|
+
const palette = useTuiPalette();
|
|
66
74
|
if (line.startsWith('### '))
|
|
67
75
|
return (_jsx(Text, { bold: true, children: _jsx(InlineText, { text: line.slice(4) }) }));
|
|
68
76
|
if (line.startsWith('## '))
|
|
69
|
-
return (_jsx(Text, { bold: true, color:
|
|
77
|
+
return (_jsx(Text, { bold: true, color: palette.accent, children: _jsx(InlineText, { text: line.slice(3) }) }));
|
|
70
78
|
if (line.startsWith('# '))
|
|
71
|
-
return (_jsx(Text, { bold: true, color:
|
|
79
|
+
return (_jsx(Text, { bold: true, color: palette.brand, children: _jsx(InlineText, { text: line.slice(2) }) }));
|
|
72
80
|
if (/^[-*] /u.test(line))
|
|
73
81
|
return (_jsxs(Text, { children: [' • ', _jsx(InlineText, { text: line.slice(2) })] }));
|
|
74
82
|
if (/^\d+\. /u.test(line))
|
|
@@ -77,14 +85,51 @@ function MarkdownLine({ line }) {
|
|
|
77
85
|
return (_jsxs(Text, { dimColor: true, children: ['│ ', _jsx(InlineText, { text: line.slice(2) })] }));
|
|
78
86
|
return line ? _jsx(InlineText, { text: line }) : _jsx(Text, { children: " " });
|
|
79
87
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
const CODE_KEYWORDS = new Set([
|
|
89
|
+
'async',
|
|
90
|
+
'await',
|
|
91
|
+
'class',
|
|
92
|
+
'const',
|
|
93
|
+
'else',
|
|
94
|
+
'export',
|
|
95
|
+
'false',
|
|
96
|
+
'from',
|
|
97
|
+
'function',
|
|
98
|
+
'if',
|
|
99
|
+
'import',
|
|
100
|
+
'let',
|
|
101
|
+
'new',
|
|
102
|
+
'null',
|
|
103
|
+
'return',
|
|
104
|
+
'true',
|
|
105
|
+
'undefined',
|
|
106
|
+
'var',
|
|
107
|
+
]);
|
|
108
|
+
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;
|
|
109
|
+
function SyntaxCodeLine({ text, prefix = '', change, }) {
|
|
110
|
+
const palette = useTuiPalette();
|
|
111
|
+
if (palette.syntaxHighlightingDisabled) {
|
|
112
|
+
return (_jsxs(Text, { children: [prefix, text || ' '] }));
|
|
113
|
+
}
|
|
114
|
+
const lineStyle = tuiSyntaxStyle(palette, 'text', change);
|
|
115
|
+
return (_jsxs(Text, { children: [prefix, _jsx(Text, { ...lineStyle, children: text.split(CODE_TOKEN_PATTERN).map((token, index) => {
|
|
116
|
+
const kind = token.startsWith('"') || token.startsWith("'")
|
|
117
|
+
? 'string'
|
|
118
|
+
: CODE_KEYWORDS.has(token)
|
|
119
|
+
? 'keyword'
|
|
120
|
+
: /^[A-Za-z_$][\w$]*$/u.test(token)
|
|
121
|
+
? 'identifier'
|
|
122
|
+
: 'text';
|
|
123
|
+
if (kind === 'text')
|
|
124
|
+
return token;
|
|
125
|
+
return (_jsx(Text, { ...tuiSyntaxStyle(palette, kind), children: token }, index));
|
|
126
|
+
}) })] }));
|
|
127
|
+
}
|
|
128
|
+
function ToolResultText({ text, prefix = '', }) {
|
|
129
|
+
const palette = useTuiPalette();
|
|
130
|
+
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('@@')
|
|
131
|
+
? { color: palette.info }
|
|
132
|
+
: { dimColor: true }), children: [index === 0 ? prefix : prefix ? ' ' : '', line || ' '] }, index))) }));
|
|
88
133
|
}
|
|
89
134
|
function inputString(call, key) {
|
|
90
135
|
const value = call.input[key];
|
|
@@ -106,6 +151,7 @@ function toolHeading(call) {
|
|
|
106
151
|
return call.name;
|
|
107
152
|
}
|
|
108
153
|
function ToolTranscriptEntry({ call, detail, result, detailed, }) {
|
|
154
|
+
const palette = useTuiPalette();
|
|
109
155
|
const displayResult = call.name === 'Read' &&
|
|
110
156
|
result?.text.startsWith('Wasted call — file unchanged since your last Read')
|
|
111
157
|
? 'Unchanged since last read'
|
|
@@ -116,17 +162,20 @@ function ToolTranscriptEntry({ call, detail, result, detailed, }) {
|
|
|
116
162
|
}
|
|
117
163
|
const visible = detailed ? resultLines : resultLines.slice(0, 3);
|
|
118
164
|
const hidden = resultLines.length - visible.length;
|
|
165
|
+
const resultIsDiff = resultLines.some((line) => line.startsWith('+') && !line.startsWith('+++')) &&
|
|
166
|
+
resultLines.some((line) => line.startsWith('-') && !line.startsWith('---'));
|
|
119
167
|
const errorText = displayResult.length > 500
|
|
120
168
|
? `${displayResult.slice(0, 497)}...`
|
|
121
169
|
: displayResult;
|
|
122
170
|
const oldLines = contentLines(inputString(call, 'old_string'));
|
|
123
171
|
const newLines = contentLines(inputString(call, 'new_string'));
|
|
124
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color:
|
|
172
|
+
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] }));
|
|
125
173
|
}
|
|
126
174
|
function ThinkingBlock({ text, active, expanded, screenReader, }) {
|
|
175
|
+
const palette = useTuiPalette();
|
|
127
176
|
const summary = text.replace(/\s+/gu, ' ').trim();
|
|
128
177
|
const showFull = screenReader || active || expanded;
|
|
129
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { ...(!screenReader ? { color:
|
|
178
|
+
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] }));
|
|
130
179
|
}
|
|
131
180
|
function ContextUsageBlock({ usedTokens, contextWindowTokens, skills, screenReader, }) {
|
|
132
181
|
const totalTokens = Math.max(1, contextWindowTokens);
|
|
@@ -150,10 +199,11 @@ export function MarkdownText({ text }) {
|
|
|
150
199
|
code = !code;
|
|
151
200
|
return (_jsx(Text, { dimColor: true, children: code ? `╭─ ${line.slice(3) || 'code'}` : '╰─' }, index));
|
|
152
201
|
}
|
|
153
|
-
return code ? (
|
|
202
|
+
return code ? (_jsx(SyntaxCodeLine, { prefix: "\u2502 ", text: line }, index)) : (_jsx(MarkdownLine, { line: line }, index));
|
|
154
203
|
}) }));
|
|
155
204
|
}
|
|
156
205
|
export function Transcript({ items, activeText, activeThinking = '', thinkingExpanded = false, detailedTranscript = false, screenReader, }) {
|
|
206
|
+
const palette = useTuiPalette();
|
|
157
207
|
const detailed = thinkingExpanded || detailedTranscript;
|
|
158
208
|
const results = new Map(items
|
|
159
209
|
.filter((item) => item.kind === 'tool-result')
|
|
@@ -212,16 +262,16 @@ export function Transcript({ items, activeText, activeThinking = '', thinkingExp
|
|
|
212
262
|
if (groupedReadTools.has(index))
|
|
213
263
|
return null;
|
|
214
264
|
if (item.kind === 'user') {
|
|
215
|
-
return (_jsxs(Box, { marginTop: index === 0 ? 0 : 1, children: [_jsx(Text, { color:
|
|
265
|
+
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));
|
|
216
266
|
}
|
|
217
267
|
if (item.kind === 'assistant') {
|
|
218
|
-
return (_jsxs(Box, { marginTop: 1, children: [screenReader ? _jsx(Text, { children: "Praxis:" }) : null, !screenReader ? _jsx(Text, { color:
|
|
268
|
+
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));
|
|
219
269
|
}
|
|
220
270
|
if (item.kind === 'thinking') {
|
|
221
271
|
return (_jsx(ThinkingBlock, { text: item.text, active: false, expanded: detailed, screenReader: screenReader }, index));
|
|
222
272
|
}
|
|
223
273
|
if (item.kind === 'compact') {
|
|
224
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color:
|
|
274
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: palette.accent, italic: true, children: screenReader
|
|
225
275
|
? 'Conversation compacted'
|
|
226
276
|
: '✻ Conversation compacted (ctrl+o for history)' }), detailed ? (_jsx(Box, { marginLeft: screenReader ? 0 : 2, children: _jsx(MarkdownText, { text: item.summary }) })) : null] }, index));
|
|
227
277
|
}
|
|
@@ -236,7 +286,7 @@ export function Transcript({ items, activeText, activeThinking = '', thinkingExp
|
|
|
236
286
|
if (pairedResults.has(item.callId))
|
|
237
287
|
return null;
|
|
238
288
|
const text = item.text.length > 500 ? `${item.text.slice(0, 497)}...` : item.text;
|
|
239
|
-
return (_jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [_jsx(Text, { color: item.isError ?
|
|
289
|
+
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));
|
|
240
290
|
}
|
|
241
291
|
if (item.kind === 'shell') {
|
|
242
292
|
const result = shellResults.get(item.callId);
|
|
@@ -252,21 +302,22 @@ export function Transcript({ items, activeText, activeThinking = '', thinkingExp
|
|
|
252
302
|
const lines = contentLines(output);
|
|
253
303
|
const visible = detailed || screenReader ? lines : lines.slice(0, 3);
|
|
254
304
|
const hidden = lines.length - visible.length;
|
|
255
|
-
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:
|
|
305
|
+
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));
|
|
256
306
|
}
|
|
257
307
|
if (item.kind === 'shell-result') {
|
|
258
308
|
if (pairedShellResults.has(item.callId))
|
|
259
309
|
return null;
|
|
260
310
|
const output = [item.stdout, item.stderr].filter(Boolean).join('\n');
|
|
261
|
-
return (_jsxs(Text, { ...(item.isError ? { color:
|
|
311
|
+
return (_jsxs(Text, { ...(item.isError ? { color: palette.error } : {}), children: ["\u23BF ", output] }, index));
|
|
262
312
|
}
|
|
263
313
|
if (item.kind === 'local-result') {
|
|
264
314
|
return (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { dimColor: true, children: ["\u23BF ", item.text] }) }, index));
|
|
265
315
|
}
|
|
266
|
-
return (_jsxs(Text, { ...(item.kind === 'warning' ? { color:
|
|
267
|
-
}), 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:
|
|
316
|
+
return (_jsxs(Text, { ...(item.kind === 'warning' ? { color: palette.error } : {}), dimColor: item.kind === 'notice', children: [item.kind === 'warning' ? '⚠ ' : '· ', item.text] }, index));
|
|
317
|
+
}), 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] }));
|
|
268
318
|
}
|
|
269
319
|
export function DiffDashboard({ snapshots, sourceIndex, selectedIndex, viewingFile, scrollOffset, width, screenReader, }) {
|
|
320
|
+
const palette = useTuiPalette();
|
|
270
321
|
const source = snapshots[sourceIndex];
|
|
271
322
|
const snapshot = source?.snapshot ?? { files: [], additions: 0, deletions: 0 };
|
|
272
323
|
const selected = snapshot.files[selectedIndex];
|
|
@@ -274,15 +325,11 @@ export function DiffDashboard({ snapshots, sourceIndex, selectedIndex, viewingFi
|
|
|
274
325
|
const line = '─'.repeat(panelWidth);
|
|
275
326
|
if (viewingFile && selected) {
|
|
276
327
|
const lines = visiblePatchLines(selected.patch).slice(scrollOffset, scrollOffset + 18);
|
|
277
|
-
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) => (
|
|
278
|
-
? { color: 'green' }
|
|
279
|
-
: patchLine.startsWith('-')
|
|
280
|
-
? { color: 'red' }
|
|
281
|
-
: { dimColor: true }), children: [' ', patchLine] }, `${scrollOffset}-${index}`))), _jsx(Text, { dimColor: true, children: " \u2191/\u2193 to scroll \u00B7 Esc to back" })] }));
|
|
328
|
+
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" })] }));
|
|
282
329
|
}
|
|
283
|
-
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:
|
|
330
|
+
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" })] }));
|
|
284
331
|
}
|
|
285
|
-
export function PermissionDashboard({ tabIndex, selectedIndex, query, rules, recentDenied, workspaceDirectories, width, screenReader, }) {
|
|
332
|
+
export function PermissionDashboard({ tabIndex, selectedIndex, query, rules, recentDenied, retryingDeniedId, workspaceDirectories, width, screenReader, }) {
|
|
286
333
|
const tabs = ['Recently denied', 'Allow', 'Ask', 'Deny', 'Workspace'];
|
|
287
334
|
const behavior = ['allow', 'ask', 'deny'][tabIndex - 1];
|
|
288
335
|
const normalizedQuery = query.trim().toLowerCase();
|
|
@@ -292,13 +339,13 @@ export function PermissionDashboard({ tabIndex, selectedIndex, query, rules, rec
|
|
|
292
339
|
rule.rule.toLowerCase().includes(normalizedQuery) ||
|
|
293
340
|
rule.scope.includes(normalizedQuery)))
|
|
294
341
|
: [];
|
|
295
|
-
const rows =
|
|
342
|
+
const rows = matchingRules.map((rule) => rule.rule);
|
|
296
343
|
const originalWorkspace = workspaceDirectories.find((directory) => directory.original);
|
|
297
344
|
const additionalWorkspaces = workspaceDirectories.filter((directory) => !directory.original);
|
|
298
345
|
const description = tabIndex === 0
|
|
299
346
|
? recentDenied.length === 0
|
|
300
347
|
? 'No recent denials. Commands denied by the auto mode classifier will appear here.'
|
|
301
|
-
: 'Commands denied by the auto mode classifier
|
|
348
|
+
: 'Commands recently denied by the auto mode classifier.'
|
|
302
349
|
: tabIndex === 1
|
|
303
350
|
? "Praxis Code won't ask before using allowed tools."
|
|
304
351
|
: tabIndex === 2
|
|
@@ -306,9 +353,60 @@ export function PermissionDashboard({ tabIndex, selectedIndex, query, rules, rec
|
|
|
306
353
|
: tabIndex === 3
|
|
307
354
|
? 'Praxis Code will reject requests to use denied tools.'
|
|
308
355
|
: 'Praxis Code can read files in the workspace, and make edits when auto-accept edits is on.';
|
|
309
|
-
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: [
|
|
310
|
-
? '
|
|
311
|
-
:
|
|
356
|
+
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
|
|
357
|
+
? 'Enter to approve · r to retry · ↑/↓ to navigate · Esc to cancel'
|
|
358
|
+
: selectedIndex >= 0
|
|
359
|
+
? '↑/↓ navigate · Enter to select · ←/→ to switch · Esc to cancel'
|
|
360
|
+
: '←/→ to switch · ↓ to select · Esc to cancel' })] }));
|
|
361
|
+
}
|
|
362
|
+
const THEME_OPTIONS = [
|
|
363
|
+
{ theme: 'auto', label: 'Auto (match terminal)' },
|
|
364
|
+
{ theme: 'dark', label: 'Dark mode' },
|
|
365
|
+
{ theme: 'light', label: 'Light mode' },
|
|
366
|
+
{ theme: 'dark-daltonized', label: 'Dark mode (colorblind-friendly)' },
|
|
367
|
+
{ theme: 'light-daltonized', label: 'Light mode (colorblind-friendly)' },
|
|
368
|
+
{ theme: 'dark-ansi', label: 'Dark mode (ANSI colors only)' },
|
|
369
|
+
{ theme: 'light-ansi', label: 'Light mode (ANSI colors only)' },
|
|
370
|
+
];
|
|
371
|
+
export function ThemePicker({ currentTheme, selectedIndex, syntaxHighlightingDisabled, customThemes = [], allowCustomThemes = true, width, screenReader, }) {
|
|
372
|
+
const options = [
|
|
373
|
+
...THEME_OPTIONS.map((option) => ({ ...option, customTheme: undefined })),
|
|
374
|
+
...customThemes.map((theme) => ({
|
|
375
|
+
theme: `custom:${theme.slug}`,
|
|
376
|
+
label: `${theme.name} (custom)`,
|
|
377
|
+
customTheme: theme,
|
|
378
|
+
})),
|
|
379
|
+
...(allowCustomThemes
|
|
380
|
+
? [{ theme: '__new__', label: 'New custom theme…' }]
|
|
381
|
+
: []),
|
|
382
|
+
];
|
|
383
|
+
const selected = options[selectedIndex];
|
|
384
|
+
const selectedCustomTheme = selected && 'customTheme' in selected ? selected.customTheme : undefined;
|
|
385
|
+
const previewTheme = selected?.theme.startsWith('custom:') && selectedCustomTheme
|
|
386
|
+
? selectedCustomTheme.base
|
|
387
|
+
: selected?.theme === '__new__'
|
|
388
|
+
? 'dark'
|
|
389
|
+
: (selected?.theme ??
|
|
390
|
+
(currentTheme.startsWith('custom:') ? 'dark' : currentTheme));
|
|
391
|
+
const preview = tuiPalette(previewTheme, syntaxHighlightingDisabled, process.env, selectedCustomTheme);
|
|
392
|
+
const syntax = preview.syntax;
|
|
393
|
+
const syntaxColor = (color) => syntaxHighlightingDisabled ? {} : { color };
|
|
394
|
+
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
|
|
395
|
+
? {}
|
|
396
|
+
: { 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
|
|
397
|
+
? {}
|
|
398
|
+
: { backgroundColor: syntax.addedBackground }), children: [' console.', _jsx(Text, { ...syntaxColor(syntax.identifier), children: "log" }), '(', _jsx(Text, { ...syntaxColor(syntax.string), children: "\"Hello, " }), _jsx(Text, { ...(syntaxHighlightingDisabled || !syntax.addedHighlight
|
|
399
|
+
? {}
|
|
400
|
+
: { 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__'
|
|
401
|
+
? 'Enter to create a custom theme'
|
|
402
|
+
: syntaxHighlightingDisabled
|
|
403
|
+
? 'Syntax highlighting disabled (ctrl+t to enable)'
|
|
404
|
+
: `Syntax theme: ${preview.syntaxTheme} (ctrl+t to disable)`] }), _jsx(Text, { dimColor: true, children: " Enter to select \u00B7 Esc to cancel" })] }));
|
|
405
|
+
}
|
|
406
|
+
export function CustomThemeEditor({ theme, token, value, tokens = [], selectedIndex = 0, query = '', width, screenReader, }) {
|
|
407
|
+
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
|
|
408
|
+
.slice(selectedIndex, selectedIndex + 8)
|
|
409
|
+
.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] }));
|
|
312
410
|
}
|
|
313
411
|
export function StatusDashboard({ tabIndex, version, sessionId, display, usage, costUsd, turnCount, toolCount, commandCount, detailedTranscript, width, screenReader, }) {
|
|
314
412
|
const tabs = ['Settings', 'Status', 'Config', 'Usage', 'Stats'];
|
|
@@ -363,10 +461,73 @@ export function ListDashboard({ title, rows, emptyText, selectedIndex, width, sc
|
|
|
363
461
|
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" })] }));
|
|
364
462
|
}
|
|
365
463
|
export function MemoryDashboard({ autoMemoryEnabled, entries, selectedIndex, openedIndex, loading = false, width, screenReader, }) {
|
|
464
|
+
const palette = useTuiPalette();
|
|
366
465
|
const panelWidth = Math.min(100, width);
|
|
367
|
-
return (_jsxs(Box, { flexDirection: "column", width: panelWidth, children: [!screenReader ? (_jsx(Text, { color:
|
|
466
|
+
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" })] }));
|
|
467
|
+
}
|
|
468
|
+
function selectedWindow(length, selectedIndex, size) {
|
|
469
|
+
return Math.max(0, Math.min(selectedIndex - Math.floor(size / 2), Math.max(0, length - size)));
|
|
470
|
+
}
|
|
471
|
+
export function HookDashboard({ configuration, depth, eventIndex, matcherIndex, hookIndex, width, screenReader, }) {
|
|
472
|
+
const event = configuration.events[eventIndex];
|
|
473
|
+
const matcher = event?.matchers[matcherIndex];
|
|
474
|
+
const hook = matcher?.hooks[hookIndex];
|
|
475
|
+
if (depth === 'detail') {
|
|
476
|
+
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [!screenReader ? (_jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(12, Math.min(100, width))) })) : null, _jsx(Text, { bold: true, children: " Hook details" }), _jsxs(Text, { children: [" Event: ", event?.name ?? 'Hooks'] }), _jsxs(Text, { children: [" Matcher: ", matcher?.matcher ?? '(all)'] }), _jsxs(Text, { children: [" Type: ", hook?.type ?? 'command'] }), _jsxs(Text, { children: [" Source: ", hook?.scopeLabel ?? 'Settings'] }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [" ", hook?.label ?? ''] }), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "Esc to go back" })] }));
|
|
477
|
+
}
|
|
478
|
+
const rows = depth === 'events'
|
|
479
|
+
? configuration.events
|
|
480
|
+
: depth === 'matchers'
|
|
481
|
+
? (event?.matchers ?? [])
|
|
482
|
+
: (matcher?.hooks ?? []);
|
|
483
|
+
const selectedIndex = depth === 'events'
|
|
484
|
+
? eventIndex
|
|
485
|
+
: depth === 'matchers'
|
|
486
|
+
? matcherIndex
|
|
487
|
+
: hookIndex;
|
|
488
|
+
const maxVisible = depth === 'events' ? TUI_HOOK_MENU.visibleRows : 7;
|
|
489
|
+
const start = selectedWindow(rows.length, selectedIndex, maxVisible);
|
|
490
|
+
const visible = rows.slice(start, start + maxVisible);
|
|
491
|
+
const line = '─'.repeat(Math.max(12, Math.min(100, width)));
|
|
492
|
+
return (_jsxs(Box, { flexDirection: "column", width: Math.min(100, width), children: [!screenReader ? _jsx(Text, { dimColor: true, children: line }) : null, _jsxs(Text, { bold: true, children: [' ', depth === 'events'
|
|
493
|
+
? TUI_HOOK_MENU.title
|
|
494
|
+
: depth === 'matchers'
|
|
495
|
+
? `${event?.name ?? 'Hooks'} - Matchers`
|
|
496
|
+
: `${event?.name ?? 'Hooks'} - Matcher: ${matcher?.matcher ?? '(all)'}`] }), depth === 'events' ? (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [" ", configuration.hookCount, " hooks configured"] }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [' ', ' ℹ ', TUI_HOOK_MENU.readOnlyNotice] }), _jsx(Text, { dimColor: true, children: " Learn more" }), _jsx(Text, { children: " " })] })) : (_jsxs(_Fragment, { children: [(event?.detail ?? []).map((detail) => (_jsxs(Text, { children: [" ", detail] }, detail))), _jsx(Text, { children: " " })] })), start > 0 ? _jsxs(Text, { dimColor: true, children: [" \u2191 ", start, " more above"] }) : null, visible.length === 0 ? (_jsxs(_Fragment, { children: [_jsxs(Text, { dimColor: true, children: [' ', depth === 'matchers'
|
|
497
|
+
? 'No hooks configured for this event'
|
|
498
|
+
: 'No hooks configured for this matcher'] }), depth === 'matchers' ? (_jsxs(Text, { dimColor: true, children: [' ', "To add hooks, edit settings.json directly or ask Claude"] })) : null] })) : (visible.map((row, visibleIndex) => {
|
|
499
|
+
const index = start + visibleIndex;
|
|
500
|
+
const selected = index === selectedIndex;
|
|
501
|
+
if (depth === 'events') {
|
|
502
|
+
const item = row;
|
|
503
|
+
return (_jsxs(Box, { children: [_jsx(Box, { width: 30, children: _jsxs(Text, { inverse: !screenReader && selected, children: [screenReader && selected
|
|
504
|
+
? 'Selected: '
|
|
505
|
+
: selected
|
|
506
|
+
? '❯ '
|
|
507
|
+
: ' ', index + 1, ". ", item.name, item.matchers.length > 0
|
|
508
|
+
? ` (${item.matchers.reduce((count, current) => count + current.hooks.length, 0)})`
|
|
509
|
+
: ''] }) }), _jsx(Text, { dimColor: true, children: item.description })] }, item.name));
|
|
510
|
+
}
|
|
511
|
+
if (depth === 'matchers') {
|
|
512
|
+
const item = row;
|
|
513
|
+
return (_jsxs(Text, { inverse: !screenReader && selected, children: [screenReader && selected
|
|
514
|
+
? 'Selected: '
|
|
515
|
+
: selected
|
|
516
|
+
? '❯ '
|
|
517
|
+
: ' ', index + 1, ". [", item.scope, "] ", item.matcher, " ", item.hooks.length, ' ', item.hooks.length === 1 ? 'hook' : 'hooks'] }, `${item.scope}-${item.matcher}-${index}`));
|
|
518
|
+
}
|
|
519
|
+
const item = row;
|
|
520
|
+
return (_jsxs(Box, { children: [_jsx(Box, { flexGrow: 1, children: _jsxs(Text, { inverse: !screenReader && selected, wrap: "truncate-end", children: [screenReader && selected
|
|
521
|
+
? 'Selected: '
|
|
522
|
+
: selected
|
|
523
|
+
? '❯ '
|
|
524
|
+
: ' ', index + 1, ". [", item.type, "] ", item.label] }) }), _jsxs(Text, { dimColor: true, children: [" ", item.scopeLabel] })] }, `${item.path}-${index}`));
|
|
525
|
+
})), start + visible.length < rows.length ? (_jsxs(Text, { dimColor: true, children: [' ', "\u2193 ", rows.length - start - visible.length, " more below"] })) : null, _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: depth === 'hooks' || rows.length === 0
|
|
526
|
+
? 'Esc to go back'
|
|
527
|
+
: 'Enter to confirm · Esc to cancel' })] }));
|
|
368
528
|
}
|
|
369
529
|
export function BtwPanel({ entries, selectedIndex, scrollOffset, copied, width, screenReader, }) {
|
|
530
|
+
const palette = useTuiPalette();
|
|
370
531
|
const selected = entries[selectedIndex];
|
|
371
532
|
const lines = selected?.answer.split('\n') ?? [];
|
|
372
533
|
const visibleLines = lines.slice(scrollOffset, scrollOffset + 16);
|
|
@@ -390,20 +551,22 @@ export function BtwPanel({ entries, selectedIndex, scrollOffset, copied, width,
|
|
|
390
551
|
].join(' · ');
|
|
391
552
|
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
|
|
392
553
|
? visibleLines.map((line, index) => (_jsxs(Text, { children: [' ', ' ', line || ' '] }, `${scrollOffset + index}-${line}`)))
|
|
393
|
-
: null] })) : selected?.status === 'forking' ? (_jsxs(Text, { children: [" ", ' ', "\u00B7 Forking\u2026"] })) : selected?.status === 'error' ? (_jsxs(Text, { color:
|
|
554
|
+
: 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] })] }));
|
|
394
555
|
}
|
|
395
556
|
export function SessionPicker({ sessions, selectedIndex, screenReader, query = '', }) {
|
|
557
|
+
const palette = useTuiPalette();
|
|
396
558
|
const maxVisible = 8;
|
|
397
559
|
const start = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), sessions.length - maxVisible));
|
|
398
560
|
const visible = sessions.slice(start, start + maxVisible);
|
|
399
|
-
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:
|
|
561
|
+
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) => {
|
|
400
562
|
const index = start + visibleIndex;
|
|
401
|
-
return (_jsxs(Box, { children: [_jsxs(Text, { ...(index === selectedIndex ? { color:
|
|
563
|
+
return (_jsxs(Box, { children: [_jsxs(Text, { ...(index === selectedIndex ? { color: palette.brand } : {}), bold: index === selectedIndex, children: [index === selectedIndex ? '❯ ' : ' ', session
|
|
402
564
|
? (session.name ?? session.lastPrompt ?? 'Untitled')
|
|
403
565
|
: 'Start a new session'] }), session ? (_jsxs(Text, { dimColor: true, children: [' ', "\u00B7 ", session.sessionId, " \u00B7 ", session.status] })) : null] }, session?.sessionId ?? 'new'));
|
|
404
566
|
}), 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] }));
|
|
405
567
|
}
|
|
406
568
|
export function CommandPalette({ commands, selectedIndex, width, screenReader, }) {
|
|
569
|
+
const palette = useTuiPalette();
|
|
407
570
|
const maxVisible = 12;
|
|
408
571
|
const start = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), Math.max(0, commands.length - maxVisible)));
|
|
409
572
|
const visible = commands.slice(start, start + maxVisible);
|
|
@@ -413,7 +576,7 @@ export function CommandPalette({ commands, selectedIndex, width, screenReader, }
|
|
|
413
576
|
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) => {
|
|
414
577
|
const index = start + visibleIndex;
|
|
415
578
|
const selected = index === selectedIndex;
|
|
416
|
-
return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 30, children: _jsxs(Text, { ...(selected ? { color:
|
|
579
|
+
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));
|
|
417
580
|
})) }));
|
|
418
581
|
}
|
|
419
582
|
export function FilePicker({ entries, selectedIndex, width, screenReader, }) {
|
|
@@ -464,54 +627,63 @@ export function ShortcutHelp({ width }) {
|
|
|
464
627
|
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}`))))) }));
|
|
465
628
|
}
|
|
466
629
|
export function HelpMenu({ tabIndex, selectedIndex, builtinCommands, customCommands, width, screenReader, }) {
|
|
630
|
+
const palette = useTuiPalette();
|
|
467
631
|
const tabs = ['General', 'Commands', 'Custom commands'];
|
|
468
632
|
const commands = tabIndex === 1 ? builtinCommands : customCommands;
|
|
469
633
|
const maxVisible = 10;
|
|
470
634
|
const start = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), Math.max(0, commands.length - maxVisible)));
|
|
471
635
|
const visible = commands.slice(start, start + maxVisible);
|
|
472
636
|
const line = '─'.repeat(Math.max(12, Math.min(100, width)));
|
|
473
|
-
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
|
|
637
|
+
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
|
|
638
|
+
? { color: palette.brand, bold: true }
|
|
639
|
+
: {}), 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
|
|
474
640
|
? 'Browse default commands'
|
|
475
641
|
: 'Browse shared commands and skills' }), visible.length === 0 ? (_jsx(Text, { dimColor: true, children: "No commands found." })) : (visible.map((command, visibleIndex) => {
|
|
476
642
|
const index = start + visibleIndex;
|
|
477
643
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { ...(index === selectedIndex
|
|
478
|
-
? { color:
|
|
644
|
+
? { color: palette.brand, bold: true }
|
|
479
645
|
: {}), children: [index === selectedIndex ? '↓ ' : ' ', "/", command.name] }), _jsxs(Text, { dimColor: true, children: [" ", command.description] })] }, command.name));
|
|
480
646
|
}))] })) }), _jsx(Text, { dimColor: true, children: "\u2190/\u2192 to switch \u00B7 \u2191/\u2193 to navigate \u00B7 Esc to cancel" })] }));
|
|
481
647
|
}
|
|
482
648
|
export function SelectionMenu({ title, description, options, selectedIndex, footer, width, screenReader, }) {
|
|
649
|
+
const palette = useTuiPalette();
|
|
483
650
|
const maxVisible = 7;
|
|
484
651
|
const start = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), Math.max(0, options.length - maxVisible)));
|
|
485
652
|
const visible = options.slice(start, start + maxVisible);
|
|
486
|
-
|
|
653
|
+
const current = options.find((option) => option.selected);
|
|
654
|
+
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) => {
|
|
487
655
|
const index = start + visibleIndex;
|
|
488
656
|
const selected = index === selectedIndex;
|
|
489
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { ...(
|
|
657
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { ...(!screenReader && selected
|
|
658
|
+
? { color: palette.brand, bold: true }
|
|
659
|
+
: {}), children: [selectionPrefix(selected, screenReader), index + 1, ". ", option.label, !screenReader && option.selected ? ' ✔' : ''] }), option.description ? (_jsxs(Text, { dimColor: true, children: [" ", option.description] })) : null] }, `${index}-${option.label}`));
|
|
490
660
|
}), 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
|
|
491
661
|
? `↓ ${options.length - start - visible.length} more`
|
|
492
662
|
: ''] })) : null, _jsx(Text, { dimColor: true, children: footer })] }));
|
|
493
663
|
}
|
|
494
664
|
function ComposerInput({ input, cursor }) {
|
|
665
|
+
const palette = useTuiPalette();
|
|
495
666
|
const { before, current, after } = composerEditorSegments({
|
|
496
667
|
text: input,
|
|
497
668
|
cursor,
|
|
498
669
|
});
|
|
499
670
|
const cursorText = current === '\n' ? '↵' : (current ?? ' ');
|
|
500
|
-
return (_jsxs(Text, { children: [before, _jsx(Text, { color:
|
|
671
|
+
return (_jsxs(Text, { children: [before, _jsx(Text, { color: palette.selectionText, backgroundColor: palette.accent, children: cursorText }), after] }));
|
|
501
672
|
}
|
|
502
673
|
export function ExternalEditorWait({ screenReader, }) {
|
|
503
674
|
if (screenReader)
|
|
504
675
|
return _jsx(Text, { children: "External editor open. Save and close it to continue." });
|
|
505
676
|
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" })] }));
|
|
506
677
|
}
|
|
507
|
-
export function Composer({ input, cursor, busy, clipboardBusy = false, status, display, usage, costUsd, width, screenReader, hasThinking = false, thinkingExpanded = false, shortcutsVisible = false, shellMode = false, footerMessage, }) {
|
|
678
|
+
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, }) {
|
|
679
|
+
const palette = useTuiPalette();
|
|
508
680
|
const [spinnerIndex, setSpinnerIndex] = useState(0);
|
|
509
681
|
useEffect(() => {
|
|
510
|
-
if (!busy || screenReader)
|
|
682
|
+
if (!busy || screenReader || reduceMotion)
|
|
511
683
|
return;
|
|
512
684
|
const timer = setInterval(() => setSpinnerIndex((current) => (current + 1) % SPINNER.length), 90);
|
|
513
685
|
return () => clearInterval(timer);
|
|
514
|
-
}, [busy, screenReader]);
|
|
686
|
+
}, [busy, reduceMotion, screenReader]);
|
|
515
687
|
if (screenReader)
|
|
516
688
|
return (_jsx(Text, { children: clipboardBusy
|
|
517
689
|
? 'Pasting…'
|
|
@@ -527,13 +699,14 @@ export function Composer({ input, cursor, busy, clipboardBusy = false, status, d
|
|
|
527
699
|
100))}%)`
|
|
528
700
|
: '', usage.cacheReadInputTokens
|
|
529
701
|
? ` · ${usage.cacheReadInputTokens} cached`
|
|
530
|
-
: '', 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:
|
|
702
|
+
: '', 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
|
|
531
703
|
? 'Enter a shell command'
|
|
532
704
|
: '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
|
|
533
705
|
? ` · ctrl+o ${thinkingExpanded ? 'collapse' : 'expand'}`
|
|
534
|
-
: ''] })) }), _jsx(Box, { flexGrow: 1 }), footerMessage ? (footerMessage.isError ? (_jsx(Text, { color:
|
|
706
|
+
: ''] })) }), _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] }))] }));
|
|
535
707
|
}
|
|
536
708
|
export function DialogFrame({ title, children, screenReader, }) {
|
|
537
|
-
|
|
709
|
+
const palette = useTuiPalette();
|
|
710
|
+
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] }));
|
|
538
711
|
}
|
|
539
712
|
//# sourceMappingURL=claude-style.js.map
|