@linzumi/cli 0.0.30-beta → 0.0.32-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 +10 -10
  2. package/dist/index.js +24 -8
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -46,8 +46,8 @@ Terms:
46
46
  - **Bootstrapper Codex**: the outer Codex started by the pasted command. It
47
47
  sets up Linzumi and local processes, but does not edit the demo app.
48
48
  - **Linzumi Commander**: the long-running local bridge started with
49
- `linzumi commander`; it owns the secure tunnel, trusted folder, browser
50
- editor, and inner Codex launch.
49
+ `linzumi commander`; it runs as the claimed human's Commander and owns the
50
+ secure tunnel, trusted folder, browser editor, and inner Codex launch.
51
51
  - **Linzumi Codex session**: the inner agent running inside the Linzumi thread;
52
52
  it edits `/tmp/hello_linzumi` and posts progress.
53
53
  - **Human**: the workspace owner who opens the one-time login link and watches
@@ -152,12 +152,12 @@ npx -y @linzumi/cli@latest commander daemon \
152
152
  npx -y @linzumi/cli@latest commander wait --runner-id "$commander_id" --timeout-ms 30000
153
153
  ```
154
154
 
155
- The agent-owned Commander reads `~/.linzumi/agent-token.json`, uses the
156
- workspace/channel scope from the approval flow, reads trusted folders from
157
- `~/.linzumi/config.json`, marks approved project directories trusted in
158
- Codex's normal project config so Codex does not stop for an interactive trust
159
- prompt, advertises the explicit preview port, and listens only to the
160
- approving human unless `--listen-user` is explicitly passed. Use a unique
155
+ The human-owned Commander reads `~/.linzumi/agent-token.json`, uses the
156
+ claimed human Commander token and workspace/channel scope from the approval
157
+ flow, reads trusted folders from `~/.linzumi/config.json`, marks approved
158
+ project directories trusted in Codex's normal project config so Codex does not
159
+ stop for an interactive trust prompt, advertises the explicit preview port, and
160
+ listens only to the approving human unless `--listen-user` is explicitly passed. Use a unique
161
161
  Commander id per launch. `linzumi commander daemon` writes a status record and
162
162
  log under `~/.linzumi/commanders`, and `linzumi commander wait` returns only
163
163
  after the Commander is connected.
@@ -293,7 +293,7 @@ intentionally. Every action is auditable from the thread.
293
293
  ## Pinning a version
294
294
 
295
295
  ```bash
296
- npm install -g @linzumi/cli@0.0.30-beta
296
+ npm install -g @linzumi/cli@0.0.32-beta
297
297
  linzumi --version
298
298
  ```
299
299
 
@@ -316,7 +316,7 @@ linzumi connect \
316
316
  ### All the flags
317
317
 
318
318
  ```text
319
- --agent-token-file <path> Agent token cache for `linzumi commander`
319
+ --agent-token-file <path> Bootstrap token cache for `linzumi commander`
320
320
  --oauth-callback-host <ip> Sign-in callback host your browser can reach
321
321
  --codex-bin <path> Codex executable, default `codex`
322
322
  --model <name> Model requested for Codex sessions and labelled in Linzumi
package/dist/index.js CHANGED
@@ -1382,6 +1382,9 @@ function reviewPortForwardCandidate(options) {
1382
1382
  if (options.suppressedPorts?.has(options.candidate.port) === true) {
1383
1383
  return { type: "skip", reason: "suppressed_port" };
1384
1384
  }
1385
+ if (isInternalCodexProcess(options.candidate)) {
1386
+ return { type: "skip", reason: "internal_codex_process" };
1387
+ }
1385
1388
  const dismissedTarget = options.dismissedTargets?.get(options.candidate.port);
1386
1389
  if (dismissedTarget !== undefined && sameDismissedPortForwardTarget(dismissedTarget, options.candidate)) {
1387
1390
  return { type: "skip", reason: "recently_dismissed" };
@@ -1467,6 +1470,9 @@ function revocationCapabilities(capabilities, port) {
1467
1470
  function sameDismissedPortForwardTarget(left, right) {
1468
1471
  return left.port === right.port && left.command === right.command && left.cwd === right.cwd;
1469
1472
  }
1473
+ function isInternalCodexProcess(candidate) {
1474
+ return commandLabel(candidate.command) === "codex";
1475
+ }
1470
1476
 
1471
1477
  // src/channelSession.ts
1472
1478
  var codexTypingHeartbeatMs = 5000;
@@ -7759,6 +7765,8 @@ async function runClaim(command, deps) {
7759
7765
  const tokenFile = {
7760
7766
  apiUrl: command.apiUrl,
7761
7767
  agentToken: requiredString(response, "agent_token"),
7768
+ commanderToken: requiredString(response, "commander_token"),
7769
+ commanderTokenExpiresInSeconds: numberValue2(response.commander_token_expires_in_seconds),
7762
7770
  agentId: requiredString(response, "agent_id"),
7763
7771
  workspaceId: requiredString(response, "workspace_id"),
7764
7772
  workspaceName: stringValue(response.workspace_name),
@@ -7772,7 +7780,7 @@ async function runClaim(command, deps) {
7772
7780
  cursors: {}
7773
7781
  };
7774
7782
  writeTokenFile(command.tokenFile, tokenFile, deps.writeTextFile);
7775
- deps.stdout.write(`Logged in as agent ${tokenFile.agentId}
7783
+ deps.stdout.write(`Logged in as ${tokenFile.ownerUsername ?? "claimed user"}
7776
7784
  `);
7777
7785
  if (tokenFile.workspaceName !== undefined) {
7778
7786
  deps.stdout.write(`workspace_name: ${tokenFile.workspaceName}
@@ -8014,6 +8022,8 @@ function readStoredAgentTokenFile(path, readTextFile = readOptionalTextFile) {
8014
8022
  return {
8015
8023
  apiUrl: requiredString(parsed, "apiUrl"),
8016
8024
  agentToken: requiredString(parsed, "agentToken"),
8025
+ commanderToken: requiredString(parsed, "commanderToken"),
8026
+ commanderTokenExpiresInSeconds: numberValue2(parsed.commanderTokenExpiresInSeconds),
8017
8027
  agentId: requiredString(parsed, "agentId"),
8018
8028
  workspaceId: requiredString(parsed, "workspaceId"),
8019
8029
  workspaceName: stringValue(parsed.workspaceName),
@@ -8912,7 +8922,7 @@ async function main(args) {
8912
8922
  process.stdout.write(connectGuideText());
8913
8923
  return;
8914
8924
  case "version":
8915
- process.stdout.write(`linzumi 0.0.30-beta
8925
+ process.stdout.write(`linzumi 0.0.32-beta
8916
8926
  `);
8917
8927
  return;
8918
8928
  case "auth":
@@ -9308,7 +9318,7 @@ async function parseAgentRunnerArgs(args, deps = {
9308
9318
  assertStartDependencies(initialDependencyStatus);
9309
9319
  const editorRuntime = await deps.resolveEditorRuntime({
9310
9320
  kandanUrl,
9311
- token: tokenFile.agentToken,
9321
+ token: tokenFile.commanderToken,
9312
9322
  customCodeServerBin,
9313
9323
  fetchImpl: trustedFetch(kandanTlsTrustFromEnv())
9314
9324
  });
@@ -9321,7 +9331,7 @@ async function parseAgentRunnerArgs(args, deps = {
9321
9331
  assertStartDependencies(dependencyStatus);
9322
9332
  return {
9323
9333
  kandanUrl,
9324
- token: tokenFile.agentToken,
9334
+ token: tokenFile.commanderToken,
9325
9335
  runnerId: stringValue3(values, "runner-id") ?? `agent-runner-${randomUUID3()}`,
9326
9336
  cwd,
9327
9337
  codexBin,
@@ -9352,9 +9362,15 @@ function readAgentTokenTextFile(path) {
9352
9362
  return existsSync10(path) ? readFileSync9(path, "utf8") : undefined;
9353
9363
  }
9354
9364
  function rejectAgentRunnerTargetingFlags(values) {
9355
- const unsupportedFlags = ["workspace", "channel", "token", "auth-file", "oauth-callback-host"].filter((flag) => values.has(flag));
9365
+ const unsupportedFlags = [
9366
+ "workspace",
9367
+ "channel",
9368
+ "token",
9369
+ "auth-file",
9370
+ "oauth-callback-host"
9371
+ ].filter((flag) => values.has(flag));
9356
9372
  if (unsupportedFlags.length > 0) {
9357
- throw new Error(`linzumi commander uses the claimed agent token scope; remove ${unsupportedFlags.map((flag) => `--${flag}`).join(", ")}.`);
9373
+ throw new Error(`linzumi commander uses the claimed human Commander token scope; remove ${unsupportedFlags.map((flag) => `--${flag}`).join(", ")}.`);
9358
9374
  }
9359
9375
  }
9360
9376
  function requiredStoredAgentChannel(channelId) {
@@ -9419,7 +9435,7 @@ async function parseRunnerArgs(args, deps = {
9419
9435
  process.exit(0);
9420
9436
  }
9421
9437
  if (values.get("version") === true) {
9422
- process.stdout.write(`linzumi 0.0.30-beta
9438
+ process.stdout.write(`linzumi 0.0.32-beta
9423
9439
  `);
9424
9440
  process.exit(0);
9425
9441
  }
@@ -9846,7 +9862,7 @@ Usage:
9846
9862
  linzumi agent runner <folder> [options]
9847
9863
 
9848
9864
  What it does:
9849
- Starts this computer as the claimed agent's scoped Linzumi Commander. The command
9865
+ Starts this computer as the claimed human's scoped Linzumi Commander. The command
9850
9866
  reads ~/.linzumi/agent-token.json, uses its workspace/channel scope, reads
9851
9867
  trusted folders from ~/.linzumi/config.json when no folder is passed, and
9852
9868
  listens only to the owning human recorded during claim unless --listen-user is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linzumi/cli",
3
- "version": "0.0.30-beta",
3
+ "version": "0.0.32-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": {