@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 CHANGED
@@ -1,14 +1,14 @@
1
- # kai-bridge
1
+ # Kai Code Bridge
2
2
 
3
- Run [Gleap Kai Code](https://gleap.io) sessions on your own machine — with your own
4
- Claude Code / Codex login — and preview your real dev servers from the dashboard or the
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.
@@ -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 harness list|install <id>|login <id> Claude Code + Codex are bundled; Cursor is downloaded
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
- const c = loginCommand(p.harness, p.configDir);
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 <claude|codex|cursor>|login <id>");
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 …]`);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@gleapai/kai-bridge",
3
- "version": "0.7.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.7.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.7.0",
4
- "description": "Run Gleap Kai Code sessions on your own machine with your own Claude Code / Codex login — and preview your real dev servers from the dashboard or the phone.",
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/codex-broker.mjs');
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
  }