@openchamber/web 1.2.7 → 1.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/bin/cli.js +274 -4
- package/dist/assets/{ToolOutputDialog-BBROuRhd.js → ToolOutputDialog-BYb4g1c7.js} +2 -2
- package/dist/assets/{index-vvDNUcuS.js → index--hIzFLog.js} +2 -2
- package/dist/assets/{index-BmFAlpPD.css → index-BSN-fGG5.css} +1 -1
- package/dist/assets/{main-CjbXdQMY.js → main-DI52tBPC.js} +39 -39
- package/dist/assets/{vendor-.pnpm-Bax6Hn5Z.js → vendor-.pnpm-Buk6Khtx.js} +324 -324
- package/dist/index.html +3 -3
- package/package.json +1 -1
- package/server/index.js +106 -0
- package/server/lib/package-manager.js +255 -0
package/README.md
CHANGED
|
@@ -5,13 +5,22 @@ Web interface for the [OpenCode](https://opencode.ai) AI coding agent.
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
8
|
+
# Quick install (auto-detects your package manager)
|
|
9
|
+
curl -fsSL https://raw.githubusercontent.com/btriapitsyn/openchamber/main/scripts/install.sh | bash
|
|
9
10
|
|
|
11
|
+
# Or install manually
|
|
12
|
+
npm add -g @openchamber/web # or pnpm, yarn, bun
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```bash
|
|
10
18
|
openchamber # Start on port 3000
|
|
11
19
|
openchamber --port 8080 # Custom port
|
|
12
20
|
openchamber --daemon # Background mode
|
|
13
21
|
openchamber --ui-password secret # Password-protect UI
|
|
14
22
|
openchamber stop # Stop server
|
|
23
|
+
openchamber update # Update to latest version
|
|
15
24
|
```
|
|
16
25
|
|
|
17
26
|
## Prerequisites
|
package/bin/cli.js
CHANGED
|
@@ -94,6 +94,7 @@ COMMANDS:
|
|
|
94
94
|
stop Stop running instance(s)
|
|
95
95
|
restart Stop and start the server
|
|
96
96
|
status Show server status
|
|
97
|
+
update Check for and install updates
|
|
97
98
|
|
|
98
99
|
OPTIONS:
|
|
99
100
|
-p, --port Web server port (default: ${DEFAULT_PORT})
|
|
@@ -112,6 +113,7 @@ EXAMPLES:
|
|
|
112
113
|
openchamber stop # Stop all running instances
|
|
113
114
|
openchamber stop --port 3000 # Stop specific instance
|
|
114
115
|
openchamber status # Check status
|
|
116
|
+
openchamber update # Update to latest version
|
|
115
117
|
`);
|
|
116
118
|
}
|
|
117
119
|
|
|
@@ -245,6 +247,12 @@ async function getPidFilePath(port) {
|
|
|
245
247
|
return path.join(tmpDir, `openchamber-${port}.pid`);
|
|
246
248
|
}
|
|
247
249
|
|
|
250
|
+
async function getInstanceFilePath(port) {
|
|
251
|
+
const os = await import('os');
|
|
252
|
+
const tmpDir = os.tmpdir();
|
|
253
|
+
return path.join(tmpDir, `openchamber-${port}.json`);
|
|
254
|
+
}
|
|
255
|
+
|
|
248
256
|
function readPidFile(pidFilePath) {
|
|
249
257
|
try {
|
|
250
258
|
const content = fs.readFileSync(pidFilePath, 'utf8').trim();
|
|
@@ -276,6 +284,50 @@ function removePidFile(pidFilePath) {
|
|
|
276
284
|
}
|
|
277
285
|
}
|
|
278
286
|
|
|
287
|
+
/**
|
|
288
|
+
* Read stored instance options (port, daemon, uiPassword)
|
|
289
|
+
*/
|
|
290
|
+
function readInstanceOptions(instanceFilePath) {
|
|
291
|
+
try {
|
|
292
|
+
const content = fs.readFileSync(instanceFilePath, 'utf8');
|
|
293
|
+
return JSON.parse(content);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Write instance options for restart/update to reuse
|
|
301
|
+
*/
|
|
302
|
+
function writeInstanceOptions(instanceFilePath, options) {
|
|
303
|
+
try {
|
|
304
|
+
// Only store non-sensitive restart-relevant options
|
|
305
|
+
const toStore = {
|
|
306
|
+
port: options.port,
|
|
307
|
+
daemon: options.daemon || false,
|
|
308
|
+
// Store password existence but not value - will use env var
|
|
309
|
+
hasUiPassword: typeof options.uiPassword === 'string',
|
|
310
|
+
};
|
|
311
|
+
// For daemon mode, we need to store the password to restart properly
|
|
312
|
+
if (options.daemon && typeof options.uiPassword === 'string') {
|
|
313
|
+
toStore.uiPassword = options.uiPassword;
|
|
314
|
+
}
|
|
315
|
+
fs.writeFileSync(instanceFilePath, JSON.stringify(toStore, null, 2));
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.warn(`Warning: Could not write instance file: ${error.message}`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function removeInstanceFile(instanceFilePath) {
|
|
322
|
+
try {
|
|
323
|
+
if (fs.existsSync(instanceFilePath)) {
|
|
324
|
+
fs.unlinkSync(instanceFilePath);
|
|
325
|
+
}
|
|
326
|
+
} catch (error) {
|
|
327
|
+
// Ignore
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
279
331
|
function isProcessRunning(pid) {
|
|
280
332
|
try {
|
|
281
333
|
process.kill(pid, 0);
|
|
@@ -288,6 +340,7 @@ function isProcessRunning(pid) {
|
|
|
288
340
|
const commands = {
|
|
289
341
|
async serve(options) {
|
|
290
342
|
const pidFilePath = await getPidFilePath(options.port);
|
|
343
|
+
const instanceFilePath = await getInstanceFilePath(options.port);
|
|
291
344
|
|
|
292
345
|
const existingPid = readPidFile(pidFilePath);
|
|
293
346
|
if (existingPid && isProcessRunning(existingPid)) {
|
|
@@ -323,6 +376,7 @@ const commands = {
|
|
|
323
376
|
setTimeout(() => {
|
|
324
377
|
if (isProcessRunning(child.pid)) {
|
|
325
378
|
writePidFile(pidFilePath, child.pid);
|
|
379
|
+
writeInstanceOptions(instanceFilePath, options);
|
|
326
380
|
console.log(`OpenChamber started in daemon mode on port ${options.port}`);
|
|
327
381
|
console.log(`PID: ${child.pid}`);
|
|
328
382
|
console.log(`Visit: http://localhost:${options.port}`);
|
|
@@ -338,6 +392,7 @@ const commands = {
|
|
|
338
392
|
if (typeof options.uiPassword === 'string') {
|
|
339
393
|
process.env.OPENCHAMBER_UI_PASSWORD = options.uiPassword;
|
|
340
394
|
}
|
|
395
|
+
writeInstanceOptions(instanceFilePath, options);
|
|
341
396
|
const { startWebUiServer } = await import(serverPath);
|
|
342
397
|
await startWebUiServer({
|
|
343
398
|
port: options.port,
|
|
@@ -365,10 +420,12 @@ const commands = {
|
|
|
365
420
|
const pid = readPidFile(pidFilePath);
|
|
366
421
|
|
|
367
422
|
if (pid && isProcessRunning(pid)) {
|
|
368
|
-
|
|
423
|
+
const instanceFilePath = path.join(tmpDir, `openchamber-${port}.json`);
|
|
424
|
+
runningInstances.push({ port, pid, pidFilePath, instanceFilePath });
|
|
369
425
|
} else {
|
|
370
426
|
|
|
371
427
|
removePidFile(pidFilePath);
|
|
428
|
+
removeInstanceFile(path.join(tmpDir, `openchamber-${port}.json`));
|
|
372
429
|
}
|
|
373
430
|
}
|
|
374
431
|
}
|
|
@@ -404,12 +461,14 @@ const commands = {
|
|
|
404
461
|
if (!isProcessRunning(targetInstance.pid)) {
|
|
405
462
|
clearInterval(checkShutdown);
|
|
406
463
|
removePidFile(targetInstance.pidFilePath);
|
|
464
|
+
removeInstanceFile(targetInstance.instanceFilePath);
|
|
407
465
|
console.log('OpenChamber stopped successfully');
|
|
408
466
|
} else if (attempts >= maxAttempts) {
|
|
409
467
|
clearInterval(checkShutdown);
|
|
410
468
|
console.log('Force killing process...');
|
|
411
469
|
process.kill(targetInstance.pid, 'SIGKILL');
|
|
412
470
|
removePidFile(targetInstance.pidFilePath);
|
|
471
|
+
removeInstanceFile(targetInstance.instanceFilePath);
|
|
413
472
|
console.log('OpenChamber force stopped');
|
|
414
473
|
}
|
|
415
474
|
}, 500);
|
|
@@ -437,6 +496,7 @@ const commands = {
|
|
|
437
496
|
if (!isProcessRunning(instance.pid)) {
|
|
438
497
|
clearInterval(checkShutdown);
|
|
439
498
|
removePidFile(instance.pidFilePath);
|
|
499
|
+
removeInstanceFile(instance.instanceFilePath);
|
|
440
500
|
console.log(` Port ${instance.port} stopped successfully`);
|
|
441
501
|
resolve(true);
|
|
442
502
|
} else if (attempts >= maxAttempts) {
|
|
@@ -445,6 +505,7 @@ const commands = {
|
|
|
445
505
|
try {
|
|
446
506
|
process.kill(instance.pid, 'SIGKILL');
|
|
447
507
|
removePidFile(instance.pidFilePath);
|
|
508
|
+
removeInstanceFile(instance.instanceFilePath);
|
|
448
509
|
console.log(` Port ${instance.port} force stopped`);
|
|
449
510
|
} catch (e) {
|
|
450
511
|
|
|
@@ -464,11 +525,95 @@ const commands = {
|
|
|
464
525
|
},
|
|
465
526
|
|
|
466
527
|
async restart(options) {
|
|
467
|
-
await
|
|
468
|
-
|
|
528
|
+
const os = await import('os');
|
|
529
|
+
const tmpDir = os.tmpdir();
|
|
530
|
+
|
|
531
|
+
// Find running instances to get their stored options
|
|
532
|
+
let instancesToRestart = [];
|
|
533
|
+
|
|
534
|
+
try {
|
|
535
|
+
const files = fs.readdirSync(tmpDir);
|
|
536
|
+
const pidFiles = files.filter(file => file.startsWith('openchamber-') && file.endsWith('.pid'));
|
|
537
|
+
|
|
538
|
+
for (const file of pidFiles) {
|
|
539
|
+
const port = parseInt(file.replace('openchamber-', '').replace('.pid', ''));
|
|
540
|
+
if (!isNaN(port)) {
|
|
541
|
+
const pidFilePath = path.join(tmpDir, file);
|
|
542
|
+
const instanceFilePath = path.join(tmpDir, `openchamber-${port}.json`);
|
|
543
|
+
const pid = readPidFile(pidFilePath);
|
|
544
|
+
|
|
545
|
+
if (pid && isProcessRunning(pid)) {
|
|
546
|
+
const storedOptions = readInstanceOptions(instanceFilePath);
|
|
547
|
+
instancesToRestart.push({
|
|
548
|
+
port,
|
|
549
|
+
pid,
|
|
550
|
+
pidFilePath,
|
|
551
|
+
instanceFilePath,
|
|
552
|
+
storedOptions: storedOptions || { port, daemon: false },
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
} catch (error) {
|
|
558
|
+
// Ignore
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const portWasSpecified = process.argv.includes('--port') || process.argv.includes('-p');
|
|
562
|
+
|
|
563
|
+
if (instancesToRestart.length === 0) {
|
|
564
|
+
console.log('No running OpenChamber instances to restart');
|
|
565
|
+
console.log('Use "openchamber serve" to start a new instance');
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
if (portWasSpecified) {
|
|
570
|
+
// Restart specific instance
|
|
571
|
+
const target = instancesToRestart.find(inst => inst.port === options.port);
|
|
572
|
+
if (!target) {
|
|
573
|
+
console.log(`No OpenChamber instance found running on port ${options.port}`);
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
instancesToRestart = [target];
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
for (const instance of instancesToRestart) {
|
|
580
|
+
console.log(`Restarting OpenChamber on port ${instance.port}...`);
|
|
581
|
+
|
|
582
|
+
// Merge stored options with any explicitly provided options
|
|
583
|
+
const restartOptions = {
|
|
584
|
+
...instance.storedOptions,
|
|
585
|
+
// CLI-provided options override stored ones
|
|
586
|
+
...(portWasSpecified ? { port: options.port } : {}),
|
|
587
|
+
...(process.argv.includes('--daemon') || process.argv.includes('-d') ? { daemon: options.daemon } : {}),
|
|
588
|
+
...(process.argv.includes('--ui-password') ? { uiPassword: options.uiPassword } : {}),
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
// Stop the instance
|
|
592
|
+
try {
|
|
593
|
+
process.kill(instance.pid, 'SIGTERM');
|
|
594
|
+
// Wait for it to stop
|
|
595
|
+
let attempts = 0;
|
|
596
|
+
while (isProcessRunning(instance.pid) && attempts < 20) {
|
|
597
|
+
await new Promise(resolve => setTimeout(resolve, 250));
|
|
598
|
+
attempts++;
|
|
599
|
+
}
|
|
600
|
+
if (isProcessRunning(instance.pid)) {
|
|
601
|
+
process.kill(instance.pid, 'SIGKILL');
|
|
602
|
+
}
|
|
603
|
+
removePidFile(instance.pidFilePath);
|
|
604
|
+
} catch (error) {
|
|
605
|
+
console.warn(`Warning: Could not stop instance: ${error.message}`);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// Small delay before restart
|
|
609
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
610
|
+
|
|
611
|
+
// Start with merged options
|
|
612
|
+
await commands.serve(restartOptions);
|
|
613
|
+
}
|
|
469
614
|
},
|
|
470
615
|
|
|
471
|
-
async status(
|
|
616
|
+
async status() {
|
|
472
617
|
const os = await import('os');
|
|
473
618
|
const tmpDir = os.tmpdir();
|
|
474
619
|
|
|
@@ -527,6 +672,131 @@ const commands = {
|
|
|
527
672
|
}
|
|
528
673
|
},
|
|
529
674
|
|
|
675
|
+
async update() {
|
|
676
|
+
const os = await import('os');
|
|
677
|
+
const tmpDir = os.tmpdir();
|
|
678
|
+
const packageManagerPath = path.join(__dirname, '..', 'server', 'lib', 'package-manager.js');
|
|
679
|
+
const {
|
|
680
|
+
checkForUpdates,
|
|
681
|
+
executeUpdate,
|
|
682
|
+
detectPackageManager,
|
|
683
|
+
getCurrentVersion,
|
|
684
|
+
} = await import(packageManagerPath);
|
|
685
|
+
|
|
686
|
+
// Check for running instances before update
|
|
687
|
+
let runningInstances = [];
|
|
688
|
+
try {
|
|
689
|
+
const files = fs.readdirSync(tmpDir);
|
|
690
|
+
const pidFiles = files.filter(file => file.startsWith('openchamber-') && file.endsWith('.pid'));
|
|
691
|
+
|
|
692
|
+
for (const file of pidFiles) {
|
|
693
|
+
const port = parseInt(file.replace('openchamber-', '').replace('.pid', ''));
|
|
694
|
+
if (!isNaN(port)) {
|
|
695
|
+
const pidFilePath = path.join(tmpDir, file);
|
|
696
|
+
const instanceFilePath = path.join(tmpDir, `openchamber-${port}.json`);
|
|
697
|
+
const pid = readPidFile(pidFilePath);
|
|
698
|
+
|
|
699
|
+
if (pid && isProcessRunning(pid)) {
|
|
700
|
+
const storedOptions = readInstanceOptions(instanceFilePath);
|
|
701
|
+
runningInstances.push({
|
|
702
|
+
port,
|
|
703
|
+
pid,
|
|
704
|
+
pidFilePath,
|
|
705
|
+
instanceFilePath,
|
|
706
|
+
storedOptions: storedOptions || { port, daemon: true },
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
} catch (error) {
|
|
712
|
+
// Ignore
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
console.log('Checking for updates...');
|
|
716
|
+
console.log(`Current version: ${getCurrentVersion()}`);
|
|
717
|
+
|
|
718
|
+
const updateInfo = await checkForUpdates();
|
|
719
|
+
|
|
720
|
+
if (updateInfo.error) {
|
|
721
|
+
console.error(`Error: ${updateInfo.error}`);
|
|
722
|
+
process.exit(1);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
if (!updateInfo.available) {
|
|
726
|
+
console.log('\nYou are running the latest version.');
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
console.log(`\nNew version available: ${updateInfo.version}`);
|
|
731
|
+
|
|
732
|
+
if (updateInfo.body) {
|
|
733
|
+
console.log('\nChangelog:');
|
|
734
|
+
console.log('─'.repeat(40));
|
|
735
|
+
// Simple formatting for CLI
|
|
736
|
+
const formatted = updateInfo.body
|
|
737
|
+
.replace(/^## \[(\d+\.\d+\.\d+)\] - \d{4}-\d{2}-\d{2}/gm, '\nv$1')
|
|
738
|
+
.replace(/^### /gm, '\n')
|
|
739
|
+
.replace(/^- /gm, ' • ');
|
|
740
|
+
console.log(formatted);
|
|
741
|
+
console.log('─'.repeat(40));
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// Stop running instances before update
|
|
745
|
+
if (runningInstances.length > 0) {
|
|
746
|
+
console.log(`\nStopping ${runningInstances.length} running instance(s) before update...`);
|
|
747
|
+
for (const instance of runningInstances) {
|
|
748
|
+
try {
|
|
749
|
+
process.kill(instance.pid, 'SIGTERM');
|
|
750
|
+
let attempts = 0;
|
|
751
|
+
while (isProcessRunning(instance.pid) && attempts < 20) {
|
|
752
|
+
await new Promise(resolve => setTimeout(resolve, 250));
|
|
753
|
+
attempts++;
|
|
754
|
+
}
|
|
755
|
+
if (isProcessRunning(instance.pid)) {
|
|
756
|
+
process.kill(instance.pid, 'SIGKILL');
|
|
757
|
+
}
|
|
758
|
+
removePidFile(instance.pidFilePath);
|
|
759
|
+
console.log(` Stopped instance on port ${instance.port}`);
|
|
760
|
+
} catch (error) {
|
|
761
|
+
console.warn(` Warning: Could not stop instance on port ${instance.port}`);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const pm = detectPackageManager();
|
|
767
|
+
console.log(`\nDetected package manager: ${pm}`);
|
|
768
|
+
console.log('Installing update...\n');
|
|
769
|
+
|
|
770
|
+
const result = executeUpdate(pm);
|
|
771
|
+
|
|
772
|
+
if (result.success) {
|
|
773
|
+
console.log('\nUpdate successful!');
|
|
774
|
+
|
|
775
|
+
// Restart previously running instances
|
|
776
|
+
if (runningInstances.length > 0) {
|
|
777
|
+
console.log(`\nRestarting ${runningInstances.length} instance(s)...`);
|
|
778
|
+
for (const instance of runningInstances) {
|
|
779
|
+
try {
|
|
780
|
+
// Force daemon mode for restart after update
|
|
781
|
+
const restartOptions = {
|
|
782
|
+
...instance.storedOptions,
|
|
783
|
+
daemon: true,
|
|
784
|
+
};
|
|
785
|
+
await commands.serve(restartOptions);
|
|
786
|
+
console.log(` Restarted instance on port ${instance.port}`);
|
|
787
|
+
} catch (error) {
|
|
788
|
+
console.error(` Failed to restart instance on port ${instance.port}: ${error.message}`);
|
|
789
|
+
console.log(` Run manually: openchamber serve --port ${instance.port} --daemon`);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
} else {
|
|
794
|
+
console.error('\nUpdate failed.');
|
|
795
|
+
console.error(`Exit code: ${result.exitCode}`);
|
|
796
|
+
process.exit(1);
|
|
797
|
+
}
|
|
798
|
+
},
|
|
799
|
+
|
|
530
800
|
};
|
|
531
801
|
|
|
532
802
|
async function main() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{g as L,j as e,
|
|
1
|
+
import{g as L,j as e,bg as v,bu as g,aj as P,b2 as C,au as T,b4 as w,Q as _,aT as z,aH as j,br as D,bs as O,bt as F,W}from"./vendor-.pnpm-Buk6Khtx.js";import{D as I,a as R,c as b,b as $,t as f,g as p,f as H,p as B,r as Q,d as V,e as E,h as A,S as G,i as U}from"./main-DI52tBPC.js";import"./index--hIzFLog.js";const q=r=>{const o="h-3.5 w-3.5 flex-shrink-0",t=r.toLowerCase();return t==="reasoning"?e.jsx(P,{className:o}):t==="image-preview"?e.jsx(C,{className:o}):t==="edit"||t==="multiedit"||t==="str_replace"||t==="str_replace_based_edit_tool"?e.jsx(T,{className:o}):t==="write"||t==="create"||t==="file_write"?e.jsx(w,{className:o}):t==="read"||t==="view"||t==="file_read"||t==="cat"?e.jsx(w,{className:o}):t==="bash"||t==="shell"||t==="cmd"||t==="terminal"?e.jsx(_,{className:o}):t==="list"||t==="ls"||t==="dir"||t==="list_files"?e.jsx(z,{className:o}):t==="search"||t==="grep"||t==="find"||t==="ripgrep"?e.jsx(j,{className:o}):t==="glob"?e.jsx(D,{className:o}):t==="fetch"||t==="curl"||t==="wget"||t==="webfetch"?e.jsx(O,{className:o}):t==="web-search"||t==="websearch"||t==="search_web"||t==="google"||t==="bing"||t==="duckduckgo"?e.jsx(j,{className:o}):t==="todowrite"||t==="todoread"?e.jsx(F,{className:o}):t.startsWith("git")?e.jsx(W,{className:o}):e.jsx(v,{className:o})},X=({popup:r,onOpenChange:o,syntaxTheme:t,isMobile:u})=>{const[y,N]=L.useState(u?"unified":"side-by-side");return e.jsx(I,{open:r.open,onOpenChange:o,children:e.jsxs(R,{className:b("overflow-hidden flex flex-col min-h-0 pt-3 pb-4 px-4 gap-1","[&>button]:top-1.5",u?"w-[95vw] max-w-[95vw]":"max-w-5xl",u?"[&>button]:right-1":"[&>button]:top-2.5 [&>button]:right-4"),style:{maxHeight:"90vh"},children:[e.jsx("div",{className:"flex-shrink-0 pb-1",children:e.jsxs("div",{className:"flex items-start gap-2 text-foreground typography-ui-header font-semibold",children:[r.metadata?.tool?q(r.metadata.tool):e.jsx(v,{className:"h-3.5 w-3.5 text-foreground flex-shrink-0"}),e.jsx("span",{className:"break-words flex-1 leading-tight",children:r.title}),r.isDiff&&e.jsx($,{mode:y,onModeChange:N,className:"mr-8 flex-shrink-0"})]})}),e.jsx("div",{className:"flex-1 min-h-0 rounded-xl border border-border/30 bg-muted/10 overflow-hidden",children:e.jsxs("div",{className:"tool-output-surface h-full max-h-[75vh] overflow-y-auto px-3 pr-4",children:[r.metadata?.input&&typeof r.metadata.input=="object"&&Object.keys(r.metadata.input).length>0&&r.metadata?.tool!=="todowrite"&&r.metadata?.tool!=="todoread"?(()=>{const n=r.metadata,m=n.input,a=i=>{const s=m[i];return typeof s=="string"?s:typeof s=="number"?String(s):null};return e.jsxs("div",{className:"border-b border-border/20 p-4 -mx-3",children:[e.jsx("div",{className:"typography-markdown font-medium text-muted-foreground mb-2 px-3",children:n.tool==="bash"?"Command:":n.tool==="task"?"Task Details:":"Input:"}),n.tool==="bash"&&a("command")?e.jsx("div",{className:"tool-input-surface bg-transparent rounded-xl border border-border/20 mx-3",children:e.jsx(g,{style:t,language:"bash",PreTag:"div",customStyle:f.getPopupStyles(),codeTagProps:{style:{background:"transparent",backgroundColor:"transparent",fontSize:"inherit"}},wrapLongLines:!0,children:a("command")})}):n.tool==="task"&&a("prompt")?e.jsxs("div",{className:"tool-input-surface bg-transparent rounded-xl border border-border/20 font-mono whitespace-pre-wrap text-foreground/90 mx-3",style:f.getPopupStyles(),children:[a("description")?`Task: ${a("description")}
|
|
2
2
|
`:"",a("subagent_type")?`Agent Type: ${a("subagent_type")}
|
|
3
3
|
`:"",`Instructions:
|
|
4
|
-
${a("prompt")}`]}):n.tool==="write"&&a("content")?e.jsx("div",{className:"tool-input-surface bg-transparent rounded-xl border border-border/20 mx-3",children:e.jsx(g,{style:t,language:p(a("filePath")||a("file_path")||"")||"text",PreTag:"div",customStyle:f.getPopupStyles(),codeTagProps:{style:{background:"transparent",backgroundColor:"transparent",fontSize:"inherit"}},wrapLongLines:!0,children:a("content")})}):e.jsx("div",{className:"tool-input-surface bg-transparent rounded-xl border border-border/20 font-mono whitespace-pre-wrap text-foreground/90 mx-3",style:f.getPopupStyles(),children:H(m,n.tool)})]})})():null,r.isDiff?y==="unified"?e.jsx("div",{className:"typography-code",children:B(r.content).map((n,m)=>e.jsxs("div",{className:"border-b border-border/20 last:border-b-0",children:[e.jsx("div",{className:b("bg-muted/20 px-3 py-2 font-medium text-muted-foreground border-b border-border/10 sticky top-0 z-10 break-words -mx-3",u?"typography-micro":"typography-markdown"),children:`${n.file} (line ${n.oldStart})`}),e.jsx("div",{children:n.lines.map((a,i)=>e.jsxs("div",{className:b("typography-code font-mono px-3 py-0.5 flex",a.type==="context"&&"bg-transparent",a.type==="removed"&&"bg-transparent",a.type==="added"&&"bg-transparent"),style:{lineHeight:"1.1",...a.type==="removed"?{backgroundColor:"var(--tools-edit-removed-bg)"}:a.type==="added"?{backgroundColor:"var(--tools-edit-added-bg)"}:{}},children:[e.jsx("span",{className:"text-muted-foreground/60 w-10 flex-shrink-0 text-right pr-3 self-start select-none",children:a.lineNumber||""}),e.jsx("div",{className:"flex-1 min-w-0",children:(()=>{const s=typeof r.metadata?.input=="object"&&r.metadata.input!==null?r.metadata.input.file_path||r.metadata.input.filePath:null,d=typeof s=="string"?s:"",l=typeof n=="object"&&n!==null&&"file"in n?n.file:null,h=d||(typeof l=="string"?l:"")||"";return e.jsx(g,{style:t,language:p(h)||"text",PreTag:"div",wrapLines:!0,wrapLongLines:!0,customStyle:{margin:0,padding:0,fontSize:"inherit",background:"transparent",backgroundColor:"transparent",borderRadius:0,overflow:"visible",whiteSpace:"pre-wrap",wordBreak:"break-all",overflowWrap:"anywhere"},codeTagProps:{style:{background:"transparent",backgroundColor:"transparent"}},children:a.content})})()})]},i))})]},m))}):r.diffHunks?e.jsx("div",{className:"typography-code",children:r.diffHunks.map((n,m)=>e.jsxs("div",{className:"border-b border-border/20 last:border-b-0",children:[e.jsx("div",{className:b("bg-muted/20 px-3 py-2 font-medium text-muted-foreground border-b border-border/10 sticky top-0 z-10 break-words -mx-3",u?"typography-micro":"typography-markdown"),children:`${n.file} (line ${n.oldStart})`}),e.jsx("div",{children:n.lines.map((a,i)=>e.jsxs("div",{className:"grid grid-cols-2 divide-x divide-border/20",children:[e.jsx("div",{className:b("typography-code font-mono px-3 py-0.5 overflow-hidden",a.leftLine.type==="context"&&"bg-transparent",a.leftLine.type==="empty"&&"bg-transparent"),style:{lineHeight:"1.1",...a.leftLine.type==="removed"?{backgroundColor:"var(--tools-edit-removed-bg)"}:{}},children:e.jsxs("div",{className:"flex",children:[e.jsx("span",{className:"text-muted-foreground/60 w-10 flex-shrink-0 text-right pr-3 self-start select-none",children:a.leftLine.lineNumber||""}),e.jsx("div",{className:"flex-1 min-w-0",children:a.leftLine.content&&e.jsx(g,{style:t,language:(()=>{const s=r.metadata?.input,d=typeof s=="object"&&s!==null?s:{},l=d.file_path||d.filePath,c=n.file;return p(typeof l=="string"?l:c)||"text"})(),PreTag:"div",wrapLines:!0,wrapLongLines:!0,customStyle:{margin:0,padding:0,fontSize:"inherit",background:"transparent",backgroundColor:"transparent",borderRadius:0,overflow:"visible",whiteSpace:"pre-wrap",wordBreak:"break-all",overflowWrap:"anywhere"},codeTagProps:{style:{background:"transparent",backgroundColor:"transparent"}},children:a.leftLine.content})})]})}),e.jsx("div",{className:b("typography-code font-mono px-3 py-0.5 overflow-hidden",a.rightLine.type==="context"&&"bg-transparent",a.rightLine.type==="empty"&&"bg-transparent"),style:{lineHeight:"1.1",...a.rightLine.type==="added"?{backgroundColor:"var(--tools-edit-added-bg)"}:{}},children:e.jsxs("div",{className:"flex",children:[e.jsx("span",{className:"text-muted-foreground/60 w-10 flex-shrink-0 text-right pr-3 self-start select-none",children:a.rightLine.lineNumber||""}),e.jsx("div",{className:"flex-1 min-w-0",children:a.rightLine.content&&e.jsx(g,{style:t,language:(()=>{const s=r.metadata?.input,d=typeof s=="object"&&s!==null?s:{},l=d.file_path||d.filePath,c=n.file;return p(typeof l=="string"?l:c)||"text"})(),PreTag:"div",wrapLines:!0,wrapLongLines:!0,customStyle:{margin:0,padding:0,fontSize:"inherit",background:"transparent",backgroundColor:"transparent",borderRadius:0,overflow:"visible",whiteSpace:"pre-wrap",wordBreak:"break-all",overflowWrap:"anywhere"},codeTagProps:{style:{background:"transparent",backgroundColor:"transparent"}},children:a.rightLine.content})})]})})]},i))})]},m))}):null:r.image?e.jsx("div",{className:"p-4",children:e.jsxs("div",{className:"flex flex-col items-center gap-3",children:[e.jsx("div",{className:"max-h-[70vh] overflow-hidden rounded-2xl border border-border/40 bg-muted/10",children:e.jsx("img",{src:r.image.url,alt:r.image.filename||r.title||"Image preview",className:"block h-full max-h-[70vh] w-auto max-w-full object-contain",loading:"lazy"})}),r.image.filename&&e.jsx("span",{className:"typography-meta text-muted-foreground text-center",children:r.image.filename})]})}):r.content?e.jsx("div",{className:"p-4",children:(()=>{const n=r.metadata?.tool;if(n==="todowrite"||n==="todoread")return Q(r.content)||e.jsx(g,{style:t,language:"json",PreTag:"div",wrapLongLines:!0,customStyle:f.getPopupContainerStyles(),codeTagProps:{style:{background:"transparent",backgroundColor:"transparent",fontSize:"inherit"}},children:r.content});if(n==="list")return V(r.content)||e.jsx("pre",{className:"typography-markdown bg-muted/30 p-2 rounded-xl border border-border/20 font-mono whitespace-pre-wrap",children:r.content});if(n==="grep")return E(r.content,u)||e.jsx("pre",{className:"typography-code bg-muted/30 p-2 rounded-xl border border-border/20 font-mono whitespace-pre-wrap",children:r.content});if(n==="glob")return A(r.content,u)||e.jsx("pre",{className:"typography-code bg-muted/30 p-2 rounded-xl border border-border/20 font-mono whitespace-pre-wrap",children:r.content});if(n==="task"||n==="reasoning")return e.jsx("div",{className:n==="reasoning"?"text-muted-foreground/70":"",children:e.jsx(G,{content:r.content,variant:"tool"})});if(n==="web-search"||n==="websearch"||n==="search_web")return
|
|
4
|
+
${a("prompt")}`]}):n.tool==="write"&&a("content")?e.jsx("div",{className:"tool-input-surface bg-transparent rounded-xl border border-border/20 mx-3",children:e.jsx(g,{style:t,language:p(a("filePath")||a("file_path")||"")||"text",PreTag:"div",customStyle:f.getPopupStyles(),codeTagProps:{style:{background:"transparent",backgroundColor:"transparent",fontSize:"inherit"}},wrapLongLines:!0,children:a("content")})}):e.jsx("div",{className:"tool-input-surface bg-transparent rounded-xl border border-border/20 font-mono whitespace-pre-wrap text-foreground/90 mx-3",style:f.getPopupStyles(),children:H(m,n.tool)})]})})():null,r.isDiff?y==="unified"?e.jsx("div",{className:"typography-code",children:B(r.content).map((n,m)=>e.jsxs("div",{className:"border-b border-border/20 last:border-b-0",children:[e.jsx("div",{className:b("bg-muted/20 px-3 py-2 font-medium text-muted-foreground border-b border-border/10 sticky top-0 z-10 break-words -mx-3",u?"typography-micro":"typography-markdown"),children:`${n.file} (line ${n.oldStart})`}),e.jsx("div",{children:n.lines.map((a,i)=>e.jsxs("div",{className:b("typography-code font-mono px-3 py-0.5 flex",a.type==="context"&&"bg-transparent",a.type==="removed"&&"bg-transparent",a.type==="added"&&"bg-transparent"),style:{lineHeight:"1.1",...a.type==="removed"?{backgroundColor:"var(--tools-edit-removed-bg)"}:a.type==="added"?{backgroundColor:"var(--tools-edit-added-bg)"}:{}},children:[e.jsx("span",{className:"text-muted-foreground/60 w-10 flex-shrink-0 text-right pr-3 self-start select-none",children:a.lineNumber||""}),e.jsx("div",{className:"flex-1 min-w-0",children:(()=>{const s=typeof r.metadata?.input=="object"&&r.metadata.input!==null?r.metadata.input.file_path||r.metadata.input.filePath:null,d=typeof s=="string"?s:"",l=typeof n=="object"&&n!==null&&"file"in n?n.file:null,h=d||(typeof l=="string"?l:"")||"";return e.jsx(g,{style:t,language:p(h)||"text",PreTag:"div",wrapLines:!0,wrapLongLines:!0,customStyle:{margin:0,padding:0,fontSize:"inherit",background:"transparent",backgroundColor:"transparent",borderRadius:0,overflow:"visible",whiteSpace:"pre-wrap",wordBreak:"break-all",overflowWrap:"anywhere"},codeTagProps:{style:{background:"transparent",backgroundColor:"transparent"}},children:a.content})})()})]},i))})]},m))}):r.diffHunks?e.jsx("div",{className:"typography-code",children:r.diffHunks.map((n,m)=>e.jsxs("div",{className:"border-b border-border/20 last:border-b-0",children:[e.jsx("div",{className:b("bg-muted/20 px-3 py-2 font-medium text-muted-foreground border-b border-border/10 sticky top-0 z-10 break-words -mx-3",u?"typography-micro":"typography-markdown"),children:`${n.file} (line ${n.oldStart})`}),e.jsx("div",{children:n.lines.map((a,i)=>e.jsxs("div",{className:"grid grid-cols-2 divide-x divide-border/20",children:[e.jsx("div",{className:b("typography-code font-mono px-3 py-0.5 overflow-hidden",a.leftLine.type==="context"&&"bg-transparent",a.leftLine.type==="empty"&&"bg-transparent"),style:{lineHeight:"1.1",...a.leftLine.type==="removed"?{backgroundColor:"var(--tools-edit-removed-bg)"}:{}},children:e.jsxs("div",{className:"flex",children:[e.jsx("span",{className:"text-muted-foreground/60 w-10 flex-shrink-0 text-right pr-3 self-start select-none",children:a.leftLine.lineNumber||""}),e.jsx("div",{className:"flex-1 min-w-0",children:a.leftLine.content&&e.jsx(g,{style:t,language:(()=>{const s=r.metadata?.input,d=typeof s=="object"&&s!==null?s:{},l=d.file_path||d.filePath,c=n.file;return p(typeof l=="string"?l:c)||"text"})(),PreTag:"div",wrapLines:!0,wrapLongLines:!0,customStyle:{margin:0,padding:0,fontSize:"inherit",background:"transparent",backgroundColor:"transparent",borderRadius:0,overflow:"visible",whiteSpace:"pre-wrap",wordBreak:"break-all",overflowWrap:"anywhere"},codeTagProps:{style:{background:"transparent",backgroundColor:"transparent"}},children:a.leftLine.content})})]})}),e.jsx("div",{className:b("typography-code font-mono px-3 py-0.5 overflow-hidden",a.rightLine.type==="context"&&"bg-transparent",a.rightLine.type==="empty"&&"bg-transparent"),style:{lineHeight:"1.1",...a.rightLine.type==="added"?{backgroundColor:"var(--tools-edit-added-bg)"}:{}},children:e.jsxs("div",{className:"flex",children:[e.jsx("span",{className:"text-muted-foreground/60 w-10 flex-shrink-0 text-right pr-3 self-start select-none",children:a.rightLine.lineNumber||""}),e.jsx("div",{className:"flex-1 min-w-0",children:a.rightLine.content&&e.jsx(g,{style:t,language:(()=>{const s=r.metadata?.input,d=typeof s=="object"&&s!==null?s:{},l=d.file_path||d.filePath,c=n.file;return p(typeof l=="string"?l:c)||"text"})(),PreTag:"div",wrapLines:!0,wrapLongLines:!0,customStyle:{margin:0,padding:0,fontSize:"inherit",background:"transparent",backgroundColor:"transparent",borderRadius:0,overflow:"visible",whiteSpace:"pre-wrap",wordBreak:"break-all",overflowWrap:"anywhere"},codeTagProps:{style:{background:"transparent",backgroundColor:"transparent"}},children:a.rightLine.content})})]})})]},i))})]},m))}):null:r.image?e.jsx("div",{className:"p-4",children:e.jsxs("div",{className:"flex flex-col items-center gap-3",children:[e.jsx("div",{className:"max-h-[70vh] overflow-hidden rounded-2xl border border-border/40 bg-muted/10",children:e.jsx("img",{src:r.image.url,alt:r.image.filename||r.title||"Image preview",className:"block h-full max-h-[70vh] w-auto max-w-full object-contain",loading:"lazy"})}),r.image.filename&&e.jsx("span",{className:"typography-meta text-muted-foreground text-center",children:r.image.filename})]})}):r.content?e.jsx("div",{className:"p-4",children:(()=>{const n=r.metadata?.tool;if(n==="todowrite"||n==="todoread")return Q(r.content)||e.jsx(g,{style:t,language:"json",PreTag:"div",wrapLongLines:!0,customStyle:f.getPopupContainerStyles(),codeTagProps:{style:{background:"transparent",backgroundColor:"transparent",fontSize:"inherit"}},children:r.content});if(n==="list")return V(r.content)||e.jsx("pre",{className:"typography-markdown bg-muted/30 p-2 rounded-xl border border-border/20 font-mono whitespace-pre-wrap",children:r.content});if(n==="grep")return E(r.content,u)||e.jsx("pre",{className:"typography-code bg-muted/30 p-2 rounded-xl border border-border/20 font-mono whitespace-pre-wrap",children:r.content});if(n==="glob")return A(r.content,u)||e.jsx("pre",{className:"typography-code bg-muted/30 p-2 rounded-xl border border-border/20 font-mono whitespace-pre-wrap",children:r.content});if(n==="task"||n==="reasoning")return e.jsx("div",{className:n==="reasoning"?"text-muted-foreground/70":"",children:e.jsx(G,{content:r.content,variant:"tool"})});if(n==="web-search"||n==="websearch"||n==="search_web")return U(r.content)||e.jsx(g,{style:t,language:"text",PreTag:"div",wrapLongLines:!0,customStyle:f.getPopupContainerStyles(),codeTagProps:{style:{background:"transparent",backgroundColor:"transparent",fontSize:"inherit"}},children:r.content});if(n==="read"){const m=r.content.split(`
|
|
5
5
|
`),a=r.metadata?.input,i=typeof a=="object"&&a!==null?a:{},s=typeof i.offset=="number"?i.offset:0,d=typeof i.limit=="number"?i.limit:void 0,l=c=>c.trim().startsWith("(");return e.jsx("div",{children:m.map((c,h)=>{const x=l(c),k=s+h+1,S=!x&&(d===void 0||h<d);return e.jsxs("div",{className:`typography-code font-mono flex ${x?"text-muted-foreground/70 italic":""}`,children:[e.jsx("span",{className:"text-muted-foreground/60 w-10 flex-shrink-0 text-right pr-4 self-start select-none",children:S?k:""}),e.jsx("div",{className:"flex-1 min-w-0",children:x?e.jsx("div",{className:"whitespace-pre-wrap break-words",children:c}):e.jsx(g,{style:t,language:r.language||"text",PreTag:"div",wrapLines:!0,wrapLongLines:!0,customStyle:{margin:0,padding:0,fontSize:"inherit",background:"transparent",backgroundColor:"transparent",borderRadius:0,overflow:"visible",whiteSpace:"pre-wrap",wordBreak:"break-all",overflowWrap:"anywhere"},codeTagProps:{style:{background:"transparent",backgroundColor:"transparent",fontSize:"inherit"}},children:c})})]},h)})})}return e.jsx(g,{style:t,language:r.language||"text",PreTag:"div",wrapLongLines:!0,customStyle:f.getPopupContainerStyles(),codeTagProps:{style:{background:"transparent",backgroundColor:"transparent",fontSize:"inherit"}},children:r.content})})()}):e.jsxs("div",{className:"p-8 text-muted-foreground typography-ui-header",children:[e.jsx("div",{className:"mb-2",children:"Command completed successfully"}),e.jsx("div",{className:"typography-meta",children:"No output was produced"})]})]})})]})})};export{X as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/main-
|
|
2
|
-
import{_ as P}from"./vendor-.pnpm-Bax6Hn5Z.js";(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))o(n);new MutationObserver(n=>{for(const a of n)if(a.type==="childList")for(const l of a.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&o(l)}).observe(document,{childList:!0,subtree:!0});function r(n){const a={};return n.integrity&&(a.integrity=n.integrity),n.referrerPolicy&&(a.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?a.credentials="include":n.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function o(n){if(n.ep)return;n.ep=!0;const a=r(n);fetch(n.href,a)}})();async function x(t){const e=await fetch("/api/terminal/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cwd:t.cwd,cols:t.cols||80,rows:t.rows||24})});if(!e.ok){const r=await e.json().catch(()=>({error:"Failed to create terminal"}));throw new Error(r.error||"Failed to create terminal session")}return e.json()}function $(t,e,r,o={}){const{maxRetries:n=3,initialRetryDelay:a=1e3,maxRetryDelay:l=8e3,connectionTimeout:F=1e4}=o;let c=null,d=0,p=null,y=null,m=!1,g=!1,h=!1;const T=()=>{p&&(clearTimeout(p),p=null),y&&(clearTimeout(y),y=null)},E=()=>{m=!0,T(),c&&(c.close(),c=null)},j=()=>{if(!(m||h)){if(c&&c.readyState!==EventSource.CLOSED){console.warn("Attempted to create duplicate EventSource, skipping");return}g=!1,c=new EventSource(`/api/terminal/${t}/stream`),y=setTimeout(()=>{!g&&c?.readyState!==EventSource.OPEN&&(console.error("Terminal connection timeout"),c?.close(),b(new Error("Connection timeout"),!1))},F),c.onopen=()=>{g||(g=!0,d=0,T(),e({type:"connected"}))},c.onmessage=u=>{try{const f=JSON.parse(u.data);f.type==="exit"&&(h=!0,E()),e(f)}catch(f){console.error("Failed to parse terminal event:",f),r?.(f,!1)}},c.onerror=u=>{console.error("Terminal stream error:",u,"readyState:",c?.readyState),T();const f=h||c?.readyState===EventSource.CLOSED;c?.close(),c=null,h||b(new Error("Terminal stream connection error"),f)}}},b=(u,f)=>{if(!(m||h))if(d<n&&!f){d++;const S=Math.min(a*Math.pow(2,d-1),l);console.log(`Reconnecting to terminal stream (attempt ${d}/${n}) in ${S}ms`),e({type:"reconnecting",attempt:d,maxAttempts:n}),p=setTimeout(()=>{!m&&!h&&j()},S)}else console.error(`Terminal connection failed after ${d} attempts`),r?.(u,!0),E()};return j(),E}async function C(t,e){const r=await fetch(`/api/terminal/${t}/input`,{method:"POST",headers:{"Content-Type":"text/plain"},body:e});if(!r.ok){const o=await r.json().catch(()=>({error:"Failed to send input"}));throw new Error(o.error||"Failed to send terminal input")}}async function N(t,e,r){const o=await fetch(`/api/terminal/${t}/resize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cols:e,rows:r})});if(!o.ok){const n=await o.json().catch(()=>({error:"Failed to resize terminal"}));throw new Error(n.error||"Failed to resize terminal")}}async function G(t){const e=await fetch(`/api/terminal/${t}`,{method:"DELETE"});if(!e.ok){const r=await e.json().catch(()=>({error:"Failed to close terminal"}));throw new Error(r.error||"Failed to close terminal")}}async function I(t,e){const r=await fetch(`/api/terminal/${t}/restart`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cwd:e.cwd,cols:e.cols??80,rows:e.rows??24})});if(!r.ok){const o=await r.json().catch(()=>({error:"Failed to restart terminal"}));throw new Error(o.error||"Failed to restart terminal")}return r.json()}async function A(t){const e=await fetch("/api/terminal/force-kill",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok){const r=await e.json().catch(()=>({error:"Failed to force kill terminal"}));throw new Error(r.error||"Failed to force kill terminal")}}const v=t=>{const e=t?.retry;return{maxRetries:e?.maxRetries??3,initialRetryDelay:e?.initialDelayMs??1e3,maxRetryDelay:e?.maxDelayMs??8e3,connectionTimeout:t?.connectionTimeoutMs??1e4}},D=()=>({async createSession(t){return x(t)},connect(t,e,r){const o=$(t,e.onEvent,e.onError,v(r));return{close:()=>o()}},async sendInput(t,e){await C(t,e)},async resize(t){await N(t.sessionId,t.cols,t.rows)},async close(t){await G(t)},async restartSession(t,e){return I(t,{cwd:e.cwd??"",cols:e.cols,rows:e.rows})},async forceKill(t){await A(t)}}),J=()=>{if(typeof window>"u")return"";const t=window.__OPENCHAMBER_DESKTOP_SERVER__?.origin;return t||window.location.origin},s="/api/git";function i(t,e,r){const o=new URL(t,J());if(e&&o.searchParams.set("directory",e),r)for(const[n,a]of Object.entries(r))a!==void 0&&o.searchParams.set(n,String(a));return o.toString()}async function R(t){const e=await fetch(i(`${s}/check`,t));if(!e.ok)throw new Error(`Failed to check git repository: ${e.statusText}`);return(await e.json()).isGitRepository}async function _(t){const e=await fetch(i(`${s}/status`,t));if(!e.ok)throw new Error(`Failed to get git status: ${e.statusText}`);return e.json()}async function L(t,e){const{path:r,staged:o,contextLines:n}=e;if(!r)throw new Error("path is required to fetch git diff");const a=await fetch(i(`${s}/diff`,t,{path:r,staged:o?"true":void 0,context:n}));if(!a.ok)throw new Error(`Failed to get git diff: ${a.statusText}`);return a.json()}async function W(t,e){const{path:r,staged:o}=e;if(!r)throw new Error("path is required to fetch git file diff");const n=await fetch(i(`${s}/file-diff`,t,{path:r,staged:o?"true":void 0}));if(!n.ok)throw new Error(`Failed to get git file diff: ${n.statusText}`);return n.json()}async function B(t,e){if(!e)throw new Error("path is required to revert git changes");const r=await fetch(i(`${s}/revert`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to revert git changes")}}async function q(t){if(!t)return!1;const e=await fetch(i(`${s}/worktree-type`,t));if(!e.ok)throw new Error(`Failed to detect worktree type: ${e.statusText}`);return!!(await e.json()).linked}async function M(t){const e=await fetch(i(`${s}/branches`,t));if(!e.ok)throw new Error(`Failed to get branches: ${e.statusText}`);return e.json()}async function z(t,e){if(!e?.branch)throw new Error("branch is required to delete a branch");const r=await fetch(i(`${s}/branches`,t),{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to delete branch")}return r.json()}async function U(t,e){if(!e?.branch)throw new Error("branch is required to delete remote branch");const r=await fetch(i(`${s}/remote-branches`,t),{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to delete remote branch")}return r.json()}async function K(t,e){if(!Array.isArray(e)||e.length===0)throw new Error("No files provided to generate commit message");const r=await fetch(i(`${s}/commit-message`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({files:e})});if(!r.ok){const l=await r.json().catch(()=>({error:r.statusText}));throw new Error(l.error||"Failed to generate commit message")}const o=await r.json();if(!o?.message||typeof o.message!="object")throw new Error("Malformed commit generation response");const n=typeof o.message.subject=="string"&&o.message.subject.trim().length>0?o.message.subject.trim():"",a=Array.isArray(o.message.highlights)?o.message.highlights.filter(l=>typeof l=="string"&&l.trim().length>0).map(l=>l.trim()):[];return{message:{subject:n,highlights:a}}}async function V(t){const e=await fetch(i(`${s}/worktrees`,t));if(!e.ok){const r=await e.json().catch(()=>({error:e.statusText}));throw new Error(r.error||"Failed to list worktrees")}return e.json()}async function H(t,e){if(!e?.path||!e?.branch)throw new Error("path and branch are required to add a worktree");const r=await fetch(i(`${s}/worktrees`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to add worktree")}return r.json()}async function Q(t,e){if(!e?.path)throw new Error("path is required to remove a worktree");const r=await fetch(i(`${s}/worktrees`,t),{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to remove worktree")}return r.json()}async function X(t){const e=await fetch(i(`${s}/ignore-openchamber`,t),{method:"POST"});if(!e.ok){const r=await e.json().catch(()=>({error:e.statusText}));throw new Error(r.error||"Failed to update git ignore")}}async function Y(t,e,r={}){const o=await fetch(i(`${s}/commit`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:e,addAll:r.addAll??!1,files:r.files})});if(!o.ok){const n=await o.json().catch(()=>({error:o.statusText}));throw new Error(n.error||"Failed to create commit")}return o.json()}async function Z(t,e={}){const r=await fetch(i(`${s}/push`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to push")}return r.json()}async function ee(t,e={}){const r=await fetch(i(`${s}/pull`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to pull")}return r.json()}async function te(t,e={}){const r=await fetch(i(`${s}/fetch`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to fetch")}return r.json()}async function re(t,e){const r=await fetch(i(`${s}/checkout`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({branch:e})});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to checkout branch")}return r.json()}async function oe(t,e,r){const o=await fetch(i(`${s}/branches`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e,startPoint:r})});if(!o.ok){const n=await o.json().catch(()=>({error:o.statusText}));throw new Error(n.error||"Failed to create branch")}return o.json()}async function ne(t,e={}){const r=await fetch(i(`${s}/log`,t,{maxCount:e.maxCount,from:e.from,to:e.to,file:e.file}));if(!r.ok)throw new Error(`Failed to get git log: ${r.statusText}`);return r.json()}async function se(t,e){const r=await fetch(i(`${s}/commit-files`,t,{hash:e}));if(!r.ok)throw new Error(`Failed to get commit files: ${r.statusText}`);return r.json()}async function ie(){const t=await fetch(i(`${s}/identities`,void 0));if(!t.ok)throw new Error(`Failed to get git identities: ${t.statusText}`);return t.json()}async function ae(t){const e=await fetch(i(`${s}/identities`,void 0),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok){const r=await e.json().catch(()=>({error:e.statusText}));throw new Error(r.error||"Failed to create git identity")}return e.json()}async function ce(t,e){const r=await fetch(i(`${s}/identities/${t}`,void 0),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to update git identity")}return r.json()}async function le(t){const e=await fetch(i(`${s}/identities/${t}`,void 0),{method:"DELETE"});if(!e.ok){const r=await e.json().catch(()=>({error:e.statusText}));throw new Error(r.error||"Failed to delete git identity")}}async function fe(t){if(!t)return null;const e=await fetch(i(`${s}/current-identity`,t));if(!e.ok)throw new Error(`Failed to get current git identity: ${e.statusText}`);const r=await e.json();return r?{userName:r.userName??null,userEmail:r.userEmail??null,sshCommand:r.sshCommand??null}:null}async function de(t,e){const r=await fetch(i(`${s}/set-identity`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:e})});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to set git identity")}return r.json()}const he=()=>({checkIsGitRepository:R,getGitStatus:_,getGitDiff:L,getGitFileDiff:W,revertGitFile:B,isLinkedWorktree:q,getGitBranches:M,deleteGitBranch:z,deleteRemoteBranch:U,generateCommitMessage:K,listGitWorktrees:V,addGitWorktree:H,removeGitWorktree:Q,ensureOpenChamberIgnored:X,createGitCommit(t,e,r){return Y(t,e,r)},gitPush:Z,gitPull:ee,gitFetch:te,checkoutBranch:re,createBranch:oe,getGitLog(t,e){return ne(t,e)},getCommitFiles:se,getCurrentGitIdentity:fe,setGitIdentity:de,getGitIdentities:ie,createGitIdentity:ae,updateGitIdentity:ce,deleteGitIdentity:le}),w=t=>t.replace(/\\/g,"/"),ue=()=>({async listDirectory(t){const e=w(t),r=await fetch("/api/fs/list",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to list directory")}return r.json()},async search(t){const e=await fetch("/api/fs/search",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({directory:w(t.directory),query:t.query,maxResults:t.maxResults})});if(!e.ok){const o=await e.json().catch(()=>({error:e.statusText}));throw new Error(o.error||"Failed to search files")}const r=await e.json();return Array.isArray(r)?r.filter(o=>!!o&&typeof o=="object"&&typeof o.path=="string").map(o=>({path:w(o.path),score:o.score,preview:o.preview})):[]},async createDirectory(t){const e=w(t),r=await fetch("/api/fs/mkdir",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})});if(!r.ok){const n=await r.json().catch(()=>({error:r.statusText}));throw new Error(n.error||"Failed to create directory")}const o=await r.json();return{success:!!o?.success,path:typeof o?.path=="string"?w(o.path):e}}}),k="/api/config/settings",we="/api/config/reload",O=t=>!t||typeof t!="object"?{}:t,pe=()=>({async load(){const t=await fetch(k,{method:"GET",headers:{Accept:"application/json"}});if(!t.ok)throw new Error(`Failed to load settings: ${t.statusText}`);return{settings:O(await t.json().catch(()=>({}))),source:"web"}},async save(t){const e=await fetch(k,{method:"PUT",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)});if(!e.ok){const o=await e.json().catch(()=>({error:e.statusText}));throw new Error(o.error||"Failed to save settings")}return O(await e.json().catch(()=>({})))},async restartOpenCode(){const t=await fetch(we,{method:"POST"});if(!t.ok){const e=await t.json().catch(()=>({error:t.statusText}));throw new Error(e.error||"Failed to restart OpenCode")}return{restarted:!0}}}),ye=()=>({async requestDirectoryAccess(t){return{success:!0,path:t.path}},async startAccessingDirectory(t){return{success:!0}},async stopAccessingDirectory(t){return{success:!0}}}),me=async t=>{if(typeof Notification>"u")return console.info("Notifications not supported in this environment",t),!1;if(await Notification.requestPermission()!=="granted")return console.warn("Notification permission not granted"),!1;try{return new Notification(t?.title??"OpenChamber",{body:t?.body,tag:t?.tag}),!0}catch(r){return console.warn("Failed to send notification",r),!1}},ge=()=>({async notifyAgentCompletion(t){return me(t)},canNotify:()=>typeof Notification<"u"?Notification.permission==="granted":!1}),Te=()=>({async getAvailableTools(){const t=await fetch("/api/experimental/tool/ids");if(!t.ok)throw new Error(`Tools API returned ${t.status} ${t.statusText}`);const e=await t.json();if(!Array.isArray(e))throw new Error("Tools API returned invalid data format");return e.filter(r=>typeof r=="string"&&r!=="invalid").sort()}}),Ee=()=>({runtime:{platform:"web",isDesktop:!1,isVSCode:!1,label:"web"},terminal:D(),git:he(),files:ue(),settings:pe(),permissions:ye(),notifications:ge(),tools:Te()});window.__OPENCHAMBER_RUNTIME_APIS__=Ee();P(()=>import("./main-CjbXdQMY.js").then(t=>t.m),__vite__mapDeps([0,1,2,3]));export{U as a,le as b,R as c,z as d,ae as e,fe as f,_ as g,ie as h,X as i,Z as j,H as k,V as l,Q as r,ce as u};
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/main-DI52tBPC.js","assets/vendor-.pnpm-Buk6Khtx.js","assets/vendor--B3aGWKBE.css","assets/main-BEJ2XliY.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{_ as P}from"./vendor-.pnpm-Buk6Khtx.js";(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))o(n);new MutationObserver(n=>{for(const a of n)if(a.type==="childList")for(const l of a.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&o(l)}).observe(document,{childList:!0,subtree:!0});function r(n){const a={};return n.integrity&&(a.integrity=n.integrity),n.referrerPolicy&&(a.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?a.credentials="include":n.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function o(n){if(n.ep)return;n.ep=!0;const a=r(n);fetch(n.href,a)}})();async function x(t){const e=await fetch("/api/terminal/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cwd:t.cwd,cols:t.cols||80,rows:t.rows||24})});if(!e.ok){const r=await e.json().catch(()=>({error:"Failed to create terminal"}));throw new Error(r.error||"Failed to create terminal session")}return e.json()}function $(t,e,r,o={}){const{maxRetries:n=3,initialRetryDelay:a=1e3,maxRetryDelay:l=8e3,connectionTimeout:F=1e4}=o;let c=null,d=0,p=null,y=null,m=!1,g=!1,h=!1;const T=()=>{p&&(clearTimeout(p),p=null),y&&(clearTimeout(y),y=null)},E=()=>{m=!0,T(),c&&(c.close(),c=null)},j=()=>{if(!(m||h)){if(c&&c.readyState!==EventSource.CLOSED){console.warn("Attempted to create duplicate EventSource, skipping");return}g=!1,c=new EventSource(`/api/terminal/${t}/stream`),y=setTimeout(()=>{!g&&c?.readyState!==EventSource.OPEN&&(console.error("Terminal connection timeout"),c?.close(),b(new Error("Connection timeout"),!1))},F),c.onopen=()=>{g||(g=!0,d=0,T(),e({type:"connected"}))},c.onmessage=u=>{try{const f=JSON.parse(u.data);f.type==="exit"&&(h=!0,E()),e(f)}catch(f){console.error("Failed to parse terminal event:",f),r?.(f,!1)}},c.onerror=u=>{console.error("Terminal stream error:",u,"readyState:",c?.readyState),T();const f=h||c?.readyState===EventSource.CLOSED;c?.close(),c=null,h||b(new Error("Terminal stream connection error"),f)}}},b=(u,f)=>{if(!(m||h))if(d<n&&!f){d++;const S=Math.min(a*Math.pow(2,d-1),l);console.log(`Reconnecting to terminal stream (attempt ${d}/${n}) in ${S}ms`),e({type:"reconnecting",attempt:d,maxAttempts:n}),p=setTimeout(()=>{!m&&!h&&j()},S)}else console.error(`Terminal connection failed after ${d} attempts`),r?.(u,!0),E()};return j(),E}async function C(t,e){const r=await fetch(`/api/terminal/${t}/input`,{method:"POST",headers:{"Content-Type":"text/plain"},body:e});if(!r.ok){const o=await r.json().catch(()=>({error:"Failed to send input"}));throw new Error(o.error||"Failed to send terminal input")}}async function N(t,e,r){const o=await fetch(`/api/terminal/${t}/resize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cols:e,rows:r})});if(!o.ok){const n=await o.json().catch(()=>({error:"Failed to resize terminal"}));throw new Error(n.error||"Failed to resize terminal")}}async function G(t){const e=await fetch(`/api/terminal/${t}`,{method:"DELETE"});if(!e.ok){const r=await e.json().catch(()=>({error:"Failed to close terminal"}));throw new Error(r.error||"Failed to close terminal")}}async function I(t,e){const r=await fetch(`/api/terminal/${t}/restart`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cwd:e.cwd,cols:e.cols??80,rows:e.rows??24})});if(!r.ok){const o=await r.json().catch(()=>({error:"Failed to restart terminal"}));throw new Error(o.error||"Failed to restart terminal")}return r.json()}async function A(t){const e=await fetch("/api/terminal/force-kill",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok){const r=await e.json().catch(()=>({error:"Failed to force kill terminal"}));throw new Error(r.error||"Failed to force kill terminal")}}const v=t=>{const e=t?.retry;return{maxRetries:e?.maxRetries??3,initialRetryDelay:e?.initialDelayMs??1e3,maxRetryDelay:e?.maxDelayMs??8e3,connectionTimeout:t?.connectionTimeoutMs??1e4}},D=()=>({async createSession(t){return x(t)},connect(t,e,r){const o=$(t,e.onEvent,e.onError,v(r));return{close:()=>o()}},async sendInput(t,e){await C(t,e)},async resize(t){await N(t.sessionId,t.cols,t.rows)},async close(t){await G(t)},async restartSession(t,e){return I(t,{cwd:e.cwd??"",cols:e.cols,rows:e.rows})},async forceKill(t){await A(t)}}),J=()=>{if(typeof window>"u")return"";const t=window.__OPENCHAMBER_DESKTOP_SERVER__?.origin;return t||window.location.origin},s="/api/git";function i(t,e,r){const o=new URL(t,J());if(e&&o.searchParams.set("directory",e),r)for(const[n,a]of Object.entries(r))a!==void 0&&o.searchParams.set(n,String(a));return o.toString()}async function R(t){const e=await fetch(i(`${s}/check`,t));if(!e.ok)throw new Error(`Failed to check git repository: ${e.statusText}`);return(await e.json()).isGitRepository}async function _(t){const e=await fetch(i(`${s}/status`,t));if(!e.ok)throw new Error(`Failed to get git status: ${e.statusText}`);return e.json()}async function L(t,e){const{path:r,staged:o,contextLines:n}=e;if(!r)throw new Error("path is required to fetch git diff");const a=await fetch(i(`${s}/diff`,t,{path:r,staged:o?"true":void 0,context:n}));if(!a.ok)throw new Error(`Failed to get git diff: ${a.statusText}`);return a.json()}async function W(t,e){const{path:r,staged:o}=e;if(!r)throw new Error("path is required to fetch git file diff");const n=await fetch(i(`${s}/file-diff`,t,{path:r,staged:o?"true":void 0}));if(!n.ok)throw new Error(`Failed to get git file diff: ${n.statusText}`);return n.json()}async function B(t,e){if(!e)throw new Error("path is required to revert git changes");const r=await fetch(i(`${s}/revert`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to revert git changes")}}async function q(t){if(!t)return!1;const e=await fetch(i(`${s}/worktree-type`,t));if(!e.ok)throw new Error(`Failed to detect worktree type: ${e.statusText}`);return!!(await e.json()).linked}async function M(t){const e=await fetch(i(`${s}/branches`,t));if(!e.ok)throw new Error(`Failed to get branches: ${e.statusText}`);return e.json()}async function z(t,e){if(!e?.branch)throw new Error("branch is required to delete a branch");const r=await fetch(i(`${s}/branches`,t),{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to delete branch")}return r.json()}async function U(t,e){if(!e?.branch)throw new Error("branch is required to delete remote branch");const r=await fetch(i(`${s}/remote-branches`,t),{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to delete remote branch")}return r.json()}async function K(t,e){if(!Array.isArray(e)||e.length===0)throw new Error("No files provided to generate commit message");const r=await fetch(i(`${s}/commit-message`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({files:e})});if(!r.ok){const l=await r.json().catch(()=>({error:r.statusText}));throw new Error(l.error||"Failed to generate commit message")}const o=await r.json();if(!o?.message||typeof o.message!="object")throw new Error("Malformed commit generation response");const n=typeof o.message.subject=="string"&&o.message.subject.trim().length>0?o.message.subject.trim():"",a=Array.isArray(o.message.highlights)?o.message.highlights.filter(l=>typeof l=="string"&&l.trim().length>0).map(l=>l.trim()):[];return{message:{subject:n,highlights:a}}}async function V(t){const e=await fetch(i(`${s}/worktrees`,t));if(!e.ok){const r=await e.json().catch(()=>({error:e.statusText}));throw new Error(r.error||"Failed to list worktrees")}return e.json()}async function H(t,e){if(!e?.path||!e?.branch)throw new Error("path and branch are required to add a worktree");const r=await fetch(i(`${s}/worktrees`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to add worktree")}return r.json()}async function Q(t,e){if(!e?.path)throw new Error("path is required to remove a worktree");const r=await fetch(i(`${s}/worktrees`,t),{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to remove worktree")}return r.json()}async function X(t){const e=await fetch(i(`${s}/ignore-openchamber`,t),{method:"POST"});if(!e.ok){const r=await e.json().catch(()=>({error:e.statusText}));throw new Error(r.error||"Failed to update git ignore")}}async function Y(t,e,r={}){const o=await fetch(i(`${s}/commit`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:e,addAll:r.addAll??!1,files:r.files})});if(!o.ok){const n=await o.json().catch(()=>({error:o.statusText}));throw new Error(n.error||"Failed to create commit")}return o.json()}async function Z(t,e={}){const r=await fetch(i(`${s}/push`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to push")}return r.json()}async function ee(t,e={}){const r=await fetch(i(`${s}/pull`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to pull")}return r.json()}async function te(t,e={}){const r=await fetch(i(`${s}/fetch`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to fetch")}return r.json()}async function re(t,e){const r=await fetch(i(`${s}/checkout`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({branch:e})});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to checkout branch")}return r.json()}async function oe(t,e,r){const o=await fetch(i(`${s}/branches`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e,startPoint:r})});if(!o.ok){const n=await o.json().catch(()=>({error:o.statusText}));throw new Error(n.error||"Failed to create branch")}return o.json()}async function ne(t,e={}){const r=await fetch(i(`${s}/log`,t,{maxCount:e.maxCount,from:e.from,to:e.to,file:e.file}));if(!r.ok)throw new Error(`Failed to get git log: ${r.statusText}`);return r.json()}async function se(t,e){const r=await fetch(i(`${s}/commit-files`,t,{hash:e}));if(!r.ok)throw new Error(`Failed to get commit files: ${r.statusText}`);return r.json()}async function ie(){const t=await fetch(i(`${s}/identities`,void 0));if(!t.ok)throw new Error(`Failed to get git identities: ${t.statusText}`);return t.json()}async function ae(t){const e=await fetch(i(`${s}/identities`,void 0),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok){const r=await e.json().catch(()=>({error:e.statusText}));throw new Error(r.error||"Failed to create git identity")}return e.json()}async function ce(t,e){const r=await fetch(i(`${s}/identities/${t}`,void 0),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to update git identity")}return r.json()}async function le(t){const e=await fetch(i(`${s}/identities/${t}`,void 0),{method:"DELETE"});if(!e.ok){const r=await e.json().catch(()=>({error:e.statusText}));throw new Error(r.error||"Failed to delete git identity")}}async function fe(t){if(!t)return null;const e=await fetch(i(`${s}/current-identity`,t));if(!e.ok)throw new Error(`Failed to get current git identity: ${e.statusText}`);const r=await e.json();return r?{userName:r.userName??null,userEmail:r.userEmail??null,sshCommand:r.sshCommand??null}:null}async function de(t,e){const r=await fetch(i(`${s}/set-identity`,t),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:e})});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to set git identity")}return r.json()}const he=()=>({checkIsGitRepository:R,getGitStatus:_,getGitDiff:L,getGitFileDiff:W,revertGitFile:B,isLinkedWorktree:q,getGitBranches:M,deleteGitBranch:z,deleteRemoteBranch:U,generateCommitMessage:K,listGitWorktrees:V,addGitWorktree:H,removeGitWorktree:Q,ensureOpenChamberIgnored:X,createGitCommit(t,e,r){return Y(t,e,r)},gitPush:Z,gitPull:ee,gitFetch:te,checkoutBranch:re,createBranch:oe,getGitLog(t,e){return ne(t,e)},getCommitFiles:se,getCurrentGitIdentity:fe,setGitIdentity:de,getGitIdentities:ie,createGitIdentity:ae,updateGitIdentity:ce,deleteGitIdentity:le}),w=t=>t.replace(/\\/g,"/"),ue=()=>({async listDirectory(t){const e=w(t),r=await fetch("/api/fs/list",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})});if(!r.ok){const o=await r.json().catch(()=>({error:r.statusText}));throw new Error(o.error||"Failed to list directory")}return r.json()},async search(t){const e=await fetch("/api/fs/search",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({directory:w(t.directory),query:t.query,maxResults:t.maxResults})});if(!e.ok){const o=await e.json().catch(()=>({error:e.statusText}));throw new Error(o.error||"Failed to search files")}const r=await e.json();return Array.isArray(r)?r.filter(o=>!!o&&typeof o=="object"&&typeof o.path=="string").map(o=>({path:w(o.path),score:o.score,preview:o.preview})):[]},async createDirectory(t){const e=w(t),r=await fetch("/api/fs/mkdir",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})});if(!r.ok){const n=await r.json().catch(()=>({error:r.statusText}));throw new Error(n.error||"Failed to create directory")}const o=await r.json();return{success:!!o?.success,path:typeof o?.path=="string"?w(o.path):e}}}),k="/api/config/settings",we="/api/config/reload",O=t=>!t||typeof t!="object"?{}:t,pe=()=>({async load(){const t=await fetch(k,{method:"GET",headers:{Accept:"application/json"}});if(!t.ok)throw new Error(`Failed to load settings: ${t.statusText}`);return{settings:O(await t.json().catch(()=>({}))),source:"web"}},async save(t){const e=await fetch(k,{method:"PUT",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)});if(!e.ok){const o=await e.json().catch(()=>({error:e.statusText}));throw new Error(o.error||"Failed to save settings")}return O(await e.json().catch(()=>({})))},async restartOpenCode(){const t=await fetch(we,{method:"POST"});if(!t.ok){const e=await t.json().catch(()=>({error:t.statusText}));throw new Error(e.error||"Failed to restart OpenCode")}return{restarted:!0}}}),ye=()=>({async requestDirectoryAccess(t){return{success:!0,path:t.path}},async startAccessingDirectory(t){return{success:!0}},async stopAccessingDirectory(t){return{success:!0}}}),me=async t=>{if(typeof Notification>"u")return console.info("Notifications not supported in this environment",t),!1;if(await Notification.requestPermission()!=="granted")return console.warn("Notification permission not granted"),!1;try{return new Notification(t?.title??"OpenChamber",{body:t?.body,tag:t?.tag}),!0}catch(r){return console.warn("Failed to send notification",r),!1}},ge=()=>({async notifyAgentCompletion(t){return me(t)},canNotify:()=>typeof Notification<"u"?Notification.permission==="granted":!1}),Te=()=>({async getAvailableTools(){const t=await fetch("/api/experimental/tool/ids");if(!t.ok)throw new Error(`Tools API returned ${t.status} ${t.statusText}`);const e=await t.json();if(!Array.isArray(e))throw new Error("Tools API returned invalid data format");return e.filter(r=>typeof r=="string"&&r!=="invalid").sort()}}),Ee=()=>({runtime:{platform:"web",isDesktop:!1,isVSCode:!1,label:"web"},terminal:D(),git:he(),files:ue(),settings:pe(),permissions:ye(),notifications:ge(),tools:Te()});window.__OPENCHAMBER_RUNTIME_APIS__=Ee();P(()=>import("./main-DI52tBPC.js").then(t=>t.m),__vite__mapDeps([0,1,2,3]));export{U as a,le as b,R as c,z as d,ae as e,fe as f,_ as g,ie as h,X as i,Z as j,H as k,V as l,Q as r,ce as u};
|