dockai 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +61 -0
- package/dist/api.js +17 -0
- package/dist/api.js.map +1 -0
- package/dist/commands/claude.js +301 -0
- package/dist/commands/claude.js.map +1 -0
- package/dist/commands/connect.js +55 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/deploy.js +98 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/login.js +103 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +10 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/logs.js +26 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/open.js +26 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/paste.js +63 -0
- package/dist/commands/paste.js.map +1 -0
- package/dist/commands/projects.js +31 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/proxy.js +55 -0
- package/dist/commands/proxy.js.map +1 -0
- package/dist/commands/push.js +53 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/sessions.js +330 -0
- package/dist/commands/sessions.js.map +1 -0
- package/dist/commands/ssh-config.js +138 -0
- package/dist/commands/ssh-config.js.map +1 -0
- package/dist/commands/start-stop.js +37 -0
- package/dist/commands/start-stop.js.map +1 -0
- package/dist/commands/status.js +38 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/whoami.js +27 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config.js +34 -0
- package/dist/config.js.map +1 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/client-tools.js +175 -0
- package/dist/lib/client-tools.js.map +1 -0
- package/dist/lib/pick-project.js +176 -0
- package/dist/lib/pick-project.js.map +1 -0
- package/dist/lib/remote.js +161 -0
- package/dist/lib/remote.js.map +1 -0
- package/dist/terminal.js +80 -0
- package/dist/terminal.js.map +1 -0
- package/dist/version.js +17 -0
- package/dist/version.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pol Amoros
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# dockai
|
|
2
|
+
|
|
3
|
+
Command-line client for [DockAI](https://github.com/polamoros/DockAI) — a self-hosted manager for Claude Code sessions running in Docker.
|
|
4
|
+
|
|
5
|
+
The CLI talks to your DockAI server over its HTTPS/WebSocket API. It is generic: anyone running a DockAI instance can use the same `dockai` binary, configured per-machine with the server URL.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g dockai
|
|
11
|
+
# or run ad-hoc without installing:
|
|
12
|
+
npx dockai <command>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Requires Node.js 20+.
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
1. Sign in to your DockAI server in a browser.
|
|
20
|
+
2. Open **Settings → API Tokens → Create token**, copy the generated token.
|
|
21
|
+
3. From your terminal:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
dockai login --server https://your-dockai.example.com
|
|
25
|
+
# paste your token when prompted
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The CLI stores `{ serverUrl, token }` in `~/.config/dockai/config.json`.
|
|
29
|
+
|
|
30
|
+
## Commands
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
dockai login [--server <url>] Authenticate against a DockAI server
|
|
34
|
+
dockai logout Clear the saved API token
|
|
35
|
+
dockai whoami Show the currently logged-in account
|
|
36
|
+
dockai projects List your projects
|
|
37
|
+
dockai start <slug> Start a project's worker container
|
|
38
|
+
dockai stop <slug> Stop a project's worker container
|
|
39
|
+
dockai connect <slug> Open an interactive terminal in the container
|
|
40
|
+
dockai connect <slug> --claude Drop directly into a Claude session
|
|
41
|
+
dockai connect <slug> --ssh Connect via raw SSH (LAN/VPN only — see note)
|
|
42
|
+
dockai logs <slug> [--tail N] Tail project logs
|
|
43
|
+
dockai open <slug> Open the Claude.ai session URL in your browser
|
|
44
|
+
dockai status Server status + project overview
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## A note on `connect --ssh`
|
|
48
|
+
|
|
49
|
+
The default `connect` flow uses WebSockets over the same HTTPS the dashboard
|
|
50
|
+
serves on, so it works from anywhere your DockAI server is reachable on the
|
|
51
|
+
internet.
|
|
52
|
+
|
|
53
|
+
The `--ssh` variant connects directly to the worker container's SSH daemon,
|
|
54
|
+
which is bound to a per-project port on the DockAI host (usually 2200–2299).
|
|
55
|
+
Those ports are not typically exposed to the internet, so `--ssh` only works
|
|
56
|
+
when you're on the same LAN, a VPN, or otherwise have direct network access
|
|
57
|
+
to the host. For remote use, stick with the default WebSocket transport.
|
|
58
|
+
|
|
59
|
+
## License
|
|
60
|
+
|
|
61
|
+
MIT — see the [LICENSE](https://github.com/polamoros/DockAI/blob/main/LICENSE) in the main repo.
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createTRPCClient, httpBatchLink } from "@trpc/client";
|
|
2
|
+
import superjson from "superjson";
|
|
3
|
+
import { getServerUrl, getToken } from "./config.js";
|
|
4
|
+
export function createApiClient() {
|
|
5
|
+
const serverUrl = getServerUrl();
|
|
6
|
+
const token = getToken();
|
|
7
|
+
return createTRPCClient({
|
|
8
|
+
links: [
|
|
9
|
+
httpBatchLink({
|
|
10
|
+
url: `${serverUrl}/api/trpc`,
|
|
11
|
+
transformer: superjson,
|
|
12
|
+
headers: () => (token ? { Authorization: `Bearer ${token}` } : {}),
|
|
13
|
+
}),
|
|
14
|
+
],
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAerD,MAAM,UAAU,eAAe;IAC7B,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IAEzB,OAAO,gBAAgB,CAAC;QACtB,KAAK,EAAE;YACL,aAAa,CAAC;gBACZ,GAAG,EAAE,GAAG,SAAS,WAAW;gBAC5B,WAAW,EAAE,SAAS;gBACtB,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACnE,CAAC;SACH;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { basename, resolve } from "node:path";
|
|
3
|
+
import { CLIENT_PORT_FILE, CLIENT_REMOTE_PORT, startClientTools } from "../lib/client-tools.js";
|
|
4
|
+
import { BROWSER_BRIDGE_REMOTE_DIR, apiReachable, assertRunning, dq, explainSshFailure, localBrowserBridgeSockets, resetTerminal, runRemote, sq, sshHost, workspaceDir } from "../lib/remote.js";
|
|
5
|
+
/**
|
|
6
|
+
* Open Claude Code inside a project's worker over SSH.
|
|
7
|
+
*
|
|
8
|
+
* The Claude CLI has no "run against remote host" flag — its Local/Cloud/SSH
|
|
9
|
+
* backends are an app-side concept — so from a terminal this is the two-step
|
|
10
|
+
* `ssh` + `claude`. This command is that, in one step, with the workspace
|
|
11
|
+
* directory already correct.
|
|
12
|
+
*
|
|
13
|
+
* It runs inside tmux by default. An SSH connection dies with the laptop lid,
|
|
14
|
+
* a network switch, or a train tunnel; the point of DockAI is that the work
|
|
15
|
+
* doesn't. Reconnecting re-attaches to the same session rather than starting
|
|
16
|
+
* a new conversation, and the session stays visible to the dashboard.
|
|
17
|
+
*/
|
|
18
|
+
export async function claudeCommand(slug, options, extraArgs = []) {
|
|
19
|
+
const host = sshHost(slug);
|
|
20
|
+
const workspace = workspaceDir(slug);
|
|
21
|
+
// tmux session names can't contain dots or colons, and we mangle the rest
|
|
22
|
+
// to keep the remote command free of anything needing quoting.
|
|
23
|
+
let session = (options.session || "claude-cli").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
24
|
+
await assertRunning(slug);
|
|
25
|
+
// The host block may be missing (fresh machine) or stale (the install
|
|
26
|
+
// moved); either way the failure would surface as a bare ssh error.
|
|
27
|
+
try {
|
|
28
|
+
const { ensureSshConfig } = await import("./ssh-config.js");
|
|
29
|
+
const did = ensureSshConfig();
|
|
30
|
+
if (did !== "unchanged")
|
|
31
|
+
console.log(`SSH config ${did}.`);
|
|
32
|
+
}
|
|
33
|
+
catch { /* ssh will say what is wrong */ }
|
|
34
|
+
// Join the conversation the phone is on, rather than starting a second
|
|
35
|
+
// process beside it. A conversation registered for Remote Control lives in
|
|
36
|
+
// tmux `claude-<id8>`; `claude -r` in a fresh tmux session resumed the same
|
|
37
|
+
// transcript in a second process, so the laptop's turns never reached the
|
|
38
|
+
// app and both processes wrote one file (2026-09-20). With no session named
|
|
39
|
+
// and no flags, one live conversation is attached to outright; several, or
|
|
40
|
+
// `-r`/`--resume`, go through DockAI's own picker, which attaches to a live
|
|
41
|
+
// one and registers an idle one before attaching. Bound conversations (the
|
|
42
|
+
// server's own children) have no terminal to join and are said so.
|
|
43
|
+
if (options.tmux !== false && !options.session) {
|
|
44
|
+
const joined = await joinRemoteConversation(slug, extraArgs);
|
|
45
|
+
if (joined.session)
|
|
46
|
+
session = joined.session;
|
|
47
|
+
extraArgs = joined.extraArgs;
|
|
48
|
+
}
|
|
49
|
+
// Attaching to a running session cannot change its flags, so flags with an
|
|
50
|
+
// existing session would be silently ignored — the trap that reads as
|
|
51
|
+
// "--permission-mode didn't work". Ask, when there is someone to ask.
|
|
52
|
+
if (extraArgs.length && options.tmux !== false) {
|
|
53
|
+
const exists = (await runRemote(slug, `tmux has-session -t ${sq(session)} 2>/dev/null`)).code === 0;
|
|
54
|
+
if (exists && process.stdin.isTTY && process.stdout.isTTY) {
|
|
55
|
+
const { selectFromList } = await import("../lib/pick-project.js");
|
|
56
|
+
const fresh = `${session}-${Date.now().toString(36).slice(-4)}`;
|
|
57
|
+
const choice = await selectFromList(`Session "${session}" is already running; its flags can't be changed.`, [
|
|
58
|
+
{ label: `Start a new session "${fresh}" with these flags`, value: "new" },
|
|
59
|
+
{ label: `Attach to "${session}" (flags ignored)`, value: "attach" },
|
|
60
|
+
]);
|
|
61
|
+
if (choice === null)
|
|
62
|
+
process.exit(0);
|
|
63
|
+
if (choice === "new")
|
|
64
|
+
return claudeCommand(slug, { ...options, session: fresh }, extraArgs);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Claude in Chrome: forward the laptop's browser-bridge sockets into the
|
|
68
|
+
// worker so the session there can drive this machine's Chrome. The remote
|
|
69
|
+
// side must have the directory, and no stale socket from a dropped tunnel.
|
|
70
|
+
// The project may have decided this. A project set to use its own browser
|
|
71
|
+
// should not also get the laptop's Chrome forwarded — given both, the agent
|
|
72
|
+
// picks whichever it likes, and "use my Chrome" stops meaning anything.
|
|
73
|
+
// An explicit --chrome / --no-chrome on the command line still wins.
|
|
74
|
+
const explicit = options.chrome !== undefined
|
|
75
|
+
|| extraArgs.some((a) => a === "--chrome" || a === "--no-chrome");
|
|
76
|
+
const pref = await projectPreferences(slug);
|
|
77
|
+
let wantsLaptopChrome = options.chrome !== false;
|
|
78
|
+
if (!explicit && pref.agentBrowser === "project")
|
|
79
|
+
wantsLaptopChrome = false;
|
|
80
|
+
// Commands on this machine: the flag decides when given, the project's own
|
|
81
|
+
// setting otherwise. Said out loud below either way.
|
|
82
|
+
const allowRun = options.allowRun ?? pref.clientAllowRun;
|
|
83
|
+
const sockets = wantsLaptopChrome ? localBrowserBridgeSockets() : [];
|
|
84
|
+
const forwards = sockets.flatMap((s) => ["-R", `${BROWSER_BRIDGE_REMOTE_DIR}/${basename(s)}:${s}`]);
|
|
85
|
+
if (sockets.length) {
|
|
86
|
+
await runRemote(slug, `mkdir -p ${BROWSER_BRIDGE_REMOTE_DIR} && chmod 700 ${BROWSER_BRIDGE_REMOTE_DIR} && rm -f ${BROWSER_BRIDGE_REMOTE_DIR}/*.sock`);
|
|
87
|
+
const saysChrome = extraArgs.some((a) => a === "--chrome" || a === "--no-chrome");
|
|
88
|
+
if (!saysChrome)
|
|
89
|
+
extraArgs = [...extraArgs, "--chrome"];
|
|
90
|
+
}
|
|
91
|
+
// Client tools: this machine's files, clipboard and (opt-in) shell, served
|
|
92
|
+
// on a loopback port and forwarded into the worker for its `dockai` MCP
|
|
93
|
+
// server. Roots default to where this command was run.
|
|
94
|
+
if (options.client !== false) {
|
|
95
|
+
const roots = (options.root?.length ? options.root : [process.cwd()]).map((r) => resolve(r));
|
|
96
|
+
const { port } = await startClientTools({ roots, allowRun });
|
|
97
|
+
// A fresh remote port per attach, named in a file the worker's MCP server
|
|
98
|
+
// reads on every call. A fixed port is held by whatever ssh session last
|
|
99
|
+
// bound it — a detached-and-reattached laptop found its forward refused
|
|
100
|
+
// and every client tool answering "No client attached" (2026-09-20).
|
|
101
|
+
const remotePort = CLIENT_REMOTE_PORT + Math.floor(Math.random() * 200);
|
|
102
|
+
await runRemote(slug, `echo ${remotePort} > "$HOME/${CLIENT_PORT_FILE}"`);
|
|
103
|
+
forwards.push("-R", `127.0.0.1:${remotePort}:127.0.0.1:${port}`);
|
|
104
|
+
console.log(`Client tools: ${roots.join(", ")}${allowRun ? ` (commands allowed${options.allowRun === undefined ? " by the project's setting" : ""})` : ""}`);
|
|
105
|
+
}
|
|
106
|
+
const claudeCmd = ["claude", ...extraArgs.map(sq)].join(" ");
|
|
107
|
+
// `-c` sets the start directory, so no `cd` is needed and the shell-command
|
|
108
|
+
// stays a single token for tmux to hand to /bin/sh.
|
|
109
|
+
const remote = options.tmux === false
|
|
110
|
+
? `cd ${sq(workspace)} && exec ${claudeCmd}`
|
|
111
|
+
: `tmux attach-session -t ${session} 2>/dev/null || ` +
|
|
112
|
+
`tmux new-session -s ${session} -c ${sq(workspace)} ${dq(claudeCmd)}`;
|
|
113
|
+
if (options.tmux === false) {
|
|
114
|
+
console.log(`Connecting to ${host} (no tmux — session ends when you disconnect)...`);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
console.log(`Connecting to ${host} [${session}]...`);
|
|
118
|
+
// Said every time because the cost of not knowing is high: Ctrl-c twice
|
|
119
|
+
// exits the Claude process in the pane — the conversation's own process,
|
|
120
|
+
// and with it any background agents it was running (2026-09-20).
|
|
121
|
+
console.log("Leave with Ctrl-b d (detach) or by closing this window. Ctrl-c twice exits Claude there and stops its background work.");
|
|
122
|
+
}
|
|
123
|
+
if (sockets.length)
|
|
124
|
+
console.log(`Chrome: forwarding ${sockets.length} browser bridge socket(s) — Claude there can use this Chrome.`);
|
|
125
|
+
// -t forces a PTY: Claude is a full-screen TUI and ssh won't allocate one
|
|
126
|
+
// for a remote command otherwise.
|
|
127
|
+
const attach = () => new Promise((resolve) => {
|
|
128
|
+
const startedAt = Date.now();
|
|
129
|
+
const child = spawn("ssh", ["-t", ...forwards, host, remote], { stdio: "inherit" });
|
|
130
|
+
child.on("error", () => {
|
|
131
|
+
console.error("\nCould not run `ssh`.");
|
|
132
|
+
process.exit(1);
|
|
133
|
+
});
|
|
134
|
+
child.on("close", (code) => {
|
|
135
|
+
resetTerminal();
|
|
136
|
+
// ssh's own 255 after a session that was up is a dropped tunnel, not a
|
|
137
|
+
// config problem; -1 marks it so the caller can reconnect.
|
|
138
|
+
resolve(code === 255 && Date.now() - startedAt > 5000 ? -1 : code);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
for (;;) {
|
|
142
|
+
const code = await attach();
|
|
143
|
+
if (code === 255) {
|
|
144
|
+
explainSshFailure(slug);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
if (code !== -1 || options.tmux === false)
|
|
148
|
+
return;
|
|
149
|
+
// The tmux session is still there; only the tunnel went. Typical cause is
|
|
150
|
+
// a DockAI deploy, which takes half a minute — wait it out and reattach
|
|
151
|
+
// rather than dumping the user at a shell mid-conversation.
|
|
152
|
+
console.log("\nConnection to DockAI lost — reconnecting (Ctrl-C to stop)...");
|
|
153
|
+
const deadline = Date.now() + 3 * 60 * 1000;
|
|
154
|
+
let back = false;
|
|
155
|
+
while (Date.now() < deadline) {
|
|
156
|
+
await new Promise((r) => setTimeout(r, 3000));
|
|
157
|
+
if (await apiReachable()) {
|
|
158
|
+
back = true;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (!back) {
|
|
163
|
+
console.error("DockAI did not come back within 3 minutes. Re-run this command to reattach.");
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
await assertRunning(slug);
|
|
167
|
+
console.log(`Reattaching to ${host} [${session}]...`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const wantsResume = (args) => args.findIndex((a) => a === "-r" || a === "--resume" || a.startsWith("--resume="));
|
|
171
|
+
/** `-r`, `--resume`, `--resume <ref>` and `--resume=<ref>` out of the args, with the ref they named. */
|
|
172
|
+
function takeResume(args) {
|
|
173
|
+
const i = wantsResume(args);
|
|
174
|
+
if (i === -1)
|
|
175
|
+
return { rest: args, ref: null };
|
|
176
|
+
const flag = args[i];
|
|
177
|
+
if (flag.startsWith("--resume="))
|
|
178
|
+
return { rest: [...args.slice(0, i), ...args.slice(i + 1)], ref: flag.slice(9) || null };
|
|
179
|
+
const next = args[i + 1];
|
|
180
|
+
const hasRef = flag === "--resume" && next !== undefined && !next.startsWith("-");
|
|
181
|
+
return { rest: [...args.slice(0, i), ...args.slice(i + (hasRef ? 2 : 1))], ref: hasRef ? next : null };
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Decide which tmux session to attach to, from the project's conversations.
|
|
185
|
+
*
|
|
186
|
+
* Returns the session to attach to (null: start a new one) and the claude
|
|
187
|
+
* args left after DockAI has consumed `-r`/`--resume`.
|
|
188
|
+
*/
|
|
189
|
+
async function joinRemoteConversation(slug, extraArgs) {
|
|
190
|
+
const { rest, ref } = takeResume(extraArgs);
|
|
191
|
+
const picking = rest.length !== extraArgs.length;
|
|
192
|
+
let sessions;
|
|
193
|
+
try {
|
|
194
|
+
const { createApiClient } = await import("../api.js");
|
|
195
|
+
({ sessions } = (await createApiClient().project.claudeSessions.query({ slug })));
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// An older orchestrator or no network: behave as before, flags intact.
|
|
199
|
+
return { session: null, extraArgs };
|
|
200
|
+
}
|
|
201
|
+
const listed = sessions.filter((s) => s.messageCount > 0 || s.remoteState !== null);
|
|
202
|
+
const live = listed.filter((s) => s.remoteState === "interactive");
|
|
203
|
+
const paneOf = (s) => `claude-${s.id.slice(0, 8)}`;
|
|
204
|
+
const tty = process.stdin.isTTY && process.stdout.isTTY;
|
|
205
|
+
// A new conversation is made by the worker, as an interactive Remote
|
|
206
|
+
// Control session in its own pane, so it is on the phone from birth and the
|
|
207
|
+
// dashboard's card lists it the same way. Flags after the project name mean
|
|
208
|
+
// the person wants a plain `claude` with those flags instead.
|
|
209
|
+
const startNew = async () => {
|
|
210
|
+
try {
|
|
211
|
+
const { createApiClient } = await import("../api.js");
|
|
212
|
+
const started = (await createApiClient().project.remoteSessionNew.mutate({ slug }));
|
|
213
|
+
if (started.tmux) {
|
|
214
|
+
console.log("Started a new conversation, registered for Remote Control — it will appear on your phone in a few seconds.");
|
|
215
|
+
return { session: started.tmux, extraArgs: [] };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
console.log(`Could not start it through DockAI (${err instanceof Error ? err.message : String(err)}); starting claude directly.`);
|
|
220
|
+
}
|
|
221
|
+
return { session: null, extraArgs: rest };
|
|
222
|
+
};
|
|
223
|
+
if (!picking) {
|
|
224
|
+
if (extraArgs.length)
|
|
225
|
+
return { session: null, extraArgs };
|
|
226
|
+
if (live.length === 1) {
|
|
227
|
+
console.log(`Joining "${live[0].title || live[0].firstPrompt}" — the conversation on your phone.`);
|
|
228
|
+
return { session: paneOf(live[0]), extraArgs };
|
|
229
|
+
}
|
|
230
|
+
if (live.length === 0)
|
|
231
|
+
return startNew();
|
|
232
|
+
if (!tty)
|
|
233
|
+
return { session: null, extraArgs };
|
|
234
|
+
}
|
|
235
|
+
if (!tty) {
|
|
236
|
+
console.error("`-r` needs a terminal to pick from; name the conversation with --resume <id|title>.");
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
const { selectFromList } = await import("../lib/pick-project.js");
|
|
240
|
+
let chosen;
|
|
241
|
+
if (ref) {
|
|
242
|
+
const wanted = ref.toLowerCase();
|
|
243
|
+
const matches = listed.filter((s) => s.id.startsWith(wanted) || (s.title || "").toLowerCase() === wanted);
|
|
244
|
+
if (matches.length !== 1) {
|
|
245
|
+
console.error(matches.length === 0 ? `No conversation matches "${ref}".` : `"${ref}" matches ${matches.length} conversations; use the id.`);
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
chosen = matches[0];
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
const state = (s) => s.remoteState === "interactive" ? "live · on your phone"
|
|
252
|
+
: s.remoteState === "server" ? "live · served by the server (phone only)"
|
|
253
|
+
: s.origin === "phone" ? "from phone, idle"
|
|
254
|
+
: s.remoteId ? "idle" : "local only";
|
|
255
|
+
const sorted = [...listed].sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));
|
|
256
|
+
chosen = await selectFromList("Which conversation?", [
|
|
257
|
+
...sorted.map((s) => ({ label: `${(s.title || s.firstPrompt || s.id.slice(0, 8)).slice(0, 60)} — ${state(s)}`, value: s })),
|
|
258
|
+
{ label: "Start a new conversation", value: "new" },
|
|
259
|
+
]);
|
|
260
|
+
if (chosen === null)
|
|
261
|
+
process.exit(0);
|
|
262
|
+
}
|
|
263
|
+
if (chosen === "new")
|
|
264
|
+
return startNew();
|
|
265
|
+
if (chosen.remoteState === "interactive")
|
|
266
|
+
return { session: paneOf(chosen), extraArgs: rest };
|
|
267
|
+
if (chosen.remoteState === "server") {
|
|
268
|
+
console.error("That conversation is served by the project's Remote Control server: it has no terminal to join. Use it from the Claude app, or hand it off to a terminal one from the dashboard.");
|
|
269
|
+
process.exit(1);
|
|
270
|
+
}
|
|
271
|
+
// Idle: register it for Remote Control first, so the phone sees the same
|
|
272
|
+
// thread, then attach to the pane that registration creates.
|
|
273
|
+
console.log(`Resuming "${chosen.title || chosen.firstPrompt}" with Remote Control…`);
|
|
274
|
+
const { createApiClient } = await import("../api.js");
|
|
275
|
+
const started = (await createApiClient().project.remoteSessionStart.mutate({ slug, sessionId: chosen.id }));
|
|
276
|
+
if (!started.tmux) {
|
|
277
|
+
console.error("It was re-queued onto the Remote Control server instead of a terminal; use it from the Claude app.");
|
|
278
|
+
process.exit(1);
|
|
279
|
+
}
|
|
280
|
+
if (rest.length)
|
|
281
|
+
console.log(`Note: ${rest.join(" ")} cannot apply to a conversation that is already running.`);
|
|
282
|
+
return { session: started.tmux, extraArgs: [] };
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Which browser this project wants a session to use, and whether commands on
|
|
286
|
+
* the attached laptop are allowed by default.
|
|
287
|
+
*
|
|
288
|
+
* Best-effort: an older orchestrator, or no network, simply means the
|
|
289
|
+
* command behaves as it always did rather than failing.
|
|
290
|
+
*/
|
|
291
|
+
async function projectPreferences(slug) {
|
|
292
|
+
try {
|
|
293
|
+
const { createApiClient } = await import("../api.js");
|
|
294
|
+
const project = await createApiClient().project.getBySlug.query({ slug });
|
|
295
|
+
return { agentBrowser: project.agentBrowser ?? null, clientAllowRun: Boolean(project.clientAllowRun) };
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
return { agentBrowser: null, clientAllowRun: false };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/commands/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { connectTerminal } from "../terminal.js";
|
|
3
|
+
import { createApiClient } from "../api.js";
|
|
4
|
+
import { getServerUrl } from "../config.js";
|
|
5
|
+
export async function connectCommand(slug, options) {
|
|
6
|
+
if (options.ssh) {
|
|
7
|
+
console.log(`Connecting to ${slug} via SSH...`);
|
|
8
|
+
try {
|
|
9
|
+
await connectSSH(slug);
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
13
|
+
console.error(`SSH connection failed: ${msg}`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.log(`Connecting to ${slug}...`);
|
|
19
|
+
try {
|
|
20
|
+
await connectTerminal(slug, { claude: options.claude });
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
24
|
+
console.error(`Connection failed: ${msg}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function connectSSH(slug) {
|
|
30
|
+
const api = createApiClient();
|
|
31
|
+
const info = (await api.project.sshInfo.query({ slug }));
|
|
32
|
+
if (!info) {
|
|
33
|
+
console.error("No SSH info available. Is the project running?");
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
// Resolve host from server URL if SSH_HOST not set
|
|
37
|
+
const serverUrl = getServerUrl();
|
|
38
|
+
const host = info.host === "localhost" ? new URL(serverUrl).hostname : info.host;
|
|
39
|
+
console.log(`ssh -p ${info.port} ${info.user}@${host}`);
|
|
40
|
+
const child = spawn("ssh", ["-p", String(info.port), `${info.user}@${host}`], {
|
|
41
|
+
stdio: "inherit",
|
|
42
|
+
});
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
child.on("close", (code) => {
|
|
45
|
+
if (code !== 0 && code !== null) {
|
|
46
|
+
reject(new Error(`SSH exited with code ${code}`));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
resolve();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
child.on("error", reject);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,OAA4C;IAE5C,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,KAAK,CAAC,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAmB,CAAC;IAE3E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,mDAAmD;IACnD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAEjF,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IAExD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,EAAE;QAC5E,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,IAAI,EAAE,CAAC,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createApiClient } from "../api.js";
|
|
2
|
+
import { getToken } from "../config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Redeploy DockAI on its host, through DockAI itself.
|
|
5
|
+
*
|
|
6
|
+
* The orchestrator runs the deploy in a helper container with the Docker
|
|
7
|
+
* socket, so nothing here needs ssh or host credentials — which is what
|
|
8
|
+
* makes it safe to run from inside a DockAI project too. The dashboard and
|
|
9
|
+
* this command lose the server for about a minute while it restarts; the
|
|
10
|
+
* wait loop tolerates that.
|
|
11
|
+
*/
|
|
12
|
+
export async function deployCommand(name, options) {
|
|
13
|
+
if (name)
|
|
14
|
+
return deployTarget(name, options);
|
|
15
|
+
if (!getToken()) {
|
|
16
|
+
console.error("Not logged in. Run `dockai login` first.");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const api = createApiClient();
|
|
20
|
+
try {
|
|
21
|
+
await api.admin.system.deploy.mutate();
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
console.log("Deploy started.");
|
|
28
|
+
if (options.wait === false)
|
|
29
|
+
return;
|
|
30
|
+
let printed = 0;
|
|
31
|
+
let outages = 0;
|
|
32
|
+
for (let i = 0; i < 120; i++) {
|
|
33
|
+
await new Promise((r) => setTimeout(r, 3000));
|
|
34
|
+
let s;
|
|
35
|
+
try {
|
|
36
|
+
s = await api.admin.system.deployStatus.query();
|
|
37
|
+
outages = 0;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// The orchestrator is being recreated. Expected once per deploy.
|
|
41
|
+
if (outages++ === 0)
|
|
42
|
+
console.log(" (orchestrator restarting…)");
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (s.log.length > printed) {
|
|
46
|
+
process.stdout.write(s.log.slice(printed));
|
|
47
|
+
printed = s.log.length;
|
|
48
|
+
}
|
|
49
|
+
if (s.state === "done") {
|
|
50
|
+
console.log("\nDeploy complete.");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (s.state === "failed") {
|
|
54
|
+
console.error(`\nDeploy failed (exit ${s.exitCode}).`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
console.error("Timed out waiting for the deploy to finish.");
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
/** Redeploy a named target (Admin → System → Deploy targets). */
|
|
62
|
+
async function deployTarget(name, options) {
|
|
63
|
+
if (!getToken()) {
|
|
64
|
+
console.error("Not logged in. Run `dockai login` first.");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
const api = createApiClient();
|
|
68
|
+
try {
|
|
69
|
+
await api.admin.deployTargets.run.mutate({ name });
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
console.log(`Deploy of ${name} started.`);
|
|
76
|
+
if (options.wait === false)
|
|
77
|
+
return;
|
|
78
|
+
let printed = 0;
|
|
79
|
+
for (let i = 0; i < 200; i++) {
|
|
80
|
+
await new Promise((r) => setTimeout(r, 3000));
|
|
81
|
+
const s = await api.admin.deployTargets.status.query({ name });
|
|
82
|
+
if (s.log.length > printed) {
|
|
83
|
+
process.stdout.write(s.log.slice(printed));
|
|
84
|
+
printed = s.log.length;
|
|
85
|
+
}
|
|
86
|
+
if (s.state === "done") {
|
|
87
|
+
console.log(`\n${name} deployed.`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (s.state === "failed") {
|
|
91
|
+
console.error(`\nDeploy of ${name} failed (exit ${s.exitCode}).`);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
console.error("Timed out waiting for the deploy to finish.");
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
|