@openchamber/web 1.0.1

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 (114) hide show
  1. package/README.md +34 -0
  2. package/bin/cli.js +561 -0
  3. package/dist/apple-touch-icon-120x120.png +0 -0
  4. package/dist/apple-touch-icon-152x152.png +0 -0
  5. package/dist/apple-touch-icon-167x167.png +0 -0
  6. package/dist/apple-touch-icon-180x180.png +0 -0
  7. package/dist/apple-touch-icon.png +0 -0
  8. package/dist/apple-touch-icon.svg +18 -0
  9. package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  10. package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  11. package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  12. package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  13. package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  14. package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  15. package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  16. package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  17. package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  18. package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  19. package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  20. package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  21. package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  22. package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  23. package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  24. package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  25. package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  26. package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  27. package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  28. package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  29. package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  30. package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  31. package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  32. package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  33. package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  34. package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  35. package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  36. package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  37. package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  38. package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  39. package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  40. package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  41. package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  42. package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  43. package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  44. package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  45. package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  46. package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  47. package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  48. package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  49. package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  50. package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  51. package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  52. package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  53. package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  54. package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  55. package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  56. package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  57. package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  58. package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  59. package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  60. package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  61. package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  62. package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  63. package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  64. package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  65. package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  66. package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  67. package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  68. package/dist/assets/MonacoDiffViewer-J2AIDXvs.js +1 -0
  69. package/dist/assets/ToolOutputDialog-B0y5ge-3.js +5 -0
  70. package/dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  71. package/dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  72. package/dist/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  73. package/dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  74. package/dist/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  75. package/dist/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  76. package/dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  77. package/dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  78. package/dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  79. package/dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  80. package/dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  81. package/dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  82. package/dist/assets/index-iDfKTtMQ.css +1 -0
  83. package/dist/assets/index-kNntYPVa.js +2 -0
  84. package/dist/assets/main-BEJ2XliY.css +1 -0
  85. package/dist/assets/main-Ba339xde.js +59 -0
  86. package/dist/assets/vendor--B3aGWKBE.css +32 -0
  87. package/dist/assets/vendor-.pnpm-B1ce5n1Z.js +3192 -0
  88. package/dist/favicon-16.png +0 -0
  89. package/dist/favicon-32.png +0 -0
  90. package/dist/index.html +197 -0
  91. package/dist/logo-dark.svg +4 -0
  92. package/dist/logo-light.svg +4 -0
  93. package/dist/site.webmanifest +36 -0
  94. package/dist/vite.svg +1 -0
  95. package/package.json +92 -0
  96. package/public/apple-touch-icon-120x120.png +0 -0
  97. package/public/apple-touch-icon-152x152.png +0 -0
  98. package/public/apple-touch-icon-167x167.png +0 -0
  99. package/public/apple-touch-icon-180x180.png +0 -0
  100. package/public/apple-touch-icon.png +0 -0
  101. package/public/apple-touch-icon.svg +18 -0
  102. package/public/favicon-16.png +0 -0
  103. package/public/favicon-32.png +0 -0
  104. package/public/logo-dark.svg +4 -0
  105. package/public/logo-light.svg +4 -0
  106. package/public/site.webmanifest +36 -0
  107. package/public/vite.svg +1 -0
  108. package/server/index.d.ts +28 -0
  109. package/server/index.js +3038 -0
  110. package/server/lib/git-identity-storage.js +108 -0
  111. package/server/lib/git-service.js +899 -0
  112. package/server/lib/opencode-config.js +471 -0
  113. package/server/lib/opencode-config.js.d.ts +12 -0
  114. package/server/lib/ui-auth.js +266 -0
Binary file
Binary file
@@ -0,0 +1,197 @@
1
+ <!doctype html>
2
+ <html lang="en" class="h-full">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
6
+
7
+ <!-- Favicon -->
8
+ <link rel="icon" type="image/svg+xml" href="/logo-dark.svg" />
9
+ <link rel="icon" type="image/svg+xml" href="/logo-light.svg" media="(prefers-color-scheme: dark)" />
10
+ <link rel="icon" type="image/png" href="/favicon-32.png" sizes="32x32" />
11
+ <link rel="icon" type="image/png" href="/favicon-16.png" sizes="16x16" />
12
+ <link rel="mask-icon" href="/logo-dark.svg" color="#edb449" />
13
+
14
+ <!-- Apple touch icon - PNG format required for iOS PWA support -->
15
+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png" />
16
+ <link rel="apple-touch-icon" sizes="167x167" href="/apple-touch-icon-167x167.png" />
17
+ <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png" />
18
+
19
+ <!-- Web app manifest (data URL to avoid nginx auth issues) -->
20
+ <script>
21
+ const baseUrl = location.origin;
22
+ const manifest = {
23
+ "name": "OpenChamber - AI Coding Assistant",
24
+ "short_name": "OpenChamber",
25
+ "description": "Web interface companion for OpenCode AI coding agent",
26
+ "start_url": baseUrl + "/",
27
+ "display": "standalone",
28
+ "background_color": "#151313",
29
+ "theme_color": "#edb449",
30
+ "orientation": "portrait-primary",
31
+ "icons": [
32
+ {
33
+ "src": baseUrl + "/logo-dark.svg",
34
+ "sizes": "any",
35
+ "type": "image/svg+xml",
36
+ "purpose": "any maskable"
37
+ },
38
+ {
39
+ "src": baseUrl + "/favicon-16.png",
40
+ "sizes": "16x16",
41
+ "type": "image/png"
42
+ },
43
+ {
44
+ "src": baseUrl + "/favicon-32.png",
45
+ "sizes": "32x32",
46
+ "type": "image/png"
47
+ }
48
+ ],
49
+ "categories": ["developer", "tools", "productivity"],
50
+ "lang": "en"
51
+ };
52
+
53
+ const manifestBlob = new Blob([JSON.stringify(manifest)], {type: 'application/manifest+json'});
54
+ const manifestURL = URL.createObjectURL(manifestBlob);
55
+
56
+ const link = document.createElement('link');
57
+ link.rel = 'manifest';
58
+ link.href = manifestURL;
59
+ document.head.appendChild(link);
60
+ </script>
61
+
62
+ <script>
63
+ (function() {
64
+ try {
65
+ var variant = localStorage.getItem('selectedThemeVariant');
66
+ var useSystem = localStorage.getItem('useSystemTheme');
67
+ if (!variant || (variant !== 'light' && variant !== 'dark')) {
68
+ if (useSystem === null || useSystem === 'true') {
69
+ variant = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
70
+ } else {
71
+ variant = 'dark';
72
+ }
73
+ }
74
+ document.documentElement.setAttribute('data-splash-variant', variant === 'light' ? 'light' : 'dark');
75
+ } catch (error) {
76
+ console.warn('Failed to apply splash variant:', error);
77
+ }
78
+ })();
79
+ </script>
80
+
81
+ <!-- Theme color - Safari iOS 26+ prioritizes CSS background-color over this, but keep as fallback -->
82
+ <meta name="theme-color" content="#151313" />
83
+ <meta name="theme-color" content="#151313" media="(prefers-color-scheme: dark)" />
84
+
85
+ <!-- iOS Safari PWA styling -->
86
+ <meta name="apple-mobile-web-app-capable" content="yes" />
87
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
88
+ <meta name="apple-mobile-web-app-title" content="OpenChamber" />
89
+
90
+ <title>OpenChamber - AI Coding Assistant</title>
91
+ <meta name="description" content="Web interface companion for OpenCode AI coding agent" />
92
+ <meta name="application-name" content="OpenChamber" />
93
+ <meta name="apple-mobile-web-app-title" content="OpenChamber" />
94
+
95
+ <!-- Inline CSS for loading screen (before Tailwind loads) -->
96
+ <style>
97
+ :root {
98
+ --splash-background: #151313;
99
+ --splash-foreground: #cdccc3;
100
+ --splash-rect: #4B4646;
101
+ --splash-grad-stop1: #F8F8F8;
102
+ --splash-grad-stop2: #DAD6D0;
103
+ --splash-grad-stop3: #BAB4AF;
104
+ --splash-stroke1: rgba(255, 255, 255, 0.08);
105
+ --splash-stroke2: rgba(0, 0, 0, 0.15);
106
+ --splash-stroke3: rgba(0, 0, 0, 0.2);
107
+ }
108
+ html[data-splash-variant='light'] {
109
+ --splash-background: #F6F4EF;
110
+ --splash-foreground: #453f37;
111
+ --splash-rect: #CFCDCD;
112
+ --splash-grad-stop1: #B3AEA6;
113
+ --splash-grad-stop2: #928E86;
114
+ --splash-grad-stop3: #6E6A63;
115
+ --splash-stroke1: rgba(255, 255, 255, 0.22);
116
+ --splash-stroke2: rgba(60, 56, 47, 0.25);
117
+ --splash-stroke3: rgba(43, 39, 34, 0.4);
118
+ }
119
+ @keyframes pulse {
120
+ 0%, 100% { opacity: 1; }
121
+ 50% { opacity: 0.4; }
122
+ }
123
+ .loading-pulse {
124
+ animation: pulse 2s ease-in-out infinite;
125
+ }
126
+ #initial-loading {
127
+ background-color: var(--splash-background);
128
+ color: var(--splash-foreground);
129
+ display: flex;
130
+ align-items: center;
131
+ justify-content: center;
132
+ height: 100vh;
133
+ font-family: system-ui, -apple-system, sans-serif;
134
+ transition: opacity 0.3s ease-out;
135
+ position: absolute;
136
+ width: 100%;
137
+ z-index: 9999;
138
+ }
139
+ #initial-loading.fade-out {
140
+ opacity: 0;
141
+ pointer-events: none;
142
+ }
143
+ </style>
144
+ <script type="module" crossorigin src="/assets/index-kNntYPVa.js"></script>
145
+ <link rel="modulepreload" crossorigin href="/assets/vendor-.pnpm-B1ce5n1Z.js">
146
+ <link rel="stylesheet" crossorigin href="/assets/vendor--B3aGWKBE.css">
147
+ <link rel="stylesheet" crossorigin href="/assets/index-iDfKTtMQ.css">
148
+ </head>
149
+ <body class="h-full bg-background text-foreground">
150
+ <div id="root" class="h-full">
151
+ <!-- Loading fallback while React initializes -->
152
+ <div id="initial-loading">
153
+ <div style="display: flex; align-items: center; justify-content: center;">
154
+ <svg class="loading-pulse" width="96" height="96" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OpenChamber loading icon">
155
+ <defs>
156
+ <linearGradient id="loadingGlyphGradient" x1="0" y1="0" x2="0" y2="1">
157
+ <stop offset="0%" stop-color="var(--splash-grad-stop1)"/>
158
+ <stop offset="55%" stop-color="var(--splash-grad-stop2)"/>
159
+ <stop offset="100%" stop-color="var(--splash-grad-stop3)"/>
160
+ </linearGradient>
161
+ <linearGradient id="loadingGlyphStroke" x1="0" y1="0" x2="0" y2="1">
162
+ <stop offset="0%" stop-color="var(--splash-stroke1)"/>
163
+ <stop offset="45%" stop-color="var(--splash-stroke2)"/>
164
+ <stop offset="100%" stop-color="var(--splash-stroke3)"/>
165
+ </linearGradient>
166
+ </defs>
167
+ <rect x="8.75" y="31" width="17.5" height="20.5" fill="var(--splash-rect)" />
168
+ <path d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z" fill="url(#loadingGlyphGradient)" stroke="url(#loadingGlyphStroke)" stroke-width="1.1" stroke-linejoin="round" />
169
+ <path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z" fill="url(#loadingGlyphGradient)" stroke="url(#loadingGlyphStroke)" stroke-width="1.1" stroke-linejoin="round" />
170
+ </svg>
171
+ </div>
172
+ </div>
173
+ </div>
174
+
175
+ <script>
176
+ // Fallback: hide loading screen after 10 seconds if React fails to load
177
+ setTimeout(function() {
178
+ const loading = document.getElementById('initial-loading');
179
+ if (loading) {
180
+ console.warn('Loading screen timeout - forcing hide after 10s');
181
+ loading.classList.add('fade-out');
182
+ setTimeout(function() {
183
+ loading.remove();
184
+ }, 300);
185
+ }
186
+ }, 10000);
187
+ </script>
188
+
189
+ <!-- Polyfill for process before loading React -->
190
+ <script>
191
+ if (typeof process === 'undefined') {
192
+ window.process = { env: {} };
193
+ }
194
+ </script>
195
+
196
+ </body>
197
+ </html>
@@ -0,0 +1,4 @@
1
+ <svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z" fill="black"/>
3
+ <path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z" fill="black"/>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z" fill="white"/>
3
+ <path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z" fill="white"/>
4
+ </svg>
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "OpenChamber - AI Coding Companion",
3
+ "short_name": "OpenChamber",
4
+ "description": "OpenChamber desktop companion for the OpenCode AI coding agent",
5
+ "start_url": "/",
6
+ "display": "standalone",
7
+ "background_color": "#151313",
8
+ "theme_color": "#edb449",
9
+ "orientation": "portrait-primary",
10
+ "icons": [
11
+ {
12
+ "src": "/logo-dark.svg",
13
+ "sizes": "any",
14
+ "type": "image/svg+xml",
15
+ "purpose": "any maskable"
16
+ },
17
+ {
18
+ "src": "/logo-light.svg",
19
+ "sizes": "any",
20
+ "type": "image/svg+xml",
21
+ "purpose": "any maskable"
22
+ },
23
+ {
24
+ "src": "/favicon-16.png",
25
+ "sizes": "16x16",
26
+ "type": "image/png"
27
+ },
28
+ {
29
+ "src": "/favicon-32.png",
30
+ "sizes": "32x32",
31
+ "type": "image/png"
32
+ }
33
+ ],
34
+ "categories": ["developer", "tools", "productivity"],
35
+ "lang": "en"
36
+ }
package/dist/vite.svg ADDED
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@openchamber/web",
3
+ "version": "1.0.1",
4
+ "private": false,
5
+ "type": "module",
6
+ "main": "./server/index.js",
7
+ "types": "./server/index.d.ts",
8
+ "bin": {
9
+ "openchamber": "./bin/cli.js"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "scripts": {
15
+ "dev": "pnpm run build:watch",
16
+ "dev:server": "node server/index.js --port 3001",
17
+ "dev:server:watch": "nodemon --watch server --ext js --exec \"node server/index.js --port 3001\"",
18
+ "build": "vite build",
19
+ "build:watch": "vite build --watch",
20
+ "type-check": "tsc --noEmit",
21
+ "lint": "eslint \"./src/**/*.{ts,tsx}\" --config ../../eslint.config.js",
22
+ "start": "node server/index.js"
23
+ },
24
+ "dependencies": {
25
+ "@fontsource/ibm-plex-mono": "^5.2.7",
26
+ "@fontsource/ibm-plex-sans": "^5.1.1",
27
+ "@ibm/plex": "^6.4.1",
28
+ "@opencode-ai/sdk": "^1.0.65",
29
+ "@radix-ui/react-collapsible": "^1.1.12",
30
+ "@radix-ui/react-dialog": "^1.1.15",
31
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
32
+ "@radix-ui/react-scroll-area": "^1.2.10",
33
+ "@radix-ui/react-select": "^2.2.6",
34
+ "@radix-ui/react-separator": "^1.1.7",
35
+ "@radix-ui/react-slot": "^1.2.3",
36
+ "@radix-ui/react-toggle": "^1.1.10",
37
+ "@radix-ui/react-tooltip": "^1.2.8",
38
+ "@remixicon/react": "^4.7.0",
39
+ "@types/react-syntax-highlighter": "^15.5.13",
40
+ "@xterm/addon-fit": "^0.10.0",
41
+ "@xterm/xterm": "^5.3.0",
42
+ "class-variance-authority": "^0.7.1",
43
+ "clsx": "^2.1.1",
44
+ "cmdk": "^1.1.1",
45
+ "express": "^5.1.0",
46
+ "http-proxy-middleware": "^3.0.5",
47
+ "next-themes": "^0.4.6",
48
+ "node-pty": "^1.0.0",
49
+ "react": "^19.1.1",
50
+ "react-dom": "^19.1.1",
51
+ "react-markdown": "^10.1.0",
52
+ "react-syntax-highlighter": "^15.6.6",
53
+ "remark-gfm": "^4.0.1",
54
+ "simple-git": "^3.28.0",
55
+ "sonner": "^2.0.7",
56
+ "strip-json-comments": "^5.0.3",
57
+ "tailwind-merge": "^3.3.1",
58
+ "yaml": "^2.8.1",
59
+ "zustand": "^5.0.8"
60
+ },
61
+ "devDependencies": {
62
+ "@eslint/js": "^9.33.0",
63
+ "@tailwindcss/postcss": "^4.0.0",
64
+ "@types/node": "^24.3.1",
65
+ "@types/react": "^19.1.10",
66
+ "@types/react-dom": "^19.1.7",
67
+ "@vitejs/plugin-react": "^5.0.0",
68
+ "autoprefixer": "^10.4.21",
69
+ "concurrently": "^9.2.1",
70
+ "cors": "^2.8.5",
71
+ "cross-env": "^7.0.3",
72
+ "eslint": "^9.33.0",
73
+ "eslint-plugin-react-hooks": "^5.2.0",
74
+ "eslint-plugin-react-refresh": "^0.4.20",
75
+ "globals": "^16.3.0",
76
+ "nodemon": "^3.1.7",
77
+ "tailwindcss": "^4.0.0",
78
+ "tsx": "^4.20.6",
79
+ "tw-animate-css": "^1.3.8",
80
+ "typescript": "~5.8.3",
81
+ "typescript-eslint": "^8.39.1",
82
+ "vite": "^7.1.2"
83
+ },
84
+ "files": [
85
+ "dist",
86
+ "server",
87
+ "bin",
88
+ "public",
89
+ "package.json",
90
+ "README.md"
91
+ ]
92
+ }
Binary file
@@ -0,0 +1,18 @@
1
+ <svg width="180" height="180" viewBox="0 0 70 70" xmlns="http://www.w3.org/2000/svg">
2
+ <g transform="translate(8.75, 8.75) scale(0.75)">
3
+ <!-- Letter O with white fill and thin black stroke -->
4
+ <path fill-rule="evenodd" clip-rule="evenodd"
5
+ d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z"
6
+ fill="white"
7
+ stroke="black"
8
+ stroke-width="1.1"
9
+ stroke-linejoin="round"/>
10
+
11
+ <!-- Letter C with white fill and thin black stroke -->
12
+ <path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z"
13
+ fill="white"
14
+ stroke="black"
15
+ stroke-width="1.1"
16
+ stroke-linejoin="round"/>
17
+ </g>
18
+ </svg>
Binary file
Binary file
@@ -0,0 +1,4 @@
1
+ <svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z" fill="black"/>
3
+ <path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z" fill="black"/>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z" fill="white"/>
3
+ <path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z" fill="white"/>
4
+ </svg>
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "OpenChamber - AI Coding Companion",
3
+ "short_name": "OpenChamber",
4
+ "description": "OpenChamber desktop companion for the OpenCode AI coding agent",
5
+ "start_url": "/",
6
+ "display": "standalone",
7
+ "background_color": "#151313",
8
+ "theme_color": "#edb449",
9
+ "orientation": "portrait-primary",
10
+ "icons": [
11
+ {
12
+ "src": "/logo-dark.svg",
13
+ "sizes": "any",
14
+ "type": "image/svg+xml",
15
+ "purpose": "any maskable"
16
+ },
17
+ {
18
+ "src": "/logo-light.svg",
19
+ "sizes": "any",
20
+ "type": "image/svg+xml",
21
+ "purpose": "any maskable"
22
+ },
23
+ {
24
+ "src": "/favicon-16.png",
25
+ "sizes": "16x16",
26
+ "type": "image/png"
27
+ },
28
+ {
29
+ "src": "/favicon-32.png",
30
+ "sizes": "32x32",
31
+ "type": "image/png"
32
+ }
33
+ ],
34
+ "categories": ["developer", "tools", "productivity"],
35
+ "lang": "en"
36
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1,28 @@
1
+ import type { Express } from "express";
2
+ import type { Server } from "http";
3
+
4
+ export interface WebUiServerController {
5
+ expressApp: Express;
6
+ httpServer: Server;
7
+ getPort: () => number | null;
8
+ getOpenCodePort: () => number | null;
9
+ isReady: () => boolean;
10
+ restartOpenCode: () => Promise<void>;
11
+ stop: (options?: { exitProcess?: boolean }) => Promise<void>;
12
+ }
13
+
14
+ export interface StartWebUiServerOptions {
15
+ port?: number;
16
+ attachSignals?: boolean;
17
+ exitOnShutdown?: boolean;
18
+ uiPassword?: string | null;
19
+ }
20
+
21
+ export declare function startWebUiServer(
22
+ options?: StartWebUiServerOptions
23
+ ): Promise<WebUiServerController>;
24
+
25
+ export declare function gracefulShutdown(options?: { exitProcess?: boolean }): Promise<void>;
26
+ export declare function setupProxy(app: Express): void;
27
+ export declare function restartOpenCode(): Promise<void>;
28
+ export declare function parseArgs(argv?: string[]): { port: number; uiPassword: string | null };