@gleapai/kai-bridge 0.7.0 → 0.9.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/README.md +29 -4
- package/bin/kai-bridge.mjs +19 -7
- package/npm-shrinkwrap.json +2 -2
- package/package.json +3 -7
- package/scripts/runtime-smoke.mjs +1 -1
- package/src/api.mjs +8 -0
- package/src/daemon.mjs +142 -93
- package/src/executor.mjs +5 -16
- package/src/git-auth.mjs +38 -0
- package/src/harness-errors.mjs +8 -0
- package/src/harness-install.mjs +73 -0
- package/src/harnesses.mjs +30 -25
- package/src/{hosted-ports.mjs → preview-ports.mjs} +2 -2
- package/src/preview.mjs +14 -20
- package/src/profiles.mjs +6 -5
- package/src/ps.mjs +152 -0
- package/src/repository-setup.mjs +2 -2
- package/src/service.mjs +1 -1
- package/src/setup.mjs +1 -1
- package/src/workspace.mjs +92 -28
- package/fly/Dockerfile +0 -11
- package/fly/UPDATES.md +0 -76
- package/fly/codex-auth.mjs +0 -5
- package/fly/entrypoint.sh +0 -12
- package/fly/login-codex.sh +0 -9
- package/fly/runtime-cli.mjs +0 -15
- package/fly/runtime-cli.sh +0 -10
- package/fly/runtime-launch.mjs +0 -8
- package/fly/runtime-update.mjs +0 -137
- package/fly/start.mjs +0 -7
- package/fly/supervisord.conf +0 -45
- package/src/codex-broker-client.mjs +0 -16
- package/src/codex-broker.mjs +0 -85
- package/src/hosted-auth.mjs +0 -42
- package/src/hosted-git-credential.mjs +0 -24
- package/src/hosted-git.mjs +0 -33
- package/src/hosted-resources.mjs +0 -35
- package/src/hosted-tunnel.mjs +0 -76
- package/src/hosted.mjs +0 -86
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Kai Code Bridge
|
|
2
2
|
|
|
3
|
-
Run [Gleap Kai Code](https://gleap.io)
|
|
4
|
-
Claude Code / Codex login
|
|
5
|
-
Gleap app on your phone.
|
|
3
|
+
Run [Gleap Kai Code](https://gleap.io) on your computer or server with your own
|
|
4
|
+
Claude Code / Codex login, local dev-server previews, and photo or video verification.
|
|
6
5
|
|
|
7
6
|
```bash
|
|
8
7
|
npm i -g @gleapai/kai-bridge # one install, so the background service has a stable path
|
|
9
8
|
kai-bridge login # pair this machine with your Gleap account
|
|
10
9
|
kai-bridge install # run at login (launchd / systemd / Task Scheduler)
|
|
11
10
|
kai-bridge status
|
|
11
|
+
kai-bridge ps # sessions running on this machine, with dashboard links (--json for tooling)
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
(`npx @gleapai/kai-bridge login` works for a quick look, but `install` needs the
|
|
@@ -43,3 +43,28 @@ kai-bridge run --task "Explain the auth flow in this repo" --cwd ~/code/my-app
|
|
|
43
43
|
|
|
44
44
|
`npm run sync-runner` copies the ACP runner from a sibling `gleap_code_analyzer` checkout;
|
|
45
45
|
`npm test` runs the unit suite (uses real `git`).
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Computers and your own servers
|
|
49
|
+
|
|
50
|
+
Kai Code offers **Kai Code Cloud** (Gleap's managed execution, using AI credits) or **Kai Code Bridge** (your coding agents on your computer or a server you manage, using your own AI subscriptions).
|
|
51
|
+
|
|
52
|
+
Run `npm i -g @gleapai/kai-bridge && kai-bridge` in a local terminal or over SSH. The guided setup pairs the device, installs its background service and helps sign in to coding agents. Node.js 20+ and Git are required. On a Linux server, keep the user service running after logout using your system's service configuration; `kai-bridge doctor` reports service status.
|
|
53
|
+
|
|
54
|
+
Codex and Claude Code ship with Kai Code Bridge. Missing agents can be installed or repaired, and existing agents can be updated independently:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
kai-bridge harness install codex
|
|
58
|
+
kai-bridge harness update codex
|
|
59
|
+
kai-bridge harness login codex --device-auth
|
|
60
|
+
|
|
61
|
+
kai-bridge harness install claude
|
|
62
|
+
kai-bridge harness update claude
|
|
63
|
+
kai-bridge harness login claude
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Updates install into `~/.kai/harnesses`, verify the new executable, then select it for subsequent sessions. A failed download or startup leaves the previous version selected. Existing versions are retained for running sessions; your global CLI installations and agent logins are not overwritten. `--version <version>` selects a specific package version (for Claude, the Claude Agent SDK package version).
|
|
67
|
+
|
|
68
|
+
Codex automatically uses device-code sign-in over SSH or on headless Linux. Enable device-code sign-in in the account settings if Codex asks. Claude uses its native `auth login` flow: follow the URL and prompts in the SSH terminal. Dashboard **Sign in** opens a terminal on desktop devices; for headless servers it shows the exact command to run over SSH. The login is picked up automatically.
|
|
69
|
+
|
|
70
|
+
**Previews are local to the Kai Code Bridge device.** Open them on that computer, on the same network when supported, or use your own SSH port forwarding. Kai Code Bridge does not expose previews through a public tunnel. Screenshot and video verification runs on the Kai Code Bridge device and uploads its evidence to the Kai Code session, so those checks still work on a remote server.
|
package/bin/kai-bridge.mjs
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
// kai-bridge install | uninstall run at login (launchd / systemd / Task Scheduler)
|
|
8
8
|
// kai-bridge start run in the foreground (what the service runs)
|
|
9
9
|
// kai-bridge status device, service, profiles, repos
|
|
10
|
-
// kai-bridge
|
|
10
|
+
// kai-bridge ps [--json] what runs right now: daemon, turns, dev servers — with dashboard links
|
|
11
|
+
// kai-bridge harness list|install <id>|update <id>|login <id> [--device-auth] Claude Code + Codex are bundled; Cursor is downloaded
|
|
11
12
|
// kai-bridge profile list|add <id> --harness claude|codex|cursor [--label …]|login <id>|remove <id>
|
|
12
13
|
// kai-bridge repo scan|roots [add <dir>|remove <dir>]|primary <repoKey> <path>
|
|
13
14
|
// kai-bridge run --task "…" [--model …] [--profile …] [--cwd …] (local turn, no server)
|
|
@@ -28,6 +29,7 @@ import { defaultRoots, groupByRepo, scanRoots, toDeviceRepoReport } from "../src
|
|
|
28
29
|
import { install, isInstalled, uninstall, isEphemeralBinPath } from "../src/service.mjs";
|
|
29
30
|
import { HARNESS_INFO, describeHarnesses, installHarness } from "../src/harnesses.mjs";
|
|
30
31
|
import { fetchLatestVersion, installVersion, installedVersion, isNewer } from "../src/selfupdate.mjs";
|
|
32
|
+
import { collectProcessList, formatProcessList } from "../src/ps.mjs";
|
|
31
33
|
|
|
32
34
|
const BIN = fileURLToPath(import.meta.url);
|
|
33
35
|
const argv = process.argv.slice(2);
|
|
@@ -68,6 +70,12 @@ async function status() {
|
|
|
68
70
|
for (const r of toDeviceRepoReport(groups)) out(` ${r.key.padEnd(48)} ${r.primaryPath}${r.checkouts > 1 ? ` (+${r.checkouts - 1})` : ""} ${r.dirtyCount ? `· ${r.dirtyCount} dirty` : ""}`);
|
|
69
71
|
}
|
|
70
72
|
|
|
73
|
+
/** Sessions running on this machine — read from the daemon's state files, so it works while the daemon is busy or down. */
|
|
74
|
+
function ps() {
|
|
75
|
+
const list = collectProcessList();
|
|
76
|
+
out(flags.json ? JSON.stringify(list, null, 2) : formatProcessList(list));
|
|
77
|
+
}
|
|
78
|
+
|
|
71
79
|
async function profile() {
|
|
72
80
|
const config = loadConfig();
|
|
73
81
|
const sub = positional[0];
|
|
@@ -89,7 +97,8 @@ async function profile() {
|
|
|
89
97
|
if (sub === "login") {
|
|
90
98
|
const p = resolveProfiles(config).find((x) => x.id === positional[1]);
|
|
91
99
|
if (!p) fail("unknown profile");
|
|
92
|
-
|
|
100
|
+
await installHarness(p.harness, { kaiHome: KAI_HOME, onLog: out });
|
|
101
|
+
const c = loginCommand(p.harness, p.configDir, KAI_HOME, flags["device-auth"] ? { deviceAuth: true } : undefined);
|
|
93
102
|
if (!c) fail(`${p.harness} is not installed`);
|
|
94
103
|
const child = spawn(c.cmd, c.args, { env: c.env, stdio: "inherit" });
|
|
95
104
|
child.on("close", (code) => process.exit(code ?? 0));
|
|
@@ -111,9 +120,9 @@ async function harness() {
|
|
|
111
120
|
return;
|
|
112
121
|
}
|
|
113
122
|
const id = positional[1];
|
|
114
|
-
if (!HARNESS_INFO[id]) fail("usage: harness list|install <
|
|
123
|
+
if (!HARNESS_INFO[id]) fail("usage: harness list|install <id>|update <id>|login <id> (claude|codex|cursor)");
|
|
115
124
|
if (sub === "install" || sub === "update") {
|
|
116
|
-
const res = await installHarness(id, { kaiHome: KAI_HOME, onLog: out });
|
|
125
|
+
const res = await installHarness(id, { kaiHome: KAI_HOME, onLog: out, update: sub === "update", version: typeof flags.version === "string" ? flags.version : undefined });
|
|
117
126
|
if (!res.ok) fail(`${id} is not usable`);
|
|
118
127
|
out(`${HARNESS_INFO[id].label} ${res.version} → ${res.binary}`);
|
|
119
128
|
return;
|
|
@@ -123,7 +132,7 @@ async function harness() {
|
|
|
123
132
|
positional[0] = "login";
|
|
124
133
|
return profile();
|
|
125
134
|
}
|
|
126
|
-
fail("usage: harness list|install <id>|login <id>");
|
|
135
|
+
fail("usage: harness list|install <id>|update <id>|login <id> [--device-auth]");
|
|
127
136
|
}
|
|
128
137
|
|
|
129
138
|
async function repo() {
|
|
@@ -230,6 +239,9 @@ try {
|
|
|
230
239
|
case "status":
|
|
231
240
|
await status();
|
|
232
241
|
break;
|
|
242
|
+
case "ps":
|
|
243
|
+
ps();
|
|
244
|
+
break;
|
|
233
245
|
case "profile":
|
|
234
246
|
await profile();
|
|
235
247
|
break;
|
|
@@ -279,8 +291,8 @@ try {
|
|
|
279
291
|
out(`kai-bridge — run Gleap Kai Code on this machine
|
|
280
292
|
|
|
281
293
|
setup guided onboarding (pair · service · sign-ins)
|
|
282
|
-
login | logout | install | uninstall | start | status | doctor | update
|
|
283
|
-
harness list|install <id>|login <id>
|
|
294
|
+
login | logout | install | uninstall | start | status | ps | doctor | update
|
|
295
|
+
harness list|install <id>|update <id>|login <id> [--device-auth]
|
|
284
296
|
profile list|add <id> --harness claude|codex|cursor|login <id>|remove <id>
|
|
285
297
|
repo scan|roots [add|remove <dir>]|primary <repoKey> <path>
|
|
286
298
|
run --task "…" [--model …] [--profile …] [--cwd …]`);
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gleapai/kai-bridge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@gleapai/kai-bridge",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.9.1",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gleapai/kai-bridge",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.9.1",
|
|
4
|
+
"description": "Kai Code Bridge runs Kai Code on your computer or server with your own coding subscriptions, local previews, and photo or video verification.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
"runner",
|
|
14
14
|
"scripts/postinstall.mjs",
|
|
15
15
|
"README.md",
|
|
16
|
-
"fly",
|
|
17
16
|
"scripts/runtime-smoke.mjs",
|
|
18
17
|
"npm-shrinkwrap.json"
|
|
19
18
|
],
|
|
@@ -52,8 +51,5 @@
|
|
|
52
51
|
"type": "git",
|
|
53
52
|
"url": "git+https://github.com/GleapSDK/kai-bridge.git"
|
|
54
53
|
},
|
|
55
|
-
"homepage": "https://gleap.io"
|
|
56
|
-
"kaiHostedRuntime": {
|
|
57
|
-
"protocol": 1
|
|
58
|
-
}
|
|
54
|
+
"homepage": "https://gleap.io"
|
|
59
55
|
}
|
|
@@ -55,6 +55,6 @@ try {
|
|
|
55
55
|
await initialize(adapter.cmd, adapter.args, { protocolVersion: 1, clientCapabilities: {}, clientInfo: { name: 'kai-runtime-check', version: '1.0.0' } });
|
|
56
56
|
}
|
|
57
57
|
// Imports catch packaging omissions and syntax/dependency failures before boot.
|
|
58
|
-
await import('../src/daemon.mjs'); await import('../src/
|
|
58
|
+
await import('../src/daemon.mjs'); await import('../src/harness-install.mjs');
|
|
59
59
|
console.log('Native CLIs, Codex app-server and both ACP adapters passed isolated startup checks.');
|
|
60
60
|
} finally { rmSync(home, { recursive: true, force: true }); }
|
package/src/api.mjs
CHANGED
|
@@ -210,6 +210,14 @@ export class BridgeApi {
|
|
|
210
210
|
pendingTurns() {
|
|
211
211
|
return this.request("GET", "/gleapcode/bridge/devices/me/pending");
|
|
212
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Provider git credentials for one connected repository — asked for only
|
|
215
|
+
* after this machine's own credentials were rejected (see git-auth.mjs).
|
|
216
|
+
*/
|
|
217
|
+
gitCredentials(repoKey) {
|
|
218
|
+
return this.request("POST", "/gleapcode/bridge/devices/me/git-credentials", { repoKey });
|
|
219
|
+
}
|
|
220
|
+
|
|
213
221
|
commandAck(commandId, payload) {
|
|
214
222
|
return this.request("POST", `/gleapcode/bridge/commands/${encodeURIComponent(commandId)}/ack`, payload);
|
|
215
223
|
}
|