claude-remote-cli 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/claude-remote-cli.js +34 -0
- package/dist/server/index.js +1 -1
- package/package.json +1 -1
- package/public/app.js +19 -3
- package/public/index.html +9 -1
- package/public/style.css +34 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
4
6
|
import { fileURLToPath } from 'node:url';
|
|
5
7
|
import * as service from '../server/service.js';
|
|
6
8
|
import { DEFAULTS } from '../server/config.js';
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
7
10
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
11
|
// Parse CLI flags
|
|
9
12
|
const args = process.argv.slice(2);
|
|
@@ -12,6 +15,7 @@ if (args.includes('--help') || args.includes('-h')) {
|
|
|
12
15
|
claude-remote-cli <command>
|
|
13
16
|
|
|
14
17
|
Commands:
|
|
18
|
+
update Update to the latest version from npm
|
|
15
19
|
install Install as a background service (survives reboot)
|
|
16
20
|
uninstall Stop and remove the background service
|
|
17
21
|
status Show whether the service is running
|
|
@@ -53,6 +57,36 @@ function runServiceCommand(fn) {
|
|
|
53
57
|
process.exit(0);
|
|
54
58
|
}
|
|
55
59
|
const command = args[0];
|
|
60
|
+
if (command === 'update') {
|
|
61
|
+
try {
|
|
62
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf-8'));
|
|
63
|
+
console.log(`Current version: ${pkg.version}`);
|
|
64
|
+
console.log('Updating claude-remote-cli...');
|
|
65
|
+
await execFileAsync('npm', ['install', '-g', 'claude-remote-cli@latest']);
|
|
66
|
+
const updatedPkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf-8'));
|
|
67
|
+
if (updatedPkg.version === pkg.version) {
|
|
68
|
+
console.log(`Already on the latest version (${pkg.version}).`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.log(`Updated to ${updatedPkg.version}.`);
|
|
72
|
+
if (service.isInstalled()) {
|
|
73
|
+
console.log('Background service detected — restarting...');
|
|
74
|
+
service.uninstall();
|
|
75
|
+
service.install({
|
|
76
|
+
configPath: resolveConfigPath(),
|
|
77
|
+
port: getArg('--port') ?? String(DEFAULTS.port),
|
|
78
|
+
host: getArg('--host') ?? DEFAULTS.host,
|
|
79
|
+
});
|
|
80
|
+
console.log('Service restarted.');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
console.error('Update failed:', e.message);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
56
90
|
if (command === 'install' || command === 'uninstall' || command === 'status' || args.includes('--bg')) {
|
|
57
91
|
if (command === 'uninstall') {
|
|
58
92
|
runServiceCommand(() => { service.uninstall(); });
|
package/dist/server/index.js
CHANGED
|
@@ -317,7 +317,7 @@ async function main() {
|
|
|
317
317
|
return;
|
|
318
318
|
}
|
|
319
319
|
const name = repoName || repoPath.split('/').filter(Boolean).pop() || 'session';
|
|
320
|
-
const baseArgs = claudeArgs ||
|
|
320
|
+
const baseArgs = [...(config.claudeArgs || []), ...(claudeArgs || [])];
|
|
321
321
|
// Compute root by matching repoPath against configured rootDirs
|
|
322
322
|
const roots = config.rootDirs || [];
|
|
323
323
|
const root = roots.find(function (r) { return repoPath.startsWith(r); }) || '';
|
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
var sidebarRepoFilter = document.getElementById('sidebar-repo-filter');
|
|
35
35
|
var dialogRootSelect = document.getElementById('dialog-root-select');
|
|
36
36
|
var dialogRepoSelect = document.getElementById('dialog-repo-select');
|
|
37
|
+
var dialogYolo = document.getElementById('dialog-yolo');
|
|
37
38
|
var contextMenu = document.getElementById('context-menu');
|
|
39
|
+
var ctxResumeYolo = document.getElementById('ctx-resume-yolo');
|
|
38
40
|
var ctxDeleteWorktree = document.getElementById('ctx-delete-worktree');
|
|
39
41
|
var deleteWtDialog = document.getElementById('delete-worktree-dialog');
|
|
40
42
|
var deleteWtName = document.getElementById('delete-wt-name');
|
|
@@ -550,7 +552,18 @@
|
|
|
550
552
|
.catch(function () {});
|
|
551
553
|
}
|
|
552
554
|
|
|
553
|
-
// ──
|
|
555
|
+
// ── Context Menu Actions ──────────────────────────────────────────────────
|
|
556
|
+
|
|
557
|
+
ctxResumeYolo.addEventListener('click', function (e) {
|
|
558
|
+
e.stopPropagation();
|
|
559
|
+
hideContextMenu();
|
|
560
|
+
if (!contextMenuTarget) return;
|
|
561
|
+
startSession(
|
|
562
|
+
contextMenuTarget.repoPath,
|
|
563
|
+
contextMenuTarget.worktreePath,
|
|
564
|
+
['--dangerously-skip-permissions']
|
|
565
|
+
);
|
|
566
|
+
});
|
|
554
567
|
|
|
555
568
|
ctxDeleteWorktree.addEventListener('click', function (e) {
|
|
556
569
|
e.stopPropagation();
|
|
@@ -658,12 +671,13 @@
|
|
|
658
671
|
dialogRepoSelect.disabled = false;
|
|
659
672
|
});
|
|
660
673
|
|
|
661
|
-
function startSession(repoPath, worktreePath) {
|
|
674
|
+
function startSession(repoPath, worktreePath, claudeArgs) {
|
|
662
675
|
var body = {
|
|
663
676
|
repoPath: repoPath,
|
|
664
677
|
repoName: repoPath.split('/').filter(Boolean).pop(),
|
|
665
678
|
};
|
|
666
679
|
if (worktreePath) body.worktreePath = worktreePath;
|
|
680
|
+
if (claudeArgs) body.claudeArgs = claudeArgs;
|
|
667
681
|
|
|
668
682
|
fetch('/sessions', {
|
|
669
683
|
method: 'POST',
|
|
@@ -683,6 +697,7 @@
|
|
|
683
697
|
|
|
684
698
|
newSessionBtn.addEventListener('click', function () {
|
|
685
699
|
customPath.value = '';
|
|
700
|
+
dialogYolo.checked = false;
|
|
686
701
|
populateDialogRootSelect();
|
|
687
702
|
|
|
688
703
|
var sidebarRoot = sidebarRootFilter.value;
|
|
@@ -709,7 +724,8 @@
|
|
|
709
724
|
dialogStart.addEventListener('click', function () {
|
|
710
725
|
var path = customPath.value.trim() || dialogRepoSelect.value;
|
|
711
726
|
if (!path) return;
|
|
712
|
-
|
|
727
|
+
var args = dialogYolo.checked ? ['--dangerously-skip-permissions'] : undefined;
|
|
728
|
+
startSession(path, undefined, args);
|
|
713
729
|
});
|
|
714
730
|
|
|
715
731
|
dialogCancel.addEventListener('click', function () {
|
package/public/index.html
CHANGED
|
@@ -110,6 +110,13 @@
|
|
|
110
110
|
<label for="custom-path-input">Or enter a local path:</label>
|
|
111
111
|
<input type="text" id="custom-path-input" placeholder="/Users/you/code/my-repo" />
|
|
112
112
|
</div>
|
|
113
|
+
<div class="dialog-option">
|
|
114
|
+
<label>
|
|
115
|
+
<input type="checkbox" id="dialog-yolo" />
|
|
116
|
+
Yolo mode
|
|
117
|
+
</label>
|
|
118
|
+
<span class="dialog-option-hint">Skip all permission prompts</span>
|
|
119
|
+
</div>
|
|
113
120
|
<div class="dialog-actions">
|
|
114
121
|
<button id="dialog-cancel">Cancel</button>
|
|
115
122
|
<button id="dialog-start" class="btn-accent">New Worktree</button>
|
|
@@ -135,7 +142,8 @@
|
|
|
135
142
|
|
|
136
143
|
<!-- Context Menu -->
|
|
137
144
|
<div id="context-menu" class="context-menu" hidden>
|
|
138
|
-
<button id="ctx-
|
|
145
|
+
<button id="ctx-resume-yolo" class="context-menu-item">Resume in yolo mode</button>
|
|
146
|
+
<button id="ctx-delete-worktree" class="context-menu-item ctx-danger">Delete worktree</button>
|
|
139
147
|
</div>
|
|
140
148
|
|
|
141
149
|
<!-- Delete Worktree Confirmation Dialog -->
|
package/public/style.css
CHANGED
|
@@ -590,6 +590,35 @@ dialog#new-session-dialog h2 {
|
|
|
590
590
|
border-color: var(--accent);
|
|
591
591
|
}
|
|
592
592
|
|
|
593
|
+
.dialog-option {
|
|
594
|
+
display: flex;
|
|
595
|
+
flex-direction: column;
|
|
596
|
+
gap: 2px;
|
|
597
|
+
margin-bottom: 1rem;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.dialog-option label {
|
|
601
|
+
display: flex;
|
|
602
|
+
align-items: center;
|
|
603
|
+
gap: 8px;
|
|
604
|
+
font-size: 0.875rem;
|
|
605
|
+
color: var(--text);
|
|
606
|
+
cursor: pointer;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.dialog-option input[type="checkbox"] {
|
|
610
|
+
width: 16px;
|
|
611
|
+
height: 16px;
|
|
612
|
+
accent-color: var(--accent);
|
|
613
|
+
cursor: pointer;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.dialog-option-hint {
|
|
617
|
+
font-size: 0.75rem;
|
|
618
|
+
color: var(--text-muted);
|
|
619
|
+
padding-left: 24px;
|
|
620
|
+
}
|
|
621
|
+
|
|
593
622
|
.dialog-actions {
|
|
594
623
|
display: flex;
|
|
595
624
|
gap: 8px;
|
|
@@ -769,6 +798,11 @@ dialog#settings-dialog h2 {
|
|
|
769
798
|
color: var(--accent);
|
|
770
799
|
}
|
|
771
800
|
|
|
801
|
+
.context-menu-item.ctx-danger:hover,
|
|
802
|
+
.context-menu-item.ctx-danger:active {
|
|
803
|
+
color: #c0392b;
|
|
804
|
+
}
|
|
805
|
+
|
|
772
806
|
/* ===== Delete Worktree Dialog ===== */
|
|
773
807
|
dialog#delete-worktree-dialog {
|
|
774
808
|
background: var(--surface);
|