linkshell-cli 0.5.8 → 0.5.9
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/cli/src/index.js +28 -0
- package/dist/cli/src/index.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/dist/shared-protocol/src/index.d.ts +2521 -2521
- package/package.json +5 -4
- package/scripts/copy-web.mjs +34 -0
- package/src/index.ts +29 -0
- package/web/assets/index-BbeLYptY.js +94 -0
- package/web/assets/index-Dm-i3Xlm.css +33 -0
- package/web/index.html +14 -0
- package/web/logos/claude.png +0 -0
- package/web/logos/codex.png +0 -0
- package/web/logos/copilot.png +0 -0
- package/web/logos/gemini.png +0 -0
- package/web/logos/linkshell-1024.png +0 -0
- package/web/logos/linkshell-splash.png +0 -0
- package/web/logos/linkshell.png +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linkshell-cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
4
4
|
"description": "Remote terminal bridge for Claude Code / Codex / Gemini / Copilot — control from your phone",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"dist",
|
|
12
12
|
"src",
|
|
13
13
|
"scripts",
|
|
14
|
+
"web",
|
|
14
15
|
"README.md",
|
|
15
16
|
"LICENSE"
|
|
16
17
|
],
|
|
@@ -35,8 +36,8 @@
|
|
|
35
36
|
"qrcode-terminal": "^0.12.0",
|
|
36
37
|
"ws": "^8.18.1",
|
|
37
38
|
"zod": "^3.24.3",
|
|
38
|
-
"@linkshell/
|
|
39
|
-
"@linkshell/
|
|
39
|
+
"@linkshell/gateway": "0.4.27",
|
|
40
|
+
"@linkshell/protocol": "0.4.4"
|
|
40
41
|
},
|
|
41
42
|
"optionalDependencies": {
|
|
42
43
|
"@anthropic-ai/claude-agent-sdk": "^0.2.128",
|
|
@@ -48,7 +49,7 @@
|
|
|
48
49
|
"vitest": "^3.2.1"
|
|
49
50
|
},
|
|
50
51
|
"scripts": {
|
|
51
|
-
"build": "tsc -p tsconfig.json",
|
|
52
|
+
"build": "tsc -p tsconfig.json && node scripts/copy-web.mjs",
|
|
52
53
|
"postinstall": "node scripts/postinstall.mjs",
|
|
53
54
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
54
55
|
"dev": "tsx src/index.ts",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Copy the built web-dashboard SPA into the CLI package (packages/cli/web) so
|
|
3
|
+
// it ships in the npm tarball. The CLI's embedded gateway then serves it via
|
|
4
|
+
// WEB_DIST, giving LAN / self-hosted users the same in-app web console that the
|
|
5
|
+
// cloud gateway Docker image bundles separately.
|
|
6
|
+
//
|
|
7
|
+
// Non-fatal when the web build is absent: a CLI-only `tsc` build still
|
|
8
|
+
// succeeds; the embedded gateway just logs "web UI not bundled". Release builds
|
|
9
|
+
// must build apps/web-dashboard FIRST so this copy has something to pick up.
|
|
10
|
+
import { cpSync, existsSync, rmSync } from "node:fs";
|
|
11
|
+
import { dirname, resolve } from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
|
|
14
|
+
const here = dirname(fileURLToPath(import.meta.url)); // packages/cli/scripts
|
|
15
|
+
const src = resolve(here, "../../../apps/web-dashboard/dist");
|
|
16
|
+
const dest = resolve(here, "../web"); // packages/cli/web
|
|
17
|
+
|
|
18
|
+
if (!existsSync(resolve(src, "index.html"))) {
|
|
19
|
+
console.warn(
|
|
20
|
+
`[copy-web] web-dashboard build not found at ${src} — skipping. ` +
|
|
21
|
+
`The in-app agent console will be blank for embedded-gateway users. ` +
|
|
22
|
+
`Run \`pnpm --filter @linkshell/web-dashboard build\` first.`,
|
|
23
|
+
);
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
rmSync(dest, { recursive: true, force: true });
|
|
29
|
+
cpSync(src, dest, { recursive: true });
|
|
30
|
+
console.log(`[copy-web] copied ${src} -> ${dest}`);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error(`[copy-web] failed to copy web dist: ${err}`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -12,10 +12,39 @@ import { getLanIp } from "./utils/lan-ip.js";
|
|
|
12
12
|
import { shouldKeepAwake } from "./utils/keep-awake.js";
|
|
13
13
|
|
|
14
14
|
import { createRequire } from "node:module";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { dirname, resolve } from "node:path";
|
|
17
|
+
import { existsSync, statSync } from "node:fs";
|
|
15
18
|
|
|
16
19
|
const require = createRequire(import.meta.url);
|
|
17
20
|
const pkg = require("../../../package.json") as { version: string };
|
|
18
21
|
|
|
22
|
+
// Locate the bundled web-dashboard SPA and point the (embedded) gateway's
|
|
23
|
+
// static server at it via WEB_DIST — BEFORE any gateway module is imported,
|
|
24
|
+
// because static-web.ts freezes WEB_DIST at module-load time. This is what lets
|
|
25
|
+
// the in-app WebView render for LAN / self-hosted users whose CLI runs its own
|
|
26
|
+
// embedded gateway (the cloud image bundles web separately). A user-set
|
|
27
|
+
// WEB_DIST always wins. Probed across published-package, monorepo-compiled, and
|
|
28
|
+
// dev (tsx) layouts; the first candidate containing index.html is used.
|
|
29
|
+
if (!process.env.WEB_DIST) {
|
|
30
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
31
|
+
const candidates = [
|
|
32
|
+
resolve(here, "../../../web"), // published npm package root, and packages/cli/web (compiled)
|
|
33
|
+
resolve(here, "../../../apps/web-dashboard/dist"), // dev: tsx src/index.ts in the monorepo
|
|
34
|
+
];
|
|
35
|
+
for (const dir of candidates) {
|
|
36
|
+
try {
|
|
37
|
+
if (existsSync(resolve(dir, "index.html")) && statSync(dir).isDirectory()) {
|
|
38
|
+
process.env.WEB_DIST = dir;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// ignore and try the next candidate
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
19
48
|
const config = loadConfig();
|
|
20
49
|
const program = new Command();
|
|
21
50
|
|