@openchambery/web 1.18.4-beta.2 → 1.18.4-beta.20
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/bin/cli.test.js +25 -0
- package/bin/lib/DOCUMENTATION.md +2 -1
- package/bin/lib/cli-args.js +19 -0
- package/bin/lib/commands-serve.js +73 -4
- package/dist/assets/{AgentAvatar-BvhXxFvg.js → AgentAvatar-DDcjamcJ.js} +1 -1
- package/dist/assets/AssistantView-BKtWtK9a.js +1 -0
- package/dist/assets/{ChatContainer-Ba2Qqd2R.js → ChatContainer-CmZuBd4k.js} +42 -42
- package/dist/assets/{DiagramView--CkYLtF9.js → DiagramView-C3H0iaE1.js} +1 -1
- package/dist/assets/{FadeInOnReveal-98buIVdv.js → FadeInOnReveal-By2F9vcI.js} +1 -1
- package/dist/assets/{Icon-BhSwbLaF.js → Icon-DpjYnXxn.js} +1 -1
- package/dist/assets/{MarkdownRendererImpl-CuaQbwUx.js → MarkdownRendererImpl-Oq7v-1r2.js} +1 -1
- package/dist/assets/{MobileDetailNavigation-ld2mS8hq.js → MobileDetailNavigation-Bh_f-iat.js} +1 -1
- package/dist/assets/MobileShareBridge-BvcbH_WJ.js +4 -0
- package/dist/assets/MobileSurface-BTMvLLPa.js +2 -0
- package/dist/assets/{MultiRunWindow-kryfNvF6.js → MultiRunWindow-Cv4K6i1U.js} +1 -1
- package/dist/assets/{OnboardingScreen-C1n_wVb-.js → OnboardingScreen-BKmuT7AL.js} +1 -1
- package/dist/assets/{OverlayScrollbar-CXFN6Cqq.js → OverlayScrollbar-Ch3J6ASR.js} +1 -1
- package/dist/assets/{SettingsView-BBTUVI-a.js → SettingsView-DZT_nuTt.js} +11 -11
- package/dist/assets/{SettingsWindow-4RS_41Wb.js → SettingsWindow-Bjb84x0C.js} +1 -1
- package/dist/assets/{TerminalView-B1he4xRe.js → TerminalView-CXq2MDyL.js} +1 -1
- package/dist/assets/{ToolOutputDialog-ak07C60J.js → ToolOutputDialog-CTrqAwo1.js} +1 -1
- package/dist/assets/appThemeRegistry-D6EEEMQw.js +2 -0
- package/dist/assets/{button-BQY5ugjh.js → button-C7OXr4ae.js} +1 -1
- package/dist/assets/{clipboard-BvJ7NunE.js → clipboard-DWuULPzo.js} +1 -1
- package/dist/assets/{collapsible-CqcZGw3W.js → collapsible-DaEya6b6.js} +1 -1
- package/dist/assets/{context-menu-DSUJY2i3.js → context-menu-Cjof3V7x.js} +1 -1
- package/dist/assets/desktopHosts-Txp4xOVQ.js +1 -0
- package/dist/assets/desktopRelayRestore-C_FSEHKM.js +1 -0
- package/dist/assets/{diagram-B8D9Klct.js → diagram-CHfginjS.js} +1 -1
- package/dist/assets/{dialog-sGFkIKP2.js → dialog-DPS0W9eS.js} +1 -1
- package/dist/assets/{es-BuinIayO.js → es-BX0Vm3Ac.js} +4 -4
- package/dist/assets/fileQueries-BrUKKgPW.js +1 -0
- package/dist/assets/{fr-CT7us58h.js → fr-CuPzXTYx.js} +4 -4
- package/dist/assets/{gitApi-DtV2V_Fp.js → gitApi-mV826uOd.js} +2 -2
- package/dist/assets/{input-CgIoxUJc.js → input-BzYA603C.js} +1 -1
- package/dist/assets/insertionBoundaries-fFm8sTaK.js +1 -0
- package/dist/assets/{ja-CCuAH4nO.js → ja-DGtzjrFO.js} +4 -4
- package/dist/assets/{ko-lXbhGt6P.js → ko-DZ9Di0je.js} +4 -4
- package/dist/assets/{main-CoNVZvj1.js → main-CqaUoTu5.js} +2 -2
- package/dist/assets/main-DaX6y8EG.js +172 -0
- package/dist/assets/{markdown-worker-C5Om4TVK.js → markdown-worker-W06-MhF5.js} +1 -1
- package/dist/assets/{markdownTheme-BdF4C4-o.js → markdownTheme-B89dbj3N.js} +1 -1
- package/dist/assets/{miniChat-CYd1PMdJ.js → miniChat-CX64FVKM.js} +2 -2
- package/dist/assets/mobile-BljNuNl6.js +2 -0
- package/dist/assets/multirun-Bdv-VeHM.js +4 -0
- package/dist/assets/persistence-6sclr7B6.js +3 -0
- package/dist/assets/pl-BuCO3qb1.js +15 -0
- package/dist/assets/platform-CbeLpKPk.js +2 -0
- package/dist/assets/projectMeta-EGeQpzvX.js +3 -0
- package/dist/assets/{pt-BR-DWbGs1bc.js → pt-BR-Brf4RMsw.js} +4 -4
- package/dist/assets/radio-BPJ5XDOL.js +1 -0
- package/dist/assets/renderElectronMiniChatApp-7_MeDuZ2.js +2 -0
- package/dist/assets/renderMobileApp-J09WW2wY.js +23 -0
- package/dist/assets/runtimeConfig-DbkphGhQ.js +2 -0
- package/dist/assets/runtimeEndpointReset-DooWSsoH.js +147 -0
- package/dist/assets/{sortable-tabs-strip-pSnPuBXA.js → sortable-tabs-strip-nLsPC06f.js} +1 -1
- package/dist/assets/src-Yqt5hwRm.css +2 -0
- package/dist/assets/{store-BuXogmxp.js → store-DQY8Fkb0.js} +4 -4
- package/dist/assets/{terminalApi-jfes-HIU.js → terminalApi-BpPeXWIu.js} +1 -1
- package/dist/assets/{tooltip-rN8LrxMF.js → tooltip-D_orJMYd.js} +1 -1
- package/dist/assets/{uk-DgOxtvS7.js → uk-C-wmaPTi.js} +4 -4
- package/dist/assets/{url-B0Ak7X6b.js → url-BsaBG5-1.js} +1 -1
- package/dist/assets/useAppFontEffects-DFRR7hqN.js +7 -0
- package/dist/assets/{useAssistantUIStore-SPh025NE.js → useAssistantUIStore-BHsHXCKE.js} +1 -1
- package/dist/assets/{useDesktopWindowControlsLayout-BSHPIcFE.js → useDesktopWindowControlsLayout-7oe0nJkK.js} +1 -1
- package/dist/assets/{useEffectiveDirectory-Cbsu48gT.js → useEffectiveDirectory-DEbnpVAu.js} +1 -1
- package/dist/assets/{useFontPreferences-Bz3crRRO.js → useFontPreferences-ckzpXQaJ.js} +1 -1
- package/dist/assets/useMobileNavigationStore-CPi-bAr0.js +475 -0
- package/dist/assets/useSessionAutoCleanup-BFwpZAij.js +1 -0
- package/dist/assets/useUIStore-DzwCfRqr.js +1 -0
- package/dist/assets/{useWorkerHighlightedLines-D7ZRwkm3.js → useWorkerHighlightedLines-Cb7i5p7s.js} +1 -1
- package/dist/assets/{utils-DfPDhqys.js → utils-B1EK5zKa.js} +1 -1
- package/dist/assets/{zh-CN-BPGatJp9.js → zh-CN-DueRrIql.js} +4 -4
- package/dist/assets/{zh-TW-qUWWsaxK.js → zh-TW-6875X80V.js} +4 -4
- package/dist/index.html +9 -9
- package/dist/mini-chat.html +9 -9
- package/dist/mobile.html +9 -9
- package/package.json +1 -1
- package/server/index.d.ts +0 -4
- package/server/index.js +11 -20
- package/server/lib/client-auth/pairing.js +1 -7
- package/server/lib/client-auth/pairing.test.js +0 -45
- package/server/lib/config-sync/config-sync.test.js +52 -0
- package/server/lib/config-sync/scripts.js +10 -2
- package/server/lib/notifications/DOCUMENTATION.md +2 -1
- package/server/lib/notifications/emitter-runtime.js +78 -1
- package/server/lib/notifications/emitter-runtime.test.js +94 -1
- package/server/lib/opencode/DOCUMENTATION.md +4 -4
- package/server/lib/opencode/bootstrap-runtime.js +0 -6
- package/server/lib/opencode/cli-entry-runtime.js +5 -1
- package/server/lib/opencode/cli-entry-runtime.test.js +17 -0
- package/server/lib/opencode/core-routes.js +0 -3
- package/server/lib/opencode/core-routes.test.js +0 -15
- package/server/lib/opencode/openchamber-routes.js +0 -11
- package/server/lib/relay/DOCUMENTATION.md +3 -45
- package/server/lib/relay/host-client.js +1 -4
- package/server/lib/relay/service.js +28 -16
- package/server/lib/relay/service.test.js +64 -4
- package/server/lib/relay/tunnel-host.js +2 -52
- package/server/lib/relay/tunnel-host.test.js +2 -250
- package/server/lib/scheduled-tasks/DOCUMENTATION.md +4 -1
- package/server/lib/scheduled-tasks/routes.js +51 -8
- package/server/lib/session-assist/DOCUMENTATION.md +4 -2
- package/server/lib/session-assist/runtime.js +67 -30
- package/server/lib/session-assist/runtime.test.js +114 -0
- package/server/lib/session-title/DOCUMENTATION.md +15 -10
- package/server/lib/session-title/runtime.js +24 -0
- package/server/lib/session-title/runtime.test.js +143 -0
- package/server/lib/ui-auth/ui-auth.js +3 -1
- package/server/lib/ui-auth/ui-auth.test.js +25 -0
- package/server/sse-routes.test.js +64 -1
- package/dist/assets/AssistantView-DMK-KCPX.js +0 -1
- package/dist/assets/MobileShareBridge-lTfofNXr.js +0 -4
- package/dist/assets/MobileSurface-Bc_pAGrN.js +0 -2
- package/dist/assets/appThemeRegistry-ChhJvOPo.js +0 -2
- package/dist/assets/desktopHosts-aA40MHzB.js +0 -1
- package/dist/assets/desktopRelayRestore-CxUYRC6v.js +0 -1
- package/dist/assets/fileQueries-BSE4ycQt.js +0 -1
- package/dist/assets/insertionBoundaries-BIS62xbD.js +0 -1
- package/dist/assets/main-ClQdYXuu.js +0 -172
- package/dist/assets/mobile-CJkbELE1.js +0 -2
- package/dist/assets/multirun-DfYluvqf.js +0 -4
- package/dist/assets/persistence-DwXJK4-j.js +0 -3
- package/dist/assets/pl-DCsKBRAg.js +0 -15
- package/dist/assets/platform-CXJwZIZe.js +0 -2
- package/dist/assets/projectMeta-jG2rzIks.js +0 -3
- package/dist/assets/radio-CIR_xKSG.js +0 -1
- package/dist/assets/renderElectronMiniChatApp-D6cOGBOZ.js +0 -2
- package/dist/assets/renderMobileApp-BuiAqCNI.js +0 -23
- package/dist/assets/runtimeConfig-B9P24SI-.js +0 -2
- package/dist/assets/runtimeEndpointReset-BLmUiRJq.js +0 -147
- package/dist/assets/src-DF4hiLrB.css +0 -2
- package/dist/assets/useAppFontEffects-DCQnaU6M.js +0 -7
- package/dist/assets/useMobileNavigationStore-BYiwDqQe.js +0 -476
- package/dist/assets/useSessionAutoCleanup-DDdudIWc.js +0 -1
- package/dist/assets/useUIStore-BJpkPwky.js +0 -1
- package/server/lib/desktop-hosts/routes.js +0 -157
- package/server/lib/desktop-hosts/routes.test.js +0 -227
package/bin/cli.test.js
CHANGED
|
@@ -199,6 +199,31 @@ describe('cli args', () => {
|
|
|
199
199
|
expect(parsed.options.name).toBe('My laptop');
|
|
200
200
|
});
|
|
201
201
|
|
|
202
|
+
it('parses serve --relay-host with optional URL', () => {
|
|
203
|
+
expect(parseArgs(['serve', '--relay-host']).options.relayHost).toBe(true);
|
|
204
|
+
expect(parseArgs(['serve', '--relay-host', 'wss://relay.example/ws']).options.relayHost)
|
|
205
|
+
.toBe('wss://relay.example/ws');
|
|
206
|
+
expect(parseArgs(['serve', '--relay-host=wss://relay.example/ws']).options.relayHost)
|
|
207
|
+
.toBe('wss://relay.example/ws');
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('preserves ssh-remote serve runtime and writes --relay-host opt-in', async () => {
|
|
211
|
+
const { applyRelayHostOptIn, resolveServeRuntime } = await import('./lib/commands-serve.js');
|
|
212
|
+
expect(resolveServeRuntime({ OPENCHAMBER_RUNTIME: 'ssh-remote' })).toBe('ssh-remote');
|
|
213
|
+
expect(resolveServeRuntime({ OPENCHAMBER_RUNTIME: 'desktop' })).toBe('web');
|
|
214
|
+
expect(resolveServeRuntime({})).toBe('web');
|
|
215
|
+
|
|
216
|
+
const { assertServeRelayHostAllowed } = await import('./lib/commands-serve.js');
|
|
217
|
+
expect(() => assertServeRelayHostAllowed('web', { relayHost: true })).toThrow(/ssh-remote/);
|
|
218
|
+
expect(() => assertServeRelayHostAllowed('ssh-remote', { relayHost: true })).not.toThrow();
|
|
219
|
+
|
|
220
|
+
await withTempOpenChamberDataDir(async (dir) => {
|
|
221
|
+
applyRelayHostOptIn({ relayHost: true });
|
|
222
|
+
const settings = JSON.parse(fs.readFileSync(path.join(dir, 'settings.json'), 'utf8'));
|
|
223
|
+
expect(settings.privateRelay).toMatchObject({ enabled: true });
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
202
227
|
it('parses connect-url api-only help', () => {
|
|
203
228
|
const parsed = parseArgs(['connect-url', '--api-only', '--help']);
|
|
204
229
|
|
package/bin/lib/DOCUMENTATION.md
CHANGED
|
@@ -19,7 +19,8 @@ Command modules implement user-facing commands and preserve output contracts acr
|
|
|
19
19
|
- Implements `openchamber serve`.
|
|
20
20
|
- Owns OpenCode CLI checks, port resolution, log rotation, PID/instance registry writes, foreground/background server launch, startup summaries, and foreground shutdown behavior.
|
|
21
21
|
- The Host process always inherits the CLI's Node executable. Do not select Bun based on PATH availability: the Web API owns `better-sqlite3` and requires the prepared Node ABI.
|
|
22
|
-
- Sets `OPENCHAMBER_RUNTIME=web` for
|
|
22
|
+
- Sets `OPENCHAMBER_RUNTIME=web` for ordinary CLI serve (foreground and daemon) so a leftover desktop env cannot host or probe the private relay. Preserves `OPENCHAMBER_RUNTIME=ssh-remote` when SSH manager already set it.
|
|
23
|
+
- `--relay-host [url]` is valid only when `OPENCHAMBER_RUNTIME=ssh-remote`. It enables the private relay host before startup: writes `settings.privateRelay.enabled=true` (and optional pinned `relayUrl`), and when a URL is provided also sets `OPENCHAMBER_RELAY_URL`. Ordinary `web` serve rejects the flag.
|
|
23
24
|
|
|
24
25
|
- `commands-lifecycle.js`
|
|
25
26
|
- Implements `openchamber stop` and `openchamber restart`.
|
package/bin/lib/cli-args.js
CHANGED
|
@@ -76,6 +76,8 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
76
76
|
foreground: false,
|
|
77
77
|
lan: false,
|
|
78
78
|
apiOnly: false,
|
|
79
|
+
// false = unset; true = enable with default/stored URL; string = pin URL
|
|
80
|
+
relayHost: false,
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
const removedFlagErrors = [];
|
|
@@ -204,6 +206,18 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
204
206
|
case 'relay':
|
|
205
207
|
options.relay = true;
|
|
206
208
|
break;
|
|
209
|
+
case 'relay-host': {
|
|
210
|
+
// Optional value: `--relay-host` enables with default/stored URL;
|
|
211
|
+
// `--relay-host wss://…` (or `=`) pins a custom endpoint.
|
|
212
|
+
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
213
|
+
i = nextIndex;
|
|
214
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
215
|
+
options.relayHost = value.trim();
|
|
216
|
+
} else {
|
|
217
|
+
options.relayHost = true;
|
|
218
|
+
}
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
207
221
|
case 'qr':
|
|
208
222
|
options.qr = true;
|
|
209
223
|
options.explicitQr = true;
|
|
@@ -305,6 +319,8 @@ OPTIONS:
|
|
|
305
319
|
--lan Bind to 0.0.0.0 for LAN access
|
|
306
320
|
--server <url> Public/server URL for connect-url links
|
|
307
321
|
--relay connect-url: also include the end-to-end-encrypted relay transport
|
|
322
|
+
--relay-host [url] serve: enable the private relay host (desktop/SSH-remote only).
|
|
323
|
+
Optional ws(s) URL pins the relay endpoint.
|
|
308
324
|
--ui-password Protect browser UI with single password
|
|
309
325
|
--api-only Start API routes only, without serving browser UI assets
|
|
310
326
|
--foreground Run server in foreground (use with systemd/process managers)
|
|
@@ -317,6 +333,7 @@ ENVIRONMENT:
|
|
|
317
333
|
OPENCHAMBER_UI_PASSWORD Alternative to --ui-password flag
|
|
318
334
|
OPENCHAMBER_API_ONLY Set to true/1 to start API routes only
|
|
319
335
|
OPENCHAMBER_DATA_DIR Override OpenChamber data directory
|
|
336
|
+
OPENCHAMBER_RELAY_URL Pin private relay endpoint (ws:// or wss://)
|
|
320
337
|
OPENCODE_HOST External OpenCode server base URL, e.g. http://hostname:4096
|
|
321
338
|
OPENCODE_PORT Port of external OpenCode server to connect to
|
|
322
339
|
OPENCODE_SKIP_START Skip starting OpenCode, use external server
|
|
@@ -327,6 +344,8 @@ EXAMPLES:
|
|
|
327
344
|
openchamber --port 8080 # Start on port 8080 (daemon)
|
|
328
345
|
openchamber --lan --port 3002 # Start on LAN at 0.0.0.0:3002
|
|
329
346
|
openchamber serve --foreground # Start in foreground (for systemd Type=simple)
|
|
347
|
+
openchamber serve --relay-host # Enable private relay host (SSH-managed remote)
|
|
348
|
+
openchamber serve --relay-host wss://relay.example/ws
|
|
330
349
|
openchamber connect-url --port 3000 --qr
|
|
331
350
|
openchamber connect-url --server https://openchamber.example.com
|
|
332
351
|
openchamber startup enable # Start OpenChamber at user login
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
2
3
|
import { pathToFileURL } from 'url';
|
|
3
4
|
import { spawn } from 'child_process';
|
|
4
5
|
import { EXIT_CODE, TunnelCliError } from './cli-errors.js';
|
|
5
6
|
import { buildLocalUrl, resolveServeHost, assertSafeBrowserPort, hasUiPasswordConfigured, assertAuthenticatedNetworkExposure } from './cli-network.js';
|
|
6
7
|
import { fetchSystemInfoFromPort } from './cli-http.js';
|
|
7
8
|
import { isPortAvailable, resolveAvailablePort } from './cli-ports.js';
|
|
8
|
-
import { ensureLogsDir, getLogFilePath } from './cli-paths.js';
|
|
9
|
+
import { ensureLogsDir, getDataDir, getLogFilePath } from './cli-paths.js';
|
|
9
10
|
import { rotateLogFile } from './cli-log-files.js';
|
|
10
11
|
import { discoverOpenChamberInstanceOnPort, isDesktopRuntimeForPort } from './cli-lifecycle.js';
|
|
11
12
|
import { getPidFilePath, getInstanceFilePath, writePidFile, writeInstanceOptions, removePidFile, removeInstanceFile, isProcessRunning, terminateProcessTree } from './cli-process.js';
|
|
12
13
|
import { isNetworkExposedBindHost } from '../../server/lib/security/bind-host.js';
|
|
14
|
+
import {
|
|
15
|
+
canonicalizeRelayUrl,
|
|
16
|
+
DEFAULT_RELAY_URL,
|
|
17
|
+
} from '../../server/lib/relay/service.js';
|
|
13
18
|
import {
|
|
14
19
|
intro as clackIntro,
|
|
15
20
|
outro as clackOutro,
|
|
@@ -22,6 +27,67 @@ import {
|
|
|
22
27
|
} from '../cli-output.js';
|
|
23
28
|
|
|
24
29
|
const DAEMON_READY_TIMEOUT_MS = 30000;
|
|
30
|
+
const SETTINGS_FILE_NAME = 'settings.json';
|
|
31
|
+
|
|
32
|
+
// Ordinary CLI serve must not inherit a leftover desktop env and become a
|
|
33
|
+
// relay host. SSH-manager remotes set OPENCHAMBER_RUNTIME=ssh-remote and may
|
|
34
|
+
// pass --relay-host — preserve that so the remote can host a private relay.
|
|
35
|
+
function resolveServeRuntime(env = process.env) {
|
|
36
|
+
return env?.OPENCHAMBER_RUNTIME === 'ssh-remote' ? 'ssh-remote' : 'web';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function assertServeRelayHostAllowed(serveRuntime, options) {
|
|
40
|
+
if (options?.relayHost && serveRuntime !== 'ssh-remote') {
|
|
41
|
+
throw new TunnelCliError(
|
|
42
|
+
'--relay-host is only valid for an SSH-managed remote (OPENCHAMBER_RUNTIME=ssh-remote). Ordinary `openchamber serve` cannot host the private relay.',
|
|
43
|
+
EXIT_CODE.USAGE_ERROR,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Persist privateRelay.enabled before the server starts so reconcile /
|
|
49
|
+
// startIfEnabled sees the opt-in. Optional URL pins the endpoint in settings
|
|
50
|
+
// and OPENCHAMBER_RELAY_URL (env override stays authoritative while set).
|
|
51
|
+
function applyRelayHostOptIn(options) {
|
|
52
|
+
if (!options?.relayHost) return;
|
|
53
|
+
|
|
54
|
+
let pinnedUrl = null;
|
|
55
|
+
if (typeof options.relayHost === 'string') {
|
|
56
|
+
pinnedUrl = canonicalizeRelayUrl(options.relayHost);
|
|
57
|
+
if (!pinnedUrl) {
|
|
58
|
+
throw new TunnelCliError(
|
|
59
|
+
'Invalid --relay-host URL. Use a ws:// or wss:// URL without credentials.',
|
|
60
|
+
EXIT_CODE.USAGE_ERROR,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
process.env.OPENCHAMBER_RELAY_URL = pinnedUrl;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const settingsPath = path.join(getDataDir(), SETTINGS_FILE_NAME);
|
|
67
|
+
let settings = {};
|
|
68
|
+
try {
|
|
69
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
70
|
+
if (!settings || typeof settings !== 'object' || Array.isArray(settings)) settings = {};
|
|
71
|
+
} catch {
|
|
72
|
+
settings = {};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const existingUrl = typeof settings?.privateRelay?.relayUrl === 'string'
|
|
76
|
+
? settings.privateRelay.relayUrl
|
|
77
|
+
: null;
|
|
78
|
+
const relayUrl = pinnedUrl
|
|
79
|
+
?? (canonicalizeRelayUrl(existingUrl) || DEFAULT_RELAY_URL);
|
|
80
|
+
|
|
81
|
+
fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
|
|
82
|
+
fs.writeFileSync(
|
|
83
|
+
settingsPath,
|
|
84
|
+
`${JSON.stringify({
|
|
85
|
+
...settings,
|
|
86
|
+
privateRelay: { enabled: true, relayUrl },
|
|
87
|
+
}, null, 2)}\n`,
|
|
88
|
+
'utf8',
|
|
89
|
+
);
|
|
90
|
+
}
|
|
25
91
|
|
|
26
92
|
function createServeCommand({
|
|
27
93
|
serverPath,
|
|
@@ -103,6 +169,9 @@ async function serveCommand(options) {
|
|
|
103
169
|
// package scripts. Selecting Bun merely because it is installed makes an
|
|
104
170
|
// otherwise valid CLI launch fail before the Host can report readiness.
|
|
105
171
|
const runtimeBin = process.execPath;
|
|
172
|
+
const serveRuntime = resolveServeRuntime();
|
|
173
|
+
assertServeRelayHostAllowed(serveRuntime, options);
|
|
174
|
+
applyRelayHostOptIn(options);
|
|
106
175
|
|
|
107
176
|
ensureLogsDir();
|
|
108
177
|
const initialLogPort = targetPort === 0 ? 'auto' : String(targetPort);
|
|
@@ -156,7 +225,7 @@ async function serveCommand(options) {
|
|
|
156
225
|
process.env.OPENCHAMBER_UI_PASSWORD = effectiveUiPassword;
|
|
157
226
|
}
|
|
158
227
|
process.env.OPENCHAMBER_HOST = effectiveHost;
|
|
159
|
-
process.env.OPENCHAMBER_RUNTIME =
|
|
228
|
+
process.env.OPENCHAMBER_RUNTIME = serveRuntime;
|
|
160
229
|
|
|
161
230
|
// In --quiet mode, redirect stdout/stderr to the log file so that
|
|
162
231
|
// server runtime output (console.log calls) does not pollute the
|
|
@@ -270,7 +339,7 @@ async function serveCommand(options) {
|
|
|
270
339
|
env: {
|
|
271
340
|
...process.env,
|
|
272
341
|
OPENCHAMBER_PORT: String(targetPort),
|
|
273
|
-
OPENCHAMBER_RUNTIME:
|
|
342
|
+
OPENCHAMBER_RUNTIME: serveRuntime,
|
|
274
343
|
OPENCODE_BINARY: opencodeBinary,
|
|
275
344
|
OPENCHAMBER_HOST: effectiveHost,
|
|
276
345
|
...(effectiveUiPassword ? { OPENCHAMBER_UI_PASSWORD: effectiveUiPassword } : {}),
|
|
@@ -393,4 +462,4 @@ async function serveCommand(options) {
|
|
|
393
462
|
return serveCommand;
|
|
394
463
|
}
|
|
395
464
|
|
|
396
|
-
export { createServeCommand };
|
|
465
|
+
export { createServeCommand, resolveServeRuntime, applyRelayHostOptIn, assertServeRelayHostAllowed };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./rolldown-runtime-C0FnF6B9.js";import{nt as e,rt as t}from"./vendor-base-ui-CnHfUmDN.js";import{n}from"./vendor-react-DLPElpoQ.js";import{t as r}from"./utils-
|
|
1
|
+
import"./rolldown-runtime-C0FnF6B9.js";import{nt as e,rt as t}from"./vendor-base-ui-CnHfUmDN.js";import{n}from"./vendor-react-DLPElpoQ.js";import{t as r}from"./utils-B1EK5zKa.js";t();var i=n(),a=[{var:`--status-success`,class:`agent-success`},{var:`--syntax-keyword`,class:`agent-keyword`},{var:`--syntax-type`,class:`agent-type`},{var:`--syntax-function`,class:`agent-function`},{var:`--syntax-number`,class:`agent-number`},{var:`--status-info`,class:`agent-info`},{var:`--status-warning`,class:`agent-warning`},{var:`--syntax-variable`,class:`agent-variable`}];function o(e){if(!e||e===`build`)return a[0];let t=0;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);t=(t<<5)-t+r,t&=t}return a[1+Math.abs(t)%(a.length-1)]}var s=5,c=Math.ceil(s/2);function l(e){let t=0;for(let n=0;n<e.length;n++)t=(t<<5)-t+e.charCodeAt(n),t|=0;return t>>>0}function u(e){let t=Array.from({length:s},()=>Array.from({length:s},()=>!1));if(!e)return t;let n=l(e);for(let e=0;e<s;e++)for(let r=0;r<c;r++){let i=(n&1)==1;n>>>=1,t[e][r]=i,t[e][4-r]=i}return t}var d=e(),f=e=>{let t=(0,i.c)(27),{name:n,emoji:a,size:s,className:c,label:l}=e,f=s===void 0?16:s,m,h,g;if(t[0]!==c||t[1]!==a||t[2]!==n){m=o(n);let e;t[6]===n?e=t[7]:(e=u(n),t[6]=n,t[7]=e),h=e,g=r(`inline-flex aspect-square shrink-0 overflow-hidden rounded-sm`,a&&`items-center justify-center select-none`,m.class,c),t[0]=c,t[1]=a,t[2]=n,t[3]=m,t[4]=h,t[5]=g}else m=t[3],h=t[4],g=t[5];let _=`calc(${f}px * var(--dpt-n, 1))`,v=`calc(${f}px * var(--dpt-n, 1))`,y=`calc(${f}px * var(--dpt-n, 1))`,b=`calc(${f}px * var(--dpt-n, 1))`,x=`calc(${f}px * var(--dpt-n, 1))`,S=`calc(${f}px * var(--dpt-n, 1))`,C=`var(${m.var})`,w;t[8]!==_||t[9]!==v||t[10]!==y||t[11]!==b||t[12]!==x||t[13]!==S||t[14]!==C?(w={width:_,minWidth:v,maxWidth:y,height:b,minHeight:x,maxHeight:S,color:C},t[8]=_,t[9]=v,t[10]=y,t[11]=b,t[12]=x,t[13]=S,t[14]=C,t[15]=w):w=t[15];let T=l?`img`:void 0,E=!l||void 0,D;t[16]!==a||t[17]!==h||t[18]!==f?(D=a?(0,d.jsx)(`span`,{"aria-hidden":`true`,style:{fontSize:`calc(${f*.75}px * var(--dpt-n, 1))`,lineHeight:1},children:a}):(0,d.jsxs)(`svg`,{width:f,height:f,viewBox:`0 0 5 5`,shapeRendering:`crispEdges`,className:`oc-agent-avatar block h-full w-full`,"aria-hidden":`true`,children:[(0,d.jsx)(`rect`,{width:`5`,height:`5`,fill:`currentColor`,opacity:.14}),h.map(p)]}),t[16]=a,t[17]=h,t[18]=f,t[19]=D):D=t[19];let O;return t[20]!==l||t[21]!==w||t[22]!==T||t[23]!==E||t[24]!==D||t[25]!==g?(O=(0,d.jsx)(`span`,{className:g,style:w,role:T,"aria-label":l,"aria-hidden":E,children:D}),t[20]=l,t[21]=w,t[22]=T,t[23]=E,t[24]=D,t[25]=g,t[26]=O):O=t[26],O};function p(e,t){return e.map((e,n)=>e?(0,d.jsx)(`rect`,{x:n,y:t,width:`1`,height:`1`,fill:`currentColor`},`${n}-${t}`):null)}export{o as n,f as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as e,r as t}from"./rolldown-runtime-C0FnF6B9.js";import{A as n,E as r,t as i,w as a}from"./useUIStore-DzwCfRqr.js";import{Ot as o,et as s,rt as c,yt as l}from"./persistence-6sclr7B6.js";import{nt as u,rt as d}from"./vendor-base-ui-CnHfUmDN.js";import{r as f}from"./platform-CbeLpKPk.js";import{n as p}from"./vendor-react-DLPElpoQ.js";import{r as m}from"./vendor-sonner-DVzioF3d.js";import{n as h}from"./vendor-reactuses-core-DDoDDyM9.js";import{n as g}from"./clipboard-DWuULPzo.js";import{a as _,n as v,s as y}from"./MobileShareBridge-BvcbH_WJ.js";import{Fo as b,Ja as x,Si as S,Vi as C,Xr as w,Za as T,_n as E,bo as D,cn as O,ei as k,gn as A,hn as j,o as M,rn as N,ua as P,xo as F}from"./useMobileNavigationStore-CPi-bAr0.js";import{_ as I,a as L,c as R,d as ee,f as te,g as ne,l as re,n as ie,o as ae,p as oe,r as se,t as z,v as ce,x as B,y as le}from"./MobileDetailNavigation-Bh_f-iat.js";import{i as ue,r as de}from"./useAssistantUIStore-BHsHXCKE.js";import{t as fe}from"./AgentAvatar-DDcjamcJ.js";import{t as pe}from"./utils-B1EK5zKa.js";import{n as me}from"./Icon-DpjYnXxn.js";import{a as V,i as he,n as ge,o as H,r as U,t as W}from"./dialog-DPS0W9eS.js";import{t as _e}from"./button-C7OXr4ae.js";import{i as ve}from"./OverlayScrollbar-Ch3J6ASR.js";import{J as ye,L as be,N as xe,P as G,R as Se,t as K}from"./ChatContainer-CmZuBd4k.js";import{a as Ce,i as we,n as Te,r as Ee,t as De}from"./context-menu-Cjof3V7x.js";var q=p(),J=e(d(),1),Y=u(),Oe=e=>{let t=(0,q.c)(46),{assistant:n,sessionID:r,warning:i,surface:a,onRevertMessage:o,onEditMessage:s,pendingUserMessages:c,onPendingUserMessagesMaterialized:l}=e,u=n.effectiveWorkspacePath,d;t[0]!==n.sessionGeneration||t[1]!==r?(d={sessionID:r,sessionGeneration:n.sessionGeneration},t[0]=n.sessionGeneration,t[1]=r,t[2]=d):d=t[2];let p=ce(n.id,d,a.active);p.data?.pages;let m;t[3]===p.data?.pages?m=t[4]:(m=p.data?.pages??[],t[3]=p.data?.pages,t[4]=m);let g;t[5]===m?g=t[6]:(g=S(m),t[5]=m,t[6]=g);let _=g,v;if(t[7]!==_){v=new Map;for(let e of _){let t=v.get(e.sessionID);v.set(e.sessionID,t===void 0||t===e.directory?e.directory:null)}t[7]=_,t[8]=v}else v=t[8];let y=v,b;t[9]===p?b=t[10]:(b=async()=>{(p.hasNextPage||p.isFetchNextPageError)&&await p.fetchNextPage()},t[9]=p,t[10]=b);let x=h(b),C=n.mode===`continuous`,w=xe(),T;t[11]!==u||t[12]!==y||t[13]!==w||t[14]!==r?(T=(e,t)=>{let n=e===r?u:y.get(e);if(!n||n!==t){A(e,`missing-directory`);return}E(e,t,{phoneShell:!!(w&&!f()),switchToChat:!0})},t[11]=u,t[12]=y,t[13]=w,t[14]=r,t[15]=T):T=t[15];let D=h(T),O;t[16]===C?O=t[17]:(O={...G,forkSession:!1,navigateNestedSession:!1,mutateSession:C},t[16]=C,t[17]=O);let k;t[18]===s?k=t[19]:(k=s?{onEditMessage:s}:{},t[18]=s,t[19]=k);let j;t[20]!==u||t[21]!==o||t[22]!==D||t[23]!==r||t[24]!==a.active||t[25]!==a.surfaceID||t[26]!==O||t[27]!==k?(j={kind:`embedded`,surfaceId:a.surfaceID,sessionId:r,directory:u,active:a.active,capabilities:O,onRevertMessage:o,...k,openSourceSession:D},t[20]=u,t[21]=o,t[22]=D,t[23]=r,t[24]=a.active,t[25]=a.surfaceID,t[26]=O,t[27]=k,t[28]=j):j=t[28];let M=j,N=p.isError||p.isSuccess&&!p.hasNextPage,P=p.isLoading||p.isFetchingNextPage,F;t[29]!==x||t[30]!==N||t[31]!==_||t[32]!==P?(F={entries:_,complete:N,loading:P,fetchPrevious:x},t[29]=x,t[30]=N,t[31]=_,t[32]=P,t[33]=F):F=t[33];let I;t[34]!==u||t[35]!==l||t[36]!==o||t[37]!==c||t[38]!==r||t[39]!==M||t[40]!==a||t[41]!==F||t[42]!==i?(I={sessionId:r,directory:u,composerSurface:a,sessionSurface:M,warning:i,pendingUserMessages:c,onPendingUserMessagesMaterialized:l,assistantHistory:F,onRevertMessage:o},t[34]=u,t[35]=l,t[36]=o,t[37]=c,t[38]=r,t[39]=M,t[40]=a,t[41]=F,t[42]=i,t[43]=I):I=t[43];let L=I,R;return t[44]===L?R=t[45]:(R=(0,Y.jsx)(K,{autoOpenDraft:!1,host:L}),t[44]=L,t[45]=R),R},ke=class extends Error{constructor(){super(`assistant_selection_stale`)}},Ae=(e,t)=>e.assistantID===t.assistantID&&e.transportIdentity===t.transportIdentity&&e.runtimeGeneration===t.runtimeGeneration,je=class{onBusyChange;onError;flight=null;authoritativeIdentity=null;constructor(e,t){this.onBusyChange=e,this.onError=t}activate(e){this.authoritativeIdentity&&!Ae(this.authoritativeIdentity,e)&&this.flight&&this.retire(this.flight),this.authoritativeIdentity=e}enqueue(e,t,n){if(!this.isAuthoritative(e))return Promise.reject(new ke);let r=this.flight;r||(r={identity:e,controller:new AbortController,running:!1,desired:null,waiters:[],activeWaiters:[],idleWaiters:[],retired:!1},this.flight=r),r.desired=t;let i=new Promise((e,t)=>{r.waiters.push({resolve:e,reject:t})});return r.running||(r.running=!0,this.onBusyChange(!0),this.run(r,n)),i}async flush(e){if(!this.isAuthoritative(e))throw new ke;let t=this.flight;t?.running&&await new Promise((e,n)=>t.idleWaiters.push({resolve:e,reject:n}))}assertAuthoritative(e){if(!this.isAuthoritative(e))throw new ke}dispose(){this.flight&&this.retire(this.flight),this.authoritativeIdentity=null}async run(e,t){for(;!e.retired&&e.desired;){let n=e.desired;e.desired=null;let r=e.waiters.splice(0);e.activeWaiters=r;try{if(await t({identity:e.identity,selection:n,signal:e.controller.signal}),!e.retired)for(let e of r)e.resolve()}catch(t){if(!e.retired){this.onError(t);for(let e of r)e.reject(t)}}e.activeWaiters=[]}e.running=!1;for(let t of e.idleWaiters.splice(0))t.resolve();this.flight===e&&this.onBusyChange(!1)}retire(e){e.retired=!0,e.controller.abort();let t=new ke;for(let n of e.activeWaiters.splice(0))n.reject(t);for(let n of e.waiters.splice(0))n.reject(t);for(let n of e.idleWaiters.splice(0))n.reject(t);this.flight===e&&(this.flight=null,this.onBusyChange(!1))}isAuthoritative(e){return this.authoritativeIdentity!==null&&Ae(this.authoritativeIdentity,e)}},X=(e,t)=>{let n=t.providerID??e.providerID,r=t.modelID??e.modelID,i=n!==e.providerID||r!==e.modelID;return{enabled:e.enabled,name:e.name,defaultPrompt:e.defaultPrompt,workspacePath:e.workspacePath,providerID:n,modelID:r,agent:t.agent??null,variant:i?null:t.variant??null,mode:e.mode}},Me=async(e,t,n)=>{n.assertAuthoritative();let r=n.readSnapshot()?.assistants.find(t=>t.id===e.assistantID);if(!r)throw Error(`assistant_unavailable`);try{n.assertAuthoritative(),await n.updateAssistant(r,X(r,t)),n.assertAuthoritative()}catch(i){if(n.assertAuthoritative(),n.signal.aborted)throw new ke;if(!(i instanceof B)||i.code!==`revision_conflict`)throw i;if(n.assertAuthoritative(),r=(await n.ensureSnapshot(n.signal)).assistants.find(t=>t.id===e.assistantID),n.assertAuthoritative(),!r)throw new B(`revision_conflict`,409);n.assertAuthoritative(),await n.updateAssistant(r,X(r,t)),n.assertAuthoritative()}};async function Z(e){await L(e);let t=ue.getState().defaultShareAssistant;if(t?.assistantID!==e.id)return;let n=await R();n.serverInstanceID&&t.serverInstanceID===n.serverInstanceID&&ue.getState().setDefaultShareAssistant(null)}function Ne({assistant:e,open:t,onOpenChange:n,onDeleted:r}){let{t:i}=g(),[a,o]=J.useState(!1),s=e?_(e.name).displayName||e.name:``,c=h(e=>{a&&!e||n(e)}),l=h(()=>{a||n(!1)}),u=h(async()=>{if(!(!e||a)){o(!0);try{await Z(e),r?.(e.id),n(!1),m.success(i(`assistants.settings.toast.deleted`))}catch{m.error(i(`assistants.settings.toast.deleteFailed`))}finally{o(!1)}}});return(0,Y.jsx)(W,{open:t&&e!==null,onOpenChange:c,children:(0,Y.jsxs)(ge,{className:`max-w-md`,children:[(0,Y.jsxs)(V,{children:[(0,Y.jsx)(H,{children:i(`assistants.settings.delete`)}),(0,Y.jsx)(U,{children:i(`assistants.settings.deleteConfirm`,{name:s})})]}),(0,Y.jsxs)(he,{children:[(0,Y.jsx)(_e,{size:`sm`,variant:`ghost`,onClick:l,disabled:a,children:i(`settings.common.actions.cancel`)}),(0,Y.jsx)(_e,{size:`sm`,variant:`destructive`,onClick:u,disabled:a,children:i(`settings.common.actions.delete`)})]})]})})}var Pe=[0,500,1500,4e3],Fe=(e,t,n)=>{let r=!1,i=e.map(e=>e.info.id!==t||e.info.sessionID===n?e:(r=!0,{...e,info:{...e.info,sessionID:n}}));return r?i:e},Ie=e=>{let t=e.refreshDelaysMs??Pe,n=e.sleep??(e=>new Promise(t=>setTimeout(t,e)));(async()=>{for(let r of t){if(r>0&&await n(r),!e.isCurrent())return;try{await e.refresh(e.binding);break}catch{}}})()},Le=e=>`${e.transport}\u0000${e.assistantID}`,Re=e=>({transport:e.transport,assistantID:e.assistantID}),ze=(e,t)=>e.assistantID===t.assistantID&&e.sessionID===t.sessionID&&e.directory===t.directory&&e.sessionGeneration===t.sessionGeneration&&e.transport===t.transport&&e.runtimeGeneration===t.runtimeGeneration,Be=(e,t)=>e.assistantID===t.assistantID&&e.sessionID===t.sessionID&&e.directory===t.directory&&e.sessionGeneration===t.sessionGeneration&&e.messageID===t.messageID&&e.transport===t.transport&&e.runtimeGeneration===t.runtimeGeneration,Ve=()=>{let e=new Map,t=new Map,n=1,r=e=>Le(e),i=async(e,n)=>{let i=r(e),a=t.get(i)??Promise.resolve(),o,s=new Promise(e=>{o=e}),c=a.catch(()=>void 0).then(()=>s);t.set(i,c),await a.catch(()=>void 0);try{return await n()}finally{o(),t.get(i)===c&&t.delete(i)}},a=(t,i)=>{let a=r(Re(t)),o=n++;return e.set(a,{identity:t,rollback:i,token:o}),o},o=t=>e.get(r(t))?.identity,s=t=>e.delete(r(t)),c=async e=>i(e,()=>s(e)),l=async t=>{let n=r(t),i=e.get(n);if(!i)return{kind:`none`};let a=i.token,o=i.identity,s;try{s=await i.rollback()}catch{return{kind:`blocked`,status:`failed`}}let c=e.get(n);return!c||c.token!==a||!Be(c.identity,o)?{kind:`superseded`}:s.status===`rolled-back`||s.status===`conflict`?(e.delete(n),{kind:`cleared`,status:s.status}):{kind:`blocked`,status:s.status}},u=async(t,n)=>{let i=r(t),a=e.get(i);if(!a)return{kind:`none`};if(ze(a.identity,n))return{kind:`match`};let o=a.token,s=a.identity,c=await a.rollback(),l=e.get(i);return!l||l.token!==o||!Be(l.identity,s)?{kind:`superseded`}:c.status===`rolled-back`||c.status===`conflict`?(e.delete(i),{kind:`cleared`,status:c.status}):{kind:`rollback_failed`,retained:!0,status:c.status}};return{register:a,read:o,clear:s,clearExclusive:c,retireCurrent:l,rollbackAndClearIfBindingMismatch:async(e,t)=>i(e,()=>u(e,t)),rollbackAllBestEffort:async t=>{let n=[...e.entries()];await Promise.all(n.map(async([,n])=>{if(t?.excludeTransport!==void 0&&n.identity.transport===t.excludeTransport)return;let a=Re(n.identity);await i(a,async()=>{let t=r(a),i=e.get(t);if(!i||i.token!==n.token)return;let o=i.token,s=i.identity;try{let n=await i.rollback(),r=e.get(t);if(!r||r.token!==o||!Be(r.identity,s))return;(n.status===`rolled-back`||n.status===`conflict`)&&e.delete(t)}catch{}})}))},stageExclusive:async(e,t)=>i(e,async()=>{let n=await l(e);if(n.kind===`blocked`)return{kind:`blocked`,status:n.status};let r=await t();if(!r)return{kind:`skipped`};let i=a(r.identity,r.rollback);return r.protectOnStale?{kind:`stale_protected`,token:i,identity:r.identity}:{kind:`registered`,token:i,identity:r.identity}})}},He=(e,t)=>!e?.attachments?.length||!t?[]:e.attachments.flatMap(e=>{let n=t[e.attachmentRefID];return n?[n]:[]}),Ue=(e,t)=>{let n=t??{};return e.map(e=>({partID:e.partID,text:e.text,...e.synthetic===!0?{synthetic:!0}:{},attachments:e.attachments.flatMap(e=>n[e.attachmentRefID]?[n[e.attachmentRefID]]:[])}))},We=(e,t)=>{if(t.length===0)return[...e];let n=new Map;for(let t of e)n.set(t.partID,t);for(let e of t)n.set(e.partID,e);let r=new Set,i=[];for(let t of e){let e=n.get(t.partID);e&&(i.push(e),r.add(t.partID))}for(let e of t)r.has(e.partID)||(i.push(e),r.add(e.partID));return i},Ge=t({AssistantView:()=>Qe}),Ke={},qe=[],Je=[],Ye=(e,t,n)=>[...e===void 0?[]:[{type:`text`,text:e}],...(t??[]).flatMap(e=>[{type:`text`,text:e.text,...e.synthetic===!0?{synthetic:!0}:{}},...(e.attachments??[]).map(e=>({type:`file`,mime:e.mimeType,url:e.dataUrl}))]),...(n??[]).map(e=>({type:`file`,mime:e.mimeType,url:e.dataUrl}))],Xe=e=>{let t=(0,q.c)(11),{assistant:n,onBack:r}=e,{t:i}=g(),a;t[0]===n?a=t[1]:(a=n?_(n.name):null,t[0]=n,t[1]=a);let o=a,s=n&&o?o.displayName||n.name:``,c;t[2]!==s||t[3]!==i?(c=s||i(`assistants.title`),t[2]=s,t[3]=i,t[4]=c):c=t[4];let l;t[5]===i?l=t[6]:(l=i(`assistants.actions.backToChat`),t[5]=i,t[6]=l);let u;return t[7]!==r||t[8]!==c||t[9]!==l?(u=(0,Y.jsx)(z,{title:c,backAriaLabel:l,onBack:r}),t[7]=r,t[8]=c,t[9]=l,t[10]=u):u=t[10],u},Ze=e=>{let t=(0,q.c)(45),{assistantID:n,displayName:r,avatarEmoji:i,modeLabel:a,selected:o,enabled:s,editLabel:c,deleteLabel:l,onSelect:u,onEdit:d,onDelete:f}=e,[p,m]=J.useState(!1),g;t[0]===u?g=t[1]:(g=()=>u(),t[0]=u,t[1]=g);let _=h(g),v;t[2]===d?v=t[3]:(v=()=>{m(!1),d()},t[2]=d,t[3]=v);let y=h(v),b;t[4]===f?b=t[5]:(b=()=>{m(!1),f()},t[4]=f,t[5]=b);let x=h(b),S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(S=e=>{e.preventDefault(),m(!0)},t[6]=S):S=t[6];let C=o?`border-border/50 bg-[var(--surface-elevated)]`:`border-transparent hover:bg-interactive-hover`,w=!s&&`opacity-65`,T;t[7]!==C||t[8]!==w?(T=pe(`flex w-full min-h-11 items-center gap-3 rounded-xl border px-3 py-3 text-left outline-none transition-[background-color,border-color,transform,opacity] duration-150 ease-out active:scale-[0.995] focus-visible:ring-2 focus-visible:ring-[var(--interactive-focus-ring)] motion-reduce:transition-none`,C,w),t[7]=C,t[8]=w,t[9]=T):T=t[9];let E;t[10]!==_||t[11]!==o||t[12]!==T?(E=(0,Y.jsx)(`button`,{type:`button`,role:`option`,"aria-selected":o,onClick:_,onContextMenu:S,className:T}),t[10]=_,t[11]=o,t[12]=T,t[13]=E):E=t[13];let D;t[14]!==n||t[15]!==i||t[16]!==r?(D=(0,Y.jsx)(fe,{name:n,emoji:i,size:24,label:r}),t[14]=n,t[15]=i,t[16]=r,t[17]=D):D=t[17];let O;t[18]===r?O=t[19]:(O=(0,Y.jsx)(`span`,{className:`block truncate typography-ui-label font-medium`,children:r}),t[18]=r,t[19]=O);let k;t[20]===a?k=t[21]:(k=(0,Y.jsx)(`span`,{className:`mt-0.5 block truncate typography-micro text-muted-foreground`,children:a}),t[20]=a,t[21]=k);let A;t[22]!==O||t[23]!==k?(A=(0,Y.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[O,k]}),t[22]=O,t[23]=k,t[24]=A):A=t[24];let j;t[25]!==A||t[26]!==E||t[27]!==D?(j=(0,Y.jsxs)(Ce,{render:E,children:[D,A]}),t[25]=A,t[26]=E,t[27]=D,t[28]=j):j=t[28];let M;t[29]===Symbol.for(`react.memo_cache_sentinel`)?(M=(0,Y.jsx)(me,{name:`edit`,className:`size-4`}),t[29]=M):M=t[29];let N;t[30]!==c||t[31]!==y?(N=(0,Y.jsxs)(Ee,{onClick:y,children:[M,c]}),t[30]=c,t[31]=y,t[32]=N):N=t[32];let P;t[33]===Symbol.for(`react.memo_cache_sentinel`)?(P=(0,Y.jsx)(we,{}),t[33]=P):P=t[33];let F;t[34]===Symbol.for(`react.memo_cache_sentinel`)?(F=(0,Y.jsx)(me,{name:`delete-bin`,className:`size-4`}),t[34]=F):F=t[34];let I;t[35]!==l||t[36]!==x?(I=(0,Y.jsxs)(Ee,{onClick:x,className:`text-[var(--status-error)] focus:text-[var(--status-error)] data-[highlighted]:text-[var(--status-error)] [&_svg]:text-[var(--status-error)]`,children:[F,l]}),t[35]=l,t[36]=x,t[37]=I):I=t[37];let L;t[38]!==N||t[39]!==I?(L=(0,Y.jsxs)(Te,{className:`min-w-[10rem]`,children:[N,P,I]}),t[38]=N,t[39]=I,t[40]=L):L=t[40];let R;return t[41]!==p||t[42]!==j||t[43]!==L?(R=(0,Y.jsxs)(De,{open:p,onOpenChange:m,children:[j,L]}),t[41]=p,t[42]=j,t[43]=L,t[44]=R):R=t[44],R},Qe=({activeOverride:e,onMobileBack:t})=>{let{t:u}=g(),{isMobile:d}=ve(),f=xe(),p=J.useSyncExternalStore(n,r,r),S=a(),E=i(e=>e.activeMainTab===`assistant`),A=e??E,L=i(e=>e.isMobile),R=d||L,z=I(),ce=le(),B=ce.data,V=ue(e=>e.assistantByTransport[p]??null),he=ue(e=>e.selectAssistant),ge=ue(e=>e.requestCreate),H=B?.assistants.find(e=>e.id===V)??null,U=H?.id??``,W=H?.sessionID??``,G=H?.effectiveWorkspacePath??``,K=J.useMemo(()=>o({transportIdentity:p},`assistant:${U}`),[U,p]),Ce=l(K),we=b(e=>e.draftAttachmentViews[Ce]??Ke),Te=b(e=>e.drafts[Ce]),Ee=J.useMemo(()=>{let e=He(Te,we);return e.length===0?qe:e},[we,Te]),De=Te?.attachments,q=Te?.syntheticParts,Ae=J.useMemo(()=>!De||!q?``:`${De.map(e=>e.attachmentRefID).join(``)}\u0004${q.map(e=>`${e.partID}\u0002${e.attachments.map(e=>e.attachmentRefID).join(``)}`).join(``)}`,[De,q]);J.useEffect(()=>{U&&b.getState().hydrateDraftAttachments(K)},[U,K,Ae]);let X=F(G||null,{enabled:!!G&&A}),Z=D(G||null,{enabled:!!G&&A}),Pe=N(W,G||void 0),Le=O(W,G||void 0),ze=j(W),Be=ye(),[Ge,Qe]=J.useState(()=>new Map),$e=J.useRef(0),et=J.useRef(Ve()),tt=Ge.get(U)??Je,[,nt]=J.useState(!1),rt=J.useRef(()=>{});rt.current=()=>{m.error(u(`assistants.composer.selectionSaveFailed`))};let it=J.useRef(null);it.current||=new je(nt,e=>rt.current(e));let at=J.useMemo(()=>({assistantID:U,transportIdentity:p,runtimeGeneration:S}),[U,S,p]),Q=it.current,ot=J.useMemo(()=>({transport:p,assistantID:U}),[U,p]),st=h(async(e,t=p)=>{await et.current.clearExclusive({transport:t,assistantID:e})}),ct=h(e=>{et.current.rollbackAllBestEffort(e).catch(()=>void 0)});J.useEffect(()=>{!V&&B?.assistants[0]&&he(B.assistants[0].id)},[he,V,B?.assistants]),J.useEffect(()=>{ce.isSuccess&&V&&!H&&he(B?.assistants[0]?.id??null)},[H,he,V,B?.assistants,ce.isSuccess]),J.useEffect(()=>{A&&U&&!W&&ae(U)},[A,U,W]),J.useEffect(()=>{$e.current++,Qe(new Map),ct({excludeTransport:p})},[p,S,ct]),J.useEffect(()=>()=>{$e.current++,ct()},[ct]),J.useEffect(()=>{Q.activate(at)},[Q,at]),J.useEffect(()=>()=>{Q.dispose()},[Q]),J.useEffect(()=>{U&&et.current.rollbackAndClearIfBindingMismatch(ot,{assistantID:U,sessionID:W,directory:G,sessionGeneration:H?.sessionGeneration??-1,transport:p,runtimeGeneration:S}).catch(()=>void 0)},[H?.sessionGeneration,U,G,S,W,ot,p]);let lt=h(e=>at.assistantID?Q.enqueue(at,e,async({identity:e,selection:t,signal:n})=>{await Me(e,t,{readSnapshot:()=>te(void 0,e.transportIdentity),ensureSnapshot:e=>re(e),updateAssistant:ne,signal:n,assertAuthoritative:()=>{if(Q.assertAuthoritative(e),r()!==e.transportIdentity||a()!==e.runtimeGeneration)throw new ke}})}):Promise.reject(Error(`assistant_unavailable`))),ut=J.useMemo(()=>Se(Z.data),[Z.data]),dt=h(e=>{if(!H)return;let t=x(ut,H.agent??void 0,e);if(t){let e=T({providerID:H.providerID,modelID:H.modelID,agent:H.agent},t,ut,X.data??[]),n=e.providerID===H.providerID&&e.modelID===H.modelID;lt({...e,agent:e.agent??void 0,variant:n?H.variant??void 0:void 0})}}),$=h(async(e,t)=>{e.sessionID&&await Be.ensureSessionRenderable(e.sessionID,{directory:e.directory,...t?.force?{force:!0}:{}})}),ft=H?.sessionGeneration;J.useEffect(()=>{!A||!U||!W||!G||ft===void 0||$({sessionID:W,directory:G,sessionGeneration:ft},{force:!0})},[A,U,G,$,ft,W]);let pt=h((e,t)=>{if(t.length===0)return;let n=new Set(t);Qe(t=>{let r=t.get(e);if(!r?.some(e=>n.has(e.info.id)))return t;let i=new Map(t),a=r.filter(e=>!n.has(e.info.id));return a.length>0?i.set(e,a):i.delete(e),i})}),mt=h((e,t,n)=>{Qe(r=>{let i=r.get(e);if(!i)return r;let a=Fe(i,t,n);if(a===i)return r;let o=new Map(r);return o.set(e,a),o})}),ht=h(e=>{pt(U,e)}),gt=h(async e=>{if(!W||!G)throw Error(`assistant_unavailable`);P(W,G).some(t=>t?.id===e)&&(await w(W,e,{directory:G,draftKey:K,restorePrimaryInput:!1}),await st(U))}),_t=h(async(e,t)=>{if(!H||H.mode!==`continuous`)return;if(!W||!G)throw Error(`assistant_unavailable`);if(!P(W,G).some(t=>t?.id===e))return;if(t.info.id!==e||t.info.sessionID!==W||t.info.role!==`user`)throw Error(`The selected user message is unavailable`);let n={assistantID:H.id,sessionID:W,directory:G,sessionGeneration:H.sessionGeneration,messageID:e,transport:p,runtimeGeneration:S},i=Re(n),o=await et.current.stageExclusive(i,async()=>{let i=await k(W,e,t,{directory:G,draftKey:K}),o=r()===n.transport&&a()===n.runtimeGeneration,s=o?te(void 0,n.transport)?.assistants.find(e=>e.id===n.assistantID):void 0,c=!!(s&&s.mode===`continuous`&&s.sessionID===n.sessionID&&s.sessionGeneration===n.sessionGeneration&&(s.effectiveWorkspacePath??``)===n.directory);if(o&&c)return{identity:n,rollback:()=>i.rollback()};let l=await i.rollback();return l.status===`failed`||l.status===`skipped`?{identity:n,rollback:()=>i.rollback(),protectOnStale:!0}:null});if(o.kind===`blocked`)throw Error(`assistant_stage_message_edit_prior_blocked`);if(o.kind===`stale_protected`)throw Error(`assistant_stage_message_edit_rollback_failed`)}),vt=J.useMemo(()=>{let e=C(K,()=>b.getState());return{busy:!1,attachments:Ee,addAttachment:t=>e.addLocal(t),removeAttachment:t=>e.removeByAttachmentID(t),clearAttachments:()=>e.clearRootAttachments(),restoreAttachments:t=>e.restoreRootAttachments(t),pendingInput:null,consumePendingInput:()=>null,pendingPreset:null,consumePendingPreset:()=>null,consumeSyntheticParts:()=>{let e=b.getState(),t=e.draftAttachmentViews[l(K)]??Ke,n=e.consumeDraftSyntheticParts(K,y);return n?Ue(n,t):null},restoreSyntheticParts:e=>{(async()=>{let t=b.getState(),n=e.map(e=>({partID:e.partID??s(),text:e.text,attachments:[],...e.synthetic===!0?{synthetic:!0}:{}})),r=We(t.getDraft(K)?.syntheticParts??[],n);t.setDraftSyntheticParts(K,r);for(let r=0;r<n.length;r++){let i=n[r].partID;for(let n of e[r]?.attachments??[])n.source===`server`&&n.dataUrl?t.addDraftDurableAttachment(K,{attachmentID:n.id,filename:n.filename,mimeType:n.mimeType,size:n.size,source:`server`,url:n.dataUrl,serverPath:n.serverPath,partID:i}):await t.addDraftLocalAttachment(K,n.file,{attachmentID:n.id,filename:n.filename,source:n.source===`vscode`?`vscode`:`local`,vscodePath:n.vscodePath,vscodeSource:n.vscodeSource===`selection`?`selection`:void 0,partID:i})}})()},inlineDrafts:[],removeInlineDraft:()=>{},restoreInlineDrafts:()=>{},history:ze,captureRuntime:()=>b.getState().captureDraftRuntime(),getDraft:e=>b.getState().getDraft(e),abortPrompt:{sessionID:null,clear:()=>{}}}},[Ee,K,ze]),yt=J.useMemo(()=>{let e=(X.data??[]).find(e=>e.id===H?.providerID)?.models?.find(e=>e.id===H?.modelID);return be(e)},[H?.modelID,H?.providerID,X.data]),bt=Pe.length>0,xt=J.useMemo(()=>{if(!H||!W||!G)return null;let e={sessionID:W,directory:G,sessionGeneration:H.sessionGeneration};return{kind:`secondary`,surfaceID:`assistant:${H.id}`,active:A,sessionID:W,directory:G,draftKey:K,transportIdentity:p,runtimeGeneration:S,deliveryTarget:{kind:`assistant`,assistantID:H.id},resources:vt,...H.mode===`stateless`?{queueSessionID:`assistant:${H.id}`}:{},selection:{value:{providerID:H.providerID,modelID:H.modelID,agent:H.agent??void 0,variant:H.variant??void 0},catalog:{providers:X.data??[],agents:ut,variants:yt,variantsReady:X.isSuccess,ready:X.isSuccess&&Z.isSuccess,loading:X.isPending||Z.isPending,error:X.isError||Z.isError},change:lt,flush:()=>Q.flush(at)},activity:{phase:Le?.type===`busy`?`busy`:Le?.type===`retry`?`retry`:`idle`,canAbort:Le?.type===`busy`||Le?.type===`retry`},commands:{sessionID:W,hasMessages:bt,hasNewDraft:!1},commandPolicy:e=>e.name!==`fork`&&e.name!==`thread`,backend:{send:async t=>{let n;for(let t of P(e.sessionID,e.directory)){let e=typeof t?.id==`string`?t.id:``;/^msg_[0-9a-f]{12}[0-9A-Za-z]{14}$/.test(e)&&(!n||e>n)&&(n=e)}let r=c(`msg`,n);t.options?.commitStagedMessageEdit&&et.current.clear({transport:p,assistantID:H.id});let i=M({messageID:r,sessionID:e.sessionID,providerID:t.providerID??H.providerID,modelID:t.modelID??H.modelID,agent:t.agent??H.agent??void 0,text:t.text,attachments:t.attachments,additionalParts:t.parts});Qe(e=>{let t=new Map(e);return t.set(H.id,[...e.get(H.id)??[],i]),t});let a;try{a=await oe(H.id,e,r,Ye(t.text,t.parts,t.attachments))}catch(e){throw pt(H.id,[r]),e}if(z.data?.serverInstanceID){let e=_(H.name);v({serverInstanceID:z.data.serverInstanceID,assistantID:H.id,name:e.displayName||H.name,avatarSeed:H.id,...e.avatarEmoji?{avatarEmoji:e.avatarEmoji}:{}}).catch(()=>void 0)}a.binding.sessionID&&mt(H.id,r,a.binding.sessionID);let o=$e.current;Ie({binding:a.binding,refresh:t=>$(t,{force:t.sessionID!==e.sessionID||t.sessionGeneration!==e.sessionGeneration}),isCurrent:()=>$e.current===o})},sendQueued:async()=>{throw Error(`assistant-server-queue-required`)},create:async()=>{let e=await ee(H.id);await st(H.id),await $(e,{force:!0})},compact:async()=>{let t=await se(H.id,e);await st(H.id),await $(t.binding,{force:!0})},abort:async()=>{await ie(H.id,e)}},shortcuts:{cycle:dt,new:async()=>{let e=await ee(H.id);await st(H.id),await $(e,{force:!0})},abort:async()=>{await ie(H.id,e)},submit:()=>{}}}},[A,H,z.data?.serverInstanceID,lt,st,dt,G,K,bt,X.data,X.isError,X.isPending,X.isSuccess,Z.isError,Z.isPending,Z.isSuccess,$,mt,pt,vt,S,Q,at,W,Le,p,yt,ut]),St=h(()=>{if(ge(),f){f.openSettings();return}let e=i.getState();e.setSettingsPage(`assistants`),e.setSettingsDialogOpen(!0)}),Ct=h(e=>{de(e,f?{openMobileSettings:f.openSettings}:void 0)}),[wt,Tt]=J.useState(null),Et=h(e=>{Tt(e)}),Dt=h(e=>{e||Tt(null)}),Ot=h(()=>{i.getState().setActiveMainTab(`chat`)}),kt=h(()=>{if(t){t();return}Ot()}),At=(e,t,n,r)=>(0,Y.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[R?(0,Y.jsx)(Xe,{assistant:H,onBack:kt}):null,(0,Y.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col items-center justify-center px-6 text-center`,children:[(0,Y.jsx)(me,{name:e,className:`size-6 text-muted-foreground`}),(0,Y.jsx)(`h1`,{className:`mt-4 typography-ui-header font-semibold`,children:t}),n?(0,Y.jsx)(`p`,{className:`mt-2 max-w-md typography-ui text-muted-foreground`,children:n}):null,r?(0,Y.jsx)(`div`,{className:`mt-5`,children:r}):null]})]});if(z.isPending||ce.isPending)return At(`ai-agent`,u(`assistants.state.unavailable`));if(z.isError||!z.data?.supported||!z.data.enabled||!B?.enabled)return At(`cloud-off`,u(`assistants.state.unavailable`));if(!B.assistants.length)return At(`ai-agent`,u(`assistants.onboarding.title`),u(`assistants.onboarding.description`),(0,Y.jsx)(_e,{onClick:St,children:u(`assistants.onboarding.action`)}));if(!H)return At(`ai-agent`,u(`assistants.state.unavailable`));if(!xt)return(0,Y.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col bg-background`,children:[R?(0,Y.jsx)(Xe,{assistant:H,onBack:kt}):null,(0,Y.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col items-center justify-center gap-3 px-6`,"aria-busy":`true`,"aria-label":u(`assistants.state.unavailable`),children:[(0,Y.jsx)(`div`,{className:`size-10 animate-pulse rounded-xl bg-[var(--surface-muted)] motion-reduce:animate-none`}),(0,Y.jsx)(`div`,{className:`h-3.5 w-36 animate-pulse rounded-md bg-[var(--surface-muted)] motion-reduce:animate-none`})]})]});let jt=_(H.name),Mt=H.enabled?ce.isError?u(`assistants.state.staleSnapshot`):null:u(`assistants.state.assistantDisabled`);return(0,Y.jsxs)(`div`,{className:`relative flex h-full min-h-0 overflow-hidden bg-background`,"data-presentation":`workspace`,children:[R?null:(0,Y.jsxs)(`section`,{className:`flex h-full min-h-0 w-[clamp(16rem,22vw,20rem)] shrink-0 flex-col overflow-hidden`,children:[(0,Y.jsx)(`header`,{className:`shrink-0 px-4 pb-3 pt-4 sm:px-5`,children:(0,Y.jsx)(`h1`,{className:`truncate typography-ui-label font-semibold text-foreground`,children:u(`assistants.title`)})}),(0,Y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-3 pb-4 sm:px-4`,role:`listbox`,"aria-label":u(`assistants.listAria`),children:(0,Y.jsx)(`div`,{className:`flex flex-col gap-1 border-t border-border/40 pt-3`,children:B.assistants.map(e=>{let t=e.id===V,n=_(e.name);return(0,Y.jsx)(Ze,{assistantID:e.id,displayName:n.displayName,avatarEmoji:n.avatarEmoji??void 0,modeLabel:e.mode===`stateless`?u(`assistants.mode.stateless`):u(`assistants.mode.continuous`),selected:t,enabled:e.enabled,editLabel:u(`assistants.menu.edit`),deleteLabel:u(`assistants.settings.delete`),onSelect:()=>he(e.id),onEdit:()=>Ct(e.id),onDelete:()=>Et(e)},e.id)})})})]}),(0,Y.jsx)(Ne,{assistant:wt,open:wt!==null,onOpenChange:Dt}),(0,Y.jsxs)(`div`,{className:pe(`flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden bg-background`,!R&&`border-l border-border/60`),children:[R?(0,Y.jsx)(Xe,{assistant:H,onBack:kt}):(0,Y.jsxs)(`header`,{className:`flex h-14 shrink-0 items-center gap-3 border-b border-border/40 px-4 sm:px-5`,children:[(0,Y.jsx)(fe,{name:H.id,emoji:jt.avatarEmoji,size:24,label:jt.displayName||H.name}),(0,Y.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Y.jsx)(`div`,{className:`truncate typography-ui-label font-medium`,children:jt.displayName}),(0,Y.jsx)(`div`,{className:`mt-0.5 truncate typography-micro leading-none text-muted-foreground/70`,children:H.mode===`stateless`?u(`assistants.conversation.statelessHint`):u(`assistants.conversation.continuousHint`)})]})]}),(0,Y.jsx)(Oe,{onRevertMessage:gt,onEditMessage:H.mode===`continuous`?_t:void 0,assistant:H,sessionID:W,warning:Mt,surface:xt,pendingUserMessages:tt,onPendingUserMessagesMaterialized:ht})]})]})};export{Ge as n,Ne as r,Qe as t};
|