@bibobonking/opensol 0.0.0-stage → 3.0.2

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 (127) hide show
  1. package/.github/workflows/build.yml +25 -0
  2. package/README.md +74 -2
  3. package/dist/assets/index-BmN7pBji.css +1 -0
  4. package/dist/assets/index-DgNDjkOz.js +301 -0
  5. package/dist/favicon.svg +15 -0
  6. package/dist/index.html +55 -0
  7. package/dist/preview-host.html +33 -0
  8. package/index.html +54 -0
  9. package/package.json +43 -4
  10. package/postcss.config.js +6 -0
  11. package/public/favicon.svg +15 -0
  12. package/public/preview-host.html +33 -0
  13. package/server/README.md +75 -0
  14. package/server/daemon.mjs +1082 -0
  15. package/server/lib/checkpoints.mjs +124 -0
  16. package/server/lib/checkpoints.test.mjs +110 -0
  17. package/server/lib/deploy.mjs +436 -0
  18. package/server/lib/http.mjs +237 -0
  19. package/server/lib/plugins.mjs +321 -0
  20. package/server/lib/plugins.test.mjs +140 -0
  21. package/server/lib/providers.mjs +594 -0
  22. package/server/lib/store.mjs +491 -0
  23. package/server/lib/tools.mjs +990 -0
  24. package/server/opensol.mjs +202 -0
  25. package/server/package.json +42 -0
  26. package/shared/plugin-builder.test.mjs +43 -0
  27. package/shared/plugin-package.d.mts +34 -0
  28. package/shared/plugin-package.mjs +197 -0
  29. package/shared/plugin-package.test.mjs +94 -0
  30. package/src/App.tsx +152 -0
  31. package/src/agent/adapters/anthropic.ts +233 -0
  32. package/src/agent/adapters/gemini.ts +225 -0
  33. package/src/agent/adapters/openai-responses.ts +215 -0
  34. package/src/agent/adapters/openai.ts +200 -0
  35. package/src/agent/adapters/shared.ts +96 -0
  36. package/src/agent/approval.ts +20 -0
  37. package/src/agent/compact.ts +234 -0
  38. package/src/agent/index.ts +36 -0
  39. package/src/agent/model.ts +20 -0
  40. package/src/agent/prompt.ts +107 -0
  41. package/src/agent/queue.test.mjs +111 -0
  42. package/src/agent/queue.ts +84 -0
  43. package/src/agent/subagent.ts +109 -0
  44. package/src/agent/tools.ts +541 -0
  45. package/src/components/ChatView.tsx +403 -0
  46. package/src/components/CommandPalette.tsx +416 -0
  47. package/src/components/Composer.tsx +678 -0
  48. package/src/components/ContextBar.tsx +58 -0
  49. package/src/components/DeployModal.tsx +512 -0
  50. package/src/components/ErrorBoundary.tsx +75 -0
  51. package/src/components/HomeDashboard.tsx +189 -0
  52. package/src/components/Logo.tsx +41 -0
  53. package/src/components/Markdown.tsx +232 -0
  54. package/src/components/MessageItem.tsx +655 -0
  55. package/src/components/ModelPicker.tsx +487 -0
  56. package/src/components/PixleSol.tsx +243 -0
  57. package/src/components/PluginBuilder.tsx +285 -0
  58. package/src/components/PluginManager.tsx +341 -0
  59. package/src/components/PreviewPane.tsx +166 -0
  60. package/src/components/SettingsModal.tsx +2052 -0
  61. package/src/components/Sidebar.tsx +504 -0
  62. package/src/components/Splash.tsx +104 -0
  63. package/src/components/ToolCallCard.tsx +177 -0
  64. package/src/components/TopBar.tsx +182 -0
  65. package/src/components/TrajectoryView.tsx +178 -0
  66. package/src/components/WorkspacePanel.tsx +710 -0
  67. package/src/components/ui.tsx +311 -0
  68. package/src/core/kernel.ts +45 -0
  69. package/src/core/plugins/tools/fs.ts +219 -0
  70. package/src/core/plugins/tools/git.ts +83 -0
  71. package/src/core/plugins/tools/grep.ts +98 -0
  72. package/src/core/plugins/tools/shell.ts +88 -0
  73. package/src/core/plugins/tools/subagent.ts +36 -0
  74. package/src/core/plugins/tools/web.ts +97 -0
  75. package/src/core/services/agent-loop.ts +417 -0
  76. package/src/core/services/approval.ts +66 -0
  77. package/src/core/services/compaction.ts +45 -0
  78. package/src/core/services/llm.ts +32 -0
  79. package/src/core/services/sessions.ts +47 -0
  80. package/src/core/services/subagents.ts +15 -0
  81. package/src/core/services/system-prompt.ts +177 -0
  82. package/src/core/services/tools.ts +135 -0
  83. package/src/core/services/ui.ts +109 -0
  84. package/src/core/types.ts +139 -0
  85. package/src/data/providers.ts +125 -0
  86. package/src/data/skills.ts +68 -0
  87. package/src/index.css +776 -0
  88. package/src/lib/boot.ts +94 -0
  89. package/src/lib/context.ts +75 -0
  90. package/src/lib/conversation.test.mjs +64 -0
  91. package/src/lib/conversation.ts +59 -0
  92. package/src/lib/daemon.ts +475 -0
  93. package/src/lib/hooks.ts +33 -0
  94. package/src/lib/permissions.ts +60 -0
  95. package/src/lib/pixlesol.test.mjs +51 -0
  96. package/src/lib/pixlesol.ts +55 -0
  97. package/src/lib/plugin-folder.test.mjs +145 -0
  98. package/src/lib/plugin-folder.ts +96 -0
  99. package/src/lib/reasoning.ts +87 -0
  100. package/src/lib/sse.ts +75 -0
  101. package/src/lib/themes.test.mjs +72 -0
  102. package/src/lib/themes.ts +52 -0
  103. package/src/lib/usage.test.mjs +72 -0
  104. package/src/lib/usage.ts +155 -0
  105. package/src/lib/utils.ts +73 -0
  106. package/src/main.tsx +16 -0
  107. package/src/plugins/api.test.mjs +77 -0
  108. package/src/plugins/api.ts +113 -0
  109. package/src/plugins/bridge.d.mts +1 -0
  110. package/src/plugins/bridge.mjs +26 -0
  111. package/src/plugins/bridge.test.mjs +17 -0
  112. package/src/plugins/index.ts +52 -0
  113. package/src/plugins/preview.test.mjs +18 -0
  114. package/src/plugins/preview.ts +34 -0
  115. package/src/plugins/runtime.ts +194 -0
  116. package/src/plugins/types.ts +40 -0
  117. package/src/store/chats.ts +278 -0
  118. package/src/store/models.ts +120 -0
  119. package/src/store/settings.ts +445 -0
  120. package/src/store/ui.ts +132 -0
  121. package/src/store/workspace.ts +299 -0
  122. package/src/types.ts +337 -0
  123. package/src/vite-env.d.ts +1 -0
  124. package/tailwind.config.js +83 -0
  125. package/tsconfig.json +22 -0
  126. package/tsconfig.tsbuildinfo +1 -0
  127. package/vite.config.ts +19 -0
@@ -0,0 +1,15 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
2
+ <defs>
3
+ <radialGradient id="g" cx="32" cy="30" r="22" gradientUnits="userSpaceOnUse">
4
+ <stop offset="0" stop-color="#ffd25a"/>
5
+ <stop offset="1" stop-color="#f59e0b"/>
6
+ </radialGradient>
7
+ </defs>
8
+ <rect width="64" height="64" rx="16" fill="#141413"/>
9
+ <rect x=".75" y=".75" width="62.5" height="62.5" rx="15.25" stroke="#fff" stroke-opacity=".08" stroke-width="1.5"/>
10
+ <circle cx="32" cy="32" r="11" fill="url(#g)"/>
11
+ <g stroke="#f59e0b" stroke-width="4" stroke-linecap="round">
12
+ <path d="M32 9v6M32 49v6M9 32h6M49 32h6"/>
13
+ <path d="M15.7 15.7l4.2 4.2M44.1 44.1l4.2 4.2M15.7 48.3l4.2-4.2M44.1 19.9l4.2-4.2" opacity=".55"/>
14
+ </g>
15
+ </svg>
@@ -0,0 +1,55 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <meta name="theme-color" content="#ffffff" />
7
+ <meta
8
+ name="description"
9
+ content="OpenSol by OpenSoft is a local-first coding agent. Work in a real folder, run commands, edit files and deploy with your own model keys. Keys stay encrypted on your machine."
10
+ />
11
+ <title>OpenSol — Local coding agent by OpenSoft</title>
12
+ <link rel="icon" type="image/svg+xml" href="./favicon.svg" />
13
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
14
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
15
+ <link
16
+ href="https://fonts.googleapis.com/css2?family=Geist:wght@300..700&family=Geist+Mono:wght@400..600&display=swap"
17
+ rel="stylesheet"
18
+ />
19
+ <script>
20
+ try {
21
+ const NAMED = ['light', 'dark', 'night-owl', 'claude-code', 'flame']
22
+ const DARK = ['dark', 'night-owl', 'claude-code', 'flame']
23
+ const stored = localStorage.getItem('opensol.theme') || localStorage.getItem('maxcode.theme')
24
+ const theme = NAMED.includes(stored)
25
+ ? stored
26
+ : window.matchMedia('(prefers-color-scheme: dark)').matches
27
+ ? 'dark'
28
+ : 'light'
29
+ const root = document.documentElement
30
+ root.dataset.theme = theme
31
+ if (DARK.includes(theme)) root.classList.add('dark')
32
+ } catch {}
33
+ </script>
34
+ <script type="module" crossorigin src="./assets/index-DgNDjkOz.js"></script>
35
+ <link rel="stylesheet" crossorigin href="./assets/index-BmN7pBji.css">
36
+ </head>
37
+ <body>
38
+ <div id="root"><div class="splash" id="boot-splash" aria-hidden="true">
39
+ <style>
40
+ .splash{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgb(var(--panel))}
41
+ .bs{display:flex;flex-direction:column;align-items:center;gap:18px}
42
+ .bs svg{color:rgb(var(--accent))}
43
+ .bs-word{font:600 22px/1 Geist,Inter,system-ui,sans-serif;letter-spacing:-.03em;color:rgb(var(--ink))}
44
+ .bs-bar{width:120px;height:2px;border-radius:2px;background:rgb(var(--line));overflow:hidden;position:relative}
45
+ .bs-bar::after{content:"";position:absolute;inset:0;width:40%;background:linear-gradient(90deg,transparent,rgb(var(--accent)),transparent);animation:bs-sweep 1.4s cubic-bezier(.65,0,.35,1) infinite}
46
+ @keyframes bs-sweep{0%{transform:translateX(-100%)}100%{transform:translateX(250%)}}
47
+ </style>
48
+ <div class="bs">
49
+ <svg viewBox="0 0 64 64" width="56" height="56" fill="none"><circle cx="32" cy="32" r="12" fill="currentColor"/><g stroke="currentColor" stroke-width="4.4" stroke-linecap="round"><path d="M32 7v7M32 50v7M7 32h7M50 32h7"/><path d="M14.3 14.3l5 5M44.7 44.7l5 5M14.3 49.7l5-5M44.7 19.3l5-5" opacity=".55"/></g></svg>
50
+ <div class="bs-word">OpenSol</div>
51
+ <div class="bs-bar"></div>
52
+ </div>
53
+ </div></div>
54
+ </body>
55
+ </html>
@@ -0,0 +1,33 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>OpenSol preview</title>
7
+ <style>
8
+ html,
9
+ body {
10
+ margin: 0;
11
+ height: 100%;
12
+ background: #fff;
13
+ color: #1f1f1d;
14
+ font: 13px/1.5 system-ui, sans-serif;
15
+ }
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <script>
20
+ // Hosts model-written HTML inside a sandboxed frame (no same-origin access). The parent
21
+ // posts the document once this page reports it is ready.
22
+ window.addEventListener('message', function (event) {
23
+ if (event.source !== window.parent) return
24
+ var data = event.data
25
+ if (!data || data.type !== 'maxcode-preview' || typeof data.html !== 'string') return
26
+ document.open()
27
+ document.write(data.html)
28
+ document.close()
29
+ })
30
+ window.parent.postMessage({ type: 'maxcode-preview-ready' }, '*')
31
+ </script>
32
+ </body>
33
+ </html>
package/index.html ADDED
@@ -0,0 +1,54 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <meta name="theme-color" content="#ffffff" />
7
+ <meta
8
+ name="description"
9
+ content="OpenSol by OpenSoft is a local-first coding agent. Work in a real folder, run commands, edit files and deploy with your own model keys. Keys stay encrypted on your machine."
10
+ />
11
+ <title>OpenSol — Local coding agent by OpenSoft</title>
12
+ <link rel="icon" type="image/svg+xml" href="./favicon.svg" />
13
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
14
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
15
+ <link
16
+ href="https://fonts.googleapis.com/css2?family=Geist:wght@300..700&family=Geist+Mono:wght@400..600&display=swap"
17
+ rel="stylesheet"
18
+ />
19
+ <script>
20
+ try {
21
+ const NAMED = ['light', 'dark', 'night-owl', 'claude-code', 'flame']
22
+ const DARK = ['dark', 'night-owl', 'claude-code', 'flame']
23
+ const stored = localStorage.getItem('opensol.theme') || localStorage.getItem('maxcode.theme')
24
+ const theme = NAMED.includes(stored)
25
+ ? stored
26
+ : window.matchMedia('(prefers-color-scheme: dark)').matches
27
+ ? 'dark'
28
+ : 'light'
29
+ const root = document.documentElement
30
+ root.dataset.theme = theme
31
+ if (DARK.includes(theme)) root.classList.add('dark')
32
+ } catch {}
33
+ </script>
34
+ </head>
35
+ <body>
36
+ <div id="root"><div class="splash" id="boot-splash" aria-hidden="true">
37
+ <style>
38
+ .splash{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgb(var(--panel))}
39
+ .bs{display:flex;flex-direction:column;align-items:center;gap:18px}
40
+ .bs svg{color:rgb(var(--accent))}
41
+ .bs-word{font:600 22px/1 Geist,Inter,system-ui,sans-serif;letter-spacing:-.03em;color:rgb(var(--ink))}
42
+ .bs-bar{width:120px;height:2px;border-radius:2px;background:rgb(var(--line));overflow:hidden;position:relative}
43
+ .bs-bar::after{content:"";position:absolute;inset:0;width:40%;background:linear-gradient(90deg,transparent,rgb(var(--accent)),transparent);animation:bs-sweep 1.4s cubic-bezier(.65,0,.35,1) infinite}
44
+ @keyframes bs-sweep{0%{transform:translateX(-100%)}100%{transform:translateX(250%)}}
45
+ </style>
46
+ <div class="bs">
47
+ <svg viewBox="0 0 64 64" width="56" height="56" fill="none"><circle cx="32" cy="32" r="12" fill="currentColor"/><g stroke="currentColor" stroke-width="4.4" stroke-linecap="round"><path d="M32 7v7M32 50v7M7 32h7M50 32h7"/><path d="M14.3 14.3l5 5M44.7 44.7l5 5M14.3 49.7l5-5M44.7 19.3l5-5" opacity=".55"/></g></svg>
48
+ <div class="bs-word">OpenSol</div>
49
+ <div class="bs-bar"></div>
50
+ </div>
51
+ </div></div>
52
+ <script type="module" src="/src/main.tsx"></script>
53
+ </body>
54
+ </html>
package/package.json CHANGED
@@ -1,6 +1,45 @@
1
1
  {
2
2
  "name": "@bibobonking/opensol",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "private": false,
4
+ "version": "3.0.2",
5
+ "type": "module",
6
+ "bin": {
7
+ "opensol": "./server/opensol.mjs"
8
+ },
9
+ "scripts": {
10
+ "dev": "node server/opensol.mjs start && vite",
11
+ "build": "tsc -b && vite build",
12
+ "preview": "vite preview",
13
+ "typecheck": "tsc -b --pretty",
14
+ "test": "node --test",
15
+ "start": "node server/opensol.mjs start --open",
16
+ "daemon": "node server/opensol.mjs start",
17
+ "daemon:foreground": "node server/daemon.mjs",
18
+ "daemon:stop": "node server/opensol.mjs stop",
19
+ "daemon:status": "node server/opensol.mjs status",
20
+ "daemon:logs": "node server/opensol.mjs logs"
21
+ },
22
+ "dependencies": {
23
+ "clsx": "^2.1.1",
24
+ "cordis": "^4.0.0-rc.12",
25
+ "fflate": "^0.8.2",
26
+ "highlight.js": "^11.11.1",
27
+ "lucide-react": "^0.544.0",
28
+ "react": "^19.1.1",
29
+ "react-dom": "^19.1.1",
30
+ "react-markdown": "^10.1.0",
31
+ "rehype-highlight": "^7.0.2",
32
+ "remark-gfm": "^4.0.1",
33
+ "zustand": "^5.0.8"
34
+ },
35
+ "devDependencies": {
36
+ "@types/react": "^19.1.10",
37
+ "@types/react-dom": "^19.1.7",
38
+ "@vitejs/plugin-react": "^5.0.0",
39
+ "autoprefixer": "^10.4.21",
40
+ "postcss": "^8.5.6",
41
+ "tailwindcss": "^3.4.19",
42
+ "typescript": "^5.9.2",
43
+ "vite": "^7.1.3"
44
+ }
45
+ }
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
@@ -0,0 +1,15 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
2
+ <defs>
3
+ <radialGradient id="g" cx="32" cy="30" r="22" gradientUnits="userSpaceOnUse">
4
+ <stop offset="0" stop-color="#ffd25a"/>
5
+ <stop offset="1" stop-color="#f59e0b"/>
6
+ </radialGradient>
7
+ </defs>
8
+ <rect width="64" height="64" rx="16" fill="#141413"/>
9
+ <rect x=".75" y=".75" width="62.5" height="62.5" rx="15.25" stroke="#fff" stroke-opacity=".08" stroke-width="1.5"/>
10
+ <circle cx="32" cy="32" r="11" fill="url(#g)"/>
11
+ <g stroke="#f59e0b" stroke-width="4" stroke-linecap="round">
12
+ <path d="M32 9v6M32 49v6M9 32h6M49 32h6"/>
13
+ <path d="M15.7 15.7l4.2 4.2M44.1 44.1l4.2 4.2M15.7 48.3l4.2-4.2M44.1 19.9l4.2-4.2" opacity=".55"/>
14
+ </g>
15
+ </svg>
@@ -0,0 +1,33 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>OpenSol preview</title>
7
+ <style>
8
+ html,
9
+ body {
10
+ margin: 0;
11
+ height: 100%;
12
+ background: #fff;
13
+ color: #1f1f1d;
14
+ font: 13px/1.5 system-ui, sans-serif;
15
+ }
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <script>
20
+ // Hosts model-written HTML inside a sandboxed frame (no same-origin access). The parent
21
+ // posts the document once this page reports it is ready.
22
+ window.addEventListener('message', function (event) {
23
+ if (event.source !== window.parent) return
24
+ var data = event.data
25
+ if (!data || data.type !== 'maxcode-preview' || typeof data.html !== 'string') return
26
+ document.open()
27
+ document.write(data.html)
28
+ document.close()
29
+ })
30
+ window.parent.postMessage({ type: 'maxcode-preview-ready' }, '*')
31
+ </script>
32
+ </body>
33
+ </html>
@@ -0,0 +1,75 @@
1
+ # OpenSol
2
+
3
+ A local-first AI coding agent by OpenSoft. OpenSol pairs a warm React chat interface with a zero-dependency Node daemon that owns the real workspace, shell, git, search, deploy and provider credentials on your machine.
4
+
5
+ The daemon binds to `127.0.0.1` only. It serves the prebuilt app from `dist/` and stores everything under `~/.maxcode`. API keys and hosting tokens are encrypted with AES-256-GCM using a local `master.key`; the browser only ever receives a masked hint.
6
+
7
+ ## Run the built app
8
+
9
+ Requires Node.js 20 or newer. No `npm install` is needed to run the built app.
10
+
11
+ ```bash
12
+ npm start
13
+ ```
14
+
15
+ `npm start` launches the daemon in the background and opens `http://127.0.0.1:4174`. Equivalent commands:
16
+
17
+ ```bash
18
+ node server/opensol.mjs start --open
19
+ node server/opensol.mjs status
20
+ node server/opensol.mjs logs
21
+ node server/opensol.mjs stop
22
+ ```
23
+
24
+ On first launch, choose a real project folder, then add a provider key in **Settings → Models** and pick a live model. Everything else — workspace tree, editor, git, search, build/plan modes, subagents and deploys — runs through the local daemon.
25
+
26
+ ## What is in the app
27
+
28
+ - **Build and Plan modes.** Build can edit files and run commands; Plan is read-only investigation.
29
+ - **Live models and reasoning.** Model lists come from each provider; the models.dev catalog is only a fallback. Thinking is the provider's job: an effort control appears only when the selected model advertises effort levels or a token budget, and it is sent automatically.
30
+ - **Themes.** Light, Dark, Night Owl, Claude Code and Flame, plus System, which follows the OS preference. Syntax highlighting follows the theme.
31
+ - **Real tools.** Read/write/edit files, grep, list files, shell, git, web search, URL reading and a read-only SubAgent. Each user turn renders as one answer, with consecutive tool rounds collapsed into a single “Used N tools” group.
32
+ - **Turn queue.** A prompt sent while a turn is streaming waits its turn and runs next, instead of splitting into a second reply.
33
+ - **Local plugins.** Two plugin modes:
34
+ - **API v1 (sandboxed):** Install a package, review its declared workspace capabilities and HTTPS domains, preview in a sandbox, mark it Safe. Plugin code gets a restricted API (`registerCommand`, `registerPanel`, `registerTheme`, workspace read/write, HTTPS-only network to declared hosts).
35
+ - **API v2 (free):** Plugin receives the full Cordis kernel context — register custom AI tools, hook into `agent/request` / `tools/execute` / `system-prompt/assemble` events, patch any app behaviour at runtime. No capability declarations needed. When removed, the Cordis fiber disposes automatically and the app returns to its original state — no source files are ever modified.
36
+ The same panel builds a package from a folder you pick. Packages live under `~/.maxcode/plugins`, outside the selected workspace.
37
+ - **Workspace panel.** Folder tree, file editor, git status and quick file actions.
38
+ - **Deploy.** Cloudflare Pages, Netlify and Vercel, for the open workspace or another existing folder. Tokens stay in the daemon and are passed to CLIs through environment variables.
39
+ - **Local history.** Conversations, settings, workspaces and encrypted keys survive restarts.
40
+
41
+ Slash commands include `/search`, `/plan`, `/build`, `/new`, `/workspace`, `/deploy`, `/settings` and `/clear`.
42
+
43
+ ## Development
44
+
45
+ ```bash
46
+ npm install
47
+ npm run dev # starts the daemon and Vite on http://127.0.0.1:5173
48
+ npm run build # typecheck + production build into dist/
49
+ npm run typecheck
50
+ ```
51
+
52
+ `npm run dev` proxies `/api` to the daemon on port 4174. For a production-style run, use `npm run build` followed by `npm start`.
53
+
54
+ Remote models need provider access from this machine. Local providers such as Ollama are keyless but must already be running; OpenSol reports an actionable error when they are not.
55
+
56
+ OpenCode free-tier models only work inside OpenCode itself, so they are hidden here. Paid OpenCode models work with an API key. Deploys require the matching CLI (`wrangler`, `netlify` or `vercel`) or `npx`, plus credentials in **Settings → Deploy**.
57
+
58
+ ## Data and security
59
+
60
+ - Data directory: `~/.maxcode` (override with `MAXCODE_DATA`).
61
+ - `secrets.enc` and `master.key` are created with mode `600`.
62
+ - All API routes require the local session cookie and a CSRF header; Host and Origin are checked.
63
+ - The daemon rejects code execution outside the selected workspace except for an explicit, existing deploy folder.
64
+ - No telemetry or OpenSoft-hosted proxy. Provider requests go directly from the daemon to the provider you configured.
65
+
66
+ ## Stack
67
+
68
+ TypeScript, React 19, Vite, Tailwind CSS, Zustand, direct provider adapters (OpenAI, Anthropic, Gemini, OpenCode and OpenAI-compatible endpoints), and a Node HTTP daemon with no runtime dependencies.
69
+
70
+ ```
71
+ src/ React app, stores, agent loop, adapters and tools
72
+ server/ local daemon, encrypted store, workspace tools and deploy
73
+ dist/ verified production build
74
+ public/ favicon
75
+ ```