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.
- package/README.md +193 -0
- package/bin/otherwise.js +5 -0
- package/frontend/404.html +84 -0
- package/frontend/assets/OpenDyslexic3-Bold-CDyRs55Y.ttf +0 -0
- package/frontend/assets/OpenDyslexic3-Regular-CIBXa4WE.ttf +0 -0
- package/frontend/assets/__vite-browser-external-BIHI7g3E.js +1 -0
- package/frontend/assets/conversational-worker-CeKiciGk.js +2929 -0
- package/frontend/assets/dictation-worker-D0aYfq8b.js +29 -0
- package/frontend/assets/gemini-color-CgSQmmva.png +0 -0
- package/frontend/assets/index-BLux5ps4.js +21 -0
- package/frontend/assets/index-Blh8_TEM.js +5272 -0
- package/frontend/assets/index-BpQ1PuKu.js +18 -0
- package/frontend/assets/index-Df737c8w.css +1 -0
- package/frontend/assets/index-xaYHL6wb.js +113 -0
- package/frontend/assets/ort-wasm-simd-threaded.asyncify-BynIiDiv.wasm +0 -0
- package/frontend/assets/ort-wasm-simd-threaded.jsep-B0T3yYHD.wasm +0 -0
- package/frontend/assets/transformers-tULNc5V3.js +31 -0
- package/frontend/assets/tts-worker-DPJWqT7N.js +2899 -0
- package/frontend/assets/voice-mode-worker-GzvIE_uh.js +2927 -0
- package/frontend/assets/worker-2d5ABSLU.js +31 -0
- package/frontend/banner.png +0 -0
- package/frontend/favicon.svg +3 -0
- package/frontend/google55e5ec47ee14a5f8.html +1 -0
- package/frontend/index.html +234 -0
- package/frontend/manifest.json +17 -0
- package/frontend/pdf.worker.min.mjs +21 -0
- package/frontend/robots.txt +5 -0
- package/frontend/sitemap.xml +27 -0
- package/package.json +81 -0
- package/src/agent/index.js +1066 -0
- package/src/agent/location.js +51 -0
- package/src/agent/prompt.js +548 -0
- package/src/agent/tools.js +4372 -0
- package/src/browser/detect.js +68 -0
- package/src/browser/session.js +1109 -0
- package/src/config.js +137 -0
- package/src/email/client.js +503 -0
- package/src/index.js +557 -0
- package/src/inference/anthropic.js +113 -0
- package/src/inference/google.js +373 -0
- package/src/inference/index.js +81 -0
- package/src/inference/ollama.js +383 -0
- package/src/inference/openai.js +140 -0
- package/src/inference/openrouter.js +378 -0
- package/src/inference/xai.js +200 -0
- package/src/logBridge.js +9 -0
- package/src/models.js +146 -0
- package/src/remote/client.js +225 -0
- package/src/scheduler/cron.js +243 -0
- package/src/server.js +3876 -0
- package/src/storage/db.js +1135 -0
- package/src/storage/supabase.js +364 -0
- package/src/tunnel/cloudflare.js +241 -0
- package/src/ui/components/App.jsx +687 -0
- package/src/ui/components/BrowserSelect.jsx +111 -0
- package/src/ui/components/FilePicker.jsx +472 -0
- package/src/ui/components/Header.jsx +444 -0
- package/src/ui/components/HelpPanel.jsx +173 -0
- package/src/ui/components/HistoryPanel.jsx +158 -0
- package/src/ui/components/MessageList.jsx +235 -0
- package/src/ui/components/ModelSelector.jsx +304 -0
- package/src/ui/components/PromptInput.jsx +515 -0
- package/src/ui/components/StreamingResponse.jsx +134 -0
- package/src/ui/components/ThinkingIndicator.jsx +365 -0
- package/src/ui/components/ToolExecution.jsx +714 -0
- package/src/ui/components/index.js +82 -0
- package/src/ui/context/TerminalContext.jsx +150 -0
- package/src/ui/context/index.js +13 -0
- package/src/ui/hooks/index.js +16 -0
- package/src/ui/hooks/useChatState.js +675 -0
- package/src/ui/hooks/useCommands.js +280 -0
- package/src/ui/hooks/useFileAttachments.js +216 -0
- package/src/ui/hooks/useKeyboardShortcuts.js +173 -0
- package/src/ui/hooks/useNotifications.js +185 -0
- package/src/ui/hooks/useTerminalSize.js +151 -0
- package/src/ui/hooks/useWebSocket.js +273 -0
- package/src/ui/index.js +94 -0
- package/src/ui/ink-runner.js +22 -0
- package/src/ui/utils/formatters.js +424 -0
- package/src/ui/utils/index.js +6 -0
- package/src/ui/utils/markdown.js +166 -0
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
google-site-verification: google55e5ec47ee14a5f8.html
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta
|
|
6
|
+
name="viewport"
|
|
7
|
+
content="width=device-width, initial-scale=1.0, interactive-widget=resizes-content, viewport-fit=cover"
|
|
8
|
+
/>
|
|
9
|
+
|
|
10
|
+
<!-- Primary Meta Tags -->
|
|
11
|
+
<title>Otherwise</title>
|
|
12
|
+
<meta
|
|
13
|
+
name="title"
|
|
14
|
+
content="Otherwise | Local AI Models, ChatGPT, Claude & Gemini"
|
|
15
|
+
/>
|
|
16
|
+
<meta
|
|
17
|
+
name="description"
|
|
18
|
+
content="Chat with AI models privately in your browser. Otherwise runs local AI models via WebGPU and supports ChatGPT, Claude, Gemini, Grok. No data leaves your device."
|
|
19
|
+
/>
|
|
20
|
+
<meta
|
|
21
|
+
name="keywords"
|
|
22
|
+
content="AI chatbot, local AI, WebGPU, private AI, ChatGPT alternative, Claude AI, Gemini AI, free AI chat, transformers.js"
|
|
23
|
+
/>
|
|
24
|
+
<meta name="author" content="Otherwise" />
|
|
25
|
+
<meta name="robots" content="index, follow" />
|
|
26
|
+
|
|
27
|
+
<!-- Favicon -->
|
|
28
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
29
|
+
<link rel="alternate icon" href="/favicon.ico" />
|
|
30
|
+
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
31
|
+
|
|
32
|
+
<!-- Open Graph / Facebook -->
|
|
33
|
+
<meta property="og:type" content="website" />
|
|
34
|
+
<meta property="og:url" content="https://otherwise.app/" />
|
|
35
|
+
<meta
|
|
36
|
+
property="og:title"
|
|
37
|
+
content="Otherwise | Local AI Models, ChatGPT, Claude & Gemini"
|
|
38
|
+
/>
|
|
39
|
+
<meta
|
|
40
|
+
property="og:description"
|
|
41
|
+
content="Chat with AI models privately in your browser. Runs local AI models via WebGPU and supports OpenAI, Claude, Gemini, Grok."
|
|
42
|
+
/>
|
|
43
|
+
<meta property="og:image" content="https://otherwise.app/banner.png" />
|
|
44
|
+
<meta property="og:site_name" content="Otherwise" />
|
|
45
|
+
|
|
46
|
+
<!-- Twitter Card -->
|
|
47
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
48
|
+
<meta name="twitter:url" content="https://otherwise.app/" />
|
|
49
|
+
<meta
|
|
50
|
+
name="twitter:title"
|
|
51
|
+
content="Otherwise | Local AI Models, ChatGPT, Claude & Gemini"
|
|
52
|
+
/>
|
|
53
|
+
<meta
|
|
54
|
+
name="twitter:description"
|
|
55
|
+
content="Chat with AI models privately in your browser. Runs local AI models via WebGPU and supports OpenAI, Claude, Gemini, Grok."
|
|
56
|
+
/>
|
|
57
|
+
<meta name="twitter:image" content="https://otherwise.app/banner.png" />
|
|
58
|
+
|
|
59
|
+
<!-- Theme Colors -->
|
|
60
|
+
<meta
|
|
61
|
+
name="theme-color"
|
|
62
|
+
content="#111827"
|
|
63
|
+
media="(prefers-color-scheme: dark)"
|
|
64
|
+
/>
|
|
65
|
+
<meta
|
|
66
|
+
name="theme-color"
|
|
67
|
+
content="#ffffff"
|
|
68
|
+
media="(prefers-color-scheme: light)"
|
|
69
|
+
/>
|
|
70
|
+
|
|
71
|
+
<!-- PWA Manifest -->
|
|
72
|
+
<link rel="manifest" href="/manifest.json" />
|
|
73
|
+
|
|
74
|
+
<!-- Canonical URL -->
|
|
75
|
+
<link rel="canonical" href="https://otherwise.app/" />
|
|
76
|
+
|
|
77
|
+
<!-- Google Fonts -->
|
|
78
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
79
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
80
|
+
<link
|
|
81
|
+
href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Playfair+Display:ital,wght@0,400..900;1,400..900&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap"
|
|
82
|
+
rel="stylesheet"
|
|
83
|
+
/>
|
|
84
|
+
|
|
85
|
+
<!-- Structured Data -->
|
|
86
|
+
<script type="application/ld+json">
|
|
87
|
+
{
|
|
88
|
+
"@context": "https://schema.org",
|
|
89
|
+
"@type": "WebApplication",
|
|
90
|
+
"name": "Otherwise",
|
|
91
|
+
"url": "https://otherwise.app",
|
|
92
|
+
"description": "A private and powerful AI chatbot that runs locally in your browser",
|
|
93
|
+
"applicationCategory": "UtilitiesApplication",
|
|
94
|
+
"operatingSystem": "Any",
|
|
95
|
+
"offers": {
|
|
96
|
+
"@type": "Offer",
|
|
97
|
+
"price": "0",
|
|
98
|
+
"priceCurrency": "USD"
|
|
99
|
+
},
|
|
100
|
+
"featureList": [
|
|
101
|
+
"ChatGPT integration",
|
|
102
|
+
"Claude AI integration",
|
|
103
|
+
"Gemini AI integration",
|
|
104
|
+
"Local AI models via WebGPU",
|
|
105
|
+
"Voice conversations",
|
|
106
|
+
"AI music generation"
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
</script>
|
|
110
|
+
<script type="module" crossorigin src="/assets/index-Blh8_TEM.js"></script>
|
|
111
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Df737c8w.css">
|
|
112
|
+
</head>
|
|
113
|
+
|
|
114
|
+
<body class="bg-gray-50 dark:bg-gray-900">
|
|
115
|
+
<div id="root"></div>
|
|
116
|
+
|
|
117
|
+
<!-- Apply theme and font preferences before React loads to prevent flash -->
|
|
118
|
+
<script>
|
|
119
|
+
(function () {
|
|
120
|
+
// Apply theme mode
|
|
121
|
+
var themeMode = localStorage.getItem('themeMode');
|
|
122
|
+
// Migrate from old darkMode boolean if it exists
|
|
123
|
+
if (themeMode === null) {
|
|
124
|
+
var oldDarkMode = localStorage.getItem('darkMode');
|
|
125
|
+
if (oldDarkMode !== null) {
|
|
126
|
+
themeMode = JSON.parse(oldDarkMode) ? 'dark' : 'light';
|
|
127
|
+
localStorage.removeItem('darkMode');
|
|
128
|
+
localStorage.setItem('themeMode', themeMode);
|
|
129
|
+
} else {
|
|
130
|
+
themeMode = 'system'; // Default to system mode
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
var isDark;
|
|
135
|
+
if (themeMode === 'system') {
|
|
136
|
+
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
137
|
+
} else {
|
|
138
|
+
isDark = themeMode === 'dark';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (isDark) {
|
|
142
|
+
document.documentElement.classList.add('dark');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Apply font family
|
|
146
|
+
var fontFamily = localStorage.getItem('fontFamily');
|
|
147
|
+
if (fontFamily === 'roboto') {
|
|
148
|
+
document.documentElement.classList.add('font-roboto');
|
|
149
|
+
} else if (fontFamily === 'playfair') {
|
|
150
|
+
document.documentElement.classList.add('font-playfair');
|
|
151
|
+
} else if (fontFamily === 'opensans') {
|
|
152
|
+
document.documentElement.classList.add('font-opensans');
|
|
153
|
+
}
|
|
154
|
+
})();
|
|
155
|
+
</script>
|
|
156
|
+
|
|
157
|
+
<!-- Suppress MathJax loader "No version information available" for [tex]/ams, newcommand, noundefined -->
|
|
158
|
+
<script>
|
|
159
|
+
(function () {
|
|
160
|
+
var orig = console.warn;
|
|
161
|
+
console.warn = function () {
|
|
162
|
+
if (arguments[0] && typeof arguments[0] === 'string' && arguments[0].indexOf('No version information available') !== -1) return;
|
|
163
|
+
orig.apply(console, arguments);
|
|
164
|
+
};
|
|
165
|
+
})();
|
|
166
|
+
</script>
|
|
167
|
+
<script>
|
|
168
|
+
window.MathJax = {
|
|
169
|
+
startup: {
|
|
170
|
+
typeset: false, // Prevent initial typeset
|
|
171
|
+
ready: () => {
|
|
172
|
+
MathJax.startup.defaultReady();
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
loader: {
|
|
176
|
+
// Suppress version warnings for dynamically loaded components
|
|
177
|
+
source: {},
|
|
178
|
+
require: (url) => {
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
const script = document.createElement('script');
|
|
181
|
+
script.src = url;
|
|
182
|
+
script.onload = resolve;
|
|
183
|
+
script.onerror = reject;
|
|
184
|
+
document.head.appendChild(script);
|
|
185
|
+
});
|
|
186
|
+
},
|
|
187
|
+
load: [
|
|
188
|
+
'[tex]/ams',
|
|
189
|
+
'[tex]/newcommand',
|
|
190
|
+
'[tex]/noundefined',
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
tex: {
|
|
194
|
+
// NOTE: Single $ delimiters removed to prevent currency symbols from
|
|
195
|
+
// being interpreted as math (e.g., "$89,412" triggering math mode).
|
|
196
|
+
// Use \(...\) for inline math instead.
|
|
197
|
+
inlineMath: [
|
|
198
|
+
['\\(', '\\)'],
|
|
199
|
+
],
|
|
200
|
+
displayMath: [
|
|
201
|
+
['$$', '$$'],
|
|
202
|
+
['\\[', '\\]'],
|
|
203
|
+
],
|
|
204
|
+
packages: {
|
|
205
|
+
'[+]': [
|
|
206
|
+
'ams',
|
|
207
|
+
'newcommand',
|
|
208
|
+
'noundefined',
|
|
209
|
+
],
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
svg: {
|
|
213
|
+
fontCache: 'global',
|
|
214
|
+
},
|
|
215
|
+
options: {
|
|
216
|
+
enableMenu: false, // Disable right-click menu
|
|
217
|
+
ignoreHtmlClass: 'mathjax_ignore', // Ignore elements with this class
|
|
218
|
+
renderActions: {
|
|
219
|
+
// Handle any errors gracefully
|
|
220
|
+
assistiveMml: [],
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
</script>
|
|
225
|
+
<script
|
|
226
|
+
id="MathJax-script"
|
|
227
|
+
async
|
|
228
|
+
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"
|
|
229
|
+
></script>
|
|
230
|
+
<!-- Skulpt scripts -->
|
|
231
|
+
<script src="https://cdn.jsdelivr.net/npm/skulpt@1.2.0/dist/skulpt.min.js"></script>
|
|
232
|
+
<script src="https://cdn.jsdelivr.net/npm/skulpt@1.2.0/dist/skulpt-stdlib.js"></script>
|
|
233
|
+
</body>
|
|
234
|
+
</html>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Otherwise - AI Chatbot",
|
|
3
|
+
"short_name": "Otherwise",
|
|
4
|
+
"description": "Chat with AI models privately in your browser. Supports ChatGPT, Claude, Gemini, and local AI models.",
|
|
5
|
+
"start_url": "/",
|
|
6
|
+
"display": "standalone",
|
|
7
|
+
"background_color": "#111827",
|
|
8
|
+
"theme_color": "#111827",
|
|
9
|
+
"orientation": "portrait-primary",
|
|
10
|
+
"icons": [
|
|
11
|
+
{
|
|
12
|
+
"src": "/favicon.svg",
|
|
13
|
+
"sizes": "any",
|
|
14
|
+
"type": "image/svg+xml"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|