otherwise-cli 0.1.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.
Files changed (81) hide show
  1. package/README.md +193 -0
  2. package/bin/otherwise.js +5 -0
  3. package/frontend/404.html +84 -0
  4. package/frontend/assets/OpenDyslexic3-Bold-CDyRs55Y.ttf +0 -0
  5. package/frontend/assets/OpenDyslexic3-Regular-CIBXa4WE.ttf +0 -0
  6. package/frontend/assets/__vite-browser-external-BIHI7g3E.js +1 -0
  7. package/frontend/assets/conversational-worker-CeKiciGk.js +2929 -0
  8. package/frontend/assets/dictation-worker-D0aYfq8b.js +29 -0
  9. package/frontend/assets/gemini-color-CgSQmmva.png +0 -0
  10. package/frontend/assets/index-BLux5ps4.js +21 -0
  11. package/frontend/assets/index-Blh8_TEM.js +5272 -0
  12. package/frontend/assets/index-BpQ1PuKu.js +18 -0
  13. package/frontend/assets/index-Df737c8w.css +1 -0
  14. package/frontend/assets/index-xaYHL6wb.js +113 -0
  15. package/frontend/assets/ort-wasm-simd-threaded.asyncify-BynIiDiv.wasm +0 -0
  16. package/frontend/assets/ort-wasm-simd-threaded.jsep-B0T3yYHD.wasm +0 -0
  17. package/frontend/assets/transformers-tULNc5V3.js +31 -0
  18. package/frontend/assets/tts-worker-DPJWqT7N.js +2899 -0
  19. package/frontend/assets/voice-mode-worker-GzvIE_uh.js +2927 -0
  20. package/frontend/assets/worker-2d5ABSLU.js +31 -0
  21. package/frontend/banner.png +0 -0
  22. package/frontend/favicon.svg +3 -0
  23. package/frontend/google55e5ec47ee14a5f8.html +1 -0
  24. package/frontend/index.html +234 -0
  25. package/frontend/manifest.json +17 -0
  26. package/frontend/pdf.worker.min.mjs +21 -0
  27. package/frontend/robots.txt +5 -0
  28. package/frontend/sitemap.xml +27 -0
  29. package/package.json +81 -0
  30. package/src/agent/index.js +1066 -0
  31. package/src/agent/location.js +51 -0
  32. package/src/agent/prompt.js +548 -0
  33. package/src/agent/tools.js +4372 -0
  34. package/src/browser/detect.js +68 -0
  35. package/src/browser/session.js +1109 -0
  36. package/src/config.js +137 -0
  37. package/src/email/client.js +503 -0
  38. package/src/index.js +557 -0
  39. package/src/inference/anthropic.js +113 -0
  40. package/src/inference/google.js +373 -0
  41. package/src/inference/index.js +81 -0
  42. package/src/inference/ollama.js +383 -0
  43. package/src/inference/openai.js +140 -0
  44. package/src/inference/openrouter.js +378 -0
  45. package/src/inference/xai.js +200 -0
  46. package/src/logBridge.js +9 -0
  47. package/src/models.js +146 -0
  48. package/src/remote/client.js +225 -0
  49. package/src/scheduler/cron.js +243 -0
  50. package/src/server.js +3876 -0
  51. package/src/storage/db.js +1135 -0
  52. package/src/storage/supabase.js +364 -0
  53. package/src/tunnel/cloudflare.js +241 -0
  54. package/src/ui/components/App.jsx +687 -0
  55. package/src/ui/components/BrowserSelect.jsx +111 -0
  56. package/src/ui/components/FilePicker.jsx +472 -0
  57. package/src/ui/components/Header.jsx +444 -0
  58. package/src/ui/components/HelpPanel.jsx +173 -0
  59. package/src/ui/components/HistoryPanel.jsx +158 -0
  60. package/src/ui/components/MessageList.jsx +235 -0
  61. package/src/ui/components/ModelSelector.jsx +304 -0
  62. package/src/ui/components/PromptInput.jsx +515 -0
  63. package/src/ui/components/StreamingResponse.jsx +134 -0
  64. package/src/ui/components/ThinkingIndicator.jsx +365 -0
  65. package/src/ui/components/ToolExecution.jsx +714 -0
  66. package/src/ui/components/index.js +82 -0
  67. package/src/ui/context/TerminalContext.jsx +150 -0
  68. package/src/ui/context/index.js +13 -0
  69. package/src/ui/hooks/index.js +16 -0
  70. package/src/ui/hooks/useChatState.js +675 -0
  71. package/src/ui/hooks/useCommands.js +280 -0
  72. package/src/ui/hooks/useFileAttachments.js +216 -0
  73. package/src/ui/hooks/useKeyboardShortcuts.js +173 -0
  74. package/src/ui/hooks/useNotifications.js +185 -0
  75. package/src/ui/hooks/useTerminalSize.js +151 -0
  76. package/src/ui/hooks/useWebSocket.js +273 -0
  77. package/src/ui/index.js +94 -0
  78. package/src/ui/ink-runner.js +22 -0
  79. package/src/ui/utils/formatters.js +424 -0
  80. package/src/ui/utils/index.js +6 -0
  81. package/src/ui/utils/markdown.js +166 -0
@@ -0,0 +1,82 @@
1
+ /**
2
+ * UI components index
3
+ */
4
+
5
+ export { App } from './App.jsx';
6
+
7
+ // Header components
8
+ export {
9
+ Header,
10
+ Banner,
11
+ AnimatedBanner,
12
+ StatusBar,
13
+ ConnectionStatus,
14
+ ModelIndicator,
15
+ ChatTitle,
16
+ Divider,
17
+ WelcomeMessage,
18
+ } from './Header.jsx';
19
+
20
+ // Message components
21
+ export {
22
+ MessageList,
23
+ Message,
24
+ UserMessage,
25
+ AssistantMessage,
26
+ SystemMessage,
27
+ MessageDivider,
28
+ GenerationStats,
29
+ } from './MessageList.jsx';
30
+
31
+ // Streaming components
32
+ export { StreamingResponse, StreamingText } from './StreamingResponse.jsx';
33
+
34
+ // Indicator components
35
+ export {
36
+ ThinkingIndicator,
37
+ CompletedThinking,
38
+ GradientSpinner,
39
+ PulsingDots,
40
+ ShimmerText,
41
+ LoadingIndicator,
42
+ SuccessIndicator,
43
+ ErrorIndicator,
44
+ WarningIndicator,
45
+ InfoIndicator,
46
+ } from './ThinkingIndicator.jsx';
47
+
48
+ // Tool execution components
49
+ export {
50
+ ToolExecution,
51
+ ToolHeader,
52
+ ToolResult,
53
+ ToolError,
54
+ StreamingProgress,
55
+ AnimatedProgressBar,
56
+ DiffView,
57
+ DirectoryTree,
58
+ ShellOutput,
59
+ ToolSummary,
60
+ CollapsibleToolExecution,
61
+ CompactToolList,
62
+ } from './ToolExecution.jsx';
63
+
64
+ // Input components
65
+ export {
66
+ PromptInput,
67
+ FileChip,
68
+ FileChips,
69
+ CommandAutocomplete,
70
+ TokenEstimate,
71
+ MultilineIndicator,
72
+ useInputHistory,
73
+ SimplePrompt,
74
+ TypingIndicator,
75
+ QuickActions,
76
+ } from './PromptInput.jsx';
77
+
78
+ // Overlay components
79
+ export { FilePicker } from './FilePicker.jsx';
80
+ export { ModelSelector } from './ModelSelector.jsx';
81
+ export { HelpPanel } from './HelpPanel.jsx';
82
+ export { HistoryPanel } from './HistoryPanel.jsx';
@@ -0,0 +1,150 @@
1
+ /**
2
+ * TerminalContext - React Context for terminal dimensions
3
+ * Provides reactive terminal size to all Ink components without prop drilling
4
+ */
5
+
6
+ import React, { createContext, useContext, useMemo } from 'react';
7
+ import { useTerminalSize } from '../hooks/useTerminalSize.js';
8
+
9
+ /**
10
+ * Context for terminal dimensions
11
+ */
12
+ const TerminalContext = createContext(null);
13
+
14
+ /**
15
+ * Default terminal values for SSR/testing or when outside provider
16
+ */
17
+ const DEFAULT_TERMINAL = {
18
+ columns: 80,
19
+ rows: 24,
20
+ isNarrow: false,
21
+ isMedium: true,
22
+ isWide: false,
23
+ isExtraWide: false,
24
+ contentWidth: 76,
25
+ textWidth: 76,
26
+ uiWidth: 50,
27
+ useCompactMode: false,
28
+ rawWidth: 80,
29
+ rawHeight: 24,
30
+ };
31
+
32
+ /**
33
+ * TerminalProvider component
34
+ * Wrap your Ink app with this to provide terminal dimensions to all children
35
+ *
36
+ * @param {object} props
37
+ * @param {React.ReactNode} props.children - Child components
38
+ * @param {object} props.options - Options to pass to useTerminalSize
39
+ */
40
+ export function TerminalProvider({ children, options = {} }) {
41
+ const terminalSize = useTerminalSize(options);
42
+
43
+ // Memoize to prevent unnecessary re-renders
44
+ const value = useMemo(() => terminalSize, [
45
+ terminalSize.columns,
46
+ terminalSize.rows,
47
+ terminalSize.contentWidth,
48
+ terminalSize.textWidth,
49
+ terminalSize.uiWidth,
50
+ ]);
51
+
52
+ return (
53
+ <TerminalContext.Provider value={value}>
54
+ {children}
55
+ </TerminalContext.Provider>
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Hook to access terminal dimensions from context
61
+ * Falls back to default values if used outside provider
62
+ *
63
+ * @returns {object} Terminal size information
64
+ */
65
+ export function useTerminal() {
66
+ const context = useContext(TerminalContext);
67
+
68
+ if (!context) {
69
+ // Fallback for usage outside provider (e.g., during testing)
70
+ // Return a sensible default that won't break rendering
71
+ return DEFAULT_TERMINAL;
72
+ }
73
+
74
+ return context;
75
+ }
76
+
77
+ /**
78
+ * Higher-order component to inject terminal dimensions as props
79
+ * Useful for class components or when you need terminal props directly
80
+ *
81
+ * @param {React.Component} Component - Component to wrap
82
+ * @returns {React.Component} Wrapped component with terminal props
83
+ */
84
+ export function withTerminal(Component) {
85
+ const WrappedComponent = (props) => {
86
+ const terminal = useTerminal();
87
+ return <Component {...props} terminal={terminal} />;
88
+ };
89
+
90
+ WrappedComponent.displayName = `withTerminal(${Component.displayName || Component.name || 'Component'})`;
91
+
92
+ return WrappedComponent;
93
+ }
94
+
95
+ /**
96
+ * Responsive component helper - renders different content based on terminal width
97
+ *
98
+ * @param {object} props
99
+ * @param {React.ReactNode} props.narrow - Content for narrow terminals (<60 cols)
100
+ * @param {React.ReactNode} props.medium - Content for medium terminals (60-100 cols)
101
+ * @param {React.ReactNode} props.wide - Content for wide terminals (>100 cols)
102
+ * @param {React.ReactNode} props.children - Default/fallback content
103
+ */
104
+ export function Responsive({ narrow, medium, wide, children }) {
105
+ const { isNarrow, isWide } = useTerminal();
106
+
107
+ if (isNarrow && narrow) return narrow;
108
+ if (isWide && wide) return wide;
109
+ if (medium) return medium;
110
+
111
+ return children || null;
112
+ }
113
+
114
+ /**
115
+ * Component that only renders when terminal is wide enough
116
+ *
117
+ * @param {object} props
118
+ * @param {number} props.minWidth - Minimum terminal width to render
119
+ * @param {React.ReactNode} props.children - Content to render
120
+ * @param {React.ReactNode} props.fallback - Fallback content for narrow terminals
121
+ */
122
+ export function WideOnly({ minWidth = 60, children, fallback = null }) {
123
+ const { columns } = useTerminal();
124
+
125
+ if (columns < minWidth) {
126
+ return fallback;
127
+ }
128
+
129
+ return children;
130
+ }
131
+
132
+ /**
133
+ * Component that shows compact version on narrow terminals
134
+ *
135
+ * @param {object} props
136
+ * @param {React.ReactNode} props.children - Full content
137
+ * @param {React.ReactNode} props.compact - Compact version
138
+ * @param {number} props.threshold - Width threshold (default: 60)
139
+ */
140
+ export function Compact({ children, compact, threshold = 60 }) {
141
+ const { columns } = useTerminal();
142
+
143
+ if (columns < threshold && compact) {
144
+ return compact;
145
+ }
146
+
147
+ return children;
148
+ }
149
+
150
+ export default TerminalContext;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Context index
3
+ * Export all context providers and hooks
4
+ */
5
+
6
+ export {
7
+ TerminalProvider,
8
+ useTerminal,
9
+ withTerminal,
10
+ Responsive,
11
+ WideOnly,
12
+ Compact,
13
+ } from './TerminalContext.jsx';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * UI hooks index
3
+ */
4
+
5
+ export { useWebSocket, ConnectionState } from './useWebSocket.js';
6
+ export { useChatState, MessageRole, GenerationState, ToolState } from './useChatState.js';
7
+ export { useFileAttachments, FileType } from './useFileAttachments.js';
8
+ export { useCommands, parseCommand, COMMANDS, CommandAction } from './useCommands.js';
9
+ export { useKeyboardShortcuts, formatKeyCombo, DEFAULT_SHORTCUTS } from './useKeyboardShortcuts.js';
10
+ export { useNotifications, notifyGenerationComplete } from './useNotifications.js';
11
+ export {
12
+ useTerminalSize,
13
+ getTerminalWidth,
14
+ getTerminalHeight,
15
+ calculateResponsiveWidth
16
+ } from './useTerminalSize.js';