@linzumi/cli 0.0.34-beta → 0.0.35-beta

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.
Files changed (3) hide show
  1. package/README.md +58 -0
  2. package/dist/index.js +39 -28
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -50,10 +50,61 @@ real dotfiles, and your real branches. No "works in the sandbox VM,
50
50
  breaks in your repo" surprises. The chat side runs in your browser;
51
51
  the work side runs locally. This npm package is the local half.
52
52
 
53
+ ## What you'll have in three minutes
54
+
55
+ - A Linzumi workspace in your browser.
56
+ - A local Commander connected to one trusted project folder.
57
+ - A live Coding agent thread your team can watch and steer.
58
+ - Optional browser editor and preview forwarding for the running app.
59
+
60
+ ## Manual Runner Setup
61
+
62
+ Install the CLI or run it with `npx`:
63
+
53
64
  ```bash
65
+ npm install -g @linzumi/cli@latest
66
+ npx -y @linzumi/cli@0.0.35-beta --version
54
67
  linzumi --version
55
68
  ```
56
69
 
70
+ Start a local runner from a trusted folder:
71
+
72
+ ```bash
73
+ linzumi paths add ~/code/my-app
74
+ linzumi start ~/code/my-app
75
+ ```
76
+
77
+ For explicit runner roots, pass a comma-separated allowlist:
78
+
79
+ ```bash
80
+ linzumi start ~/code/my-app --allowed-cwd <paths>
81
+ ```
82
+
83
+ ## Agent-first launch path
84
+
85
+ The fastest path is still the `codex` prompt above. It uses the npm CLI
86
+ to sign in, trust a demo project, connect the Commander, and start the
87
+ first visible Coding agent thread.
88
+
89
+ ## What just happened
90
+
91
+ Linzumi keeps the browser/chat surface separate from the local work
92
+ surface. The CLI authenticates your local Commander, publishes runner
93
+ capabilities, and lets Kandan ask that Commander to start Codex inside
94
+ trusted folders only.
95
+
96
+ ## Three things to try first
97
+
98
+ - Ask the Coding agent to make a small UI change and watch the thread.
99
+ - Open the browser editor from the thread controls.
100
+ - Share the preview URL with a teammate or your phone.
101
+
102
+ ## Working as a team
103
+
104
+ Use the Linzumi thread as the shared source of truth. Humans can reply,
105
+ steer, interrupt, or inspect output while the actual commands still run
106
+ on the trusted local machine.
107
+
57
108
  ## Trusted folders
58
109
 
59
110
  Linzumi only edits inside folders you've explicitly trusted.
@@ -65,6 +116,13 @@ linzumi paths add ~/code/my-app
65
116
  The trust list lives at `~/.linzumi/config.json`. The bootstrap agent
66
117
  adds `/tmp/hello_linzumi` for you on first run.
67
118
 
119
+ ## When something looks wrong
120
+
121
+ Run `linzumi --help` or reconnect with `linzumi start ~/code/my-app`.
122
+ If the browser says no runner is connected, check that the terminal
123
+ running the Commander is still open and that the folder is listed in
124
+ `~/.linzumi/config.json`.
125
+
68
126
  ---
69
127
 
70
128
  *Slack-shaped on the surface. A multiplayer compiler underneath.*
package/dist/index.js CHANGED
@@ -5680,7 +5680,7 @@ function kandanHttpBaseUrl(kandanUrl) {
5680
5680
  case "https:":
5681
5681
  break;
5682
5682
  default:
5683
- throw new Error("--kandan-url must be ws://, wss://, http://, or https://");
5683
+ throw new Error("--linzumi-url must be ws://, wss://, http://, or https://");
5684
5684
  }
5685
5685
  parsed.pathname = "";
5686
5686
  parsed.search = "";
@@ -9354,6 +9354,7 @@ async function waitForFileChangeOrTimeout(path, deadline, now, ready2 = () => fa
9354
9354
  // src/index.ts
9355
9355
  var flagDefinitions = new Map([
9356
9356
  ["version", { kind: "boolean" }],
9357
+ ["linzumi-url", { kind: "value" }],
9357
9358
  ["kandan-url", { kind: "value" }],
9358
9359
  ["token", { kind: "value" }],
9359
9360
  ["runner-id", { kind: "value" }],
@@ -9363,6 +9364,7 @@ var flagDefinitions = new Map([
9363
9364
  ["launch-tui", { kind: "boolean" }],
9364
9365
  ["workspace", { kind: "value" }],
9365
9366
  ["channel", { kind: "value" }],
9367
+ ["linzumi-thread-id", { kind: "value" }],
9366
9368
  ["kandan-thread-id", { kind: "value" }],
9367
9369
  ["listen-user", { kind: "value" }],
9368
9370
  ["model", { kind: "value" }],
@@ -9382,6 +9384,10 @@ var flagDefinitions = new Map([
9382
9384
  ["oauth-callback-host", { kind: "value" }],
9383
9385
  ["help", { kind: "boolean" }]
9384
9386
  ]);
9387
+ var flagAliases = new Map([
9388
+ ["kandan-url", "linzumi-url"],
9389
+ ["kandan-thread-id", "linzumi-thread-id"]
9390
+ ]);
9385
9391
  var helloFlagDefinitions = new Map([
9386
9392
  ["dir", { kind: "value" }],
9387
9393
  ["parent-dir", { kind: "value" }],
@@ -9415,7 +9421,7 @@ async function main(args) {
9415
9421
  process.stdout.write(connectGuideText());
9416
9422
  return;
9417
9423
  case "version":
9418
- process.stdout.write(`linzumi 0.0.34-beta
9424
+ process.stdout.write(`linzumi 0.0.35-beta
9419
9425
  `);
9420
9426
  return;
9421
9427
  case "auth":
@@ -9661,7 +9667,7 @@ async function runAuthCommand(args) {
9661
9667
  process.stdout.write(helpText());
9662
9668
  return;
9663
9669
  }
9664
- const kandanUrl = required(values, "kandan-url");
9670
+ const kandanUrl = required(values, "linzumi-url");
9665
9671
  const target = parseOptionalChannelTarget(values);
9666
9672
  const token = await acquireLocalRunnerTokenDetails({
9667
9673
  kandanUrl,
@@ -9675,7 +9681,7 @@ async function runAuthCommand(args) {
9675
9681
  expiresInSeconds: token.expiresInSeconds,
9676
9682
  authFilePath: stringValue3(values, "auth-file")
9677
9683
  });
9678
- process.stdout.write(`Saved Kandan local runner auth for ${cached.kandanBaseUrl}
9684
+ process.stdout.write(`Saved Linzumi local runner auth for ${cached.kandanBaseUrl}
9679
9685
  `);
9680
9686
  }
9681
9687
  async function parseStartRunnerArgs(args, deps = {
@@ -9692,7 +9698,7 @@ async function parseStartRunnerArgs(args, deps = {
9692
9698
  process.exit(0);
9693
9699
  }
9694
9700
  rejectStartTargetingFlags(values);
9695
- const kandanUrl = stringValue3(values, "kandan-url") ?? defaultLinzumiWebSocketUrl;
9701
+ const kandanUrl = stringValue3(values, "linzumi-url") ?? defaultLinzumiWebSocketUrl;
9696
9702
  const requestedCwd = resolveUserPath(cwdArg ?? process.cwd());
9697
9703
  const cwd = assertConfiguredAllowedCwds([requestedCwd])[0] ?? requestedCwd;
9698
9704
  const explicitAllowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(parseAllowedCwdList(stringValue3(values, "allowed-cwd"))) : [];
@@ -9709,7 +9715,7 @@ async function parseStartRunnerArgs(args, deps = {
9709
9715
  const authFilePath = stringValue3(values, "auth-file");
9710
9716
  const callbackHost = stringValue3(values, "oauth-callback-host");
9711
9717
  const reportRejectedCachedToken = () => {
9712
- process.stderr.write(`Cached Kandan local runner auth was rejected; starting OAuth.
9718
+ process.stderr.write(`Cached Linzumi local runner auth was rejected; starting OAuth.
9713
9719
  `);
9714
9720
  };
9715
9721
  const token = await deps.resolveToken({
@@ -9768,7 +9774,7 @@ async function parseStartRunnerArgs(args, deps = {
9768
9774
  channelSession: {
9769
9775
  workspaceSlug: target.workspaceSlug,
9770
9776
  channelSlug: target.channelSlug,
9771
- kandanThreadId: stringValue3(values, "kandan-thread-id"),
9777
+ kandanThreadId: stringValue3(values, "linzumi-thread-id"),
9772
9778
  listenUser: stringValue3(values, "listen-user") ?? defaultListenUserFromToken(targetToken),
9773
9779
  model: stringValue3(values, "model"),
9774
9780
  reasoningEffort: stringValue3(values, "reasoning-effort"),
@@ -9797,7 +9803,7 @@ async function parseAgentRunnerArgs(args, deps = {
9797
9803
  const tokenFile = readStoredAgentTokenFile(tokenFilePath, deps.readTextFile);
9798
9804
  const channelSlug = requiredStoredAgentChannel(tokenFile.channelId);
9799
9805
  const listenUser = stringValue3(values, "listen-user") ?? requiredStoredOwnerUsername(tokenFile.ownerUsername);
9800
- const kandanUrl = stringValue3(values, "kandan-url") ?? agentApiUrlToKandanUrl(tokenFile.apiUrl);
9806
+ const kandanUrl = stringValue3(values, "linzumi-url") ?? agentApiUrlToKandanUrl(tokenFile.apiUrl);
9801
9807
  const requestedCwdValue = cwdArg ?? stringValue3(values, "cwd");
9802
9808
  const requestedCwd = resolveUserPath(requestedCwdValue ?? process.cwd());
9803
9809
  const allowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(parseAllowedCwdList(stringValue3(values, "allowed-cwd"))) : requestedCwdValue === undefined ? readConfiguredAllowedCwds() : assertConfiguredAllowedCwds([requestedCwd]);
@@ -9842,7 +9848,7 @@ async function parseAgentRunnerArgs(args, deps = {
9842
9848
  channelSession: {
9843
9849
  workspaceSlug: tokenFile.workspaceId,
9844
9850
  channelSlug,
9845
- kandanThreadId: stringValue3(values, "kandan-thread-id"),
9851
+ kandanThreadId: stringValue3(values, "linzumi-thread-id"),
9846
9852
  listenUser,
9847
9853
  model: stringValue3(values, "model"),
9848
9854
  reasoningEffort: stringValue3(values, "reasoning-effort"),
@@ -9929,12 +9935,12 @@ async function parseRunnerArgs(args, deps = {
9929
9935
  process.exit(0);
9930
9936
  }
9931
9937
  if (values.get("version") === true) {
9932
- process.stdout.write(`linzumi 0.0.34-beta
9938
+ process.stdout.write(`linzumi 0.0.35-beta
9933
9939
  `);
9934
9940
  process.exit(0);
9935
9941
  }
9936
9942
  const channelTarget = parseChannelSessionTarget(values);
9937
- const kandanUrl = required(values, "kandan-url");
9943
+ const kandanUrl = required(values, "linzumi-url");
9938
9944
  const cwd = stringValue3(values, "cwd") ?? process.cwd();
9939
9945
  const codexBin = stringValue3(values, "codex-bin") ?? "codex";
9940
9946
  const customCodeServerBin = stringValue3(values, "code-server-bin");
@@ -9947,7 +9953,7 @@ async function parseRunnerArgs(args, deps = {
9947
9953
  authFilePath: stringValue3(values, "auth-file"),
9948
9954
  callbackHost: stringValue3(values, "oauth-callback-host"),
9949
9955
  reportRejectedCachedToken: () => {
9950
- process.stderr.write(`Cached Kandan local runner auth was rejected; starting OAuth.
9956
+ process.stderr.write(`Cached Linzumi local runner auth was rejected; starting OAuth.
9951
9957
  `);
9952
9958
  }
9953
9959
  });
@@ -9991,18 +9997,19 @@ function strictFlagValues(args, definitions = flagDefinitions) {
9991
9997
  if (arg === undefined || !arg.startsWith("--")) {
9992
9998
  throw new Error(`invalid argument: ${arg ?? ""}`);
9993
9999
  }
9994
- const key = arg.slice(2);
9995
- const definition = definitions.get(key);
10000
+ const rawKey = arg.slice(2);
10001
+ const definition = definitions.get(rawKey);
9996
10002
  if (definition === undefined) {
9997
- throw new Error(`invalid flag: --${key}`);
10003
+ throw new Error(`invalid flag: --${rawKey}`);
9998
10004
  }
10005
+ const key = flagAliases.get(rawKey) ?? rawKey;
9999
10006
  if (definition.kind === "boolean") {
10000
10007
  values.set(key, true);
10001
10008
  continue;
10002
10009
  }
10003
10010
  const next = args[index + 1];
10004
10011
  if (next === undefined || next.startsWith("--")) {
10005
- throw new Error(`missing value for --${key}`);
10012
+ throw new Error(`missing value for --${rawKey}`);
10006
10013
  }
10007
10014
  values.set(key, next);
10008
10015
  index += 1;
@@ -10089,7 +10096,7 @@ function parseChannelSession(values, token, target) {
10089
10096
  return {
10090
10097
  workspaceSlug: target.workspaceSlug,
10091
10098
  channelSlug: target.channelSlug,
10092
- kandanThreadId: stringValue3(values, "kandan-thread-id"),
10099
+ kandanThreadId: stringValue3(values, "linzumi-thread-id"),
10093
10100
  listenUser,
10094
10101
  model: stringValue3(values, "model"),
10095
10102
  reasoningEffort: stringValue3(values, "reasoning-effort"),
@@ -10185,11 +10192,12 @@ Usage:
10185
10192
  linzumi commander <folder> [options]
10186
10193
  linzumi start <folder> [options]
10187
10194
  linzumi paths list|add|remove [path]
10188
- linzumi connect --kandan-url <ws-url> --workspace <slug> --channel <slug> [options]
10189
- linzumi auth --kandan-url <ws-url> [--workspace <slug> --channel <slug>]
10195
+ linzumi connect --linzumi-url <ws-url> --workspace <slug> --channel <slug> [options]
10196
+ linzumi auth --linzumi-url <ws-url> [--workspace <slug> --channel <slug>]
10190
10197
 
10191
10198
  Required:
10192
- --kandan-url <ws-url> Linzumi backend URL, default ${defaultLinzumiWebSocketUrl}
10199
+ --linzumi-url <ws-url> Linzumi backend URL, default ${defaultLinzumiWebSocketUrl}
10200
+ (deprecated alias: --kandan-url)
10193
10201
  --token <jwt> Optional override token. Otherwise ~/.linzumi/auth.json is validated or OAuth opens.
10194
10202
  --auth-file <path> Auth cache path, default ~/.linzumi/auth.json
10195
10203
  --oauth-callback-host <ip> Callback host reachable by your browser
@@ -10197,7 +10205,8 @@ Required:
10197
10205
  Channel binding:
10198
10206
  --workspace <slug> Workspace slug
10199
10207
  --channel <slug|w/c> Channel slug, or workspace/channel
10200
- --kandan-thread-id <uuid> Resume an existing Linzumi thread instead of announcing a new root
10208
+ --linzumi-thread-id <uuid> Resume an existing Linzumi thread instead of announcing a new root
10209
+ (deprecated alias: --kandan-thread-id)
10201
10210
  --listen-user <user|all> User whose replies are accepted, default authenticated user
10202
10211
 
10203
10212
  Codex:
@@ -10326,7 +10335,8 @@ What it does:
10326
10335
  previews, and the browser VS Code editor.
10327
10336
 
10328
10337
  Options:
10329
- --kandan-url <ws-url> Linzumi backend URL, default ${defaultLinzumiWebSocketUrl}
10338
+ --linzumi-url <ws-url> Linzumi backend URL, default ${defaultLinzumiWebSocketUrl}
10339
+ (deprecated alias: --kandan-url)
10330
10340
  --token <jwt> Optional scoped local-runner token override
10331
10341
  --auth-file <path> Auth cache path, default ~/.linzumi/auth.json
10332
10342
  --oauth-callback-host <ip> Callback host reachable by your browser
@@ -10366,23 +10376,24 @@ What it does:
10366
10376
 
10367
10377
  Options:
10368
10378
  --agent-token-file <path> Agent token cache, default ~/.linzumi/agent-token.json
10369
- --kandan-url <ws-url> Kandan websocket base URL. Defaults deterministically from the stored apiUrl.
10379
+ --linzumi-url <ws-url> Linzumi websocket base URL. Defaults deterministically from the stored apiUrl.
10380
+ (deprecated alias: --kandan-url)
10370
10381
  --runner-id <id> Stable Commander id
10371
10382
  --codex-bin <path> Codex executable, default codex
10372
- --code-server-bin <path> Custom development code-server executable. By default Kandan installs the approved editor runtime.
10383
+ --code-server-bin <path> Custom development code-server executable. By default Linzumi installs the approved editor runtime.
10373
10384
  --listen-user <user> Human whose replies Codex may accept, default owner from claim
10374
10385
  --model <name> Model requested for Codex sessions
10375
10386
  --reasoning-effort <value> Reasoning effort requested for Codex sessions
10376
- --sandbox <value> Sandbox metadata shown in Kandan
10377
- --approval-policy <value> Approval-policy metadata shown in Kandan
10378
- --forward-port <ports> Comma-separated local TCP ports Kandan may expose as previews
10387
+ --sandbox <value> Sandbox metadata shown in Linzumi
10388
+ --approval-policy <value> Approval-policy metadata shown in Linzumi
10389
+ --forward-port <ports> Comma-separated local TCP ports Linzumi may expose as previews
10379
10390
  --allowed-cwd <paths> Override ~/.linzumi/config.json or selected folder with comma-separated trusted roots
10380
10391
  --fast Mark this Commander as low-latency/fast in Linzumi
10381
10392
 
10382
10393
  Examples:
10383
10394
  linzumi paths add "$PWD"
10384
10395
  linzumi commander daemon --runner-id hello-world-commander
10385
- linzumi commander ~/code/my-app --kandan-url ws://127.0.0.1:4162 --runner-id local-qa-commander
10396
+ linzumi commander ~/code/my-app --linzumi-url ws://127.0.0.1:4162 --runner-id local-qa-commander
10386
10397
  `;
10387
10398
  }
10388
10399
  function connectGuideText() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linzumi/cli",
3
- "version": "0.0.34-beta",
3
+ "version": "0.0.35-beta",
4
4
  "description": "Linzumi CLI — point a Codex agent at the real code on your laptop, with your team watching and steering from shared threads.",
5
5
  "type": "module",
6
6
  "bin": {